wp/wp-admin/js/customize-nav-menus.js
changeset 21 48c4eec2b7e6
parent 18 be944660c56a
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     1 /**
     1 /**
     2  * @output wp-admin/js/customize-nav-menus.js
     2  * @output wp-admin/js/customize-nav-menus.js
     3  */
     3  */
     4 
     4 
     5 /* global _wpCustomizeNavMenusSettings, wpNavMenu, console */
     5 /* global menus, _wpCustomizeNavMenusSettings, wpNavMenu, console */
     6 ( function( api, wp, $ ) {
     6 ( function( api, wp, $ ) {
     7 	'use strict';
     7 	'use strict';
     8 
     8 
     9 	/**
     9 	/**
    10 	 * Set up wpNavMenu for drag and drop.
    10 	 * Set up wpNavMenu for drag and drop.
  1130 
  1130 
  1131 				// Add attributes needed by wpNavMenu.
  1131 				// Add attributes needed by wpNavMenu.
  1132 				$( '#menu-to-edit' ).removeAttr( 'id' );
  1132 				$( '#menu-to-edit' ).removeAttr( 'id' );
  1133 				wpNavMenu.menuList.attr( 'id', 'menu-to-edit' ).addClass( 'menu' );
  1133 				wpNavMenu.menuList.attr( 'id', 'menu-to-edit' ).addClass( 'menu' );
  1134 
  1134 
       
  1135 				api.Menus.MenuItemControl.prototype.initAccessibility();
       
  1136 
  1135 				_.each( api.section( section.id ).controls(), function( control ) {
  1137 				_.each( api.section( section.id ).controls(), function( control ) {
  1136 					if ( 'nav_menu_item' === control.params.type ) {
  1138 					if ( 'nav_menu_item' === control.params.type ) {
  1137 						control.actuallyEmbed();
  1139 						control.actuallyEmbed();
  1138 					}
  1140 					}
  1139 				} );
  1141 				} );
  1573 				return value;
  1575 				return value;
  1574 			};
  1576 			};
  1575 		},
  1577 		},
  1576 
  1578 
  1577 		/**
  1579 		/**
       
  1580 		 * Set up the initial state of the screen reader accessibility information for menu items.
       
  1581 		 *
       
  1582 		 * @since 6.6.0
       
  1583 		 */
       
  1584 		initAccessibility: function() {
       
  1585 			var control = this,
       
  1586 				menu = $( '#menu-to-edit' );
       
  1587 
       
  1588 			// Refresh the accessibility when the user comes close to the item in any way.
       
  1589 			menu.on( 'mouseenter.refreshAccessibility focus.refreshAccessibility touchstart.refreshAccessibility', '.menu-item', function(){
       
  1590 				control.refreshAdvancedAccessibilityOfItem( $( this ).find( 'button.item-edit' ) );
       
  1591 			} );
       
  1592 
       
  1593 			// We have to update on click as well because we might hover first, change the item, and then click.
       
  1594 			menu.on( 'click', 'button.item-edit', function() {
       
  1595 				control.refreshAdvancedAccessibilityOfItem( $( this ) );
       
  1596 			} );
       
  1597 		},
       
  1598 
       
  1599 		/**
       
  1600 		 * refreshAdvancedAccessibilityOfItem( [itemToRefresh] )
       
  1601 		 *
       
  1602 		 * Refreshes advanced accessibility buttons for one menu item.
       
  1603 		 * Shows or hides buttons based on the location of the menu item.
       
  1604 		 *
       
  1605 		 * @param {Object} itemToRefresh The menu item that might need its advanced accessibility buttons refreshed
       
  1606 		 * 
       
  1607 		 * @since 6.6.0
       
  1608 		 */
       
  1609 		refreshAdvancedAccessibilityOfItem: function( itemToRefresh ) {
       
  1610 			// Only refresh accessibility when necessary.
       
  1611 			if ( true !== $( itemToRefresh ).data( 'needs_accessibility_refresh' ) ) {
       
  1612 				return;
       
  1613 			}
       
  1614 
       
  1615 			var primaryItems, itemPosition, title,
       
  1616 				parentItem, parentItemId, parentItemName, subItems, totalSubItems,
       
  1617 				$this = $( itemToRefresh ),
       
  1618 				menuItem = $this.closest( 'li.menu-item' ).first(),
       
  1619 				depth = menuItem.menuItemDepth(),
       
  1620 				isPrimaryMenuItem = ( 0 === depth ),
       
  1621 				itemName = $this.closest( '.menu-item-handle' ).find( '.menu-item-title' ).text(),
       
  1622 				menuItemType = $this.closest( '.menu-item-handle' ).find( '.item-type' ).text(),
       
  1623 				totalMenuItems = $( '#menu-to-edit li' ).length;
       
  1624 
       
  1625 			if ( isPrimaryMenuItem ) {
       
  1626 				primaryItems = $( '.menu-item-depth-0' ),
       
  1627 				itemPosition = primaryItems.index( menuItem ) + 1,
       
  1628 				totalMenuItems = primaryItems.length,
       
  1629 				// String together help text for primary menu items.
       
  1630 				title = menus.menuFocus.replace( '%1$s', itemName ).replace( '%2$s', menuItemType ).replace( '%3$d', itemPosition ).replace( '%4$d', totalMenuItems );
       
  1631 			} else {
       
  1632 				parentItem = menuItem.prevAll( '.menu-item-depth-' + parseInt( depth - 1, 10 ) ).first(),
       
  1633 				parentItemId = parentItem.find( '.menu-item-data-db-id' ).val(),
       
  1634 				parentItemName = parentItem.find( '.menu-item-title' ).text(),
       
  1635 				subItems = $( '.menu-item .menu-item-data-parent-id[value="' + parentItemId + '"]' ),
       
  1636 				totalSubItems = subItems.length,
       
  1637 				itemPosition = $( subItems.parents( '.menu-item' ).get().reverse() ).index( menuItem ) + 1;
       
  1638 
       
  1639 				// String together help text for sub menu items.
       
  1640 				if ( depth < 2 ) {
       
  1641 					title = menus.subMenuFocus.replace( '%1$s', itemName ).replace( '%2$s', menuItemType ).replace( '%3$d', itemPosition ).replace( '%4$d', totalSubItems ).replace( '%5$s', parentItemName );
       
  1642 				} else {
       
  1643 					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 );
       
  1644 				}
       
  1645 			}
       
  1646 
       
  1647 			$this.find( '.screen-reader-text' ).text( title );
       
  1648 
       
  1649 			// Mark this item's accessibility as refreshed.
       
  1650 			$this.data( 'needs_accessibility_refresh', false );
       
  1651 		},
       
  1652 
       
  1653 		/**
  1578 		 * Override the embed() method to do nothing,
  1654 		 * Override the embed() method to do nothing,
  1579 		 * so that the control isn't embedded on load,
  1655 		 * so that the control isn't embedded on load,
  1580 		 * unless the containing section is already expanded.
  1656 		 * unless the containing section is already expanded.
  1581 		 *
  1657 		 *
  1582 		 * @since 4.3.0
  1658 		 * @since 4.3.0
  1605 			if ( 'resolved' === control.deferred.embedded.state() ) {
  1681 			if ( 'resolved' === control.deferred.embedded.state() ) {
  1606 				return;
  1682 				return;
  1607 			}
  1683 			}
  1608 			control.renderContent();
  1684 			control.renderContent();
  1609 			control.deferred.embedded.resolve(); // This triggers control.ready().
  1685 			control.deferred.embedded.resolve(); // This triggers control.ready().
       
  1686 			
       
  1687 			// Mark all menu items as unprocessed.
       
  1688 			$( 'button.item-edit' ).data( 'needs_accessibility_refresh', true );
  1610 		},
  1689 		},
  1611 
  1690 
  1612 		/**
  1691 		/**
  1613 		 * Set up the control.
  1692 		 * Set up the control.
  1614 		 */
  1693 		 */
  1662 
  1741 
  1663 			// Handle clicks for up/down/left-right on the reorder nav.
  1742 			// Handle clicks for up/down/left-right on the reorder nav.
  1664 			$reorderNav = control.container.find( '.menu-item-reorder-nav' );
  1743 			$reorderNav = control.container.find( '.menu-item-reorder-nav' );
  1665 			$reorderNav.find( '.menus-move-up, .menus-move-down, .menus-move-left, .menus-move-right' ).on( 'click', function() {
  1744 			$reorderNav.find( '.menus-move-up, .menus-move-down, .menus-move-left, .menus-move-right' ).on( 'click', function() {
  1666 				var moveBtn = $( this );
  1745 				var moveBtn = $( this );
       
  1746 				control.params.depth = control.getDepth();
       
  1747 
  1667 				moveBtn.focus();
  1748 				moveBtn.focus();
  1668 
  1749 
  1669 				var isMoveUp = moveBtn.is( '.menus-move-up' ),
  1750 				var isMoveUp = moveBtn.is( '.menus-move-up' ),
  1670 					isMoveDown = moveBtn.is( '.menus-move-down' ),
  1751 					isMoveDown = moveBtn.is( '.menus-move-down' ),
  1671 					isMoveLeft = moveBtn.is( '.menus-move-left' ),
  1752 					isMoveLeft = moveBtn.is( '.menus-move-left' ),
  1677 					control.moveDown();
  1758 					control.moveDown();
  1678 				} else if ( isMoveLeft ) {
  1759 				} else if ( isMoveLeft ) {
  1679 					control.moveLeft();
  1760 					control.moveLeft();
  1680 				} else if ( isMoveRight ) {
  1761 				} else if ( isMoveRight ) {
  1681 					control.moveRight();
  1762 					control.moveRight();
  1682 				}
  1763 					control.params.depth += 1;
  1683 
  1764 				}
       
  1765 				
  1684 				moveBtn.focus(); // Re-focus after the container was moved.
  1766 				moveBtn.focus(); // Re-focus after the container was moved.
       
  1767 
       
  1768 				// Mark all menu items as unprocessed.
       
  1769 				$( 'button.item-edit' ).data( 'needs_accessibility_refresh', true );
  1685 			} );
  1770 			} );
  1686 		},
  1771 		},
  1687 
  1772 
  1688 		/**
  1773 		/**
  1689 		 * Set up event handlers for menu item updating.
  1774 		 * Set up event handlers for menu item updating.
  2711 							setting.menu_item_parent = 0;
  2796 							setting.menu_item_parent = 0;
  2712 						}
  2797 						}
  2713 
  2798 
  2714 						menuItemControl.setting.set( setting );
  2799 						menuItemControl.setting.set( setting );
  2715 					});
  2800 					});
       
  2801 
       
  2802 					// Mark all menu items as unprocessed.
       
  2803 					$( 'button.item-edit' ).data( 'needs_accessibility_refresh', true );
  2716 				});
  2804 				});
  2717 
  2805 
  2718 			});
  2806 			});
  2719 			control.isReordering = false;
  2807 			control.isReordering = false;
  2720 
  2808