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 }); |
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 ) { |
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 |
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] ) { |
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 } |
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; |
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 ) |
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 ] ) { |