Skip to content

Commit 289580b

Browse files
authored
Expand current page's dropdown and maintain scroll position in RTD TOC (#132)
* Expand current page dropdown in RTD TOC * Modify scroll behavior to use previous position * Scroll to show current page, remove scroll timeout
1 parent da3b3a1 commit 289580b

File tree

1 file changed

+47
-9
lines changed

1 file changed

+47
-9
lines changed

docs/_static/toc-highlight.js

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,45 @@ document.addEventListener('DOMContentLoaded', function() {
1616
}
1717
});
1818

19-
// If we found the current page, expand the path to it
19+
// If we found the current page, expand the path to it and expand its children
2020
if (currentPageElement) {
21-
expandPathToElement(currentPageElement);
21+
expandPathToElementAndChildren(currentPageElement);
2222

23-
// Scroll to make the current page visible
24-
setTimeout(function() {
23+
// After expansion, restore the scroll position
24+
restoreScrollPosition();
25+
26+
// Check if current page is still visible after restoration
27+
const rect = currentPageElement.getBoundingClientRect();
28+
if (rect.top < 0 || rect.top > window.innerHeight) {
29+
// Current page is not visible, scroll to show it
2530
currentPageElement.scrollIntoView({
26-
behavior: 'smooth',
27-
block: 'center'
31+
behavior: 'instant',
32+
block: 'nearest'
2833
});
29-
}, 100); // Small delay to ensure expansion is complete
34+
}
3035
}
3136

3237
} catch (e) {
3338
// Log that we can't access parent URL due to cross-origin restrictions
3439
console.log('Cannot access parent URL:', e);
3540
}
41+
42+
// Save scroll position when page unloads
43+
window.addEventListener('beforeunload', saveScrollPosition);
3644
});
3745

38-
function expandPathToElement(element) {
39-
// Start from the current page's list item and walk up the ancestry
46+
function expandPathToElementAndChildren(element) {
47+
// Start from the current page's list item
4048
let currentLi = element.closest('li');
49+
if (!currentLi) return;
50+
51+
// First, expand the current page's own children if it has any
52+
const currentCheckbox = currentLi.querySelector(':scope > .toctree-checkbox');
53+
if (currentCheckbox) {
54+
currentCheckbox.checked = true;
55+
}
4156

57+
// Then walk up the ancestry to expand the path to this element
4258
while (currentLi) {
4359
// Find the parent ul of this li
4460
const parentUl = currentLi.parentElement;
@@ -61,4 +77,26 @@ function expandPathToElement(element) {
6177
// Move up to the next level
6278
currentLi = parentLi;
6379
}
80+
}
81+
82+
function saveScrollPosition() {
83+
try {
84+
window.savedScrollPosition = window.pageYOffset || document.documentElement.scrollTop;
85+
} catch (e) {
86+
console.log('Could not save scroll position:', e);
87+
}
88+
}
89+
90+
function restoreScrollPosition() {
91+
try {
92+
if (window.savedScrollPosition === undefined) return;
93+
94+
// Restore the exact scroll position
95+
window.scrollTo({
96+
top: window.savedScrollPosition,
97+
behavior: 'instant'
98+
});
99+
} catch (e) {
100+
console.log('Could not restore scroll position:', e);
101+
}
64102
}

0 commit comments

Comments
 (0)