Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions sphinx_fuma/static/fuma.css
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,7 @@ body[data-toc-style="clerk"] .fd-toc-item a {
transition: color 0.15s, opacity 0.15s;
}

body[data-toc-style="clerk"] .fd-toc-item.fd-active a,
body[data-toc-style="clerk"] .fd-toc-item.fd-visible a {
body[data-toc-style="clerk"] .fd-toc-item.fd-active a {
opacity: 1;
}

Expand Down Expand Up @@ -1144,6 +1143,11 @@ body[data-toc-style="clerk"] .fd-toc-item.fd-visible a {
line-height: 1.75;
}

.fd-prose ul.simple > li > p,
.fd-prose ol.simple > li > p {
margin: 0;
}

.fd-prose a {
color: var(--color-fd-foreground);
font-weight: 500;
Expand Down
24 changes: 15 additions & 9 deletions sphinx_fuma/static/fuma.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,21 +162,21 @@
var targets = tocItems
.map(function (item) {
var href = item.querySelector("a").getAttribute("href") || "";
var heading = href.charAt(0) === "#" ? document.getElementById(decodeURIComponent(href.slice(1))) : null;
var anchor = href.charAt(0) === "#" ? document.getElementById(decodeURIComponent(href.slice(1))) : null;
var heading = anchor && (anchor.matches("h1, h2, h3, h4, h5, h6") ? anchor : anchor.querySelector("h1, h2, h3, h4, h5, h6"));
return heading ? { item: item, heading: heading } : null;
})
.filter(Boolean);

// The thumb spans every heading currently on screen, not just the first.
var mark = function (active) {
tocItems.forEach(function (item) {
item.classList.remove("fd-active", "fd-visible");
item.classList.remove("fd-active");
});
if (!active.length) return;
active.forEach(function (entry) {
entry.item.classList.add("fd-visible");
entry.item.classList.add("fd-active");
});
active[0].item.classList.add("fd-active");
if (rail) {
var first = active[0].item.querySelector("a");
var last = active[active.length - 1].item.querySelector("a");
Expand All @@ -199,15 +199,21 @@
return visible.has(target.heading);
});
if (!active.length) {
// Nothing in the band: fall back to the last heading scrolled past.
var passed = targets.filter(function (target) {
return target.heading.getBoundingClientRect().top < 0;
var viewTop = entries[0] && entries[0].rootBounds ? entries[0].rootBounds.top : 0;
var fallback = null;
var fallbackDistance = Infinity;
targets.forEach(function (target) {
var distance = Math.abs(target.heading.getBoundingClientRect().top - viewTop);
if (distance < fallbackDistance) {
fallback = target;
fallbackDistance = distance;
}
});
active = passed.length ? [passed[passed.length - 1]] : [targets[0]];
if (fallback) active = [fallback];
}
mark(active);
},
{ rootMargin: "-80px 0px -60% 0px", threshold: 0 }
{ threshold: 0.9 }
);

targets.forEach(function (target) {
Expand Down
15 changes: 15 additions & 0 deletions sphinx_fuma/tests/test_theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,21 @@ def test_toc_rail_is_an_svg_with_track_and_thumb(self, built):
assert 'class="fd-toc-track"' in html
assert 'class="fd-toc-thumb"' in html

def test_toc_scroll_spy_observes_headings_across_the_viewport(self, built):
script = (built / "_static" / "fuma.js").read_text()
assert 'anchor.querySelector("h1, h2, h3, h4, h5, h6")' in script
assert "threshold: 0.9" in script
assert "rootMargin:" not in script

def test_toc_scroll_spy_marks_every_visible_item_active(self, built):
script = (built / "_static" / "fuma.js").read_text()
assert 'entry.item.classList.add("fd-active")' in script
assert 'active[0].item.classList.add("fd-active")' not in script

def test_tight_list_paragraphs_do_not_expand_item_spacing(self, built):
stylesheet = (built / "_static" / "fuma.css").read_text()
assert (".fd-prose ul.simple > li > p,\n.fd-prose ol.simple > li > p {\n margin: 0;\n}") in stylesheet


class TestSteps:
def test_directive_wraps_content_in_a_steps_container(self, built):
Expand Down