// Lazy-loaded collapsible file tree on overlay detail pages. // // One delegated click handler on document. Each `.file-tree-toggle` button // carries `data-files-url`. First expand fires a fetch and innerHTMLs the // returned partial into the next `.file-tree-children`; subsequent clicks // just toggle visibility — no re-fetch. (function () { document.addEventListener("click", function (event) { const button = event.target.closest(".file-tree-toggle"); if (!button) return; const children = button.nextElementSibling; if (!children || !children.classList.contains("file-tree-children")) return; const wasExpanded = button.getAttribute("aria-expanded") === "true"; button.setAttribute("aria-expanded", wasExpanded ? "false" : "true"); children.hidden = wasExpanded; if (wasExpanded) return; // collapsing — nothing to fetch if (button.dataset.loaded === "1") return; // already populated const url = button.dataset.filesUrl; if (!url) return; button.dataset.loaded = "1"; // optimistic — prevents duplicate fetches on rapid clicks fetch(url, { headers: { Accept: "text/html" }, credentials: "same-origin" }) .then(function (response) { if (!response.ok) throw new Error("HTTP " + response.status); return response.text(); }) .then(function (html) { children.innerHTML = html; }) .catch(function (err) { delete button.dataset.loaded; // allow retry children.innerHTML = '
Failed to load directory contents.
'; console.error("file-tree:", err); }); }); })();