1/* eslint-disable */ 2 3// Main navigation script 4(() => { 5 // Variables 6 let navTimeout = false; 7 8 // Selectors 9 const searchWrapperClass = '.search-wrapper'; // Used in variable and in 'closest()' 10 const headerNavigationClass = '.header__navigation'; // Used in variable and in 'closest()' 11 const navigationList = document.querySelector('.navigation__list'); 12 const searchToggle = document.querySelector('.search-toggle'); 13 const searchWrapper = document.querySelector(searchWrapperClass); 14 const search = document.querySelector('#search'); 15 const searchCancel = document.querySelector('.search__cancel'); 16 const searchSubmit = document.querySelector('.search__submit'); 17 const navigationToggle = document.querySelector('.navigation-toggle'); 18 const searchVisibleClass = 'search:visible'; 19 const navigationVisibleClass = 'navigation:visible'; 20 const hiddenMobileClass = 'hidden:mobile'; 21 22 // console.log(searchWrapperClass); 23 // console.log(headerNavigationClass); 24 // console.log(navigationList); 25 // console.log(searchToggle); 26 // console.log(searchWrapper); 27 // console.log(search); 28 // console.log(searchCancel); 29 // console.log(searchSubmit); 30 // console.log(navigationToggle); 31 // console.log(searchVisibleClass); 32 // console.log(navigationVisibleClass); 33 // console.log(hiddenMobileClass); 34 35 // Set initial visibility 36 // ====================== 37 if (navigationList) { 38 navigationList.classList.add(hiddenMobileClass); 39 } 40 41 // Toggle Search 42 // ============= 43 function toggleSearch(type) { 44 // Clear current timeout on click to avoid transition problems 45 if (navTimeout) { 46 clearTimeout(navTimeout); 47 } 48 // Open 49 if (type === 'open') { 50 searchWrapper.classList.remove(hiddenMobileClass); 51 search.removeAttribute('tabindex'); 52 searchCancel.removeAttribute('tabindex'); 53 searchSubmit.removeAttribute('tabindex'); 54 // Set timeout so transition can kick in after hidden is removed 55 navTimeout = setTimeout(() => { 56 document.body.classList.add(searchVisibleClass); 57 search.focus(); 58 }, 16); 59 } 60 if (type === 'close') { 61 document.body.classList.remove(searchVisibleClass); 62 searchToggle.focus(); 63 search.setAttribute('tabindex', '-1'); 64 searchCancel.setAttribute('tabindex', '-1'); 65 searchSubmit.setAttribute('tabindex', '-1'); 66 } 67 } 68 69 // Search event listener 70 // ===================== 71 if (search) { 72 search.addEventListener('focus', () => { 73 toggleSearch('open'); 74 }); 75 // searchCancel.addEventListener('blur', () => { 76 // toggleSearch('close'); 77 // }); 78 // searchToggle.addEventListener('focus', () => { 79 // if (document.body.classList.contains(searchVisibleClass)) { 80 // toggleSearch('close'); 81 // } 82 // }); 83 } 84 85 // Toggle Menu 86 // =========== 87 function toggleMenu(type) { 88 // Clear current timeout on click to avoid transition problems 89 if (navTimeout) { 90 clearTimeout(navTimeout); 91 } 92 93 // Open 94 if (type === 'open') { 95 navigationList.classList.remove(hiddenMobileClass); 96 navigationToggle.setAttribute('aria-expanded', 'true'); 97 // Set timeout so transition can kick in after hidden is removed 98 navTimeout = setTimeout(() => { 99 document.body.classList.add(navigationVisibleClass); 100 }, 16); 101 } 102 103 // Close 104 if (type === 'close') { 105 document.body.classList.remove(navigationVisibleClass); 106 // Set timeout so transition can kick in before hidden is added 107 navTimeout = setTimeout(() => { 108 navigationList.classList.add(hiddenMobileClass); 109 navigationToggle.setAttribute('aria-expanded', 'false'); 110 }, 200); 111 } 112 } 113 114 // Search open 115 // =========== 116 // (button doesn't need a close since it's hidden and focus is being set to input) 117 if (search) { 118 // searchToggle.addEventListener('click', () => { 119 // toggleSearch('open'); 120 // }); 121 } 122 123 // Toggle navigation 124 // ================= 125 if (navigationToggle) { 126 navigationToggle.addEventListener('click', () => {
127 if (navigationList.classList.contains(hiddenMobileClass)) { 128 toggleMenu('open'); 129 } else { 130 toggleMenu('close'); 131 } 132 }); 133 } 134 135 // Erase / close search 136 // ==================== 137 if (searchCancel) { 138 searchCancel.addEventListener('click', () => { 139 if (search.value === '') { 140 toggleSearch('close'); 141 } else { 142 search.value = ''; 143 search.focus(); 144 } 145 }); 146 } 147 148 // Set focus on submit when submit is empty 149 if (searchSubmit) { 150 searchSubmit.addEventListener('click', ev => { 151 if (search.value === '') { 152 ev.preventDefault(); 153 search.focus(); 154 } 155 }); 156 } 157 158 // Close search and navigation on click outside 159 // ============================================ 160 document.addEventListener('click', ev => { 161 if (!ev.target.closest(searchWrapperClass) && document.body.classList.contains(searchVisibleClass)) { 162 toggleSearch('close'); 163 } 164 if (!ev.target.closest(headerNavigationClass) && document.body.classList.contains(navigationVisibleClass)) { 165 toggleMenu('close'); 166 } 167 }); 168 169 // Close search and navigation on esc key 170 // ====================================== 171 document.addEventListener('keydown', ev => { 172 if (ev.key === 'Escape') { 173 if (document.body.classList.contains(searchVisibleClass)) { 174 toggleSearch('close'); 175 } 176 if (document.body.classList.contains(navigationVisibleClass)) { 177 toggleMenu('close'); 178 } 179 } 180 }); 181})(); 182 183/* eslint-enable */
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.