450 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			450 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| ( function() {
 | |
| 	'use strict';
 | |
| 	var allSubMenus = document.querySelectorAll( '.main-nav .sub-menu, .main-nav .children' );
 | |
| 
 | |
| 	// Add missing aria roles and attributes for accessibility.
 | |
| 	if ( allSubMenus ) {
 | |
| 		allSubMenus.forEach( function( subMenu ) {
 | |
| 			var parentLi = subMenu.closest( 'li' );
 | |
| 			var button = parentLi.querySelector( '.dropdown-menu-toggle[role="button"]' );
 | |
| 
 | |
| 			if ( ! subMenu.id ) {
 | |
| 				var itemId = parentLi.id
 | |
| 					? parentLi.id
 | |
| 					: 'menu-item-' + Math.floor( Math.random() * 100000 ); // Just in case our menu item has no ID.
 | |
| 
 | |
| 				subMenu.id = itemId + '-sub-menu';
 | |
| 			}
 | |
| 
 | |
| 			// Bail if no button to update
 | |
| 			if ( ! button ) {
 | |
| 				button = parentLi.querySelector( 'a[role="button"]' );
 | |
| 
 | |
| 				if ( ! button ) {
 | |
| 					return;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			button.setAttribute( 'aria-controls', subMenu.id );
 | |
| 		} );
 | |
| 	}
 | |
| 
 | |
| 	if ( 'querySelector' in document && 'addEventListener' in window ) {
 | |
| 		/**
 | |
| 		 * matches() pollyfil
 | |
| 		 *
 | |
| 		 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
 | |
| 		 */
 | |
| 		if ( ! Element.prototype.matches ) {
 | |
| 			Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * closest() pollyfil
 | |
| 		 *
 | |
| 		 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
 | |
| 		 * @param {Object} s The element to check.
 | |
| 		 * @return {Object} The closest object.
 | |
| 		 */
 | |
| 		if ( ! Element.prototype.closest ) {
 | |
| 			Element.prototype.closest = function( s ) {
 | |
| 				var el = this;
 | |
| 				var ancestor = this;
 | |
| 				if ( ! document.documentElement.contains( el ) ) {
 | |
| 					return null;
 | |
| 				}
 | |
| 				do {
 | |
| 					if ( ancestor.matches( s ) ) {
 | |
| 						return ancestor;
 | |
| 					}
 | |
| 					ancestor = ancestor.parentElement;
 | |
| 				} while ( ancestor !== null );
 | |
| 				return null;
 | |
| 			};
 | |
| 		}
 | |
| 
 | |
| 		var getSiblings = function( elem ) {
 | |
| 			return Array.prototype.filter.call( elem.parentNode.children, function( sibling ) {
 | |
| 				return sibling !== elem;
 | |
| 			} );
 | |
| 		};
 | |
| 
 | |
| 		var allNavToggles = document.querySelectorAll( '.menu-toggle' ),
 | |
| 			dropdownToggles = document.querySelectorAll( 'nav .dropdown-menu-toggle' ),
 | |
| 			navLinks = document.querySelectorAll( 'nav .main-nav ul a' ),
 | |
| 			mobileMenuControls = document.querySelector( '.mobile-menu-control-wrapper' ),
 | |
| 			body = document.body,
 | |
| 			htmlEl = document.documentElement,
 | |
| 			i;
 | |
| 
 | |
| 		var enableDropdownArrows = function( nav ) {
 | |
| 			if ( nav && body.classList.contains( 'dropdown-hover' ) ) {
 | |
| 				var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' );
 | |
| 
 | |
| 				for ( i = 0; i < dropdownItems.length; i++ ) {
 | |
| 					var toggle = dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' );
 | |
| 					var parentLi = toggle.closest( 'li' );
 | |
| 					var subMenu = parentLi.querySelector( '.sub-menu, .children' );
 | |
| 
 | |
| 					toggle.setAttribute( 'tabindex', '0' );
 | |
| 					toggle.setAttribute( 'role', 'button' );
 | |
| 					toggle.setAttribute( 'aria-expanded', 'false' );
 | |
| 					toggle.setAttribute( 'aria-controls', subMenu.id );
 | |
| 					toggle.setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel );
 | |
| 				}
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		var disableDropdownArrows = function( nav ) {
 | |
| 			if ( nav && body.classList.contains( 'dropdown-hover' ) ) {
 | |
| 				var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' );
 | |
| 
 | |
| 				for ( i = 0; i < dropdownItems.length; i++ ) {
 | |
| 					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'tabindex' );
 | |
| 					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'role', 'presentation' );
 | |
| 					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-expanded' );
 | |
| 					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-controls' );
 | |
| 					dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-label' );
 | |
| 				}
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		var setDropdownArrowAttributes = function( arrow ) {
 | |
| 			if ( 'false' === arrow.getAttribute( 'aria-expanded' ) || ! arrow.getAttribute( 'aria-expanded' ) ) {
 | |
| 				arrow.setAttribute( 'aria-expanded', 'true' );
 | |
| 				arrow.setAttribute( 'aria-label', generatepressMenu.closeSubMenuLabel );
 | |
| 			} else {
 | |
| 				arrow.setAttribute( 'aria-expanded', 'false' );
 | |
| 				arrow.setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel );
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		/**
 | |
| 		 * Start mobile menu toggle.
 | |
| 		 *
 | |
| 		 * @param {Object} e     The event.
 | |
| 		 * @param {Object} _this The clicked item.
 | |
| 		 */
 | |
| 		var toggleNav = function( e, _this ) {
 | |
| 			if ( ! _this ) {
 | |
| 				_this = this;
 | |
| 			}
 | |
| 
 | |
| 			var parentContainer = '';
 | |
| 
 | |
| 			if ( _this.getAttribute( 'data-nav' ) ) {
 | |
| 				parentContainer = document.getElementById( _this.getAttribute( 'data-nav' ) );
 | |
| 			} else {
 | |
| 				parentContainer = document.getElementById( _this.closest( 'nav' ).getAttribute( 'id' ) );
 | |
| 			}
 | |
| 
 | |
| 			if ( ! parentContainer ) {
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			var isExternalToggle = false;
 | |
| 
 | |
| 			if ( _this.closest( '.mobile-menu-control-wrapper' ) ) {
 | |
| 				isExternalToggle = true;
 | |
| 			}
 | |
| 
 | |
| 			var nav = parentContainer.getElementsByTagName( 'ul' )[ 0 ];
 | |
| 
 | |
| 			if ( parentContainer.classList.contains( 'toggled' ) ) {
 | |
| 				parentContainer.classList.remove( 'toggled' );
 | |
| 				htmlEl.classList.remove( 'mobile-menu-open' );
 | |
| 
 | |
| 				if ( nav ) {
 | |
| 					nav.setAttribute( 'aria-hidden', 'true' );
 | |
| 				}
 | |
| 
 | |
| 				_this.setAttribute( 'aria-expanded', 'false' );
 | |
| 
 | |
| 				if ( isExternalToggle ) {
 | |
| 					mobileMenuControls.classList.remove( 'toggled' );
 | |
| 				} else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) {
 | |
| 					mobileMenuControls.classList.remove( 'toggled' );
 | |
| 				}
 | |
| 
 | |
| 				disableDropdownArrows( nav );
 | |
| 			} else {
 | |
| 				parentContainer.classList.add( 'toggled' );
 | |
| 				htmlEl.classList.add( 'mobile-menu-open' );
 | |
| 
 | |
| 				if ( nav ) {
 | |
| 					nav.setAttribute( 'aria-hidden', 'false' );
 | |
| 				}
 | |
| 
 | |
| 				_this.setAttribute( 'aria-expanded', 'true' );
 | |
| 
 | |
| 				if ( isExternalToggle ) {
 | |
| 					mobileMenuControls.classList.add( 'toggled' );
 | |
| 
 | |
| 					if ( mobileMenuControls.querySelector( '.search-item' ) ) {
 | |
| 						if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) {
 | |
| 							mobileMenuControls.querySelector( '.search-item' ).click();
 | |
| 						}
 | |
| 					}
 | |
| 				} else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) {
 | |
| 					mobileMenuControls.classList.add( 'toggled' );
 | |
| 				}
 | |
| 
 | |
| 				enableDropdownArrows( nav );
 | |
| 			}
 | |
| 		};
 | |
| 
 | |
| 		for ( i = 0; i < allNavToggles.length; i++ ) {
 | |
| 			allNavToggles[ i ].addEventListener( 'click', toggleNav, false );
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Open sub-menus
 | |
| 		 *
 | |
| 		 * @param {Object} e     The event.
 | |
| 		 * @param {Object} _this The clicked item.
 | |
| 		 */
 | |
| 		var toggleSubNav = function( e, _this ) {
 | |
| 			if ( ! _this ) {
 | |
| 				_this = this;
 | |
| 			}
 | |
| 
 | |
| 			if ( ( _this.closest( 'nav' ).classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) && ! body.classList.contains( 'dropdown-click' ) ) {
 | |
| 				e.preventDefault();
 | |
| 				var closestLi = _this.closest( 'li' );
 | |
| 
 | |
| 				setDropdownArrowAttributes( closestLi.querySelector( '.dropdown-menu-toggle' ) );
 | |
| 
 | |
| 				if ( closestLi.querySelector( '.sub-menu' ) ) {
 | |
| 					var subMenu = closestLi.querySelector( '.sub-menu' );
 | |
| 				} else {
 | |
| 					subMenu = closestLi.querySelector( '.children' );
 | |
| 				}
 | |
| 
 | |
| 				if ( generatepressMenu.toggleOpenedSubMenus ) {
 | |
| 					var siblings = getSiblings( closestLi );
 | |
| 
 | |
| 					for ( i = 0; i < siblings.length; i++ ) {
 | |
| 						if ( siblings[ i ].classList.contains( 'sfHover' ) ) {
 | |
| 							siblings[ i ].classList.remove( 'sfHover' );
 | |
| 							siblings[ i ].querySelector( '.toggled-on' ).classList.remove( 'toggled-on' );
 | |
| 							setDropdownArrowAttributes( siblings[ i ].querySelector( '.dropdown-menu-toggle' ) );
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				closestLi.classList.toggle( 'sfHover' );
 | |
| 				subMenu.classList.toggle( 'toggled-on' );
 | |
| 			}
 | |
| 
 | |
| 			e.stopPropagation();
 | |
| 		};
 | |
| 
 | |
| 		for ( i = 0; i < dropdownToggles.length; i++ ) {
 | |
| 			dropdownToggles[ i ].addEventListener( 'click', toggleSubNav, false );
 | |
| 			dropdownToggles[ i ].addEventListener( 'keypress', function( e ) {
 | |
| 				if ( 'Enter' === e.key || ' ' === e.key ) {
 | |
| 					toggleSubNav( e, this );
 | |
| 				}
 | |
| 			}, false );
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Disable the mobile menu if our toggle isn't visible.
 | |
| 		 * Makes it possible to style mobile item with .toggled class.
 | |
| 		 */
 | |
| 		var checkMobile = function() {
 | |
| 			var openedMobileMenus = document.querySelectorAll( '.toggled, .has-active-search' );
 | |
| 
 | |
| 			for ( i = 0; i < openedMobileMenus.length; i++ ) {
 | |
| 				var menuToggle = openedMobileMenus[ i ].querySelector( '.menu-toggle' );
 | |
| 
 | |
| 				if ( mobileMenuControls && ! menuToggle.closest( 'nav' ).classList.contains( 'mobile-menu-control-wrapper' ) ) {
 | |
| 					menuToggle = mobileMenuControls.querySelector( '.menu-toggle' );
 | |
| 				}
 | |
| 
 | |
| 				if ( menuToggle && menuToggle.offsetParent === null ) {
 | |
| 					if ( openedMobileMenus[ i ].classList.contains( 'toggled' ) ) {
 | |
| 						var remoteNav = false;
 | |
| 
 | |
| 						if ( openedMobileMenus[ i ].classList.contains( 'mobile-menu-control-wrapper' ) ) {
 | |
| 							remoteNav = true;
 | |
| 						}
 | |
| 
 | |
| 						if ( ! remoteNav ) {
 | |
| 							// Navigation is toggled, but .menu-toggle isn't visible on the page (display: none).
 | |
| 							var closestNav = openedMobileMenus[ i ].getElementsByTagName( 'ul' )[ 0 ],
 | |
| 								closestNavItems = closestNav ? closestNav.getElementsByTagName( 'li' ) : [],
 | |
| 								closestSubMenus = closestNav ? closestNav.getElementsByTagName( 'ul' ) : [];
 | |
| 						}
 | |
| 
 | |
| 						document.activeElement.blur();
 | |
| 						openedMobileMenus[ i ].classList.remove( 'toggled' );
 | |
| 
 | |
| 						htmlEl.classList.remove( 'mobile-menu-open' );
 | |
| 						menuToggle.setAttribute( 'aria-expanded', 'false' );
 | |
| 
 | |
| 						if ( ! remoteNav ) {
 | |
| 							for ( var li = 0; li < closestNavItems.length; li++ ) {
 | |
| 								closestNavItems[ li ].classList.remove( 'sfHover' );
 | |
| 							}
 | |
| 
 | |
| 							for ( var sm = 0; sm < closestSubMenus.length; sm++ ) {
 | |
| 								closestSubMenus[ sm ].classList.remove( 'toggled-on' );
 | |
| 							}
 | |
| 
 | |
| 							if ( closestNav ) {
 | |
| 								closestNav.removeAttribute( 'aria-hidden' );
 | |
| 							}
 | |
| 						}
 | |
| 
 | |
| 						disableDropdownArrows( openedMobileMenus[ i ] );
 | |
| 					}
 | |
| 
 | |
| 					if ( mobileMenuControls.querySelector( '.search-item' ) ) {
 | |
| 						if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) {
 | |
| 							mobileMenuControls.querySelector( '.search-item' ).click();
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		};
 | |
| 		window.addEventListener( 'resize', checkMobile, false );
 | |
| 		window.addEventListener( 'orientationchange', checkMobile, false );
 | |
| 
 | |
| 		if ( body.classList.contains( 'dropdown-hover' ) ) {
 | |
| 			/**
 | |
| 			 * Do some essential things when menu items are clicked.
 | |
| 			 */
 | |
| 			for ( i = 0; i < navLinks.length; i++ ) {
 | |
| 				navLinks[ i ].addEventListener( 'click', function( e ) {
 | |
| 					// Remove sfHover class if we're going to another site.
 | |
| 					if ( this.hostname !== window.location.hostname ) {
 | |
| 						document.activeElement.blur();
 | |
| 					}
 | |
| 
 | |
| 					var closestNav = this.closest( 'nav' );
 | |
| 					if ( closestNav.classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) {
 | |
| 						var url = this.getAttribute( 'href' );
 | |
| 
 | |
| 						// Open the sub-menu if the link has no destination
 | |
| 						if ( '#' === url || '' === url ) {
 | |
| 							e.preventDefault();
 | |
| 							var closestLi = this.closest( 'li' );
 | |
| 							closestLi.classList.toggle( 'sfHover' );
 | |
| 							var subMenu = closestLi.querySelector( '.sub-menu' );
 | |
| 
 | |
| 							if ( subMenu ) {
 | |
| 								subMenu.classList.toggle( 'toggled-on' );
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 				}, false );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if ( body.classList.contains( 'dropdown-hover' ) ) {
 | |
| 			var menuBarItems = document.querySelectorAll( '.menu-bar-items .menu-bar-item > a' );
 | |
| 
 | |
| 			/**
 | |
| 			 * Make menu items tab accessible when using the hover dropdown type
 | |
| 			 */
 | |
| 			var toggleFocus = function() {
 | |
| 				if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) {
 | |
| 					return;
 | |
| 				}
 | |
| 
 | |
| 				var self = this;
 | |
| 
 | |
| 				while ( -1 === self.className.indexOf( 'main-nav' ) ) {
 | |
| 					if ( 'li' === self.tagName.toLowerCase() ) {
 | |
| 						self.classList.toggle( 'sfHover' );
 | |
| 					}
 | |
| 
 | |
| 					self = self.parentElement;
 | |
| 				}
 | |
| 			};
 | |
| 
 | |
| 			/**
 | |
| 			 * Make our menu bar items tab accessible.
 | |
| 			 */
 | |
| 			var toggleMenuBarItemFocus = function() {
 | |
| 				if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) {
 | |
| 					return;
 | |
| 				}
 | |
| 
 | |
| 				var self = this;
 | |
| 
 | |
| 				while ( -1 === self.className.indexOf( 'menu-bar-items' ) ) {
 | |
| 					if ( self.classList.contains( 'menu-bar-item' ) ) {
 | |
| 						self.classList.toggle( 'sfHover' );
 | |
| 					}
 | |
| 
 | |
| 					self = self.parentElement;
 | |
| 				}
 | |
| 			};
 | |
| 
 | |
| 			for ( i = 0; i < navLinks.length; i++ ) {
 | |
| 				navLinks[ i ].addEventListener( 'focus', toggleFocus );
 | |
| 				navLinks[ i ].addEventListener( 'blur', toggleFocus );
 | |
| 			}
 | |
| 
 | |
| 			for ( i = 0; i < menuBarItems.length; i++ ) {
 | |
| 				menuBarItems[ i ].addEventListener( 'focus', toggleMenuBarItemFocus );
 | |
| 				menuBarItems[ i ].addEventListener( 'blur', toggleMenuBarItemFocus );
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		/**
 | |
| 		 * Make hover dropdown touch-friendly.
 | |
| 		 */
 | |
| 		if ( 'ontouchend' in document.documentElement && document.body.classList.contains( 'dropdown-hover' ) ) {
 | |
| 			var parentElements = document.querySelectorAll( '.sf-menu .menu-item-has-children' );
 | |
| 
 | |
| 			for ( i = 0; i < parentElements.length; i++ ) {
 | |
| 				parentElements[ i ].addEventListener( 'touchend', function( e ) {
 | |
| 					// Bail on mobile
 | |
| 					if ( this.closest( 'nav' ).classList.contains( 'toggled' ) ) {
 | |
| 						return;
 | |
| 					}
 | |
| 
 | |
| 					if ( e.touches.length === 1 || e.touches.length === 0 ) {
 | |
| 						// Prevent touch events within dropdown bubbling down to document
 | |
| 						e.stopPropagation();
 | |
| 
 | |
| 						// Toggle hover
 | |
| 						if ( ! this.classList.contains( 'sfHover' ) ) {
 | |
| 							// Prevent link on first touch
 | |
| 							if ( e.target === this || e.target.parentNode === this || e.target.parentNode.parentNode ) {
 | |
| 								e.preventDefault();
 | |
| 							}
 | |
| 
 | |
| 							// Close other sub-menus.
 | |
| 							var closestLi = this.closest( 'li' ),
 | |
| 								siblings = getSiblings( closestLi );
 | |
| 
 | |
| 							for ( i = 0; i < siblings.length; i++ ) {
 | |
| 								if ( siblings[ i ].classList.contains( 'sfHover' ) ) {
 | |
| 									siblings[ i ].classList.remove( 'sfHover' );
 | |
| 								}
 | |
| 							}
 | |
| 
 | |
| 							this.classList.add( 'sfHover' );
 | |
| 
 | |
| 							// Hide dropdown on touch outside
 | |
| 							var closeDropdown,
 | |
| 								thisItem = this;
 | |
| 
 | |
| 							document.addEventListener( 'touchend', closeDropdown = function( event ) {
 | |
| 								event.stopPropagation();
 | |
| 
 | |
| 								thisItem.classList.remove( 'sfHover' );
 | |
| 								document.removeEventListener( 'touchend', closeDropdown );
 | |
| 							} );
 | |
| 						}
 | |
| 					}
 | |
| 				} );
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }() );
 |