pub(crate) fn wanted(body: &str) -> bool {
body.contains("class=\"toc\"") || body.contains("class=\"toc2\"")
}
pub(crate) const SCRIPT: &str = r##"<style>
#toc a.is-active { color: var(--accent, #1565a8); font-weight: 600; }
@media print { #toc a.is-active { font-weight: inherit; } }
</style>
<script>
(function () {
var links = [].slice.call(document.querySelectorAll('#toc a[href^="#"]'));
if (!links.length) { return; }
// An entry whose target is gone cannot be marked, and a document can carry
// an outline entry for a section whose id an author removed by hand.
var entries = [];
for (var i = 0; i < links.length; i++) {
var id = decodeURIComponent(links[i].hash.slice(1));
var heading = document.getElementById(id);
if (heading) { entries.push({ heading: heading, link: links[i] }); }
}
if (!entries.length) { return; }
var marked = null;
// How far down the viewport a heading counts as reached. A standalone page
// has nothing fixed across its top, so this is only enough to keep a heading
// resting exactly at the edge from flickering between two entries.
var LINE = 24;
function update() {
var current = entries[0];
for (var i = 0; i < entries.length; i++) {
if (entries[i].heading.getBoundingClientRect().top > LINE) { break; }
current = entries[i];
}
// The last section of a document may be too short to ever reach the line,
// which would leave its entry unreachable.
if (window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 2) {
current = entries[entries.length - 1];
}
if (current === marked) { return; }
if (marked) { marked.link.classList.remove("is-active"); }
marked = current;
current.link.classList.add("is-active");
// A docked outline scrolls on its own, so the marked entry has to be
// brought into *its* view rather than the page's.
var panel = current.link.closest("#toc");
if (panel && panel.scrollHeight > panel.clientHeight) {
var entry = current.link.getBoundingClientRect();
var frame = panel.getBoundingClientRect();
if (entry.top < frame.top || entry.bottom > frame.bottom) {
panel.scrollTop += entry.top - frame.top - frame.height / 3;
}
}
}
// Scroll fires far more often than the page can change what it shows, so the
// work is done once per frame at most.
var pending = false;
function schedule() {
if (pending) { return; }
pending = true;
window.requestAnimationFrame(function () {
pending = false;
update();
});
}
window.addEventListener("scroll", schedule, { passive: true });
window.addEventListener("resize", schedule);
update();
})();
</script>"##;