Files
datascape/assets/page/toc.js
T
luxickandClaude Opus 5.5 aa90a04f91 Boost page navigation with htmx
Links and GET forms to wiki pages swap the next page into .shell instead
of loading a new document: the server answers boosted requests and
history restores with a partial (title, page actions out-of-band, shell
content). The header stays, browsers without cross-document view
transitions (Firefox) no longer flash between pages, and the swap runs
as a same-document view transition. Files, the editor, internal
endpoints and POST forms still navigate normally.

Back/Forward refetch pages (no snapshots that could predate a move or
delete); the tree rail keeps its scroll position and the content column
returns to where it was. Mutation redirects swap their result in the
same way. Page scripts that assumed a fresh document now also run after
a swap (toc, contents, companion, scroll-sync, search actions) or
register once (fitness).

The e2e suite now also runs in Firefox.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 19:29:08 +02:00

39 lines
1.3 KiB
JavaScript

// Runs on DOMContentLoaded for a full page load, and right away when this
// script arrives with a boosted navigation (the document is loaded then).
(function () {
function run() {
var content = document.querySelector("main");
if (!content) return;
var headings = content.querySelectorAll("h2, h3, h4");
if (headings.length < 2) return;
var nav = document.createElement("nav");
nav.className = "toc panel";
var header = document.createElement("div");
header.className = "panel-header";
header.textContent = "Contents";
nav.appendChild(header);
var list = document.createElement("ul");
headings.forEach(function (h) {
if (!h.id) return;
var li = document.createElement("li");
li.className = "toc-" + h.tagName.toLowerCase();
var a = document.createElement("a");
a.href = "#" + h.id;
var clone = h.cloneNode(true);
clone.querySelectorAll(".btn, .muted, .dropdown").forEach(function (el) { el.remove(); });
a.textContent = clone.textContent.trim();
li.appendChild(a);
list.appendChild(li);
});
nav.appendChild(list);
content.insertBefore(nav, content.firstChild);
}
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", run);
else run();
})();