@@ -43,23 +43,32 @@ function addProgressIndicatorStyles() {
4343 document . head . appendChild ( style ) ;
4444}
4545
46- // Find the current TOC link based on visible headings
47- function findCurrentTocLink ( elements : TocElements ) : HTMLAnchorElement | undefined {
48- let currentTocLink : HTMLAnchorElement | undefined ;
46+ // Find the current TOC links based on visible headings
47+ function findCurrentTocLinks ( elements : TocElements ) : HTMLAnchorElement [ ] {
48+ let currentTocLinks : HTMLAnchorElement [ ] = [ ] ;
49+ let currentTop : number | null = null ;
4950
5051 for ( const heading of elements . headings ) {
5152 const rect = heading . getBoundingClientRect ( ) ;
53+ const headingText = heading . textContent ?. trim ( ) ?? '' ;
54+
5255 if ( rect . top <= HEADING_OFFSET ) {
56+ // If we find a heading at a new height, clear previous links
57+ if ( currentTop !== null && Math . abs ( rect . top - currentTop ) > 1 ) {
58+ currentTocLinks = [ ] ;
59+ }
60+ currentTop = rect . top ;
61+
5362 const foundLink = elements . tocLinks . find ( link =>
5463 link . getAttribute ( 'href' ) === `#${ heading . closest ( 'section' ) ?. id } `
5564 ) ;
5665 if ( foundLink ) {
57- currentTocLink = foundLink ;
66+ currentTocLinks . push ( foundLink ) ;
5867 }
5968 }
6069 }
6170
62- return currentTocLink ;
71+ return currentTocLinks ;
6372}
6473
6574// Get visible headings in viewport
@@ -119,21 +128,27 @@ function updateIndicator(elements: TocElements) {
119128 if ( ! elements . markdownContent || ! elements . tocNav ) return ;
120129
121130 const isAtBottom = window . innerHeight + window . scrollY >= document . documentElement . scrollHeight - 10 ;
122- const currentTocLink = findCurrentTocLink ( elements ) ;
131+ const currentTocLinks = findCurrentTocLinks ( elements ) ;
123132
124133 if ( isAtBottom ) {
125134 handleBottomScroll ( elements ) ;
126- } else if ( currentTocLink ) {
127- const link = currentTocLink . closest ( 'li' ) ;
128- if ( ! link ) return ;
129-
135+ } else if ( currentTocLinks . length > 0 ) {
130136 const tocRect = elements . tocNav . getBoundingClientRect ( ) ;
131- const linkRect = link . getBoundingClientRect ( ) ;
137+
138+ // Find the topmost and bottommost link positions
139+ const linkElements = currentTocLinks
140+ . map ( link => link . closest ( 'li' ) )
141+ . filter ( ( li ) : li is HTMLLIElement => li !== null ) ;
142+
143+ if ( linkElements . length === 0 ) return ;
144+
145+ const firstLinkRect = linkElements [ 0 ] . getBoundingClientRect ( ) ;
146+ const lastLinkRect = linkElements [ linkElements . length - 1 ] . getBoundingClientRect ( ) ;
132147
133148 updateProgressIndicatorPosition (
134149 elements . progressIndicator ,
135- linkRect . top - tocRect . top ,
136- linkRect . height
150+ firstLinkRect . top - tocRect . top ,
151+ ( lastLinkRect . top + lastLinkRect . height ) - firstLinkRect . top
137152 ) ;
138153 }
139154}
0 commit comments