fix docs table of contents scrolling

This commit is contained in:
Daniel 2026-05-08 22:41:36 +02:00
parent 94972a0c58
commit 43c06b65c6

View file

@ -107,6 +107,43 @@
}).join('');
}
// marked no longer guarantees heading ids across versions, and the docs
// reader is an internal scroll container. Add stable GitHub-style ids and
// handle same-page #toc links by scrolling the reader, not the window.
function slugHeading(text) {
return String(text || '')
.trim()
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[^a-z0-9_-]/g, '');
}
function prepareDocAnchors(body) {
if (!body) return;
var seen = {};
body.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach(function (h) {
var base = h.id || slugHeading(h.textContent || '');
if (!base) return;
var id = base;
var n = seen[base] || 0;
if (n) id = base + '-' + n;
seen[base] = n + 1;
h.id = id;
});
}
function scrollReaderToHash(hash) {
var body = $('docs-reader-body');
var reader = $('docs-reader');
if (!body || !reader || !hash) return false;
var id = String(hash).replace(/^#/, '');
if (!id) return false;
var target = document.getElementById(id);
if (!target || !body.contains(target)) return false;
reader.scrollTop = target.offsetTop - body.offsetTop - 8;
return true;
}
function loadTree() {
if (_treeLoaded) return;
fetch('/api/admin/docs/tree', { headers: getAuthHeaders() })
@ -152,6 +189,7 @@
return;
}
body.innerHTML = data.html || '';
prepareDocAnchors(body);
if (meta) {
meta.textContent = relPath + ' • ' + (data.bytes != null ? (data.bytes + ' bytes') : '');
}
@ -160,6 +198,7 @@
// Scroll content area to top so deep-link readers don't land mid-doc
var reader = $('docs-reader');
if (reader) reader.scrollTop = 0;
if (window.location.hash) setTimeout(function () { scrollReaderToHash(window.location.hash); }, 0);
})
.catch(function (err) {
body.innerHTML = '<p style="color:var(--red);">' + escHtml(err.message || String(err)) + '</p>';
@ -203,6 +242,15 @@
arrow.classList.toggle('fa-chevron-right', !willOpen);
}
persistExpanded();
return;
}
var docLink = e.target.closest('#docs-reader-body a[href^="#"]');
if (docLink) {
var href = docLink.getAttribute('href');
if (href && scrollReaderToHash(href)) {
e.preventDefault();
try { history.replaceState(null, '', href); } catch (_) { window.location.hash = href; }
}
}
});