@@ -4,99 +4,189 @@ document.addEventListener('DOMContentLoaded', function() {
44 const parentUrl = window . parent . location . href ;
55 const links = document . querySelectorAll ( '.sidebar-tree a.reference' ) ;
66 let currentPageElement = null ;
7-
7+
88 links . forEach ( function ( link ) {
99 const linkUrl = new URL ( link . href , window . location . origin ) ;
1010 const parentUrlObj = new URL ( parentUrl ) ;
11-
11+
1212 // Compare the pathname (ignoring hash and query parameters)
1313 if ( linkUrl . pathname === parentUrlObj . pathname ) {
1414 link . parentElement . classList . add ( 'current-page' ) ;
1515 currentPageElement = link . parentElement ;
1616 }
1717 } ) ;
18-
18+
1919 // If we found the current page, expand the path to it and expand its children
2020 if ( currentPageElement ) {
2121 expandPathToElementAndChildren ( currentPageElement ) ;
22-
23- // After expansion, restore the scroll position
2422 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
30- currentPageElement . scrollIntoView ( {
31- behavior : 'instant' ,
32- block : 'nearest'
33- } ) ;
34- }
23+ scrollToElementIfNotVisible ( currentPageElement ) ;
24+ restoreRelativePosition ( currentPageElement ) ;
3525 }
36-
3726 } catch ( e ) {
3827 // Log that we can't access parent URL due to cross-origin restrictions
3928 console . log ( 'Cannot access parent URL:' , e ) ;
4029 }
41-
42- // Save scroll position when page unloads
30+
31+ // Save scroll position and relative position when page unloads
4332 window . addEventListener ( 'beforeunload' , saveScrollPosition ) ;
33+ window . addEventListener ( 'beforeunload' , saveRelativePosition ) ;
4434} ) ;
4535
4636function expandPathToElementAndChildren ( element ) {
37+ console . log ( 'Expanding path to element and its children...' ) ;
4738 // Start from the current page's list item
4839 let currentLi = element . closest ( 'li' ) ;
4940 if ( ! currentLi ) return ;
50-
41+
5142 // First, expand the current page's own children if it has any
5243 const currentCheckbox = currentLi . querySelector ( ':scope > .toctree-checkbox' ) ;
5344 if ( currentCheckbox ) {
5445 currentCheckbox . checked = true ;
5546 }
56-
47+
5748 // Then walk up the ancestry to expand the path to this element
5849 while ( currentLi ) {
5950 // Find the parent ul of this li
6051 const parentUl = currentLi . parentElement ;
6152 if ( ! parentUl || parentUl . tagName !== 'UL' ) {
6253 break ;
6354 }
64-
55+
6556 // Find the parent li of that ul (this is the section that contains our current path)
6657 const parentLi = parentUl . parentElement ;
6758 if ( ! parentLi || parentLi . tagName !== 'LI' ) {
6859 break ;
6960 }
70-
61+
7162 // Look for a checkbox specifically in this parent li (not descendants)
7263 const checkbox = parentLi . querySelector ( ':scope > .toctree-checkbox' ) ;
7364 if ( checkbox ) {
7465 checkbox . checked = true ;
7566 }
76-
67+
7768 // Move up to the next level
7869 currentLi = parentLi ;
7970 }
80- }
71+ console . log ( 'Expanded path to element and its children' ) ;
72+ }
8173
8274function saveScrollPosition ( ) {
75+ console . log ( 'Saving scroll position...' ) ;
8376 try {
84- window . savedScrollPosition = window . pageYOffset || document . documentElement . scrollTop ;
77+ // Target the toc-content div which has the scroll attribute
78+ const scrollableContainer = document . querySelector ( '.toc-content' ) ;
79+ if ( ! scrollableContainer ) {
80+ console . log ( 'No scrollable container found!' ) ;
81+ return ;
82+ }
83+
84+ // Save the container's scroll position
85+ sessionStorage . setItem ( 'sidebarScrollPosition' , scrollableContainer . scrollTop ) ;
86+
87+ console . log ( 'Saved scroll position to' , scrollableContainer . scrollTop ) ;
8588 } catch ( e ) {
8689 console . log ( 'Could not save scroll position:' , e ) ;
8790 }
8891}
8992
90- function restoreScrollPosition ( ) {
93+ function saveRelativePosition ( ) {
94+ console . log ( 'Saving relative position of current page...' ) ;
9195 try {
92- if ( window . savedScrollPosition === undefined ) return ;
93-
94- // Restore the exact scroll position
95- window . scrollTo ( {
96- top : window . savedScrollPosition ,
97- behavior : 'instant'
96+ // Target the toc-content div which has the scroll attribute
97+ const scrollableContainer = document . querySelector ( '.toc-content' ) ;
98+ if ( ! scrollableContainer ) {
99+ console . log ( 'No scrollable container found!' ) ;
100+ return ;
101+ }
102+
103+ // Save the destination page's relative position within the viewport if it's visible
104+ const links = document . querySelectorAll ( '.sidebar-tree a.reference' ) ;
105+ links . forEach ( function ( link ) {
106+ const linkUrl = new URL ( link . href , window . location . origin ) ;
107+ const rect = link . parentElement . getBoundingClientRect ( ) ;
108+ const containerRect = scrollableContainer . getBoundingClientRect ( ) ;
109+ const relativePosition = rect . top - containerRect . top ;
110+
111+ // Save the relative position for each visible page using its pathname as key
112+ const key = 'pageRelativePosition_' + linkUrl . pathname ;
113+ sessionStorage . setItem ( key , relativePosition ) ;
98114 } ) ;
115+
116+ console . log ( 'Saved relative position of current page' ) ;
117+ } catch ( e ) {
118+ console . log ( 'Could not save relative position of current page:' , e ) ;
119+ }
120+ }
121+
122+ function restoreScrollPosition ( ) {
123+ console . log ( 'Restoring scroll position...' ) ;
124+ try {
125+ const scrollableContainer = document . querySelector ( '.toc-content' ) ;
126+ if ( ! scrollableContainer ) {
127+ console . log ( 'No scrollable container found!' ) ;
128+ return ;
129+ }
130+
131+ const savedScrollPosition = sessionStorage . getItem ( 'sidebarScrollPosition' ) ;
132+ if ( savedScrollPosition === null ) {
133+ console . log ( 'No scroll position to restore!' ) ;
134+ return ;
135+ } ;
136+
137+ // Restore scroll position to the toc-content container
138+ scrollableContainer . scrollTop = parseInt ( savedScrollPosition , 10 ) ;
139+ console . log ( 'Restored scroll position to' , parseInt ( savedScrollPosition , 10 ) ) ;
99140 } catch ( e ) {
100141 console . log ( 'Could not restore scroll position:' , e ) ;
101142 }
102- }
143+ }
144+
145+ function scrollToElementIfNotVisible ( element ) {
146+ console . log ( 'Checking if current page is visible...' ) ;
147+ const rect = element . getBoundingClientRect ( ) ;
148+ if ( rect . top < 0 || rect . top > window . innerHeight ) {
149+ console . log ( 'Current page is not visible, scrolling to show it...' ) ;
150+
151+ element . scrollIntoView ( {
152+ behavior : 'instant' ,
153+ block : 'center'
154+ } ) ;
155+
156+ console . log ( 'Scrolled current page into view' ) ;
157+ } else {
158+ console . log ( 'Current page is already visible' ) ;
159+ }
160+ }
161+
162+ function restoreRelativePosition ( element ) {
163+ console . log ( 'Restoring relative position of current page...' ) ;
164+
165+ // Then try to restore the relative position it had on the previous page
166+ const parentUrl = window . parent . location . href ;
167+ const parentUrlObj = new URL ( parentUrl ) ;
168+ const key = 'pageRelativePosition_' + parentUrlObj . pathname ;
169+ const savedRelativePosition = sessionStorage . getItem ( key ) ;
170+
171+ if ( savedRelativePosition == null ) {
172+ console . log ( 'No relative position to restore!' ) ;
173+ return ;
174+ }
175+
176+ const scrollableContainer = document . querySelector ( '.toc-content' ) ;
177+ if ( scrollableContainer == null ) {
178+ console . log ( 'No scrollable container found!' ) ;
179+ return ;
180+ }
181+
182+ const targetRelativePosition = parseInt ( savedRelativePosition , 10 ) ;
183+ const currentRect = element . getBoundingClientRect ( ) ;
184+ const containerRect = scrollableContainer . getBoundingClientRect ( ) ;
185+ const currentRelativePosition = currentRect . top - containerRect . top ;
186+
187+ // Calculate how much we need to scroll to restore the relative position
188+ const adjustment = currentRelativePosition - targetRelativePosition ;
189+ scrollableContainer . scrollTop += adjustment ;
190+
191+ console . log ( 'Restored relative position of current page to' , targetRelativePosition , 'with adjustment of' , adjustment ) ;
192+ }
0 commit comments