1const observer = new MutationObserver(() => { 2 const accessibilityElement = document.getElementById("userwayAccessibilityIcon"); 3 4 // Check if the screen width matches mobile view 5 if (accessibilityElement) { 6 accessibilityElement.removeAttribute("style"); 7 observer.disconnect(); // Stop observing after the element is found 8 } 9}); 10 11observer.observe(document.body, { childList: true, subtree: true }); 12 13document.addEventListener("DOMContentLoaded", () => { 14 const pageHeader = document.querySelector('header'); 15 /* --- 16 Mobile (hamburger) trigger menu 17 */ 18 const menuTrigger = document.getElementById("menutrigger"); 19 20 menuTrigger.addEventListener("click", (event) => { 21 const mobileMenu = document.getElementById(menuTrigger.getAttribute("aria-controls")); 22 23 mobileMenu.setAttribute("aria-hidden", 24 mobileMenu.getAttribute("aria-hidden") === "true" 25 ? "false" 26 : "true" 27 ); 28 29 menuTrigger.setAttribute("aria-expanded", 30 menuTrigger.getAttribute("aria-expanded") === "true" 31 ? "false" 32 : "true" 33 ); 34 35 if (menuTrigger.getAttribute('aria-expanded') === "true") { 36 pageHeader.classList.add('mobile-menu-open'); 37 document.documentElement.style.overflow = 'hidden'; // Applies to the <html> tag 38 document.body.style.overflow = 'hidden'; // Applies to the <body> tag 39 40 const sideMenuBottomLinks = document.getElementById("sideMenuBottomLinks"); 41 if (sideMenuBottomLinks) { 42 sideMenuBottomLinks.style.display = "flex"; 43 } 44 45 // FIX: Ensure main-nav-menu stays visible when mobile menu opens 46 const mainNavMenu = document.getElementById("main-nav-menu"); 47 if (mainNavMenu) { 48 mainNavMenu.classList.add('fixed', 'top-0', 'w-screen'); 49 mainNavMenu.style.zIndex = '9999'; // Ensure it's on top 50 } 51 52 } else { 53 pageHeader.classList.remove('mobile-menu-open'); 54 document.documentElement.style.overflow = 'auto'; // Applies to the <html> tag 55 document.body.style.overflow = 'auto'; // Applies to the <body> tag 56 57 const sideMenuBottomLinks = document.getElementById("sideMenuBottomLinks"); 58 if (sideMenuBottomLinks) { 59 sideMenuBottomLinks.style.display = "none"; 60 } 61 62 // Reset z-index when closing 63 const mainNavMenu = document.getElementById("main-nav-menu"); 64 if (mainNavMenu) { 65 mainNavMenu.style.zIndex = ''; 66 } 67 } 68 69 }); 70 71 72 /*--- 73 Mobile- and footer menu 74 75 MenuLists: these are used in the mobile menu and in the footer. 76 The footer ones work individually but the mobile menu ones work together: 77 there can only be one of the menu lists open, so when clicking on one of them, 78 the already open list will close. 79 */ 80 81 const liveChatButton = document.getElementById('open-live-chat-mobile'); 82 83 if (liveChatButton) { 84 liveChatButton.addEventListener('click', () => { 85 menutrigger.checked = false; 86 window.liveChat.show(); 87 }); 88 } 89 90 const menuLists = document.querySelectorAll('[data-menulist]'); 91 92 menuLists.forEach(elem => { 93 const title = elem.querySelector('h3'); 94 const isHeaderItem = elem.closest('header'); 95 title.addEventListener('click', () => toggleMobileMenu(title, isHeaderItem)); 96 }); 97 98 function toggleMobileMenu(title, isHeaderItem) { 99 const isOpenClass = "is-open"; 100 101 pageHeader.querySelectorAll(".subnav").forEach((item) => { 102 item.setAttribute("aria-hidden", true); 103 item.removeAttribute("tabindex"); 104 }); 105 106 document.querySelectorAll("[data-menulist] > div").forEach((item) => { 107 item.setAttribute("aria-hidden", true); 108 item.removeAttribute("tabindex"); 109 }); 110 111 if (isHeaderItem) { 112 const openMenuList = document.querySelector(`[data-menulist] .${isOpenClass}`); 113 114 if (openMenuList && openMenuList != title) { 115 openMenuList.classList.remove(isOpenClass); 116 } 117 } 118 119 if (title.classList.contains(isOpenClass)) { 120 title.classList.remove(isOpenClass) 121 title.setAttribute("aria-expanded", false); 122 } else { 123 title.classList.add(isOpenClass); 124 title.setAttribute("aria-expanded", true); 125 document.getElementById(title.getAttribute("aria-controls")).setAttribute("aria-hidden", false); 126 } 127 } 128 129 function startLiveChatFromMobileMenu(event) { 130 event.preventDefault(); 131 window.liveChat.show(); 132 } 133 134 /* --- 135 Desktop menu 136 137 SubNavigation: on desktop for every main navigation item there is a subnavigation component with its own content; 138 The callback function toggleDesktopMenu handles opening and closing the subnavigation. 139 */ 140 141 const mainNavItems = document.querySelectorAll('[data-main-nav-item]'); 142 const headerBackdrop = document.getElementById('header-backdrop'); 143
144 mainNavItems.forEach(elem => { 145 const title = elem.getAttribute('data-main-nav-item'); 146 147 148 elem.addEventListener('click', (event) => toggleDesktopMenu(event, title)); 149 }); 150 151 function toggleDesktopMenu(event, title) { 152 event.preventDefault(); 153 154 // Getting tabindex from main header element 155 const tabAttribute = event.target.getAttribute('tabindex'); 156 let targetElement = event.target; 157 158 if (targetElement.tagName != 'A') { 159 targetElement = targetElement.closest('a'); 160 } 161 162 const subnav = document.getElementById(title); 163 const subNavOpenClass = "subnav-open"; 164 const isActiveClass = "is-active"; 165 const openSubnav = document.querySelector(`.subnav.${subNavOpenClass}`); 166 const isActiveItem = document.querySelector(`header .${isActiveClass}`); 167 168 headerBackdrop.classList.remove(isActiveClass); 169 pageHeader.querySelectorAll(".subnav").forEach((item) => { 170 item.setAttribute("aria-hidden", true); 171 }); 172 173 document.querySelectorAll("#main-nav-menu a").forEach((item) => { 174 item.setAttribute("aria-expanded", false); 175 }); 176 177 document.querySelector('#Search [data-search-results]')?.setAttribute("aria-hidden", true); 178 document.querySelector('#Search [data-search-suggestions]')?.setAttribute("aria-hidden", false); 179 180 if (openSubnav && openSubnav !== subnav) { 181 openSubnav.classList.remove(subNavOpenClass); 182 183 //Remove tabindex from sub header element and set new tabindex 184 openSubnav.querySelectorAll('.tabIndexSet').forEach((elem) => { 185 if (elem) { 186 elem.removeAttribute('tabindex'); 187 elem.setAttribute('tabindex', '-1'); 188 } else { 189 console.error('Sub-element not found'); 190 } 191 }); 192 193 if (isActiveItem) { 194 isActiveItem.classList.remove(isActiveClass); 195 } 196 } 197 198 if (subnav) { 199 if (subnav.classList.contains(subNavOpenClass)) { 200 pageHeader.classList.remove(subNavOpenClass); 201 subnav.classList.remove(subNavOpenClass); 202 203 //Remove tabindex from sub header element and set new tabindex 204 subnav.querySelectorAll('.tabIndexSet').forEach((elem) => { 205 if (elem) { 206 elem.removeAttribute('tabindex'); 207 elem.setAttribute('tabindex', '-1'); 208 } else { 209 console.error('Sub-element not found'); 210 } 211 }); 212 targetElement.classList.remove(isActiveClass); 213 subnav.setAttribute("aria-hidden", true); 214 215 } else { 216 pageHeader.classList.add(subNavOpenClass); 217 subnav.classList.add(subNavOpenClass); 218 219 //Remove tabindex from sub header element and set new tabindex 220 subnav.querySelectorAll('.tabIndexSet').forEach((elem) => { 221 if (elem) { 222 elem.removeAttribute('tabindex', '-1'); 223 elem.setAttribute('tabindex', tabAttribute); 224 } else { 225 console.error('Sub-element not found'); 226 } 227 }); 228 229 targetElement.classList.add(isActiveClass); 230 targetElement.setAttribute("aria-expanded", true); 231 subnav.setAttribute("aria-hidden", false); 232 233 headerBackdrop.classList.add(isActiveClass); 234 235 window.addEventListener("click", closeDesktopMenu); 236 headerBackdrop.addEventListener("click", closeDesktopMenu); 237 document.addEventListener("keydown", closeByEscapeKey); 238 } 239 } 240 241 } 242 243 /* --- 244 Closing all menu's 245 */ 246 247 function closeDesktopMenu(event) { 248 if ((event?.type == "keydown" && event?.keyCode === 27) || !event?.target.closest('.wrapper > header')) { 249 const isActiveClass = "is-active"; 250 const isOpenClass = "is-open"; 251 252 pageHeader.classList.remove("subnav-open"); 253 254 pageHeader.querySelectorAll(".subnav").forEach((item) => { 255 item.setAttribute("aria-hidden", true) 256 }); 257 258 document.querySelector('#Search [data-search-results]')?.setAttribute("aria-hidden", true); 259 document.querySelector('#Search [data-search-suggestions]')?.setAttribute("aria-hidden", false); 260 261 document.querySelectorAll("#main-nav-menu a").forEach((item) => { 262 item.setAttribute("aria-expanded", false); 263 item.classList.remove(isActiveClass); 264 }); 265 266 headerBackdrop.classList.remove(isActiveClass); 267 268 pageHeader.querySelector(`div.${isOpenClass}`)?.classList.remove(isOpenClass); 269 270 pageHeader.querySelectorAll(".subnav-open").forEach((item) => { 271 item.classList.remove("subnav-open"); 272 }); 273 pageHeader.querySelectorAll(`#desktop-menu li a.${isActiveClass}`).forEach((item) => { 274 item.classList.remove(isActiveClass); 275 item.removeAttribute('tabindex'); // //Remove tabindex from sub header element 276 }); 277 278 279 document.removeEventListener("keydown", closeByEscapeKey); 280 headerBackdrop.removeEventListener("click", closeDesktopMenu); 281 } 282 } 283 284 function closeByEscapeKey(event) { 285 if (event.keyCode === 27) { 286 closeDesktopMenu(null); 287 } 288 289 } 290 291 292 // Added aria-expanded for accessibility 293 var megaMenuLinks = document.querySelectorAll('navElementDesktop'); 294 for (var i = 0; i < megaMenuLinks.length; i++) { 295 megaMenuLinks[i].addEventListener('click', handleLinkClicked) 296 } 297 298 function handleLinkClicked(e) { 299 e.preventDefault(); 300 var target = document.querySelector(`${e.target.getAttribute("navElement")}`); 301 302 if (target.getAttribute('aria-expanded') === 'true') { 303 target.setAttribute('aria-expanded', 'false'); 304 } else { 305 target.setAttribute('aria-expanded', 'true'); 306 } 307 } 308 309 /* --- 310 Search 311 */ 312 313 const toggleMobileSearch = document.querySelector('[data-toggle-search]'); 314 const mobileMenuContent = document.querySelector('[data-mob-menu]'); 315 const toggleMobileMenuBack = document.querySelector('[data-mob-backtomenu]'); 316 const mobileSearchContent = document.querySelector('[data-mob-search]'); 317 318 toggleMobileSearch?.addEventListener('click', (event) => toggleMobileMenuContent(event, 'search')); 319 toggleMobileMenuBack?.addEventListener('click', (event) => toggleMobileMenuContent(event, 'menu')); 320 321 function toggleMobileMenuContent(event, target) { 322 console.log(event.type, 'toggle content to ' + target); 323 324 if (target == 'search') { 325 if (mobileMenuContent) { 326 mobileMenuContent.classList.add('hidden'); 327 mobileMenuContent.setAttribute("aria-hidden", true); 328 toggleMobileSearch.setAttribute("aria-expanded", false); 329 toggleMobileMenuBack.setAttribute("aria-expanded", true); 330 } 331 if (mobileSearchContent) { 332 mobileSearchContent.classList.remove('hidden'); 333 mobileSearchContent.setAttribute("aria-hidden", false); 334 toggleMobileSearch.setAttribute("aria-expanded", true); 335 toggleMobileMenuBack.setAttribute("aria-expanded", false); 336 } 337 } 338 if (target == 'menu') { 339 if (mobileMenuContent) { 340 mobileMenuContent.classList.remove('hidden'); 341 mobileMenuContent.setAttribute("aria-hidden", false); 342 toggleMobileSearch.setAttribute("aria-expanded", true); 343 toggleMobileMenuBack.setAttribute("aria-expanded", false); 344 } 345 if (mobileSearchContent) { 346 mobileSearchContent.classList.add('hidden'); 347 mobileSearchContent.setAttribute("aria-hidden", true); 348 toggleMobileSearch.setAttribute("aria-expanded", false); 349 toggleMobileMenuBack.setAttribute("aria-expanded", true); 350 } 351 } 352 } 353 354 /* --- 355 Language switch 356 */ 357 358 const languageSwitch = document.getElementById('languageSwitch'); 359 const languageSwitchDropdown = document.getElementById('languageSwitchDropdown'); 360 const isOpenClass = "is-open"; 361 languageSwitch.addEventListener('click', toggleLanguageSwitchDropdown); 362 363 function toggleLanguageSwitchDropdown(event) { 364 if (languageSwitch.parentElement.classList.contains(isOpenClass)) { 365 languageSwitch.parentElement.classList.remove(isOpenClass); 366 languageSwitch.setAttribute("aria-expanded", false); 367 languageSwitchDropdown.setAttribute("aria-hidden", true); 368 } else { 369 languageSwitch.parentElement.classList.add(isOpenClass); 370 languageSwitch.setAttribute("aria-expanded", true); 371 languageSwitchDropdown.setAttribute("aria-hidden", false); 372 } 373 } 374 375 /* --- 376 General close any open dropdown or menu when clicking outside 377 */ 378 document.addEventListener('click', (e) => { 379 if (!e.target.closest('#languageSwitch')) { 380 languageSwitch.parentElement.classList.remove('is-open'); 381 languageSwitch.setAttribute("aria-expanded", false); 382 languageSwitchDropdown.setAttribute("aria-hidden", true); 383 } 384 385 // TODO: add scripting for closing the submenu and search dropdown when it is o
385pen 386 }); 387 388 /* --- 389 Header sticky when scrolling up 390 */ 391 392 let lastScrollTop = 0; 393 394 document.addEventListener('scroll', () => { 395 const st = window.scrollY || document.documentElement.scrollTop; 396 pageHeader.classList.toggle('is-scrolling-down', st > lastScrollTop); 397 pageHeader.classList.toggle('is-scrolling-up', st <= lastScrollTop); 398 399 const mh = document.getElementById("main-nav-menu"); 400 if (mh) { 401 // At document top, never pin #main-nav-menu as fixed â it leaves the flow and overlaps content below. 402 if (st <= 0) { 403 mh.classList.remove('fixed', 'top-0', 'w-screen'); 404 } else { 405 const pinMainNav = st <= lastScrollTop; 406 mh.classList.toggle('fixed', pinMainNav); 407 mh.classList.toggle('top-0', pinMainNav); 408 mh.classList.toggle('w-screen', pinMainNav); 409 } 410 } 411 412 lastScrollTop = st <= 0 ? 0 : st; 413 }, false); 414});
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.