fixed scrollspy

This commit is contained in:
Sergey Chernov 2025-12-22 06:30:40 +01:00
parent 0add0ab54c
commit 0dbfb473bf
3 changed files with 11 additions and 7 deletions

View File

@ -181,7 +181,7 @@ fun DocsPage(
scheduled = false
try {
val heads = toc.mapNotNull { id -> el.querySelector("#${id.id}") as? HTMLHeadingElement }
val tops = heads.map { it.getBoundingClientRect().top + window.scrollY }
val tops = heads.map { it.getBoundingClientRect().top }
val offset = (updateNavbarOffsetVar() + 16).toDouble()
val idx = activeIndexForTops(tops, offset)
setActiveTocId(if (idx in toc.indices) toc[idx].id else null)

View File

@ -1024,11 +1024,15 @@ internal fun normalizePath(path: String): String {
// If none are above the offset, returns 0. If list is empty, returns 0.
fun activeIndexForTops(tops: List<Double>, offsetPx: Double): Int {
if (tops.isEmpty()) return 0
var lastAbove = 0
for (i in tops.indices) {
if (tops[i] - offsetPx > 0.0) return i
if (tops[i] <= offsetPx) {
lastAbove = i
} else {
break
}
}
// If all headings are above the offset, select the last one
return tops.size - 1
return lastAbove
}
fun main() {

View File

@ -28,20 +28,20 @@ class ScrollSpyTest {
fun selectsFirstWhenOnlyFirstIsAboveOffset() {
val tops = listOf(20.0, 200.0, 800.0) // px from viewport top
val idx = activeIndexForTops(tops, offsetPx = 80.0)
assertEquals(1, idx) // 20 <= 80, 200 > 80 -> index 1 (second heading is first below offset)
assertEquals(0, idx) // 20 <= 80 (active), 200 > 80 (stops) -> index 0
}
@Test
fun selectsLastHeadingAboveOffset() {
val tops = listOf(-100.0, 50.0, 70.0)
val idx = activeIndexForTops(tops, offsetPx = 80.0)
assertEquals(2, idx) // all three are <= 80 -> last index
assertEquals(2, idx) // all three are <= 80 -> last index 2
}
@Test
fun stopsBeforeFirstBelowOffset() {
val tops = listOf(-200.0, -50.0, 30.0, 150.0, 400.0)
val idx = activeIndexForTops(tops, offsetPx = 80.0)
assertEquals(3, idx) // 30 <= 80 qualifies; 150 > 80 stops, so index 3rd (0-based -> 3?)
assertEquals(2, idx) // 30 <= 80 is the last one; 150 > 80 -> index 2
}
}