@@ -52,7 +52,9 @@ function attachFerrises(type) {
5252 continue ;
5353 }
5454
55- container . appendChild ( createFerris ( type , size ) ) ;
55+ let ferris = createFerris ( type , size )
56+ container . appendChild ( ferris ) ;
57+ addPadding ( codeBlock , ferris ) ;
5658 }
5759}
5860
@@ -100,3 +102,77 @@ function createFerris(type, size) {
100102
101103 return a ;
102104}
105+
106+ /**
107+ *
108+ * @param {HTMLElement } codeBlock
109+ * @param {HTMLAnchorElement } ferris
110+ */
111+ function addPadding ( codeBlock , ferris ) {
112+ // console.log("offsetHeight:", ferris.offsetHeight, "offsetWidth:", ferris.offsetWidth, "offsetLeft", ferris.offsetLeft, "offsetTop:", ferris.offsetTop, "offsetParent:", ferris.offsetParent);
113+ // console.log(ferris.getBoundingClientRect());
114+
115+ const suspects = [ ] ; // array of spans which *might* be hidden by Ferris
116+
117+ const walker = document . createTreeWalker ( codeBlock , NodeFilter . SHOW_TEXT ) ;
118+ const re = / ^ ( .* ?) \n ( .* ) $ / s
119+
120+ let linebreaksToFix = 10 ;
121+ while ( linebreaksToFix > 0 && walker . nextNode ( ) ) {
122+ const current = walker . currentNode ;
123+ const parent = current . parentNode ;
124+
125+ // sanity checking + lint fixes
126+ if ( ! ( current instanceof Text ) ) {
127+ console . log ( "!(current instanceof Text) shouldn't happen" ) ;
128+ continue ;
129+ }
130+ if ( ! parent ) {
131+ console . log ( "!parent shouldn't happen" ) ;
132+ continue ;
133+ }
134+
135+ let re_results ;
136+ // I know nodeValue is not null because current is Text
137+ current . splitText
138+ while ( re_results = current . nodeValue . match ( re ) ) {
139+ linebreaksToFix -- ;
140+ if ( ! linebreaksToFix ) { break ; }
141+
142+ let [ _ , before , after ] = re_results ;
143+
144+ let elemBefore = document . createElement ( "span" ) ;
145+ elemBefore . innerText = before ;
146+ suspects . push ( elemBefore ) ;
147+
148+ parent . insertBefore ( elemBefore , current ) ;
149+ parent . insertBefore ( document . createTextNode ( "\n" ) , current ) ;
150+ current . nodeValue = after ;
151+ }
152+ }
153+
154+ codeBlock . normalize ( ) ; // not strictly necessary, but good practice to leave the DOM normalized
155+
156+ const actual_ferris = ferris . firstChild ;
157+
158+ setTimeout ( detectOverlap , 0 , suspects , actual_ferris ) ;
159+ }
160+
161+ /**
162+ *
163+ * @param {[HTMLSpanElement] } suspects
164+ * @param {HTMLAnchorElement } ferris
165+ */
166+ function detectOverlap ( suspects , ferris ) {
167+ const f = ferris . getBoundingClientRect ( ) ;
168+ suspects . forEach ( ( s ) => {
169+ const { bottom, top} = s . getBoundingClientRect ( ) ;
170+ if ( // vertical overlap between ferris and span
171+ ( bottom >= f . top && bottom <= f . bottom )
172+ || ( top >= f . top && top <= f . bottom )
173+ || ( f . top >= top && f . top <= bottom )
174+ ) {
175+ s . classList . add ( "ferris-buffer" ) ;
176+ }
177+ } ) ;
178+ }
0 commit comments