1document.addEventListener("DOMContentLoaded", () => { 2 const navToggles = Array.from(document.querySelectorAll("[data-nav-toggle]")); 3 4 const closeNav = (toggle) => { 5 const targetId = toggle.getAttribute("data-nav-toggle") || toggle.getAttribute("aria-controls"); 6 if (!targetId) { 7 return; 8 } 9 10 const panel = document.getElementById(targetId); 11 if (!panel) { 12 return; 13 } 14 15 panel.classList.remove("show"); 16 toggle.classList.add("collapsed"); 17 toggle.setAttribute("aria-expanded", "false"); 18 }; 19 20 navToggles.forEach((toggle) => { 21 const targetId = toggle.getAttribute("data-nav-toggle") || toggle.getAttribute("aria-controls"); 22 if (!targetId) { 23 return; 24 } 25 26 const panel = document.getElementById(targetId); 27 if (!panel) { 28 return; 29 } 30 31 toggle.addEventListener("click", (event) => { 32 event.preventDefault(); 33 const isOpen = panel.classList.contains("show"); 34 panel.classList.toggle("show", !isOpen); 35 toggle.classList.toggle("collapsed", isOpen); 36 toggle.setAttribute("aria-expanded", String(!isOpen)); 37 }); 38 }); 39 40 const navDropdownToggles = Array.from(document.querySelectorAll("[data-nav-dropdown-toggle]")); 41 const closeAllNavDropdowns = (except) => { 42 navDropdownToggles.forEach((toggle) => { 43 if (except && toggle === except) { 44 return; 45 } 46 const item = toggle.closest(".dropdown"); 47 const menu = item?.querySelector(".dropdown-menu"); 48 if (!menu) { 49 return; 50 } 51 52 item.classList.remove("show"); 53 menu.classList.remove("show"); 54 toggle.setAttribute("aria-expanded", "false"); 55 }); 56 }; 57 58 navDropdownToggles.forEach((toggle) => { 59 toggle.addEventListener("click", (event) => { 60 event.preventDefault(); 61 event.stopPropagation(); 62 63 const item = toggle.closest(".dropdown"); 64 const menu = item?.querySelector(".dropdown-menu"); 65 if (!item || !menu) { 66 return; 67 } 68 69 const isOpen = menu.classList.contains("show"); 70 closeAllNavDropdowns(toggle); 71 72 item.classList.toggle("show", !isOpen); 73 menu.classList.toggle("show", !isOpen); 74 toggle.setAttribute("aria-expanded", String(!isOpen)); 75 }); 76 }); 77 78 document.addEventListener("click", (event) => { 79 navToggles.forEach((toggle) => { 80 const targetId = toggle.getAttribute("data-nav-toggle") || toggle.getAttribute("aria-controls"); 81 const panel = targetId ? document.getElementById(targetId) : null; 82 if (!panel || !panel.classList.contains("show")) { 83 return; 84 } 85 86 const clickedInsidePanel = panel.contains(event.target); 87 const clickedToggle = toggle.contains(event.target); 88 if (!clickedInsidePanel && !clickedToggle) { 89 closeNav(toggle); 90 } 91 }); 92 93 closeAllNavDropdowns(); 94 }); 95 96 document.addEventListener("keydown", (event) => { 97 if (event.key === "Escape") { 98 navToggles.forEach(closeNav); 99 closeAllNavDropdowns(); 100 } 101 }); 102});
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.