1/** 2 * File navigation.js. 3 * 4 * Handles toggling the navigation menu for small screens and enables TAB key 5 * navigation support for dropdown menus. 6 */ 7(function () { 8 var body, parent, container, button, menu, links, i, len, mobileOverlay; 9 10 container = document.getElementById('site-navigation'); 11 if (!container) { 12 return; 13 } 14 15 parent = document.getElementById('nav-container'); 16 if (!parent) { 17 return; 18 } 19 20 body = document.querySelector('body'); 21 22 button = container.getElementsByTagName('button')[0]; 23 if ('undefined' === typeof button) { 24 return; 25 } 26 27 menu = container.getElementsByTagName('ul')[0]; 28 29 mobileOverlay = document.getElementById('mobile-overlay'); 30 31 // Hide menu toggle button if menu is empty and return early. 32 if ('undefined' === typeof menu) { 33 button.style.display = 'none'; 34 return; 35 } 36 37 menu.setAttribute('aria-expanded', 'false'); 38 if (-1 === menu.className.indexOf('nav-menu')) { 39 menu.className += ' nav-menu'; 40 } 41 42 const doToggleOff = function () { 43 container.className = container.className.replace(' toggled', ''); 44 parent.className = parent.className.replace(' toggled', ''); 45 body.classList.remove('toggled'); 46 button.setAttribute('aria-expanded', 'false'); 47 menu.setAttribute('aria-expanded', 'false'); 48 mobileOverlay.classList.remove('visible'); 49 }; 50 51 const doToggleOn = function () { 52 container.className += ' toggled'; 53 parent.className += ' toggled'; 54 body.classList.add('toggled'); 55 button.setAttribute('aria-expanded', 'true'); 56 menu.setAttribute('aria-expanded', 'true'); 57 mobileOverlay.classList.add('visible'); 58 }; 59 60 button.onclick = function () { 61 if (-1 !== container.className.indexOf('toggled')) { 62 doToggleOff(); 63 } else { 64 doToggleOn(); 65 } 66 }; 67 68 mobileOverlay.addEventListener('click', function () { 69 doToggleOff(); 70 }); 71 72 // Get all the link elements within the menu. 73 links = menu.getElementsByTagName('a'); 74 75 // Each time a menu link is focused or blurred, toggle focus. 76 for (i = 0, len = links.length; i < len; i++) { 77 links[i].addEventListener('focus', toggleFocus, true); 78 links[i].addEventListener('blur', toggleFocus, true); 79 } 80 81 /** 82 * Sets or removes .focus class on an element. 83 */ 84 function toggleFocus() { 85 var self = this; 86 87 // Move up through the ancestors of the current link until we hit .nav-menu. 88 while (-1 === self.className.indexOf('nav-menu')) { 89 // On li elements toggle the class .focus. 90 if ('li' === self.tagName.toLowerCase()) { 91 if (-1 !== self.className.indexOf('focus')) { 92 self.className = self.className.replace(' focus', ''); 93 } else { 94 self.className += ' focus'; 95 } 96 } 97 98 self = self.parentElement; 99 } 100 } 101 102 /** 103 * Toggles `focus` class to allow submenu access on tablets. 104 */ 105 (function (container) { 106 var touchStartFn, 107 i, 108 parentLink = container.querySelectorAll( 109 '.menu-item-has-children > a, .page_item_has_children > a' 110 ); 111 112 if ('ontouchstart' in window) { 113 touchStartFn = function (e) { 114 var menuItem = this.parentNode, 115 i; 116 117 if (!menuItem.classList.contains('focus')) { 118 e.preventDefault(); 119 for (i = 0; i < menuItem.parentNode.children.length; ++i) { 120 if (menuItem === menuItem.parentNode.children[i]) { 121 continue; 122 } 123 menuItem.parentNode.children[i].classList.remove('focus'); 124 } 125 menuItem.classList.add('focus'); 126 } else { 127 menuItem.classList.remove('focus'); 128 } 129 }; 130 131 for (i = 0; i < parentLink.length; ++i) { 132 parentLink[i].addEventListener('touchstart', touchStartFn, false); 133 } 134 } 135 })(container); 136 137 // watch resize for closing sidebar 138 window.addEventListener('resize', function () { 139 if ( 140 this.innerWidth > 808 && 141 -1 !== container.className.indexOf('toggled') 142 ) { 143 container.className = container.className.replace(' toggled', ''); 144 parent.className = container.className.replace(' toggled', ''); 145 button.setAttribute('aria-expanded', 'false'); 146 menu.setAttribute('aria-expanded', 'false'); 147 } 148 }); 149})();
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.