diff -r 34716fd837a4 -r be944660c56a wp/wp-admin/js/nav-menu.js --- a/wp/wp-admin/js/nav-menu.js Tue Dec 15 15:52:01 2020 +0100 +++ b/wp/wp-admin/js/nav-menu.js Wed Sep 21 18:19:35 2022 +0200 @@ -45,6 +45,11 @@ this.attachMenuEditListeners(); + this.attachBulkSelectButtonListeners(); + this.attachMenuCheckBoxListeners(); + this.attachMenuItemDeleteButton(); + this.attachPendingMenuItemsListForDeletion(); + this.attachQuickSearchListeners(); this.attachThemeLocationsListeners(); this.attachMenuSaveSubmitListeners(); @@ -390,7 +395,7 @@ thisItem.shiftHorizontally( 1 ); break; } - $this.focus(); + $this.trigger( 'focus' ); api.registerChange(); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); @@ -572,7 +577,7 @@ break; } // Put focus back on same menu item. - $( '#edit-' + thisItemData['menu-item-db-id'] ).focus(); + $( '#edit-' + thisItemData['menu-item-db-id'] ).trigger( 'focus' ); return false; }); }); @@ -608,7 +613,7 @@ // Hide fields. api.menuList.hideAdvancedMenuItemFields(); - $('.hide-postbox-tog').click(function () { + $('.hide-postbox-tog').on( 'click', function () { var hidden = $( '.accordion-container li.accordion-section' ).filter(':hidden').map(function() { return this.id; }).get().join(','); $.post(ajaxurl, { action: 'closed-postboxes', @@ -809,7 +814,7 @@ }, initManageLocations : function () { - $('#menu-locations-wrap form').submit(function(){ + $('#menu-locations-wrap form').on( 'submit', function(){ window.onbeforeunload = null; }); $('.menu-location-menus select').on('change', function () { @@ -823,7 +828,7 @@ attachMenuEditListeners : function() { var that = this; - $('#update-nav-menu').bind('click', function(e) { + $('#update-nav-menu').on('click', function(e) { if ( e.target && e.target.className ) { if ( -1 != e.target.className.indexOf('item-edit') ) { return that.eventOnClickEditLink(e.target); @@ -852,22 +857,212 @@ } }, 500 ) ); - $('#add-custom-links input[type="text"]').keypress(function(e){ + $('#add-custom-links input[type="text"]').on( 'keypress', function(e){ $('#customlinkdiv').removeClass('form-invalid'); if ( e.keyCode === 13 ) { e.preventDefault(); - $( '#submit-customlinkdiv' ).click(); + $( '#submit-customlinkdiv' ).trigger( 'click' ); + } + }); + }, + + /** + * Handle toggling bulk selection checkboxes for menu items. + * + * @since 5.8.0 + */ + attachBulkSelectButtonListeners : function() { + var that = this; + + $( '.bulk-select-switcher' ).on( 'change', function() { + if ( this.checked ) { + $( '.bulk-select-switcher' ).prop( 'checked', true ); + that.enableBulkSelection(); + } else { + $( '.bulk-select-switcher' ).prop( 'checked', false ); + that.disableBulkSelection(); } }); }, + /** + * Enable bulk selection checkboxes for menu items. + * + * @since 5.8.0 + */ + enableBulkSelection : function() { + var checkbox = $( '#menu-to-edit .menu-item-checkbox' ); + + $( '#menu-to-edit' ).addClass( 'bulk-selection' ); + $( '#nav-menu-bulk-actions-top' ).addClass( 'bulk-selection' ); + $( '#nav-menu-bulk-actions-bottom' ).addClass( 'bulk-selection' ); + + $.each( checkbox, function() { + $(this).prop( 'disabled', false ); + }); + }, + + /** + * Disable bulk selection checkboxes for menu items. + * + * @since 5.8.0 + */ + disableBulkSelection : function() { + var checkbox = $( '#menu-to-edit .menu-item-checkbox' ); + + $( '#menu-to-edit' ).removeClass( 'bulk-selection' ); + $( '#nav-menu-bulk-actions-top' ).removeClass( 'bulk-selection' ); + $( '#nav-menu-bulk-actions-bottom' ).removeClass( 'bulk-selection' ); + + if ( $( '.menu-items-delete' ).is( '[aria-describedby="pending-menu-items-to-delete"]' ) ) { + $( '.menu-items-delete' ).removeAttr( 'aria-describedby' ); + } + + $.each( checkbox, function() { + $(this).prop( 'disabled', true ).prop( 'checked', false ); + }); + + $( '.menu-items-delete' ).addClass( 'disabled' ); + $( '#pending-menu-items-to-delete ul' ).empty(); + }, + + /** + * Listen for state changes on bulk action checkboxes. + * + * @since 5.8.0 + */ + attachMenuCheckBoxListeners : function() { + var that = this; + + $( '#menu-to-edit' ).on( 'change', '.menu-item-checkbox', function() { + that.setRemoveSelectedButtonStatus(); + }); + }, + + /** + * Create delete button to remove menu items from collection. + * + * @since 5.8.0 + */ + attachMenuItemDeleteButton : function() { + var that = this; + + $( document ).on( 'click', '.menu-items-delete', function( e ) { + var itemsPendingDeletion, itemsPendingDeletionList, deletionSpeech; + + e.preventDefault(); + + if ( ! $(this).hasClass( 'disabled' ) ) { + $.each( $( '.menu-item-checkbox:checked' ), function( index, element ) { + $( element ).parents( 'li' ).find( 'a.item-delete' ).trigger( 'click' ); + }); + + $( '.menu-items-delete' ).addClass( 'disabled' ); + $( '.bulk-select-switcher' ).prop( 'checked', false ); + + itemsPendingDeletion = ''; + itemsPendingDeletionList = $( '#pending-menu-items-to-delete ul li' ); + + $.each( itemsPendingDeletionList, function( index, element ) { + var itemName = $( element ).find( '.pending-menu-item-name' ).text(); + var itemSpeech = menus.menuItemDeletion.replace( '%s', itemName ); + + itemsPendingDeletion += itemSpeech; + if ( ( index + 1 ) < itemsPendingDeletionList.length ) { + itemsPendingDeletion += ', '; + } + }); + + deletionSpeech = menus.itemsDeleted.replace( '%s', itemsPendingDeletion ); + wp.a11y.speak( deletionSpeech, 'polite' ); + that.disableBulkSelection(); + } + }); + }, + + /** + * List menu items awaiting deletion. + * + * @since 5.8.0 + */ + attachPendingMenuItemsListForDeletion : function() { + $( '#post-body-content' ).on( 'change', '.menu-item-checkbox', function() { + var menuItemName, menuItemType, menuItemID, listedMenuItem; + + if ( ! $( '.menu-items-delete' ).is( '[aria-describedby="pending-menu-items-to-delete"]' ) ) { + $( '.menu-items-delete' ).attr( 'aria-describedby', 'pending-menu-items-to-delete' ); + } + + menuItemName = $(this).next().text(); + menuItemType = $(this).parent().next( '.item-controls' ).find( '.item-type' ).text(); + menuItemID = $(this).attr( 'data-menu-item-id' ); + + listedMenuItem = $( '#pending-menu-items-to-delete ul' ).find( '[data-menu-item-id=' + menuItemID + ']' ); + if ( listedMenuItem.length > 0 ) { + listedMenuItem.remove(); + } + + if ( this.checked === true ) { + $( '#pending-menu-items-to-delete ul' ).append( + '
  • ' + + '' + menuItemName + ' ' + + '(' + menuItemType + ')' + + '' + + '
  • ' + ); + } + + $( '#pending-menu-items-to-delete li .separator' ).html( ', ' ); + $( '#pending-menu-items-to-delete li .separator' ).last().html( '.' ); + }); + }, + + /** + * Set status of bulk delete checkbox. + * + * @since 5.8.0 + */ + setBulkDeleteCheckboxStatus : function() { + var that = this; + var checkbox = $( '#menu-to-edit .menu-item-checkbox' ); + + $.each( checkbox, function() { + if ( $(this).prop( 'disabled' ) ) { + $(this).prop( 'disabled', false ); + } else { + $(this).prop( 'disabled', true ); + } + + if ( $(this).is( ':checked' ) ) { + $(this).prop( 'checked', false ); + } + }); + + that.setRemoveSelectedButtonStatus(); + }, + + /** + * Set status of menu items removal button. + * + * @since 5.8.0 + */ + setRemoveSelectedButtonStatus : function() { + var button = $( '.menu-items-delete' ); + + if ( $( '.menu-item-checkbox:checked' ).length > 0 ) { + button.removeClass( 'disabled' ); + } else { + button.addClass( 'disabled' ); + } + }, + attachMenuSaveSubmitListeners : function() { /* * When a navigation menu is saved, store a JSON representation of all form data * in a single input to avoid PHP `max_input_vars` limitations. See #14134. */ - $( '#update-nav-menu' ).submit( function() { + $( '#update-nav-menu' ).on( 'submit', function() { var navMenuData = $( '#update-nav-menu' ).serializeArray(); $( '[name="nav-menu-data"]' ).val( JSON.stringify( navMenuData ) ); }); @@ -877,7 +1072,7 @@ var loc = $('#nav-menu-theme-locations'), params = {}; params.action = 'menu-locations-save'; params['menu-settings-column-nonce'] = $('#menu-settings-column-nonce').val(); - loc.find('input[type="submit"]').click(function() { + loc.find('input[type="submit"]').on( 'click', function() { loc.find('select').each(function() { params[this.name] = $(this).val(); }); @@ -908,7 +1103,7 @@ searchTimer = setTimeout( function() { api.updateQuickSearchResults( $this ); - }, 500 ); + }, 500 ); }).on( 'blur', '.quick-search', function() { api.lastSearch = ''; }); @@ -947,9 +1142,13 @@ }, addCustomLink : function( processMethod ) { - var url = $('#custom-menu-item-url').val().trim(), + var url = $('#custom-menu-item-url').val().toString(), label = $('#custom-menu-item-name').val(); + if ( '' !== url ) { + url = url.trim(); + } + processMethod = processMethod || api.addMenuItemToBottom; if ( '' === url || 'https://' == url || 'http://' == url ) { @@ -963,7 +1162,7 @@ // Remove the Ajax spinner. $( '.customlinkdiv .spinner' ).removeClass( 'is-active' ); // Set custom link form back to defaults. - $('#custom-menu-item-name').val('').blur(); + $('#custom-menu-item-name').val('').trigger( 'blur' ); $( '#custom-menu-item-url' ).val( '' ).attr( 'placeholder', 'https://' ); }); }, @@ -999,7 +1198,8 @@ $.post( ajaxurl, params, function(menuMarkup) { var ins = $('#menu-instructions'); - menuMarkup = $.trim( menuMarkup ); // Trim leading whitespaces. + menuMarkup = menuMarkup || ''; + menuMarkup = menuMarkup.toString().trim(); // Trim leading whitespaces. processMethod(menuMarkup, params); // Make it stand out a bit more visually, by adding a fadeIn. @@ -1043,7 +1243,7 @@ }, attachUnsavedChangesListener : function() { - $('#menu-management input, #menu-management select, #menu-management, #menu-management textarea, .menu-location-menus select').change(function(){ + $('#menu-management input, #menu-management select, #menu-management, #menu-management textarea, .menu-location-menus select').on( 'change', function(){ api.registerChange(); }); @@ -1054,7 +1254,7 @@ }; } else { // Make the post boxes read-only, as they can't be used yet. - $( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).unbind( 'click' ); + $( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).off( 'click' ); } }, @@ -1063,7 +1263,7 @@ }, attachTabsPanelListeners : function() { - $('#menu-settings-column').bind('click', function(e) { + $('#menu-settings-column').on('click', function(e) { var selectAreaMatch, selectAll, panelId, wrapper, items, target = $(e.target); @@ -1083,7 +1283,7 @@ target.parent().addClass('tabs'); // Select the search bar. - $('.quick-search', wrapper).focus(); + $('.quick-search', wrapper).trigger( 'focus' ); // Hide controls in the search tab if no items found. if ( ! wrapper.find( '.tabs-panel-active .menu-item-title' ).length ) { @@ -1136,7 +1336,7 @@ $.post( ajaxurl, this.href.replace( /.*\?/, '' ).replace( /action=([^&]*)/, '' ) + '&action=menu-get-metabox', function( resp ) { - var metaBoxData = $.parseJSON( resp ), + var metaBoxData = JSON.parse( resp ), toReplace; if ( -1 === resp.indexOf( 'replace-id' ) ) { @@ -1326,6 +1526,27 @@ }; - $(document).ready(function(){ wpNavMenu.init(); }); + $( function() { + + wpNavMenu.init(); + + // Prevent focused element from being hidden by the sticky footer. + $( '.menu-edit a, .menu-edit button, .menu-edit input, .menu-edit textarea, .menu-edit select' ).on('focus', function() { + if ( window.innerWidth >= 783 ) { + var navMenuHeight = $( '#nav-menu-footer' ).height() + 20; + var bottomOffset = $(this).offset().top - ( $(window).scrollTop() + $(window).height() - $(this).height() ); + + if ( bottomOffset > 0 ) { + bottomOffset = 0; + } + bottomOffset = bottomOffset * -1; + + if( bottomOffset < navMenuHeight ) { + var scrollTop = $(document).scrollTop(); + $(document).scrollTop( scrollTop + ( navMenuHeight - bottomOffset ) ); + } + } + }); + }); })(jQuery);