1export default function GDMFiltersAccordion(containerSelector = ".insights_filters") { 2 const container = document.querySelector(containerSelector); 3 if (!container) return; 4 5 const headers = Array.from(container.querySelectorAll(".fancytree-header")); 6 if (headers.length === 0) return; 7 8 const getPaneForHeader = (header) => { 9 const toggleId = header.getAttribute("data-toggle"); 10 11 if (toggleId) { 12 const normalizedId = toggleId.replace(/^#/, ""); 13 const paneById = document.getElementById(normalizedId); 14 if (paneById && paneById.classList.contains("dropdown-pane")) { 15 return paneById; 16 } 17 } 18 19 const siblingPane = header.nextElementSibling; 20 if (siblingPane && siblingPane.classList.contains("dropdown-pane")) { 21 return siblingPane; 22 } 23 24 return null; 25 }; 26 27 const getOrCreateNoFiltersMessage = (pane) => { 28 let message = pane.nextElementSibling; 29 30 if (!message || !message.classList.contains("gdm-no-filters-selected")) { 31 message = document.createElement("p"); 32 message.className = "gdm-no-filters-selected"; 33 message.textContent = "No filters selected"; 34 pane.insertAdjacentElement("afterend", message); 35 } 36 37 return message; 38 }; 39 40 const syncNoFiltersMessage = (pane) => { 41 const message = getOrCreateNoFiltersMessage(pane); 42 const precedingPane = message.previousElementSibling; 43 const precedingPaneIsOpen = 44 precedingPane && 45 precedingPane.classList.contains("dropdown-pane") && 46 precedingPane.classList.contains("open"); 47 48 message.style.display = precedingPaneIsOpen ? "none" : "block"; 49 }; 50 51 const canOpenPane = (pane) => { 52 if (!pane) return false; 53 return pane.style.display !== "none"; 54 }; 55 56 const firstOpenablePair = headers 57 .map((header) => ({ header, pane: getPaneForHeader(header) })) 58 .find(({ pane }) => canOpenPane(pane)); 59 60 if (firstOpenablePair) { 61 firstOpenablePair.header.classList.add("open"); 62 firstOpenablePair.pane.classList.add("open"); 63 } 64 65 headers.forEach((header) => { 66 const pane = getPaneForHeader(header); 67 if (pane) syncNoFiltersMessage(pane); 68 }); 69 70 headers.forEach((header) => { 71 header.addEventListener("click", () => { 72 const pane = getPaneForHeader(header); 73 74 if (!pane) return; 75 76 if (!canOpenPane(pane)) { 77 header.classList.remove("open"); 78 pane.classList.remove("open"); 79 syncNoFiltersMessage(pane); 80 return; 81 } 82 83 const isOpen = pane.classList.contains("open"); 84 85 if (isOpen) { 86 header.classList.remove("open"); 87 pane.classList.remove("open"); 88 syncNoFiltersMessage(pane); 89 return; 90 } 91 92 header.classList.add("open"); 93 pane.classList.add("open"); 94 syncNoFiltersMessage(pane); 95 }); 96 }); 97}
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.