diff --git a/public/js/admin-docs.js b/public/js/admin-docs.js index 4e90110..693301b 100644 --- a/public/js/admin-docs.js +++ b/public/js/admin-docs.js @@ -122,7 +122,7 @@ if (!body) return; var seen = {}; body.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach(function (h) { - var base = h.id || slugHeading(h.textContent || ''); + var base = slugHeading(h.textContent || '') || h.id; if (!base) return; var id = base; var n = seen[base] || 0; @@ -136,14 +136,41 @@ var body = $('docs-reader-body'); var reader = $('docs-reader'); if (!body || !reader || !hash) return false; - var id = String(hash).replace(/^#/, ''); + var id = decodeURIComponent(String(hash).replace(/^#/, '')); if (!id) return false; var target = document.getElementById(id); + if (!target || !body.contains(target)) { + target = Array.prototype.slice.call(body.querySelectorAll('h1,h2,h3,h4,h5,h6')).find(function (h) { + return slugHeading(h.textContent || '') === id; + }); + } if (!target || !body.contains(target)) return false; - reader.scrollTop = target.offsetTop - body.offsetTop - 8; + var readerBox = reader.getBoundingClientRect(); + var targetBox = target.getBoundingClientRect(); + reader.scrollTop += targetBox.top - readerBox.top - 8; return true; } + function handleDocAnchorClick(e) { + var link = e.target.closest('a[href]'); + var body = $('docs-reader-body'); + if (!link || !body || !body.contains(link)) return; + var href = link.getAttribute('href') || ''; + if (href.charAt(0) !== '#' && link.hash) { + try { + var u = new URL(link.href, window.location.href); + if (u.origin !== window.location.origin || u.pathname !== window.location.pathname) return; + href = u.hash; + } catch (_) { return; } + } + if (!href || href.charAt(0) !== '#') return; + e.preventDefault(); + requestAnimationFrame(function () { + scrollReaderToHash(href); + try { history.replaceState(null, '', href); } catch (_) { window.location.hash = href; } + }); + } + function loadTree() { if (_treeLoaded) return; fetch('/api/admin/docs/tree', { headers: getAuthHeaders() }) @@ -244,16 +271,14 @@ 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; } - } - } }); + var body = $('docs-reader-body'); + if (body && !body.dataset.anchorsWired) { + body.dataset.anchorsWired = '1'; + body.addEventListener('click', handleDocAnchorClick); + } + var filter = $('docs-filter'); if (filter) { var t = null;