1document.addEventListener("DOMContentLoaded", () => { 2 3 initStickyHeader(); 4 initDesktopSearch(); 5 initMobileSearch(); 6 initMobileAccount(); 7 initLeftNav(); 8 9 document.querySelectorAll(".js-primary-nav").forEach((el, i) => { 10 try { 11 initPrimaryNav(el, i); 12 } catch (ex) { } 13 }); 14 15 document.querySelectorAll(".js-mega-menu").forEach((el, i) => { 16 try { 17 initMegaMenu(el, i); 18 } catch (ex) { } 19 }); 20 21 document.querySelectorAll(".js-auxiliary-nav").forEach((el, i) => { 22 try { 23 initAuxNav(el, i); 24 } catch (ex) { } 25 }); 26 27 document.querySelectorAll(".js-mobile-nav-menu").forEach((el, i) => { 28 initMobileNav(el, i); 29 }); 30 31}); 32 33var Timer = function (callback, delay) { 34 var timerId, start, remaining = delay; 35 36 this.pause = function () { 37 window.clearTimeout(timerId); 38 remaining -= Date.now() - start; 39 }; 40 41 this.run = function () { 42 start = Date.now(); 43 window.clearTimeout(timerId); 44 timerId = window.setTimeout(callback, remaining); 45 }; 46};
47 48const websiteSearchQueryUpdated = new CustomEvent("websiteSearchQueryUpdated", { 49 detail: {}, 50 bubbles: true, 51 cancelable: true, 52 composed: false, 53}); 54 55function initStickyHeader() { 56 const headerContainer = document.querySelector("header"); 57 const headerNavBar = document.querySelector(".js-global-header"); 58 59 if (headerContainer != null && headerNavBar != null) { 60 if (headerNavBar.classList.contains("desktop-is-expanded")) { 61 headerContainer.classList.add("has-sub-menu"); 62 } 63 if (!headerNavBar.classList.contains("no-menu")) { 64 headerContainer.classList.add("has-main-menu"); 65 } 66 if (headerNavBar.classList.contains("slim-header")) { 67 headerContainer.classList.add("slim-header"); 68 } 69 if (headerContainer.querySelector(".js-global-page-heading") != null) { 70 headerContainer.classList.add("has-page-heading"); 71 } 72 if (headerContainer.querySelector(".js-global-alert-banner") != null) { 73 headerContainer.classList.add("has-alert-banner"); 74 } 75 if (!headerContainer.classList.contains("sticky")) { 76 headerContainer.classList.add("sticky"); 77 } 78 } 79}; 80 81//Left Nav 82function initLeftNav() { 83 const toggleButton = document.querySelector("#leftnav__nav__toggle button"); 84 const container = document.querySelector(".leftnav__container"); 85 const pagecontent = document.querySelector("#main-content"); 86 87 if (container != null && toggleButton != null) { 88 89 initEventHandlers(); 90 91 if (container.classList.contains("js-enable-popout") && !container.classList.contains("active") && window.innerWidth > 768) { 92 try { 93 autoPopout(); 94 } catch (ex) { } 95 } 96 } 97 98 function initEventHandlers() { 99 100 toggleButton.addEventListener("click", (e) => { 101 container.classList.toggle("active"); 102 if (!container.classList.contains("active")) { 103 container.classList.remove("hover"); 104 } 105 }); 106 toggleButton.addEventListener("mouseover", (e) => { 107 container.classList.add("hover"); 108 }); 109 toggleButton.addEventListener("mouseout", (e) => { 110 container.classList.remove("hover"); 111 }); 112 pagecontent.addEventListener("click", (e) => { 113 container.classList.remove("active"); 114 container.classList.remove("hover"); 115 }); 116 } 117 118 function autoPopout() { 119 const popoutTimer = new Timer(function () { 120 container.classList.remove("active"); 121 container.classList.remove("timed-popout"); 122 }, 4000); 123 124 setTimeout(() => { 125 container.classList.add("active"); 126 container.classList.add("timed-popout"); 127 popoutTimer.run(); 128 }, 1000); 129 130 container.addEventListener("mouseover", function () { 131 if (container.classList.contains("timed-popout")) { 132 popoutTimer.pause(); 133 } 134 }); 135 136 container.addEventListener("mouseout", function () { 137 if (container.classList.contains("timed-popout")) { 138 popoutTimer.run(); 139 } 140 }); 141 } 142 143}; 144 145// ----------- 146// Desktop Search 147// ----------- 148function initDesktopSearch() { 149 const header = document.querySelector(".js-global-header__desktop"); 150 const showBtn = document.querySelector(".js-auxiliary-nav__search-button"); 151 const cancelBtn = document.querySelector(".js-desktop-search__cancel-button"); 152 const searchInput = document.querySelector(".js-desktop-search__input"); 153 const submitSearchBtn = document.querySelector(".js-desktop-search__submit-button"); 154 155 initEventHandlers(); 156 157 function initEventHandlers() { 158 showBtn.addEventListener("click", (e) => { 159 e.preventDefault(); 160 header.classList.add("search-open"); 161 }); 162 163 submitSearchBtn.addEventListener("click", (e) => { 164 e.preventDefault(); 165 if (searchInput.value.trim().length > 0) { 166 var url = submitSearchBtn.getAttribute("data-search-url"); 167 var term = encodeURIComponent(searchInput.value).replace("+","%20"); 168 window.location = url + term; 169 submitSearchBtn.dispatchEvent(websiteSearchQueryUpdated); 170 } 171 }); 172 173 cancelBtn.addEventListener("click", (e) => { 174 e.preventDefault(); 175 searchInput.value = ""; 176 header.classList.remove("search-open"); 177 }); 178 179 searchInput.addEventListener("keydown", (e) => { 180 if (e.key == "Enter") { 181 submitSearchBtn.click(); 182 } 183 }); 184 } 185}; 186 187// ------------- 188// Mobile Search 189// ------------- 190function initMobileSearch() { 191 const body = document.querySelector("body"); 192 const header = document.querySelector(".js-global-header__mobile"); 193 const bottomNavClose = document.querySelector(".js-mobile-bottom-nav-close"); 194 195 const showBtn = document.querySelector(".js-primary-nav-mobile-search"); 196 const mobileSearch = document.querySelector(".js-mobile-search"); 197 const searchInput = document.querySelector(".js-mobile-search__input"); 198 const submitSearchBtn = document.querySelector(".js-mobile-search__submit-button"); 199 200 initEventHandlers(); 201 202 function initEventHandlers() { 203 showBtn.addEventListener("click", (e) => { 204 header.classList.remove("navmenu-open"); 205 header.classList.remove("account-open"); 206 header.classList.add("search-open"); 207 body.classList.add("mobile-header-open"); 208 mobileMenuScrollToTop(); 209 }); 210 211 submitSearchBtn.addEventListener("click", (e) => { 212 e.preventDefault(); 213 if (searchInput.value.trim().length > 0) { 214 var url = submitSearchBtn.getAttribute("data-search-url"); 215 var term = encodeURIComponent(searchInput.value).replace("+", "%20"); 216 window.location = url + term; 217 submitSearchBtn.dispatchEvent(websiteSearchQueryUpdated); 218 bottomNavClose.click(); 219 } 220 }); 221 222 searchInput.addEventListener("keydown", (e) => { 223 if (e.key == "Enter") { 224 submitSearchBtn.click(); 225 } 226 }); 227 228 // duplication from mobile nav component: 229 bottomNavClose.addEventListener("click", (e) => { 230 header.classList.remove("search-open"); 231 body.classList.remove("mobile-header-open"); 232 }); 233 } 234 235 236}; 237 238// -------------
239// Desktop Aux + My Account dropdown and Sign-in popup 240// ------------- 241function initAuxNav(el, index) { 242 const auxNavButtons = document.querySelectorAll(".js-auxiliary-nav-button"); 243 const loginPopup = document.querySelector(".js-log-in-popup-wrapper"); 244 const globalHeader = document.querySelector(".js-global-header"); 245 246 auxNavButtons.forEach((el, i) => { 247 el.addEventListener("keydown", (e) => { 248 handleAuxKeyDown(e, i); 249 }); 250 }); 251 252 let openMenuID = -1; 253 254 const onOpen = (i, margin) => { 255 if (openMenuID !== i) { 256 openMenuID = i; 257 } 258 }; 259 260 const onClose = (i) => { 261 if (openMenuID === i) { 262 openMenuID = -1; 263 } 264 }; 265 266 el.querySelectorAll(".js-auxiliary-nav-item").forEach((el, i) => { 267 const contentEl = el.querySelector(".js-auxiliary-nav-dropdown"); 268 if (contentEl != null) { 269 NavMenu({ 270 animationDelay: 500, 271 closed: true, 272 direction: "vertical", 273 menuButton: ".js-auxiliary-nav-button", 274 menuContainer: ".js-auxiliary-nav-dropdown", 275 navigationLink: ".js-auxiliary-nav-link", 276 openClass: "is-open", 277 onClose: () => onClose(i), 278 onOpen: () => onOpen(i, contentEl.offsetHeight), 279 parent: el, 280 }); 281 } 282 }); 283 284 function handleAuxKeyDown(event, index) { 285 switch (event.key) { 286 case "Left": 287 case "ArrowLeft": 288 if (index > 0) { 289 event.preventDefault(); 290 auxNavButtons[index - 1].focus(); 291 } 292 break; 293 case "Right": 294 case "ArrowRight": 295 if (index < auxNavButtons.length - 1) { 296 event.preventDefault(); 297 auxNavButtons[index + 1].focus(); 298 } 299 break; 300 default: 301 } 302 } 303 304 if (loginPopup != null && globalHeader.classList.contains("js-enable-signin") && window.location.pathname.toLowerCase().replace("%20", "-").indexOf("/my-account/") === -1) { 305 306 const popupTimer = new Timer(function () { 307 loginPopup.classList.remove("show-popup"); 308 }, 10000); 309 310 setTimeout(() => { 311 loginPopup.classList.add("show-popup"); 312 popupTimer.run(); 313 }, 1000); 314 315 loginPopup.addEventListener("mouseover", function () { 316 popupTimer.pause(); 317 }); 318 319 loginPopup.addEventListener("mouseout", function () { 320 popupTimer.run(); 321 }); 322 } 323 324}; 325 326// -------------- 327// Mobile Account 328// -------------- 329function initMobileAccount() { 330 const body = document.querySelector("body"); 331 const header = document.querySelector(".js-global-header__mobile"); 332 const bottomNavClose = document.querySelector(".js-mobile-bottom-nav-close"); 333 334 const accountButton = document.querySelector(".js-primary-nav-mobile-account"); 335 336 337 accountButton.addEventListener("click", (e) => { 338 header.classList.remove("navmenu-open"); 339 header.classList.remove("search-open"); 340 header.classList.add("account-open"); 341 body.classList.add("mobile-header-open"); 342 mobileMenuScrollToTop(); 343 }); 344 345 bottomNavClose.addEventListener("click", (e) => { 346 header.classList.remove("account-open"); 347 body.classList.remove("mobile-header-open"); 348 }); 349}; 350 351// ----------- 352// Primary Nav 353// ----------- 354function initPrimaryNav(el, index) { 355 const globalHeaderEl = document.querySelector(".js-global-header"); 356 const primaryNavEl = document.querySelector(".js-primary-nav-menu"); 357 const megaMenuHeight = document.querySelector(".js-mega-menu").offsetHeight; 358 359 //if (primaryNavEl.classList.contains("is-open")) { 360 // globalHeaderEl.style.marginBottom = `${megaMenuHeight}px`; 361 // globalHeaderEl.classList.add("is-expanded"); 362 //} else { 363 // globalHeaderEl.classList.remove("is-expanded"); 364 // globalHeaderEl.style.marginBottom = 0; 365 //} 366 367 const primaryLinks = el.querySelectorAll(".js-primary-nav-top-link"); 368 369 primaryLinks.forEach((el, i) => { 370 el.addEventListener("keydown", (e) => { 371 handleKeyDown(e, i); 372 }); 373 });
374 375 function handleKeyDown(event, index) { 376 switch (event.key) { 377 case "Left": 378 case "ArrowLeft": 379 if (index > 0) { 380 event.preventDefault(); 381 primaryLinks[index - 1].focus(); 382 } 383 break; 384 case "Right": 385 case "ArrowRight": 386 if (index < primaryLinks.length - 1) { 387 event.preventDefault(); 388 primaryLinks[index + 1].focus(); 389 } 390 break; 391 default: 392 } 393 } 394}; 395 396// --------- 397// Mega Menu 398// --------- 399function initMegaMenu(el, index) { 400 let openMenuID = -1; 401 402 const onOpen = (i, margin) => { 403 if (openMenuID !== i) { 404 openMenuID = i; 405 } 406 }; 407 408 const onClose = (i) => { 409 if (openMenuID === i) { 410 openMenuID = -1; 411 } 412 }; 413 414 const megaLinks = el.querySelectorAll(".js-mega-menu-submenu-button"); 415 416 megaLinks.forEach((el, i) => { 417 el.addEventListener("keydown", (e) => { 418 handleKeyDown(e, i); 419 }); 420 }); 421 422 el.querySelectorAll(".js-mega-menu-menu").forEach((el, i) => { 423 const contentEl = el.querySelector(".js-mega-menu-submenu"); 424 if (contentEl != null) { 425 NavMenu({ 426 animationDelay: 500, 427 closed: true, 428 direction: "vertical", 429 menuButton: ".js-mega-menu-submenu-button", 430 menuContainer: ".js-mega-menu-submenu", 431 navigationLink: ".js-primary-nav-sub-link", 432 openClass: "is-open", 433 onClose: () => onClose(i), 434 onOpen: () => onOpen(i, contentEl.offsetHeight), 435 parent: el, 436 }); 437 } 438 }); 439 440 function handleKeyDown(event, index) { 441 switch (event.key) { 442 case "Left": 443 case "ArrowLeft": 444 if (index > 0) { 445 event.preventDefault(); 446 primaryLinks[index - 1].focus(); 447 } 448 break; 449 case "Right": 450 case "ArrowRight": 451 if (index < primaryLinks.length - 1) { 452 event.preventDefault(); 453 primaryLinks[index + 1].focus(); 454 } 455 break; 456 default: 457 } 458 } 459}; 460 461// ---------- 462// Mobile Nav 463// ---------- 464function initMobileNav(el, index) { 465 const body = document.querySelector("body"); 466 const header = document.querySelector(".js-global-header__mobile"); 467 const navBack = document.querySelector(".js-mobile-bottom-nav-back"); 468 469 const submenuLink = el.querySelector(".js-mobile-nav-top-link"); 470 const submenu = submenuLink.parentNode.querySelector(".js-mobile-nav-submenu"); 471 const submenuLinks = document.querySelectorAll(".js-mobile-nav-top-link"); 472 const submenus = document.querySelectorAll(".js-mobile-nav-submenu"); 473 474 const tertmenus = document.querySelectorAll(".js-mobile-nav-tertmenu"); 475 const tertmenuLinks = el.querySelectorAll(".js-mobile-nav-sub-link"); 476 477 const bottomMenu = document.querySelector(".js-mobile-bottom-menu"); 478 const bottomNav = document.querySelector(".js-mobile-bottom-nav"); 479 const mobileNav = document.querySelector(".js-mobile-nav"); 480 const menuBtn = document.querySelector(".js-primary-nav-mobile-menu"); 481 482 initBottomMenu(); 483 initBottomNav(); 484 485 submenuLink.addEventListener("click", (e) => { 486 navBack.style.visibility = "visible"; 487 488 // add submenu 489 handleSubmenu(submenuLinks, submenu); 490 }); 491 492 function handleSubmenu(submenuLinks, submenu) { 493 if (submenu.classList.contains("mobile-nav__submenu-container--display")) { 494 // remove submenu 495 submenu.classList.remove("mobile-nav__submenu-container--display"); 496 ariaExpandToggle(null, submenu); 497 } else { 498 // add submenu 499 submenu.classList.add("mobile-nav__submenu-container--display"); 500 ariaExpandToggle(null, submenu); 501 } 502 503 submenuLinks.forEach((link, i) => { 504 if (link.classList.contains("mobile-nav__top-link--hidden")) { 505 // add main menu links back 506 link.classList.remove("mobile-nav__top-link--hidden"); 507 } else { 508 // remove main menu links 509 link.classList.add("mobile-nav__top-link--hidden"); 510 } 511 }); 512 513 mobileMenuScrollToTop(); 514 } 515 516 tertmenuLinks.forEach((link, i) => { 517 const tertmenu = link.parentNode.querySelector(".js-mobile-nav-tertmenu"); 518 const parentSubmenu = link.parentNode.parentNode.parentNode; 519 520 link.addEventListener("click", (e) => { 521 // add tertiary menu 522 handleTertmenu(parentSubmenu, tertmenu); 523 }); 524 });
525 526 function handleTertmenu(parentSubmenu, tertmenu) { 527 const tertmenuLink = tertmenu.previousElementSibling; 528 529 if (tertmenu.classList.contains("mobile-nav__tertmenu-container--display")) { 530 tertmenu.classList.remove("mobile-nav__tertmenu-container--display"); 531 parentSubmenu.classList.add("mobile-nav__submenu-container--display"); 532 ariaExpandToggle(null, parentSubmenu) 533 } else { 534 tertmenu.classList.add("mobile-nav__tertmenu-container--display"); 535 parentSubmenu.classList.remove("mobile-nav__submenu-container--display"); 536 ariaExpandToggle(null, parentSubmenu) 537 } 538 539 ariaExpandToggle(tertmenuLink); 540 541 mobileMenuScrollToTop(); 542 } 543 544 function ariaExpandToggle(menuLinkIn, menuIn) { 545 const menu = menuIn || menuLinkIn.nextElementSibling; 546 const menuLink = menuLinkIn || menuIn.previousElementSibling; 547 548 if (menuLink.hasAttribute("aria-expanded")) { 549 if (menuLink.getAttribute("aria-expanded") === "false") { 550 menuLink.setAttribute("aria-expanded", true); 551 } 552 else { 553 menuLink.setAttribute("aria-expanded", false); 554 } 555 } 556 557 if (menu.hasAttribute("aria-hidden")) { 558 if (menu.getAttribute("aria-hidden") === "true") { 559 menu.setAttribute("aria-hidden", false) 560 } 561 else { 562 menu.setAttribute("aria-hidden", true) 563 } 564 } 565 } 566 567 function initBottomMenu() { 568 if (!bottomMenu.classList.contains("click-handler")) { 569 bottomMenu.classList.add("click-handler"); 570 //mobileNav.classList.add("mobile-nav--hidden"); 571 navBack.style.visibility = "hidden"; 572 573 menuBtn.addEventListener("click", (e) => { 574 header.classList.remove("search-open"); 575 header.classList.remove("account-open"); 576 header.classList.add("navmenu-open"); 577 body.classList.add("mobile-header-open"); 578 //mobileNav.classList.remove("mobile-nav--hidden"); 579 mobileMenuScrollToTop(); 580 }); 581 } 582 } 583 584 function initBottomNav() { 585 if (!bottomNav.classList.contains("click-handler")) { 586 bottomNav.classList.add("click-handler"); 587 const bottomNavBack = document.querySelector(".js-mobile-bottom-nav-back"); 588 const bottomNavClose = document.querySelector(".js-mobile-bottom-nav-close"); 589 590 bottomNavBack.addEventListener("click", (e) => { 591 const activeSubmenu = document.querySelector(".mobile-nav__submenu-container--display"); 592 const activeTertmenu = document.querySelector(".mobile-nav__tertmenu-container--display"); 593 594 // if user is on submenu 595 if (activeSubmenu) { 596 navBack.style.visibility = "hidden"; 597 598 // remove submenu 599 handleSubmenu(submenuLinks, activeSubmenu); 600 601 // if user is on tertiary menu 602 } else if (activeTertmenu) { 603 const tertmenuParentSubmenu = activeTertmenu.parentNode.parentNode.parentNode; 604 605 // remove tertiary menu 606 handleTertmenu(tertmenuParentSubmenu, activeTertmenu); 607 } else { 608 mobileMenuScrollToTop(); 609 } 610 }); 611 612 bottomNavClose.addEventListener("click", (e) => { 613 //mobileNav.classList.add("mobile-nav--hidden"); 614 header.classList.remove("navmenu-open"); 615 body.classList.remove("mobile-header-open"); 616 }); 617 618 //bottomNav.style.display = "none"; 619 }; 620 } 621}; 622 623function mobileMenuScrollToTop() { 624 document.querySelector(".sub-nav__mobile-container").scrollTop = 0; 625}; 626 627// -------- 628// Nav Menu 629// -------- 630let timeoutId = window.setTimeout(() => { }, 0); 631 632function NavMenu(initProps) { 633 let propsFail = false; 634 635 if (!initProps.menuButton || initProps.menuButton.length === 0) { 636 console.error("'menuButton' selector is required"); 637 propsFail = true; 638 } 639 if (!initProps.menuContainer || initProps.menuContainer.length === 0) { 640 console.error("'menuContainer' selector is required"); 641 propsFail = true; 642 } 643 if (!initProps.navigationLink || initProps.navigationLink.length === 0) { 644 console.error("'navigationLink' selector is required"); 645 propsFail = true; 646 } 647 if (!initProps.parent) { 648 console.error("'parent' node element is required"); 649 propsFail = true; 650 } 651 652 if (propsFail) { 653 return; 654 } 655 656 const defaultProps = { 657 animationDelay: 600, 658 closed: true, 659 direction: "vertical", 660 reversed: false, 661 openClass: "is-open", 662 }; 663 664 const props = Object.assign({}, defaultProps, initProps); 665
666 let closedState = props.closed; 667 let direction = props.direction; 668 let animationDelay = props.animationDelay; 669 670 const elParent = props.parent; 671 672 const elMenuButton = elParent.querySelector(props.menuButton); 673 const elMenuContainer = elParent.querySelector(props.menuContainer); 674 const elMenuLinks = elMenuContainer.querySelectorAll(props.navigationLink); 675 676 bindEvents(); 677 init(); 678 679 function init() { 680 const controlId = elMenuContainer.id; 681 const buttonId = elMenuButton.id; 682 683 elMenuButton.id = buttonId; 684 elMenuButton.setAttribute("aria-haspopup", true); 685 elMenuButton.setAttribute("aria-controls", controlId); 686 687 elMenuContainer.id = controlId; 688 elMenuContainer.setAttribute("aria-labelledby", buttonId); 689 690 if (closedState) { 691 closeMenu(false); 692 } else { 693 openMenu(false); 694 } 695 } 696 697 function bindEvents() { 698 // need to run this on mousedown to properly allow the focus state to move. 699 elMenuButton.addEventListener("mousedown", (e) => { 700 e.preventDefault(); 701 toggleMenu(); 702 }); 703 704 elMenuButton.addEventListener("keydown", handleMenuKeyEvent); 705 706 [...elMenuLinks].forEach((link, index) => { 707 link.addEventListener("keydown", (e) => { 708 handleLinkKeyEvent(e, link, index); 709 }); 710 }); 711 } 712 713 function setDirection(newDirection) { 714 direction = newDirection; 715 } 716 717 function clickAway(e) { 718 if (!elParent.contains(e.target) && !closedState) { 719 closeMenu(false); 720 } 721 } 722 723 function toggleMenu(moveFocus) { 724 if (closedState) { 725 openMenu(moveFocus); 726 } else { 727 closeMenu(moveFocus); 728 } 729 } 730 731 function openMenu(moveFocus = true) { 732 closedState = false; 733 elMenuButton.setAttribute("aria-expanded", true); 734 elParent.classList.add(props.openClass); 735 elMenuContainer.removeAttribute("aria-hidden"); 736 737 if (moveFocus) { 738 window.clearTimeout(timeoutId); 739 740 timeoutId = setTimeout(() => { 741 elMenuLinks[0] && elMenuLinks[0].focus(); 742 }, animationDelay); 743 } 744 745 if (props.onOpen) { 746 props.onOpen(); 747 } 748 749 window.addEventListener("click", clickAway); 750 window.addEventListener("resize", closeMenu); 751 752 if (moveFocus) { 753 window.dataLayer = window.dataLayer || []; 754 window.dataLayer.push({ 755 type: "Menu Opened", 756 event: "dropdownClick", 757 dropdownSelection: elMenuButton.innerText, 758 }); 759 } 760 } 761 762 function closeMenu(moveFocus = true) { 763 closedState = true; 764 if (moveFocus) { 765 elMenuButton && elMenuButton.focus(); 766 } 767 elMenuButton.setAttribute("aria-expanded", false); 768 elParent.classList.remove(props.openClass); 769 elMenuContainer.setAttribute("aria-hidden", true); 770 771 if (props.onClose) { 772 props.onClose(); 773 } 774 775 window.removeEventListener("click", clickAway); 776 window.removeEventListener("resize", closeMenu); 777 778 if (moveFocus) { 779 window.dataLayer = window.dataLayer || []; 780 window.dataLayer.push({ 781 type: "Menu Closed", 782 event: "dropdownClick", 783 dropdownSelection: elMenuButton.innerText, 784 }); 785 } 786 } 787 788 function handleMenuKeyEvent(e) { 789 switch (e.key) { 790 case "Escape": 791 e.preventDefault(); 792 closeMenu(); 793 break; 794 case "Enter": 795 case " ": 796 e.preventDefault(); 797 toggleMenu(true); 798 break; 799 default: 800 } 801 } 802 803 function handleLinkKeyEvent(e, link, index) { 804 let target = index; 805 806 switch (e.key) { 807 case "Escape": 808 e.preventDefault(); 809 closeMenu(true); 810 break; 811 case "Tab": 812 if (e.shiftKey) { 813 if (index === 0) { 814 if (!props.reversed) { 815 e.preventDefault(); 816 } 817 closeMenu(!props.reversed); 818 } 819 } else { 820 if (index === elMenuLinks.length - 1) { 821 if (props.reversed) { 822 e.preventDefault(); 823 } 824 closeMenu(props.reversed); 825 } 826 } 827 break; 828 default: 829 } 830 831 if (direction === "vertical") { 832 switch (e.key) { 833 case "Up": 834 case "ArrowUp": 835 e.preventDefault(); 836 focusPrevious(elMenuLinks, index, target); 837 break; 838 case "Down": 839 case "ArrowDown": 840 e.preventDefault(); 841 focusNext(elMenuLinks, index, target); 842 break; 843 default: 844 } 845 } 846 if (direction === "horizontal") { 847 switch (e.key) { 848 case "Left": 849 case "ArrowLeft": 850 e.preventDefault(); 851 focusPrevious(elMenuLinks, index, target); 852 break; 853 case "Right": 854 case "ArrowRight": 855 e.preventDefault(); 856 focusNext(elMenuLinks, index, target); 857 break; 858 default: 859 } 860 } 861 862 function focusPrevious(elList, index, target) { 863 if (index === 0) { 864 target = elMenuLinks.length; 865 } 866 elMenuLinks[target - 1] && elMenuLinks[target - 1].focus(); 867 } 868 869 function focusNext(elList, index, target) { 870 if (index === elMenuLinks.length - 1) { 871 target = -1; 872 } 873 elMenuLinks[target + 1] && elMenuLinks[target + 1].focus(); 874 } 875 } 876 877 return { 878 init, 879 toggleMenu, 880 openMenu, 881 closeMenu, 882 setDirection, 883 }; 884}
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.