wp/wp-admin/js/nav-menu.js
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     7  * @package WordPress
     7  * @package WordPress
     8  * @subpackage Administration
     8  * @subpackage Administration
     9  * @output wp-admin/js/nav-menu.js
     9  * @output wp-admin/js/nav-menu.js
    10  */
    10  */
    11 
    11 
    12 /* global menus, postboxes, columns, isRtl, navMenuL10n, ajaxurl, wpNavMenu */
    12 /* global menus, postboxes, columns, isRtl, ajaxurl, wpNavMenu */
    13 
    13 
    14 (function($) {
    14 (function($) {
    15 
    15 
    16 	var api;
    16 	var api;
    17 
    17 
    67 
    67 
    68 			this.initPreviewing();
    68 			this.initPreviewing();
    69 		},
    69 		},
    70 
    70 
    71 		jQueryExtensions : function() {
    71 		jQueryExtensions : function() {
    72 			// jQuery extensions
    72 			// jQuery extensions.
    73 			$.fn.extend({
    73 			$.fn.extend({
    74 				menuItemDepth : function() {
    74 				menuItemDepth : function() {
    75 					var margin = api.isRTL ? this.eq(0).css('margin-right') : this.eq(0).css('margin-left');
    75 					var margin = api.isRTL ? this.eq(0).css('margin-right') : this.eq(0).css('margin-left');
    76 					return api.pxToDepth( margin && -1 != margin.indexOf('px') ? margin.slice(0, -2) : 0 );
    76 					return api.pxToDepth( margin && -1 != margin.indexOf('px') ? margin.slice(0, -2) : 0 );
    77 				},
    77 				},
   112 					return this.each(function(){
   112 					return this.each(function(){
   113 						var t = $(this),
   113 						var t = $(this),
   114 							depth = t.menuItemDepth(),
   114 							depth = t.menuItemDepth(),
   115 							newDepth = depth + dir;
   115 							newDepth = depth + dir;
   116 
   116 
   117 						// Change .menu-item-depth-n class
   117 						// Change .menu-item-depth-n class.
   118 						t.moveHorizontally( newDepth, depth );
   118 						t.moveHorizontally( newDepth, depth );
   119 					});
   119 					});
   120 				},
   120 				},
   121 				moveHorizontally : function( newDepth, depth ) {
   121 				moveHorizontally : function( newDepth, depth ) {
   122 					return this.each(function(){
   122 					return this.each(function(){
   123 						var t = $(this),
   123 						var t = $(this),
   124 							children = t.childMenuItems(),
   124 							children = t.childMenuItems(),
   125 							diff = newDepth - depth,
   125 							diff = newDepth - depth,
   126 							subItemText = t.find('.is-submenu');
   126 							subItemText = t.find('.is-submenu');
   127 
   127 
   128 						// Change .menu-item-depth-n class
   128 						// Change .menu-item-depth-n class.
   129 						t.updateDepthClass( newDepth, depth ).updateParentMenuItemDBId();
   129 						t.updateDepthClass( newDepth, depth ).updateParentMenuItemDBId();
   130 
   130 
   131 						// If it has children, move those too
   131 						// If it has children, move those too.
   132 						if ( children ) {
   132 						if ( children ) {
   133 							children.each(function() {
   133 							children.each(function() {
   134 								var t = $(this),
   134 								var t = $(this),
   135 									thisDepth = t.menuItemDepth(),
   135 									thisDepth = t.menuItemDepth(),
   136 									newDepth = thisDepth + diff;
   136 									newDepth = thisDepth + diff;
   137 								t.updateDepthClass(newDepth, thisDepth).updateParentMenuItemDBId();
   137 								t.updateDepthClass(newDepth, thisDepth).updateParentMenuItemDBId();
   138 							});
   138 							});
   139 						}
   139 						}
   140 
   140 
   141 						// Show "Sub item" helper text
   141 						// Show "Sub item" helper text.
   142 						if (0 === newDepth)
   142 						if (0 === newDepth)
   143 							subItemText.hide();
   143 							subItemText.hide();
   144 						else
   144 						else
   145 							subItemText.show();
   145 							subItemText.show();
   146 					});
   146 					});
   151 							input = item.find( '.menu-item-data-parent-id' ),
   151 							input = item.find( '.menu-item-data-parent-id' ),
   152 							depth = parseInt( item.menuItemDepth(), 10 ),
   152 							depth = parseInt( item.menuItemDepth(), 10 ),
   153 							parentDepth = depth - 1,
   153 							parentDepth = depth - 1,
   154 							parent = item.prevAll( '.menu-item-depth-' + parentDepth ).first();
   154 							parent = item.prevAll( '.menu-item-depth-' + parentDepth ).first();
   155 
   155 
   156 						if ( 0 === depth ) { // Item is on the top level, has no parent
   156 						if ( 0 === depth ) { // Item is on the top level, has no parent.
   157 							input.val(0);
   157 							input.val(0);
   158 						} else { // Find the parent item, and retrieve its object id.
   158 						} else { // Find the parent item, and retrieve its object id.
   159 							input.val( parent.find( '.menu-item-data-db-id' ).val() );
   159 							input.val( parent.find( '.menu-item-data-db-id' ).val() );
   160 						}
   160 						}
   161 					});
   161 					});
   189 
   189 
   190 						// If no items are checked, bail.
   190 						// If no items are checked, bail.
   191 						if ( !checkboxes.length )
   191 						if ( !checkboxes.length )
   192 							return false;
   192 							return false;
   193 
   193 
   194 						// Show the ajax spinner
   194 						// Show the Ajax spinner.
   195 						t.find( '.button-controls .spinner' ).addClass( 'is-active' );
   195 						t.find( '.button-controls .spinner' ).addClass( 'is-active' );
   196 
   196 
   197 						// Retrieve menu item data
   197 						// Retrieve menu item data.
   198 						$(checkboxes).each(function(){
   198 						$(checkboxes).each(function(){
   199 							var t = $(this),
   199 							var t = $(this),
   200 								listItemDBIDMatch = re.exec( t.attr('name') ),
   200 								listItemDBIDMatch = re.exec( t.attr('name') ),
   201 								listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10);
   201 								listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10);
   202 
   202 
   203 							if ( this.className && -1 != this.className.indexOf('add-to-top') )
   203 							if ( this.className && -1 != this.className.indexOf('add-to-top') )
   204 								processMethod = api.addMenuItemToTop;
   204 								processMethod = api.addMenuItemToTop;
   205 							menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID );
   205 							menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID );
   206 						});
   206 						});
   207 
   207 
   208 						// Add the items
   208 						// Add the items.
   209 						api.addItemToMenu(menuItems, processMethod, function(){
   209 						api.addItemToMenu(menuItems, processMethod, function(){
   210 							// Deselect the items and hide the ajax spinner
   210 							// Deselect the items and hide the Ajax spinner.
   211 							checkboxes.removeAttr('checked');
   211 							checkboxes.prop( 'checked', false );
       
   212 							t.find( '.button-controls .select-all' ).prop( 'checked', false );
   212 							t.find( '.button-controls .spinner' ).removeClass( 'is-active' );
   213 							t.find( '.button-controls .spinner' ).removeClass( 'is-active' );
   213 						});
   214 						});
   214 					});
   215 					});
   215 				},
   216 				},
   216 				getItemData : function( itemType, id ) {
   217 				getItemData : function( itemType, id ) {
   309 
   310 
   310 			switch ( dir ) {
   311 			switch ( dir ) {
   311 			case 'up':
   312 			case 'up':
   312 				newItemPosition = thisItemPosition - 1;
   313 				newItemPosition = thisItemPosition - 1;
   313 
   314 
   314 				// Already at top
   315 				// Already at top.
   315 				if ( 0 === thisItemPosition )
   316 				if ( 0 === thisItemPosition )
   316 					break;
   317 					break;
   317 
   318 
   318 				// If a sub item is moved to top, shift it to 0 depth
   319 				// If a sub item is moved to top, shift it to 0 depth.
   319 				if ( 0 === newItemPosition && 0 !== thisItemDepth )
   320 				if ( 0 === newItemPosition && 0 !== thisItemDepth )
   320 					thisItem.moveHorizontally( 0, thisItemDepth );
   321 					thisItem.moveHorizontally( 0, thisItemDepth );
   321 
   322 
   322 				// If prev item is sub item, shift to match depth
   323 				// If prev item is sub item, shift to match depth.
   323 				if ( 0 !== prevItemDepth )
   324 				if ( 0 !== prevItemDepth )
   324 					thisItem.moveHorizontally( prevItemDepth, thisItemDepth );
   325 					thisItem.moveHorizontally( prevItemDepth, thisItemDepth );
   325 
   326 
   326 				// Does this item have sub items?
   327 				// Does this item have sub items?
   327 				if ( thisItemChildren ) {
   328 				if ( thisItemChildren ) {
   328 					items = thisItem.add( thisItemChildren );
   329 					items = thisItem.add( thisItemChildren );
   329 					// Move the entire block
   330 					// Move the entire block.
   330 					items.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId();
   331 					items.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId();
   331 				} else {
   332 				} else {
   332 					thisItem.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId();
   333 					thisItem.detach().insertBefore( menuItems.eq( newItemPosition ) ).updateParentMenuItemDBId();
   333 				}
   334 				}
   334 				break;
   335 				break;
   348 					if ( menuItemsCount === thisItemPosition + items.length )
   349 					if ( menuItemsCount === thisItemPosition + items.length )
   349 						break;
   350 						break;
   350 
   351 
   351 					items.detach().insertAfter( menuItems.eq( thisItemPosition + items.length ) ).updateParentMenuItemDBId();
   352 					items.detach().insertAfter( menuItems.eq( thisItemPosition + items.length ) ).updateParentMenuItemDBId();
   352 				} else {
   353 				} else {
   353 					// If next item has sub items, shift depth
   354 					// If next item has sub items, shift depth.
   354 					if ( 0 !== nextItemChildren.length )
   355 					if ( 0 !== nextItemChildren.length )
   355 						thisItem.moveHorizontally( nextItemDepth, thisItemDepth );
   356 						thisItem.moveHorizontally( nextItemDepth, thisItemDepth );
   356 
   357 
   357 					// Have we reached the bottom
   358 					// Have we reached the bottom?
   358 					if ( menuItemsCount === thisItemPosition + 1 )
   359 					if ( menuItemsCount === thisItemPosition + 1 )
   359 						break;
   360 						break;
   360 					thisItem.detach().insertAfter( menuItems.eq( thisItemPosition + 1 ) ).updateParentMenuItemDBId();
   361 					thisItem.detach().insertAfter( menuItems.eq( thisItemPosition + 1 ) ).updateParentMenuItemDBId();
   361 				}
   362 				}
   362 				break;
   363 				break;
   363 			case 'top':
   364 			case 'top':
   364 				// Already at top
   365 				// Already at top.
   365 				if ( 0 === thisItemPosition )
   366 				if ( 0 === thisItemPosition )
   366 					break;
   367 					break;
   367 				// Does this item have sub items?
   368 				// Does this item have sub items?
   368 				if ( thisItemChildren ) {
   369 				if ( thisItemChildren ) {
   369 					items = thisItem.add( thisItemChildren );
   370 					items = thisItem.add( thisItemChildren );
   370 					// Move the entire block
   371 					// Move the entire block.
   371 					items.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId();
   372 					items.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId();
   372 				} else {
   373 				} else {
   373 					thisItem.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId();
   374 					thisItem.detach().insertBefore( menuItems.eq( 0 ) ).updateParentMenuItemDBId();
   374 				}
   375 				}
   375 				break;
   376 				break;
   376 			case 'left':
   377 			case 'left':
   377 				// As far left as possible
   378 				// As far left as possible.
   378 				if ( 0 === thisItemDepth )
   379 				if ( 0 === thisItemDepth )
   379 					break;
   380 					break;
   380 				thisItem.shiftHorizontally( -1 );
   381 				thisItem.shiftHorizontally( -1 );
   381 				break;
   382 				break;
   382 			case 'right':
   383 			case 'right':
   383 				// Can't be sub item at top
   384 				// Can't be sub item at top.
   384 				if ( 0 === thisItemPosition )
   385 				if ( 0 === thisItemPosition )
   385 					break;
   386 					break;
   386 				// Already sub item of prevItem
   387 				// Already sub item of prevItem.
   387 				if ( thisItemData['menu-item-parent-id'] === prevItemId )
   388 				if ( thisItemData['menu-item-parent-id'] === prevItemId )
   388 					break;
   389 					break;
   389 				thisItem.shiftHorizontally( 1 );
   390 				thisItem.shiftHorizontally( 1 );
   390 				break;
   391 				break;
   391 			}
   392 			}
   399 			var menu = $( '#menu-to-edit' );
   400 			var menu = $( '#menu-to-edit' );
   400 
   401 
   401 			api.refreshKeyboardAccessibility();
   402 			api.refreshKeyboardAccessibility();
   402 			api.refreshAdvancedAccessibility();
   403 			api.refreshAdvancedAccessibility();
   403 
   404 
   404 			// Refresh the accessibility when the user comes close to the item in any way
   405 			// Refresh the accessibility when the user comes close to the item in any way.
   405 			menu.on( 'mouseenter.refreshAccessibility focus.refreshAccessibility touchstart.refreshAccessibility' , '.menu-item' , function(){
   406 			menu.on( 'mouseenter.refreshAccessibility focus.refreshAccessibility touchstart.refreshAccessibility' , '.menu-item' , function(){
   406 				api.refreshAdvancedAccessibilityOfItem( $( this ).find( 'a.item-edit' ) );
   407 				api.refreshAdvancedAccessibilityOfItem( $( this ).find( 'a.item-edit' ) );
   407 			} );
   408 			} );
   408 
   409 
   409 			// We have to update on click as well because we might hover first, change the item, and then click.
   410 			// We have to update on click as well because we might hover first, change the item, and then click.
   410 			menu.on( 'click', 'a.item-edit', function() {
   411 			menu.on( 'click', 'a.item-edit', function() {
   411 				api.refreshAdvancedAccessibilityOfItem( $( this ) );
   412 				api.refreshAdvancedAccessibilityOfItem( $( this ) );
   412 			} );
   413 			} );
   413 
   414 
   414 			// Links for moving items
   415 			// Links for moving items.
   415 			menu.on( 'click', '.menus-move', function () {
   416 			menu.on( 'click', '.menus-move', function () {
   416 				var $this = $( this ),
   417 				var $this = $( this ),
   417 					dir = $this.data( 'dir' );
   418 					dir = $this.data( 'dir' );
   418 
   419 
   419 				if ( 'undefined' !== typeof dir ) {
   420 				if ( 'undefined' !== typeof dir ) {
   426 		 * refreshAdvancedAccessibilityOfItem( [itemToRefresh] )
   427 		 * refreshAdvancedAccessibilityOfItem( [itemToRefresh] )
   427 		 *
   428 		 *
   428 		 * Refreshes advanced accessibility buttons for one menu item.
   429 		 * Refreshes advanced accessibility buttons for one menu item.
   429 		 * Shows or hides buttons based on the location of the menu item.
   430 		 * Shows or hides buttons based on the location of the menu item.
   430 		 *
   431 		 *
   431 		 * @param  {object} itemToRefresh The menu item that might need its advanced accessibility buttons refreshed
   432 		 * @param {Object} itemToRefresh The menu item that might need its advanced accessibility buttons refreshed
   432 		 */
   433 		 */
   433 		refreshAdvancedAccessibilityOfItem : function( itemToRefresh ) {
   434 		refreshAdvancedAccessibilityOfItem : function( itemToRefresh ) {
   434 
   435 
   435 			// Only refresh accessibility when necessary
   436 			// Only refresh accessibility when necessary.
   436 			if ( true !== $( itemToRefresh ).data( 'needs_accessibility_refresh' ) ) {
   437 			if ( true !== $( itemToRefresh ).data( 'needs_accessibility_refresh' ) ) {
   437 				return;
   438 				return;
   438 			}
   439 			}
   439 
   440 
   440 			var thisLink, thisLinkText, primaryItems, itemPosition, title,
   441 			var thisLink, thisLinkText, primaryItems, itemPosition, title,
   491 			if ( isPrimaryMenuItem ) {
   492 			if ( isPrimaryMenuItem ) {
   492 				primaryItems = $( '.menu-item-depth-0' ),
   493 				primaryItems = $( '.menu-item-depth-0' ),
   493 				itemPosition = primaryItems.index( menuItem ) + 1,
   494 				itemPosition = primaryItems.index( menuItem ) + 1,
   494 				totalMenuItems = primaryItems.length,
   495 				totalMenuItems = primaryItems.length,
   495 
   496 
   496 				// String together help text for primary menu items
   497 				// String together help text for primary menu items.
   497 				title = menus.menuFocus.replace( '%1$s', itemName ).replace( '%2$d', itemPosition ).replace( '%3$d', totalMenuItems );
   498 				title = menus.menuFocus.replace( '%1$s', itemName ).replace( '%2$d', itemPosition ).replace( '%3$d', totalMenuItems );
   498 			} else {
   499 			} else {
   499 				parentItem = menuItem.prevAll( '.menu-item-depth-' + parseInt( depth - 1, 10 ) ).first(),
   500 				parentItem = menuItem.prevAll( '.menu-item-depth-' + parseInt( depth - 1, 10 ) ).first(),
   500 				parentItemId = parentItem.find( '.menu-item-data-db-id' ).val(),
   501 				parentItemId = parentItem.find( '.menu-item-data-db-id' ).val(),
   501 				parentItemName = parentItem.find( '.menu-item-title' ).text(),
   502 				parentItemName = parentItem.find( '.menu-item-title' ).text(),
   502 				subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemId + '"]' ),
   503 				subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemId + '"]' ),
   503 				itemPosition = $( subItems.parents('.menu-item').get().reverse() ).index( menuItem ) + 1;
   504 				itemPosition = $( subItems.parents('.menu-item').get().reverse() ).index( menuItem ) + 1;
   504 
   505 
   505 				// String together help text for sub menu items
   506 				// String together help text for sub menu items.
   506 				title = menus.subMenuFocus.replace( '%1$s', itemName ).replace( '%2$d', itemPosition ).replace( '%3$s', parentItemName );
   507 				title = menus.subMenuFocus.replace( '%1$s', itemName ).replace( '%2$d', itemPosition ).replace( '%3$s', parentItemName );
   507 			}
   508 			}
   508 
   509 
   509 			$this.attr( 'aria-label', title );
   510 			$this.attr( 'aria-label', title );
   510 
   511 
   511 			// Mark this item's accessibility as refreshed
   512 			// Mark this item's accessibility as refreshed.
   512 			$this.data( 'needs_accessibility_refresh', false );
   513 			$this.data( 'needs_accessibility_refresh', false );
   513 		},
   514 		},
   514 
   515 
   515 		/**
   516 		/**
   516 		 * refreshAdvancedAccessibility
   517 		 * refreshAdvancedAccessibility
   520 		refreshAdvancedAccessibility : function() {
   521 		refreshAdvancedAccessibility : function() {
   521 
   522 
   522 			// Hide all the move buttons by default.
   523 			// Hide all the move buttons by default.
   523 			$( '.menu-item-settings .field-move .menus-move' ).hide();
   524 			$( '.menu-item-settings .field-move .menus-move' ).hide();
   524 
   525 
   525 			// Mark all menu items as unprocessed
   526 			// Mark all menu items as unprocessed.
   526 			$( 'a.item-edit' ).data( 'needs_accessibility_refresh', true );
   527 			$( 'a.item-edit' ).data( 'needs_accessibility_refresh', true );
   527 
   528 
   528 			// All open items have to be refreshed or they will show no links
   529 			// All open items have to be refreshed or they will show no links.
   529 			$( '.menu-item-edit-active a.item-edit' ).each( function() {
   530 			$( '.menu-item-edit-active a.item-edit' ).each( function() {
   530 				api.refreshAdvancedAccessibilityOfItem( this );
   531 				api.refreshAdvancedAccessibilityOfItem( this );
   531 			} );
   532 			} );
   532 		},
   533 		},
   533 
   534 
   538 					var arrows,
   539 					var arrows,
   539 						$this = $( this ),
   540 						$this = $( this ),
   540 						thisItem = $this.parents( 'li.menu-item' ),
   541 						thisItem = $this.parents( 'li.menu-item' ),
   541 						thisItemData = thisItem.getItemData();
   542 						thisItemData = thisItem.getItemData();
   542 
   543 
   543 					// Bail if it's not an arrow key
   544 					// Bail if it's not an arrow key.
   544 					if ( 37 != e.which && 38 != e.which && 39 != e.which && 40 != e.which )
   545 					if ( 37 != e.which && 38 != e.which && 39 != e.which && 40 != e.which )
   545 						return;
   546 						return;
   546 
   547 
   547 					// Avoid multiple keydown events
   548 					// Avoid multiple keydown events.
   548 					$this.off('keydown');
   549 					$this.off('keydown');
   549 
   550 
   550 					// Bail if there is only one menu item
   551 					// Bail if there is only one menu item.
   551 					if ( 1 === $('#menu-to-edit li').length )
   552 					if ( 1 === $('#menu-to-edit li').length )
   552 						return;
   553 						return;
   553 
   554 
   554 					// If RTL, swap left/right arrows
   555 					// If RTL, swap left/right arrows.
   555 					arrows = { '38': 'up', '40': 'down', '37': 'left', '39': 'right' };
   556 					arrows = { '38': 'up', '40': 'down', '37': 'left', '39': 'right' };
   556 					if ( $('body').hasClass('rtl') )
   557 					if ( $('body').hasClass('rtl') )
   557 						arrows = { '38' : 'up', '40' : 'down', '39' : 'left', '37' : 'right' };
   558 						arrows = { '38' : 'up', '40' : 'down', '39' : 'left', '37' : 'right' };
   558 
   559 
   559 					switch ( arrows[e.which] ) {
   560 					switch ( arrows[e.which] ) {
   568 						break;
   569 						break;
   569 					case 'right':
   570 					case 'right':
   570 						api.moveMenuItem( $this, 'right' );
   571 						api.moveMenuItem( $this, 'right' );
   571 						break;
   572 						break;
   572 					}
   573 					}
   573 					// Put focus back on same menu item
   574 					// Put focus back on same menu item.
   574 					$( '#edit-' + thisItemData['menu-item-db-id'] ).focus();
   575 					$( '#edit-' + thisItemData['menu-item-db-id'] ).focus();
   575 					return false;
   576 					return false;
   576 				});
   577 				});
   577 			});
   578 			});
   578 		},
   579 		},
   585 				titleEl = input.closest( '.menu-item' ).find( '.menu-item-title' );
   586 				titleEl = input.closest( '.menu-item' ).find( '.menu-item-title' );
   586 				// Don't update to empty title.
   587 				// Don't update to empty title.
   587 				if ( title ) {
   588 				if ( title ) {
   588 					titleEl.text( title ).removeClass( 'no-title' );
   589 					titleEl.text( title ).removeClass( 'no-title' );
   589 				} else {
   590 				} else {
   590 					titleEl.text( navMenuL10n.untitled ).addClass( 'no-title' );
   591 					titleEl.text( wp.i18n._x( '(no label)', 'missing menu item navigation label' ) ).addClass( 'no-title' );
   591 				}
   592 				}
   592 			} );
   593 			} );
   593 		},
   594 		},
   594 
   595 
   595 		initToggles : function() {
   596 		initToggles : function() {
   596 			// init postboxes
   597 			// Init postboxes.
   597 			postboxes.add_postbox_toggles('nav-menus');
   598 			postboxes.add_postbox_toggles('nav-menus');
   598 
   599 
   599 			// adjust columns functions for menus UI
   600 			// Adjust columns functions for menus UI.
   600 			columns.useCheckboxesForHidden();
   601 			columns.useCheckboxesForHidden();
   601 			columns.checked = function(field) {
   602 			columns.checked = function(field) {
   602 				$('.field-' + field).removeClass('hidden-field');
   603 				$('.field-' + field).removeClass('hidden-field');
   603 			};
   604 			};
   604 			columns.unchecked = function(field) {
   605 			columns.unchecked = function(field) {
   605 				$('.field-' + field).addClass('hidden-field');
   606 				$('.field-' + field).addClass('hidden-field');
   606 			};
   607 			};
   607 			// hide fields
   608 			// Hide fields.
   608 			api.menuList.hideAdvancedMenuItemFields();
   609 			api.menuList.hideAdvancedMenuItemFields();
   609 
   610 
   610 			$('.hide-postbox-tog').click(function () {
   611 			$('.hide-postbox-tog').click(function () {
   611 				var hidden = $( '.accordion-container li.accordion-section' ).filter(':hidden').map(function() { return this.id; }).get().join(',');
   612 				var hidden = $( '.accordion-container li.accordion-section' ).filter(':hidden').map(function() { return this.id; }).get().join(',');
   612 				$.post(ajaxurl, {
   613 				$.post(ajaxurl, {
   636 				placeholder: 'sortable-placeholder',
   637 				placeholder: 'sortable-placeholder',
   637 				items: api.options.sortableItems,
   638 				items: api.options.sortableItems,
   638 				start: function(e, ui) {
   639 				start: function(e, ui) {
   639 					var height, width, parent, children, tempHolder;
   640 					var height, width, parent, children, tempHolder;
   640 
   641 
   641 					// handle placement for rtl orientation
   642 					// Handle placement for RTL orientation.
   642 					if ( api.isRTL )
   643 					if ( api.isRTL )
   643 						ui.item[0].style.right = 'auto';
   644 						ui.item[0].style.right = 'auto';
   644 
   645 
   645 					transport = ui.item.children('.menu-item-transport');
   646 					transport = ui.item.children('.menu-item-transport');
   646 
   647 
   647 					// Set depths. currentDepth must be set before children are located.
   648 					// Set depths. currentDepth must be set before children are located.
   648 					originalDepth = ui.item.menuItemDepth();
   649 					originalDepth = ui.item.menuItemDepth();
   649 					updateCurrentDepth(ui, originalDepth);
   650 					updateCurrentDepth(ui, originalDepth);
   650 
   651 
   651 					// Attach child elements to parent
   652 					// Attach child elements to parent.
   652 					// Skip the placeholder
   653 					// Skip the placeholder.
   653 					parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item;
   654 					parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item;
   654 					children = parent.childMenuItems();
   655 					children = parent.childMenuItems();
   655 					transport.append( children );
   656 					transport.append( children );
   656 
   657 
   657 					// Update the height of the placeholder to match the moving item.
   658 					// Update the height of the placeholder to match the moving item.
   658 					height = transport.outerHeight();
   659 					height = transport.outerHeight();
   659 					// If there are children, account for distance between top of children and parent
   660 					// If there are children, account for distance between top of children and parent.
   660 					height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0;
   661 					height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0;
   661 					height += ui.helper.outerHeight();
   662 					height += ui.helper.outerHeight();
   662 					helperHeight = height;
   663 					helperHeight = height;
   663 					height -= 2; // Subtract 2 for borders
   664 					height -= 2;                                              // Subtract 2 for borders.
   664 					ui.placeholder.height(height);
   665 					ui.placeholder.height(height);
   665 
   666 
   666 					// Update the width of the placeholder to match the moving item.
   667 					// Update the width of the placeholder to match the moving item.
   667 					maxChildDepth = originalDepth;
   668 					maxChildDepth = originalDepth;
   668 					children.each(function(){
   669 					children.each(function(){
   669 						var depth = $(this).menuItemDepth();
   670 						var depth = $(this).menuItemDepth();
   670 						maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth;
   671 						maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth;
   671 					});
   672 					});
   672 					width = ui.helper.find('.menu-item-handle').outerWidth(); // Get original width
   673 					width = ui.helper.find('.menu-item-handle').outerWidth(); // Get original width.
   673 					width += api.depthToPx(maxChildDepth - originalDepth); // Account for children
   674 					width += api.depthToPx(maxChildDepth - originalDepth);    // Account for children.
   674 					width -= 2; // Subtract 2 for borders
   675 					width -= 2;                                               // Subtract 2 for borders.
   675 					ui.placeholder.width(width);
   676 					ui.placeholder.width(width);
   676 
   677 
   677 					// Update the list of menu items.
   678 					// Update the list of menu items.
   678 					tempHolder = ui.placeholder.next( '.menu-item' );
   679 					tempHolder = ui.placeholder.next( '.menu-item' );
   679 					tempHolder.css( 'margin-top', helperHeight + 'px' ); // Set the margin to absorb the placeholder
   680 					tempHolder.css( 'margin-top', helperHeight + 'px' ); // Set the margin to absorb the placeholder.
   680 					ui.placeholder.detach(); // detach or jQuery UI will think the placeholder is a menu item
   681 					ui.placeholder.detach();         // Detach or jQuery UI will think the placeholder is a menu item.
   681 					$(this).sortable( 'refresh' ); // The children aren't sortable. We should let jQ UI know.
   682 					$(this).sortable( 'refresh' );   // The children aren't sortable. We should let jQuery UI know.
   682 					ui.item.after( ui.placeholder ); // reattach the placeholder.
   683 					ui.item.after( ui.placeholder ); // Reattach the placeholder.
   683 					tempHolder.css('margin-top', 0); // reset the margin
   684 					tempHolder.css('margin-top', 0); // Reset the margin.
   684 
   685 
   685 					// Now that the element is complete, we can update...
   686 					// Now that the element is complete, we can update...
   686 					updateSharedVars(ui);
   687 					updateSharedVars(ui);
   687 				},
   688 				},
   688 				stop: function(e, ui) {
   689 				stop: function(e, ui) {
   689 					var children, subMenuTitle,
   690 					var children, subMenuTitle,
   690 						depthChange = currentDepth - originalDepth;
   691 						depthChange = currentDepth - originalDepth;
   691 
   692 
   692 					// Return child elements to the list
   693 					// Return child elements to the list.
   693 					children = transport.children().insertAfter(ui.item);
   694 					children = transport.children().insertAfter(ui.item);
   694 
   695 
   695 					// Add "sub menu" description
   696 					// Add "sub menu" description.
   696 					subMenuTitle = ui.item.find( '.item-title .is-submenu' );
   697 					subMenuTitle = ui.item.find( '.item-title .is-submenu' );
   697 					if ( 0 < currentDepth )
   698 					if ( 0 < currentDepth )
   698 						subMenuTitle.show();
   699 						subMenuTitle.show();
   699 					else
   700 					else
   700 						subMenuTitle.hide();
   701 						subMenuTitle.hide();
   701 
   702 
   702 					// Update depth classes
   703 					// Update depth classes.
   703 					if ( 0 !== depthChange ) {
   704 					if ( 0 !== depthChange ) {
   704 						ui.item.updateDepthClass( currentDepth );
   705 						ui.item.updateDepthClass( currentDepth );
   705 						children.shiftDepthClass( depthChange );
   706 						children.shiftDepthClass( depthChange );
   706 						updateMenuMaxDepth( depthChange );
   707 						updateMenuMaxDepth( depthChange );
   707 					}
   708 					}
   708 					// Register a change
   709 					// Register a change.
   709 					api.registerChange();
   710 					api.registerChange();
   710 					// Update the item data.
   711 					// Update the item data.
   711 					ui.item.updateParentMenuItemDBId();
   712 					ui.item.updateParentMenuItemDBId();
   712 
   713 
   713 					// address sortable's incorrectly-calculated top in opera
   714 					// Address sortable's incorrectly-calculated top in Opera.
   714 					ui.item[0].style.top = 0;
   715 					ui.item[0].style.top = 0;
   715 
   716 
   716 					// handle drop placement for rtl orientation
   717 					// Handle drop placement for rtl orientation.
   717 					if ( api.isRTL ) {
   718 					if ( api.isRTL ) {
   718 						ui.item[0].style.left = 'auto';
   719 						ui.item[0].style.left = 'auto';
   719 						ui.item[0].style.right = 0;
   720 						ui.item[0].style.right = 0;
   720 					}
   721 					}
   721 
   722 
   733 				sort: function(e, ui) {
   734 				sort: function(e, ui) {
   734 					var offset = ui.helper.offset(),
   735 					var offset = ui.helper.offset(),
   735 						edge = api.isRTL ? offset.left + ui.helper.width() : offset.left,
   736 						edge = api.isRTL ? offset.left + ui.helper.width() : offset.left,
   736 						depth = api.negateIfRTL * api.pxToDepth( edge - menuEdge );
   737 						depth = api.negateIfRTL * api.pxToDepth( edge - menuEdge );
   737 
   738 
   738 					// Check and correct if depth is not within range.
   739 					/*
   739 					// Also, if the dragged element is dragged upwards over
   740 					 * Check and correct if depth is not within range.
   740 					// an item, shift the placeholder to a child position.
   741 					 * Also, if the dragged element is dragged upwards over an item,
       
   742 					 * shift the placeholder to a child position.
       
   743 					 */
   741 					if ( depth > maxDepth || offset.top < ( prevBottom - api.options.targetTolerance ) ) {
   744 					if ( depth > maxDepth || offset.top < ( prevBottom - api.options.targetTolerance ) ) {
   742 						depth = maxDepth;
   745 						depth = maxDepth;
   743 					} else if ( depth < minDepth ) {
   746 					} else if ( depth < minDepth ) {
   744 						depth = minDepth;
   747 						depth = minDepth;
   745 					}
   748 					}
   746 
   749 
   747 					if( depth != currentDepth )
   750 					if( depth != currentDepth )
   748 						updateCurrentDepth(ui, depth);
   751 						updateCurrentDepth(ui, depth);
   749 
   752 
   750 					// If we overlap the next element, manually shift downwards
   753 					// If we overlap the next element, manually shift downwards.
   751 					if( nextThreshold && offset.top + helperHeight > nextThreshold ) {
   754 					if( nextThreshold && offset.top + helperHeight > nextThreshold ) {
   752 						next.after( ui.placeholder );
   755 						next.after( ui.placeholder );
   753 						updateSharedVars( ui );
   756 						updateSharedVars( ui );
   754 						$( this ).sortable( 'refreshPositions' );
   757 						$( this ).sortable( 'refreshPositions' );
   755 					}
   758 					}
   915 			var panel, params,
   918 			var panel, params,
   916 				minSearchLength = 2,
   919 				minSearchLength = 2,
   917 				q = input.val();
   920 				q = input.val();
   918 
   921 
   919 			/*
   922 			/*
   920 			 * Minimum characters for a search. Also avoid a new AJAX search when
   923 			 * Minimum characters for a search. Also avoid a new Ajax search when
   921 			 * the pressed key (e.g. arrows) doesn't change the searched term.
   924 			 * the pressed key (e.g. arrows) doesn't change the searched term.
   922 			 */
   925 			 */
   923 			if ( q.length < minSearchLength || api.lastSearch == q ) {
   926 			if ( q.length < minSearchLength || api.lastSearch == q ) {
   924 				return;
   927 				return;
   925 			}
   928 			}
   947 			var url = $('#custom-menu-item-url').val().trim(),
   950 			var url = $('#custom-menu-item-url').val().trim(),
   948 				label = $('#custom-menu-item-name').val();
   951 				label = $('#custom-menu-item-name').val();
   949 
   952 
   950 			processMethod = processMethod || api.addMenuItemToBottom;
   953 			processMethod = processMethod || api.addMenuItemToBottom;
   951 
   954 
   952 			if ( '' === url || 'http://' == url ) {
   955 			if ( '' === url || 'https://' == url || 'http://' == url ) {
   953 				$('#customlinkdiv').addClass('form-invalid');
   956 				$('#customlinkdiv').addClass('form-invalid');
   954 				return false;
   957 				return false;
   955 			}
   958 			}
   956 
   959 
   957 			// Show the ajax spinner
   960 			// Show the Ajax spinner.
   958 			$( '.customlinkdiv .spinner' ).addClass( 'is-active' );
   961 			$( '.customlinkdiv .spinner' ).addClass( 'is-active' );
   959 			this.addLinkToMenu( url, label, processMethod, function() {
   962 			this.addLinkToMenu( url, label, processMethod, function() {
   960 				// Remove the ajax spinner
   963 				// Remove the Ajax spinner.
   961 				$( '.customlinkdiv .spinner' ).removeClass( 'is-active' );
   964 				$( '.customlinkdiv .spinner' ).removeClass( 'is-active' );
   962 				// Set custom link form back to defaults
   965 				// Set custom link form back to defaults.
   963 				$('#custom-menu-item-name').val('').blur();
   966 				$('#custom-menu-item-name').val('').blur();
   964 				$('#custom-menu-item-url').val('http://');
   967 				$( '#custom-menu-item-url' ).val( '' ).attr( 'placeholder', 'https://' );
   965 			});
   968 			});
   966 		},
   969 		},
   967 
   970 
   968 		addLinkToMenu : function(url, label, processMethod, callback) {
   971 		addLinkToMenu : function(url, label, processMethod, callback) {
   969 			processMethod = processMethod || api.addMenuItemToBottom;
   972 			processMethod = processMethod || api.addMenuItemToBottom;
   994 			};
   997 			};
   995 
   998 
   996 			$.post( ajaxurl, params, function(menuMarkup) {
   999 			$.post( ajaxurl, params, function(menuMarkup) {
   997 				var ins = $('#menu-instructions');
  1000 				var ins = $('#menu-instructions');
   998 
  1001 
   999 				menuMarkup = $.trim( menuMarkup ); // Trim leading whitespaces
  1002 				menuMarkup = $.trim( menuMarkup ); // Trim leading whitespaces.
  1000 				processMethod(menuMarkup, params);
  1003 				processMethod(menuMarkup, params);
  1001 
  1004 
  1002 				// Make it stand out a bit more visually, by adding a fadeIn
  1005 				// Make it stand out a bit more visually, by adding a fadeIn.
  1003 				$( 'li.pending' ).hide().fadeIn('slow');
  1006 				$( 'li.pending' ).hide().fadeIn('slow');
  1004 				$( '.drag-instructions' ).show();
  1007 				$( '.drag-instructions' ).show();
  1005 				if( ! ins.hasClass( 'menu-instructions-inactive' ) && ins.siblings().length )
  1008 				if( ! ins.hasClass( 'menu-instructions-inactive' ) && ins.siblings().length )
  1006 					ins.addClass( 'menu-instructions-inactive' );
  1009 					ins.addClass( 'menu-instructions-inactive' );
  1007 
  1010 
  1045 			});
  1048 			});
  1046 
  1049 
  1047 			if ( 0 !== $('#menu-to-edit').length || 0 !== $('.menu-location-menus select').length ) {
  1050 			if ( 0 !== $('#menu-to-edit').length || 0 !== $('.menu-location-menus select').length ) {
  1048 				window.onbeforeunload = function(){
  1051 				window.onbeforeunload = function(){
  1049 					if ( api.menusChanged )
  1052 					if ( api.menusChanged )
  1050 						return navMenuL10n.saveAlert;
  1053 						return wp.i18n.__( 'The changes you made will be lost if you navigate away from this page.' );
  1051 				};
  1054 				};
  1052 			} else {
  1055 			} else {
  1053 				// Make the post boxes read-only, as they can't be used yet
  1056 				// Make the post boxes read-only, as they can't be used yet.
  1054 				$( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).unbind( 'click' );
  1057 				$( '#menu-settings-column' ).find( 'input,select' ).end().find( 'a' ).attr( 'href', '#' ).unbind( 'click' );
  1055 			}
  1058 			}
  1056 		},
  1059 		},
  1057 
  1060 
  1058 		registerChange : function() {
  1061 		registerChange : function() {
  1059 			api.menusChanged = true;
  1062 			api.menusChanged = true;
  1060 		},
  1063 		},
  1061 
  1064 
  1062 		attachTabsPanelListeners : function() {
  1065 		attachTabsPanelListeners : function() {
  1063 			$('#menu-settings-column').bind('click', function(e) {
  1066 			$('#menu-settings-column').bind('click', function(e) {
  1064 				var selectAreaMatch, panelId, wrapper, items,
  1067 				var selectAreaMatch, selectAll, panelId, wrapper, items,
  1065 					target = $(e.target);
  1068 					target = $(e.target);
  1066 
  1069 
  1067 				if ( target.hasClass('nav-tab-link') ) {
  1070 				if ( target.hasClass('nav-tab-link') ) {
  1068 
  1071 
  1069 					panelId = target.data( 'type' );
  1072 					panelId = target.data( 'type' );
  1070 
  1073 
  1071 					wrapper = target.parents('.accordion-section-content').first();
  1074 					wrapper = target.parents('.accordion-section-content').first();
  1072 
  1075 
  1073 					// upon changing tabs, we want to uncheck all checkboxes
  1076 					// Upon changing tabs, we want to uncheck all checkboxes.
  1074 					$('input', wrapper).removeAttr('checked');
  1077 					$( 'input', wrapper ).prop( 'checked', false );
  1075 
  1078 
  1076 					$('.tabs-panel-active', wrapper).removeClass('tabs-panel-active').addClass('tabs-panel-inactive');
  1079 					$('.tabs-panel-active', wrapper).removeClass('tabs-panel-active').addClass('tabs-panel-inactive');
  1077 					$('#' + panelId, wrapper).removeClass('tabs-panel-inactive').addClass('tabs-panel-active');
  1080 					$('#' + panelId, wrapper).removeClass('tabs-panel-inactive').addClass('tabs-panel-active');
  1078 
  1081 
  1079 					$('.tabs', wrapper).removeClass('tabs');
  1082 					$('.tabs', wrapper).removeClass('tabs');
  1080 					target.parent().addClass('tabs');
  1083 					target.parent().addClass('tabs');
  1081 
  1084 
  1082 					// select the search bar
  1085 					// Select the search bar.
  1083 					$('.quick-search', wrapper).focus();
  1086 					$('.quick-search', wrapper).focus();
  1084 
  1087 
  1085 					// Hide controls in the search tab if no items found.
  1088 					// Hide controls in the search tab if no items found.
  1086 					if ( ! wrapper.find( '.tabs-panel-active .menu-item-title' ).length ) {
  1089 					if ( ! wrapper.find( '.tabs-panel-active .menu-item-title' ).length ) {
  1087 						wrapper.addClass( 'has-no-menu-item' );
  1090 						wrapper.addClass( 'has-no-menu-item' );
  1088 					} else {
  1091 					} else {
  1089 						wrapper.removeClass( 'has-no-menu-item' );
  1092 						wrapper.removeClass( 'has-no-menu-item' );
  1090 					}
  1093 					}
  1091 
  1094 
  1092 					e.preventDefault();
  1095 					e.preventDefault();
  1093 				} else if ( target.hasClass('select-all') ) {
  1096 				} else if ( target.hasClass( 'select-all' ) ) {
  1094 					selectAreaMatch = /#(.*)$/.exec(e.target.href);
  1097 					selectAreaMatch = target.closest( '.button-controls' ).data( 'items-type' );
  1095 					if ( selectAreaMatch && selectAreaMatch[1] ) {
  1098 					if ( selectAreaMatch ) {
  1096 						items = $('#' + selectAreaMatch[1] + ' .tabs-panel-active .menu-item-title input');
  1099 						items = $( '#' + selectAreaMatch + ' .tabs-panel-active .menu-item-title input' );
  1097 						if( items.length === items.filter(':checked').length )
  1100 
  1098 							items.removeAttr('checked');
  1101 						if ( items.length === items.filter( ':checked' ).length && ! target.is( ':checked' ) ) {
  1099 						else
  1102 							items.prop( 'checked', false );
  1100 							items.prop('checked', true);
  1103 						} else if ( target.is( ':checked' ) ) {
  1101 						return false;
  1104 							items.prop( 'checked', true );
       
  1105 						}
       
  1106 					}
       
  1107 				} else if ( target.hasClass( 'menu-item-checkbox' ) ) {
       
  1108 					selectAreaMatch = target.closest( '.tabs-panel-active' ).parent().attr( 'id' );
       
  1109 					if ( selectAreaMatch ) {
       
  1110 						items     = $( '#' + selectAreaMatch + ' .tabs-panel-active .menu-item-title input' );
       
  1111 						selectAll = $( '.button-controls[data-items-type="' + selectAreaMatch + '"] .select-all' );
       
  1112 
       
  1113 						if ( items.length === items.filter( ':checked' ).length && ! selectAll.is( ':checked' ) ) {
       
  1114 							selectAll.prop( 'checked', true );
       
  1115 						} else if ( selectAll.is( ':checked' ) ) {
       
  1116 							selectAll.prop( 'checked', false );
       
  1117 						}
  1102 					}
  1118 					}
  1103 				} else if ( target.hasClass('submit-add-to-menu') ) {
  1119 				} else if ( target.hasClass('submit-add-to-menu') ) {
  1104 					api.registerChange();
  1120 					api.registerChange();
  1105 
  1121 
  1106 					if ( e.target.id && 'submit-customlinkdiv' == e.target.id )
  1122 					if ( e.target.id && 'submit-customlinkdiv' == e.target.id )
  1144 		},
  1160 		},
  1145 
  1161 
  1146 		eventOnClickEditLink : function(clickedEl) {
  1162 		eventOnClickEditLink : function(clickedEl) {
  1147 			var settings, item,
  1163 			var settings, item,
  1148 			matchedSection = /#(.*)$/.exec(clickedEl.href);
  1164 			matchedSection = /#(.*)$/.exec(clickedEl.href);
       
  1165 
  1149 			if ( matchedSection && matchedSection[1] ) {
  1166 			if ( matchedSection && matchedSection[1] ) {
  1150 				settings = $('#'+matchedSection[1]);
  1167 				settings = $('#'+matchedSection[1]);
  1151 				item = settings.parent();
  1168 				item = settings.parent();
  1152 				if( 0 !== item.length ) {
  1169 				if( 0 !== item.length ) {
  1153 					if( item.hasClass('menu-item-edit-inactive') ) {
  1170 					if( item.hasClass('menu-item-edit-inactive') ) {
  1168 		},
  1185 		},
  1169 
  1186 
  1170 		eventOnClickCancelLink : function(clickedEl) {
  1187 		eventOnClickCancelLink : function(clickedEl) {
  1171 			var settings = $( clickedEl ).closest( '.menu-item-settings' ),
  1188 			var settings = $( clickedEl ).closest( '.menu-item-settings' ),
  1172 				thisMenuItem = $( clickedEl ).closest( '.menu-item' );
  1189 				thisMenuItem = $( clickedEl ).closest( '.menu-item' );
  1173 			thisMenuItem.removeClass('menu-item-edit-active').addClass('menu-item-edit-inactive');
  1190 
  1174 			settings.setItemData( settings.data('menu-item-data') ).hide();
  1191 			thisMenuItem.removeClass( 'menu-item-edit-active' ).addClass( 'menu-item-edit-inactive' );
       
  1192 			settings.setItemData( settings.data( 'menu-item-data' ) ).hide();
       
  1193 			// Restore the title of the currently active/expanded menu item.
       
  1194 			thisMenuItem.find( '.menu-item-title' ).text( settings.data( 'menu-item-data' )['menu-item-title'] );
       
  1195 
  1175 			return false;
  1196 			return false;
  1176 		},
  1197 		},
  1177 
  1198 
  1178 		eventOnClickMenuSave : function() {
  1199 		eventOnClickMenuSave : function() {
  1179 			var locs = '',
  1200 			var locs = '',
  1180 			menuName = $('#menu-name'),
  1201 			menuName = $('#menu-name'),
  1181 			menuNameVal = menuName.val();
  1202 			menuNameVal = menuName.val();
  1182 			// Cancel and warn if invalid menu name
  1203 
       
  1204 			// Cancel and warn if invalid menu name.
  1183 			if ( ! menuNameVal || ! menuNameVal.replace( /\s+/, '' ) ) {
  1205 			if ( ! menuNameVal || ! menuNameVal.replace( /\s+/, '' ) ) {
  1184 				menuName.parent().addClass( 'form-invalid' );
  1206 				menuName.parent().addClass( 'form-invalid' );
  1185 				return false;
  1207 				return false;
  1186 			}
  1208 			}
  1187 			// Copy menu theme locations
  1209 			// Copy menu theme locations.
  1188 			$('#nav-menu-theme-locations select').each(function() {
  1210 			$('#nav-menu-theme-locations select').each(function() {
  1189 				locs += '<input type="hidden" name="' + this.name + '" value="' + $(this).val() + '" />';
  1211 				locs += '<input type="hidden" name="' + this.name + '" value="' + $(this).val() + '" />';
  1190 			});
  1212 			});
  1191 			$('#update-nav-menu').append( locs );
  1213 			$('#update-nav-menu').append( locs );
  1192 			// Update menu item position data
  1214 			// Update menu item position data.
  1193 			api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } );
  1215 			api.menuList.find('.menu-item-data-position').val( function(index) { return index + 1; } );
  1194 			window.onbeforeunload = null;
  1216 			window.onbeforeunload = null;
  1195 
  1217 
  1196 			return true;
  1218 			return true;
  1197 		},
  1219 		},
  1198 
  1220 
  1199 		eventOnClickMenuDelete : function() {
  1221 		eventOnClickMenuDelete : function() {
  1200 			// Delete warning AYS
  1222 			// Delete warning AYS.
  1201 			if ( window.confirm( navMenuL10n.warnDeleteMenu ) ) {
  1223 			if ( window.confirm( wp.i18n.__( 'You are about to permanently delete this menu.\n\'Cancel\' to stop, \'OK\' to delete.' ) ) ) {
  1202 				window.onbeforeunload = null;
  1224 				window.onbeforeunload = null;
  1203 				return true;
  1225 				return true;
  1204 			}
  1226 			}
  1205 			return false;
  1227 			return false;
  1206 		},
  1228 		},
  1207 
  1229 
  1208 		eventOnClickMenuItemDelete : function(clickedEl) {
  1230 		eventOnClickMenuItemDelete : function(clickedEl) {
  1209 			var itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);
  1231 			var itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);
       
  1232 
  1210 			api.removeMenuItem( $('#menu-item-' + itemID) );
  1233 			api.removeMenuItem( $('#menu-item-' + itemID) );
  1211 			api.registerChange();
  1234 			api.registerChange();
  1212 			return false;
  1235 			return false;
  1213 		},
  1236 		},
  1214 
  1237 
  1224 			takenIDs = {},
  1247 			takenIDs = {},
  1225 			form = document.getElementById('nav-menu-meta'),
  1248 			form = document.getElementById('nav-menu-meta'),
  1226 			pattern = /menu-item[(\[^]\]*/,
  1249 			pattern = /menu-item[(\[^]\]*/,
  1227 			$items = $('<div>').html(resp).find('li'),
  1250 			$items = $('<div>').html(resp).find('li'),
  1228 			wrapper = panel.closest( '.accordion-section-content' ),
  1251 			wrapper = panel.closest( '.accordion-section-content' ),
       
  1252 			selectAll = wrapper.find( '.button-controls .select-all' ),
  1229 			$item;
  1253 			$item;
  1230 
  1254 
  1231 			if( ! $items.length ) {
  1255 			if( ! $items.length ) {
  1232 				$('.categorychecklist', panel).html( '<li><p>' + navMenuL10n.noResultsFound + '</p></li>' );
  1256 				$('.categorychecklist', panel).html( '<li><p>' + wp.i18n.__( 'No results found.' ) + '</p></li>' );
  1233 				$( '.spinner', panel ).removeClass( 'is-active' );
  1257 				$( '.spinner', panel ).removeClass( 'is-active' );
  1234 				wrapper.addClass( 'has-no-menu-item' );
  1258 				wrapper.addClass( 'has-no-menu-item' );
  1235 				return;
  1259 				return;
  1236 			}
  1260 			}
  1237 
  1261 
  1238 			$items.each(function(){
  1262 			$items.each(function(){
  1239 				$item = $(this);
  1263 				$item = $(this);
  1240 
  1264 
  1241 				// make a unique DB ID number
  1265 				// Make a unique DB ID number.
  1242 				matched = pattern.exec($item.html());
  1266 				matched = pattern.exec($item.html());
  1243 
  1267 
  1244 				if ( matched && matched[1] ) {
  1268 				if ( matched && matched[1] ) {
  1245 					newID = matched[1];
  1269 					newID = matched[1];
  1246 					while( form.elements['menu-item[' + newID + '][menu-item-type]'] || takenIDs[ newID ] ) {
  1270 					while( form.elements['menu-item[' + newID + '][menu-item-type]'] || takenIDs[ newID ] ) {
  1258 			});
  1282 			});
  1259 
  1283 
  1260 			$('.categorychecklist', panel).html( $items );
  1284 			$('.categorychecklist', panel).html( $items );
  1261 			$( '.spinner', panel ).removeClass( 'is-active' );
  1285 			$( '.spinner', panel ).removeClass( 'is-active' );
  1262 			wrapper.removeClass( 'has-no-menu-item' );
  1286 			wrapper.removeClass( 'has-no-menu-item' );
       
  1287 
       
  1288 			if ( selectAll.is( ':checked' ) ) {
       
  1289 				selectAll.prop( 'checked', false );
       
  1290 			}
  1263 		},
  1291 		},
  1264 
  1292 
  1265 		/**
  1293 		/**
  1266 		 * Remove a menu item.
  1294 		 * Remove a menu item.
  1267 		 * @param  {object} el The element to be removed as a jQuery object.
  1295 		 *
       
  1296 		 * @param {Object} el The element to be removed as a jQuery object.
  1268 		 *
  1297 		 *
  1269 		 * @fires document#menu-removing-item Passes the element to be removed.
  1298 		 * @fires document#menu-removing-item Passes the element to be removed.
  1270 		 */
  1299 		 */
  1271 		removeMenuItem : function(el) {
  1300 		removeMenuItem : function(el) {
  1272 			var children = el.childMenuItems();
  1301 			var children = el.childMenuItems();