Skip to content

Commit fb662aa

Browse files
authored
Improve docs.rs TOC highlight (#268)
* Fix issue with broken outline in TOC * Improve docs.rs TOC highlight
1 parent 1b8846e commit fb662aa

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

extension/script/docs-rs.js

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,37 @@ const DOC_HEADERS_SELECTOR = ".top-doc div.docblock>h1[id], .top-doc div.docbloc
1414
function highlight() {
1515
let headers = Array.from(document.querySelectorAll(DOC_HEADERS_SELECTOR))
1616
.filter(header => ["H1", "H2", "H3"].includes(header.tagName));
17+
const OFFSET = 32;
18+
const activeByHash = (hash) => {
19+
document.querySelectorAll(".rse-doc-toc-item.rse-active").forEach((item) => {
20+
item.classList.remove("rse-active");
21+
});
22+
const link = document.querySelector(`.rse-doc-toc-item a[href$="${hash}"]`)
23+
if (link) {
24+
let target = link.parentElement;
25+
target.classList.add("rse-active");
26+
target.scrollIntoView({ behavior: "auto", block: "nearest" });
27+
}
28+
}
1729
const scrollHandler = entries => {
30+
let hashEl = document.querySelector(document.location.hash);
31+
if (hashEl?.getBoundingClientRect().top === OFFSET) {
32+
activeByHash(document.location.hash);
33+
// Early return if navigating directly to a named anchor.
34+
return;
35+
}
36+
1837
entries.forEach(entry => {
1938
if (entry.intersectionRatio > 0) {
20-
document.querySelectorAll(".rse-doc-toc-item").forEach((item) => {
21-
item.classList.remove("rse-active");
22-
});
23-
2439
let url = new URL(entry.target.firstChild.href);
25-
let link = document.querySelector(`.rse-doc-toc-item a[href$="${url.hash}"]`)
26-
if (link) {
27-
let target = link.parentElement;
28-
target.classList.add("rse-active");
29-
target.scrollIntoView({ behavior: "auto", block: "nearest" });
30-
}
40+
activeByHash(url.hash);
3141
}
3242
});
3343
};
34-
const observer = new IntersectionObserver(scrollHandler);
44+
const observer = new IntersectionObserver(
45+
scrollHandler,
46+
{ rootMargin: `-${OFFSET}px 0px 0px 0px` }
47+
);
3548
headers.forEach(item => observer.observe(item));
3649
}
3750

@@ -59,11 +72,11 @@ document.addEventListener("DOMContentLoaded", () => {
5972
let ul = document.createElement("ul");
6073
ul.classList.add("rse-doc-toc");
6174
for (let header of headers) {
62-
let link = header.firstChild;
75+
let [link, text] = header.childNodes;
6376

6477
let item = document.createElement("li");
6578
item.innerHTML = `<div class="rse-doc-toc-item rse-doc-toc-${header.tagName.toLowerCase()}">
66-
<a href="${link.href}">${link.textContent}</a>
79+
<a href="${link.href}">${text.nodeValue}</a>
6780
</div>`;
6881

6982
ul.appendChild(item);

0 commit comments

Comments
 (0)