1+ /*
2+ * Fix for collapse scroll positioning issue
3+ * This script improves the scroll behavior when collapsing code blocks
4+ * for better reading continuity.
5+ *
6+ * The issue: when clicking collapse, the code block gets positioned too high
7+ * in the viewport, interrupting the reading flow.
8+ *
9+ * The solution: position the collapsed code block so its bottom is roughly
10+ * 1/3 from the top of the viewport, leaving visible content below for
11+ * continuous reading.
12+ */
13+
14+ document . addEventListener ( "DOMContentLoaded" , function ( ) {
15+ // Wait for the theme's JavaScript to load and set up collapse functionality
16+ setTimeout ( ( ) => {
17+ console . log ( 'Applying collapse scroll behavior fix...' ) ;
18+
19+ const collapsableCodeToggles = document . querySelectorAll (
20+ "div.cell[class*='tag_collapse'] .collapse-toggle-bar" ,
21+ ) ;
22+
23+ console . log ( `Found ${ collapsableCodeToggles . length } collapse toggles to fix` ) ;
24+
25+ // Remove existing event listeners by cloning and replacing elements
26+ for ( let i = 0 ; i < collapsableCodeToggles . length ; i ++ ) {
27+ const oldToggle = collapsableCodeToggles [ i ] ;
28+ const newToggle = oldToggle . cloneNode ( true ) ;
29+ oldToggle . parentNode . replaceChild ( newToggle , oldToggle ) ;
30+
31+ // Add improved event listener
32+ newToggle . addEventListener ( "click" , function ( e ) {
33+ console . log ( 'Collapse toggle clicked with improved behavior' ) ;
34+ e . preventDefault ( ) ;
35+ var codeBlock = this . closest ( "div.cell[class*='tag_collapse']" ) ;
36+ var codeBlockH = codeBlock . querySelector ( ".highlight" ) ;
37+ var indicator = this . querySelector ( ".collapse-indicator" ) ;
38+
39+ if ( codeBlock . classList . contains ( "expanded" ) ) {
40+ console . log ( 'Collapsing code block...' ) ;
41+ codeBlock . classList . remove ( "expanded" ) ;
42+ indicator . textContent = "Expand" ;
43+
44+ // Apply height based on collapse class
45+ const collapseAccToHeight = ( classList , elH ) => {
46+ for ( let className of classList ) {
47+ if ( className . startsWith ( "tag_collapse-" ) ) {
48+ const index = className . indexOf ( "-" ) ;
49+ const height = className . substring ( index + 1 ) ;
50+ if ( height && ! isNaN ( height ) ) {
51+ elH . style . height = parseInt ( height ) + 0.5 + "em" ;
52+ return true ;
53+ }
54+ }
55+ }
56+ return false ;
57+ } ;
58+
59+ collapseAccToHeight ( codeBlock . classList , codeBlockH ) ;
60+
61+ // Improved scroll behavior for better reading continuity
62+ setTimeout ( ( ) => {
63+ console . log ( 'Applying improved scroll positioning...' ) ;
64+ const rect = codeBlock . getBoundingClientRect ( ) ;
65+ const viewportHeight = window . innerHeight ;
66+
67+ // Position the collapsed code block so the reader can continue reading
68+ // Position the bottom of the collapsed block about 30% from the top of viewport
69+ // This leaves about 70% of the viewport showing content below the collapsed block
70+ const targetPositionFromTop = viewportHeight * 0.3 ;
71+ const currentScrollTop = window . pageYOffset || document . documentElement . scrollTop ;
72+ const elementTop = rect . top + currentScrollTop ;
73+ const elementHeight = rect . height ;
74+
75+ // Calculate scroll position to put the bottom of collapsed block at target position
76+ const newScrollTop = elementTop + elementHeight - targetPositionFromTop ;
77+
78+ // Ensure we don't scroll past page boundaries
79+ const maxScrollTop = Math . max ( 0 , document . documentElement . scrollHeight - viewportHeight ) ;
80+ const finalScrollTop = Math . max ( 0 , Math . min ( newScrollTop , maxScrollTop ) ) ;
81+
82+ console . log ( `Scrolling to position ${ finalScrollTop } for optimal reading flow` ) ;
83+
84+ window . scrollTo ( {
85+ top : finalScrollTop ,
86+ behavior : 'smooth'
87+ } ) ;
88+ } , 150 ) ; // Slightly longer delay for height change to complete
89+ } else {
90+ console . log ( 'Expanding code block...' ) ;
91+ codeBlock . classList . add ( "expanded" ) ;
92+ indicator . textContent = "Collapse" ;
93+ codeBlockH . style . height = "auto" ;
94+ }
95+ } ) ;
96+ }
97+ } , 1500 ) ; // Wait for theme JS to fully load
98+ } ) ;
0 commit comments