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 const siteNavigation = document.getElementById("site-navigation"); 9 10 // Return early if the navigation doesn't exist. 11 if (!siteNavigation) { 12 return; 13 } 14 15 const button = siteNavigation.getElementsByTagName("button")[0]; 16 17 // Return early if the button doesn't exist. 18 if ("undefined" === typeof button) { 19 return; 20 } 21 22 const menu = siteNavigation.getElementsByTagName("ul")[0]; 23 24 // Hide menu toggle button if menu is empty and return early. 25 if ("undefined" === typeof menu) { 26 button.style.display = "none"; 27 return; 28 } 29 30 if (!menu.classList.contains("nav-menu")) { 31 menu.classList.add("nav-menu"); 32 } 33 34 // Toggle the .toggled class and the aria-expanded value each time the button is clicked. 35 button.addEventListener("click", function () { 36 siteNavigation.classList.toggle("toggled"); 37 document.body.classList.toggle("menu-toggled"); 38 39 if (button.getAttribute("aria-expanded") === "true") { 40 button.setAttribute("aria-expanded", "false"); 41 } else { 42 button.setAttribute("aria-expanded", "true"); 43 } 44 }); 45 46 // Remove the .toggled class and set aria-expanded to false when the user clicks outside the navigation. 47 document.addEventListener("click", function (event) { 48 const isClickInside = siteNavigation.contains(event.target); 49 50 if (!isClickInside) { 51 siteNavigation.classList.remove("toggled"); 52 document.body.classList.remove("menu-toggled"); 53 54 button.setAttribute("aria-expanded", "false"); 55 } 56 }); 57 58 // Get all the link elements within the menu. 59 const links = menu.getElementsByTagName("a"); 60 61 // Get all the link elements with children within the menu. 62 const linksWithChildren = menu.querySelectorAll( 63 ".menu-item-has-children > a, .page_item_has_children > a" 64 ); 65 66 // Toggle focus each time a menu link is focused or blurred. 67 for (const link of links) { 68 link.addEventListener("focus", toggleFocus, true); 69 link.addEventListener("blur", toggleFocus, true); 70 } 71 72 // Toggle focus each time a menu link with children receive a touch event. 73 for (const link of linksWithChildren) { 74 link.addEventListener("touchstart", toggleFocus, false); 75 } 76 77 /** 78 * Sets or removes .focus class on an element. 79 */ 80 function toggleFocus() { 81 if (event.type === "focus" || event.type === "blur") { 82 let self = this; 83 // Move up through the ancestors of the current link until we hit .nav-menu. 84 while (!self.classList.contains("nav-menu")) { 85 // On li elements toggle the class .focus. 86 if ("li" === self.tagName.toLowerCase()) { 87 self.classList.toggle("focus"); 88 } 89 self = self.parentNode; 90 } 91 } 92 93 if (event.type === "touchstart") { 94 const menuItem = this.parentNode; 95 event.preventDefault(); 96 for (const link of menuItem.parentNode.children) { 97 if (menuItem !== link) { 98 link.classList.remove("focus"); 99 } 100 } 101 menuItem.classList.toggle("focus"); 102 } 103 } 104})();
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.