1( function() { 2 'use strict'; 3 4 if ( 'querySelector' in document && 'addEventListener' in window ) { 5 /** 6 * matches() pollyfil 7 * 8 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility 9 */ 10 if ( ! Element.prototype.matches ) { 11 Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; 12 } 13 14 /** 15 * closest() pollyfil 16 * 17 * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility 18 * @param {Object} s The element to check. 19 * @return {Object} The closest object. 20 */ 21 if ( ! Element.prototype.closest ) { 22 Element.prototype.closest = function( s ) { 23 var el = this; 24 var ancestor = this; 25 if ( ! document.documentElement.contains( el ) ) { 26 return null; 27 } 28 do { 29 if ( ancestor.matches( s ) ) { 30 return ancestor; 31 } 32 ancestor = ancestor.parentElement; 33 } while ( ancestor !== null ); 34 return null; 35 }; 36 } 37 38 var getSiblings = function( elem ) { 39 return Array.prototype.filter.call( elem.parentNode.children, function( sibling ) { 40 return sibling !== elem; 41 } ); 42 }; 43 44 var allNavToggles = document.querySelectorAll( '.menu-toggle' ), 45 dropdownToggles = document.querySelectorAll( 'nav .dropdown-menu-toggle' ), 46 navLinks = document.querySelectorAll( 'nav .main-nav ul a' ), 47 mobileMenuControls = document.querySelector( '.mobile-menu-control-wrapper' ), 48 body = document.body, 49 htmlEl = document.documentElement, 50 i; 51 52 var enableDropdownArrows = function( nav ) { 53 if ( nav && body.classList.contains( 'dropdown-hover' ) ) { 54 var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' ); 55 56 for ( i = 0; i < dropdownItems.length; i++ ) { 57 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'tabindex', '0' ); 58 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'role', 'button' ); 59 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'aria-expanded', 'false' ); 60 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel ); 61 } 62 } 63 }; 64 65 var disableDropdownArrows = function( nav ) { 66 if ( nav && body.classList.contains( 'dropdown-hover' ) ) { 67 var dropdownItems = nav.querySelectorAll( 'li.menu-item-has-children' ); 68 69 for ( i = 0; i < dropdownItems.length; i++ ) { 70 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'tabindex' ); 71 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).setAttribute( 'role', 'presentation' ); 72 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-expanded' ); 73 dropdownItems[ i ].querySelector( '.dropdown-menu-toggle' ).removeAttribute( 'aria-label' ); 74 } 75 } 76 }; 77 78 var setDropdownArrowAttributes = function( arrow ) { 79 if ( 'false' === arrow.getAttribute( 'aria-expanded' ) || ! arrow.getAttribute( 'aria-expanded' ) ) { 80 arrow.setAttribute( 'aria-expanded', 'true' ); 81 arrow.setAttribute( 'aria-label', generatepressMenu.closeSubMenuLabel ); 82 } else { 83 arrow.setAttribute( 'aria-expanded', 'false' ); 84 arrow.setAttribute( 'aria-label', generatepressMenu.openSubMenuLabel ); 85 } 86 }; 87 88 /** 89 * Start mobile menu toggle. 90 * 91 * @param {Object} e The event. 92 * @param {Object} _this The clicked item. 93 */ 94 var toggleNav = function( e, _this ) { 95 if ( ! _this ) { 96 _this = this; 97 } 98 99 var parentContainer = ''; 100 101 if ( _this.getAttribute( 'data-nav' ) ) { 102 parentContainer = document.getElementById( _this.getAttribute( 'data-nav' ) ); 103 } else { 104 parentContainer = document.getElementById( _this.closest( 'nav' ).getAttribute( 'id' ) ); 105 } 106 107 if ( ! parentContainer ) { 108 return; 109 } 110 111 var isExternalToggle = false; 112 113 if ( _this.closest( '.mobile-menu-control-wrapper' ) ) { 114 isExternalToggle = true; 115 } 116 117 var nav = parentContainer.getElementsByTagName( 'ul' )[ 0 ]; 118 119 if ( parentContainer.classList.contains( 'toggled' ) ) { 120 parentContainer.classList.remove( 'toggled' ); 121 htmlEl.classList.remove( 'mobile-menu-open' ); 122
123 if ( nav ) { 124 nav.setAttribute( 'aria-hidden', 'true' ); 125 } 126 127 _this.setAttribute( 'aria-expanded', 'false' ); 128 129 if ( isExternalToggle ) { 130 mobileMenuControls.classList.remove( 'toggled' ); 131 } else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) { 132 mobileMenuControls.classList.remove( 'toggled' ); 133 } 134 135 disableDropdownArrows( nav ); 136 } else { 137 parentContainer.classList.add( 'toggled' ); 138 htmlEl.classList.add( 'mobile-menu-open' ); 139 140 if ( nav ) { 141 nav.setAttribute( 'aria-hidden', 'false' ); 142 } 143 144 _this.setAttribute( 'aria-expanded', 'true' ); 145 146 if ( isExternalToggle ) { 147 mobileMenuControls.classList.add( 'toggled' ); 148 149 if ( mobileMenuControls.querySelector( '.search-item' ) ) { 150 if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) { 151 mobileMenuControls.querySelector( '.search-item' ).click(); 152 } 153 } 154 } else if ( mobileMenuControls && parentContainer.classList.contains( 'main-navigation' ) ) { 155 mobileMenuControls.classList.add( 'toggled' ); 156 } 157 158 enableDropdownArrows( nav ); 159 } 160 }; 161 162 for ( i = 0; i < allNavToggles.length; i++ ) { 163 allNavToggles[ i ].addEventListener( 'click', toggleNav, false ); 164 } 165 166 /** 167 * Open sub-menus 168 * 169 * @param {Object} e The event. 170 * @param {Object} _this The clicked item. 171 */ 172 var toggleSubNav = function( e, _this ) { 173 if ( ! _this ) { 174 _this = this; 175 } 176 177 if ( ( _this.closest( 'nav' ).classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) && ! body.classList.contains( 'dropdown-click' ) ) { 178 e.preventDefault(); 179 var closestLi = _this.closest( 'li' ); 180 181 setDropdownArrowAttributes( closestLi.querySelector( '.dropdown-menu-toggle' ) ); 182 183 if ( closestLi.querySelector( '.sub-menu' ) ) { 184 var subMenu = closestLi.querySelector( '.sub-menu' ); 185 } else { 186 subMenu = closestLi.querySelector( '.children' ); 187 } 188 189 if ( generatepressMenu.toggleOpenedSubMenus ) { 190 var siblings = getSiblings( closestLi ); 191 192 for ( i = 0; i < siblings.length; i++ ) { 193 if ( siblings[ i ].classList.contains( 'sfHover' ) ) { 194 siblings[ i ].classList.remove( 'sfHover' ); 195 siblings[ i ].querySelector( '.toggled-on' ).classList.remove( 'toggled-on' ); 196 setDropdownArrowAttributes( siblings[ i ].querySelector( '.dropdown-menu-toggle' ) ); 197 } 198 } 199 } 200 201 closestLi.classList.toggle( 'sfHover' ); 202 subMenu.classList.toggle( 'toggled-on' ); 203 } 204 205 e.stopPropagation(); 206 }; 207 208 for ( i = 0; i < dropdownToggles.length; i++ ) { 209 dropdownToggles[ i ].addEventListener( 'click', toggleSubNav, false ); 210 dropdownToggles[ i ].addEventListener( 'keypress', function( e ) { 211 if ( 'Enter' === e.key || ' ' === e.key ) { 212 toggleSubNav( e, this ); 213 } 214 }, false ); 215 } 216 217 /** 218 * Disable the mobile menu if our toggle isn't visible. 219 * Makes it possible to style mobile item with .toggled class. 220 */ 221 var checkMobile = function() { 222 var openedMobileMenus = document.querySelectorAll( '.toggled, .has-active-search' ); 223 224 for ( i = 0; i < openedMobileMenus.length; i++ ) { 225 var menuToggle = openedMobileMenus[ i ].querySelector( '.menu-toggle' ); 226 227 if ( mobileMenuControls && ! menuToggle.closest( 'nav' ).classList.contains( 'mobile-menu-control-wrapper' ) ) { 228 menuToggle = mobileMenuControls.querySelector( '.menu-toggle' ); 229 } 230 231 if ( menuToggle && menuToggle.offsetParent === null ) { 232 if ( openedMobileMenus[ i ].classList.contains( 'toggled' ) ) { 233 var remoteNav = false; 234 235 if ( openedMobileMenus[ i ].classList.contains( 'mobile-menu-control-wrapper' ) ) { 236 remoteNav = true; 237 } 238 239 if ( ! remoteNav ) { 240 // Navigation is toggled, but .menu-toggle isn't visible on the page (display: none). 241 var closestNav = openedMobileMenus[ i ].getElementsByTagName( 'ul' )[ 0 ], 242 closestNavItems = closestNav ? closestNav.getElementsByTagName( 'li' ) : [], 243 closestSubMenus = closestNav ? closestNav.getElementsByTagName( 'ul' ) : []; 244 } 245 246 document.activeElement.blur(); 247 openedMobileMenus[ i ].classList.remove( 'toggled' ); 248 249 htmlEl.classList.remove( 'mobile-menu-open' ); 250 menuToggle.setAttribute( 'aria-expanded', 'false' ); 251 252 if ( ! remoteNav ) { 253 for ( var li = 0; li < closestNavItems.length; li++ ) { 254 closestNavItems[ li ].classList.remove( 'sfHover' ); 255 } 256 257 for ( var sm = 0; sm < closestSubMenus.length; sm++ ) { 258 closestSubMenus[ sm ].classList.remove( 'toggled-on' ); 259 } 260 261 if ( closestNav ) { 262 closestNav.removeAttribute( 'aria-hidden' ); 263 } 264 } 265
266 disableDropdownArrows( openedMobileMenus[ i ] ); 267 } 268 269 if ( mobileMenuControls.querySelector( '.search-item' ) ) { 270 if ( mobileMenuControls.querySelector( '.search-item' ).classList.contains( 'active' ) ) { 271 mobileMenuControls.querySelector( '.search-item' ).click(); 272 } 273 } 274 } 275 } 276 }; 277 window.addEventListener( 'resize', checkMobile, false ); 278 window.addEventListener( 'orientationchange', checkMobile, false ); 279 280 if ( body.classList.contains( 'dropdown-hover' ) ) { 281 /** 282 * Do some essential things when menu items are clicked. 283 */ 284 for ( i = 0; i < navLinks.length; i++ ) { 285 navLinks[ i ].addEventListener( 'click', function( e ) { 286 // Remove sfHover class if we're going to another site. 287 if ( this.hostname !== window.location.hostname ) { 288 document.activeElement.blur(); 289 } 290 291 var closestNav = this.closest( 'nav' ); 292 if ( closestNav.classList.contains( 'toggled' ) || htmlEl.classList.contains( 'slide-opened' ) ) { 293 var url = this.getAttribute( 'href' ); 294 295 // Open the sub-menu if the link has no destination 296 if ( '#' === url || '' === url ) { 297 e.preventDefault(); 298 var closestLi = this.closest( 'li' ); 299 closestLi.classList.toggle( 'sfHover' ); 300 var subMenu = closestLi.querySelector( '.sub-menu' ); 301 302 if ( subMenu ) { 303 subMenu.classList.toggle( 'toggled-on' ); 304 } 305 } 306 } 307 }, false ); 308 } 309 } 310 311 if ( body.classList.contains( 'dropdown-hover' ) ) { 312 var menuBarItems = document.querySelectorAll( '.menu-bar-items .menu-bar-item > a' ); 313 314 /** 315 * Make menu items tab accessible when using the hover dropdown type 316 */ 317 var toggleFocus = function() { 318 if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) { 319 return; 320 } 321 322 var self = this; 323 324 while ( -1 === self.className.indexOf( 'main-nav' ) ) { 325 if ( 'li' === self.tagName.toLowerCase() ) { 326 self.classList.toggle( 'sfHover' ); 327 } 328 329 self = self.parentElement; 330 } 331 }; 332 333 /** 334 * Make our menu bar items tab accessible. 335 */ 336 var toggleMenuBarItemFocus = function() { 337 if ( this.closest( 'nav' ).classList.contains( 'toggled' ) || this.closest( 'nav' ).classList.contains( 'slideout-navigation' ) ) { 338 return; 339 } 340 341 var self = this; 342 343 while ( -1 === self.className.indexOf( 'menu-bar-items' ) ) { 344 if ( self.classList.contains( 'menu-bar-item' ) ) { 345 self.classList.toggle( 'sfHover' ); 346 } 347 348 self = self.parentElement; 349 } 350 }; 351 352 for ( i = 0; i < navLinks.length; i++ ) { 353 navLinks[ i ].addEventListener( 'focus', toggleFocus ); 354 navLinks[ i ].addEventListener( 'blur', toggleFocus ); 355 } 356 357 for ( i = 0; i < menuBarItems.length; i++ ) { 358 menuBarItems[ i ].addEventListener( 'focus', toggleMenuBarItemFocus ); 359 menuBarItems[ i ].addEventListener( 'blur', toggleMenuBarItemFocus ); 360 } 361 } 362 363 /** 364 * Make hover dropdown touch-friendly. 365 */ 366 if ( 'ontouchend' in document.documentElement && document.body.classList.contains( 'dropdown-hover' ) ) { 367 var parentElements = document.querySelectorAll( '.sf-menu .menu-item-has-children' ); 368 369 for ( i = 0; i < parentElements.length; i++ ) { 370 parentElements[ i ].addEventListener( 'touchend', function( e ) { 371 // Bail on mobile 372 if ( this.closest( 'nav' ).classList.contains( 'toggled' ) ) { 373 return; 374 } 375 376 if ( e.touches.length === 1 || e.touches.length === 0 ) { 377 // Prevent touch events within dropdown bubbling down to document 378 e.stopPropagation(); 379 380 // Toggle hover 381 if ( ! this.classList.contains( 'sfHover' ) ) { 382 // Prevent link on first touch 383 if ( e.target === this || e.target.parentNode === this || e.target.parentNode.parentNode ) { 384 e.preventDefault(); 385 } 386 387 // Close other sub-menus. 388 var closestLi = this.closest( 'li' ), 389 siblings = getSiblings( closestLi ); 390 391 for ( i = 0; i < siblings.length; i++ ) { 392 if ( siblings[ i ].classList.contains( 'sfHover' ) ) { 393 siblings[ i ].classList.remove( 'sfHover' ); 394 } 395 } 396 397 this.classList.add( 'sfHover' ); 398 399 // Hide dropdown on touch outside 400 var closeDropdown, 401 thisItem = this; 402 403 document.addEventListener( 'touchend', closeDropdown = function( event ) { 404 event.stopPropagation(); 405 406 thisItem.classList.remove( 'sfHover' ); 407 document.removeEventListener( 'touchend', closeDropdown ); 408 } ); 409 } 410 } 411 } ); 412 } 413 } 414 } 415}() );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.