@@ -62,7 +62,7 @@ export function addHoverClass(cssText: string): string {
6262 if ( ! ast . stylesheet ) {
6363 return cssText ;
6464 }
65- ast . stylesheet . rules . forEach ( rule => {
65+ ast . stylesheet . rules . forEach ( ( rule ) => {
6666 if ( 'selectors' in rule ) {
6767 ( rule . selectors || [ ] ) . forEach ( ( selector : string ) => {
6868 if ( HOVER_SELECTOR . test ( selector ) ) {
@@ -102,7 +102,8 @@ function buildNode(
102102 continue ;
103103 }
104104 let value = n . attributes [ name ] ;
105- value = typeof value === 'boolean' || typeof value === 'number' ? '' : value ;
105+ value =
106+ typeof value === 'boolean' || typeof value === 'number' ? '' : value ;
106107 // attribute names start with rr_ are internal attributes added by rrweb
107108 if ( ! name . startsWith ( 'rr_' ) ) {
108109 const isTextarea = tagName === 'textarea' && name === 'value' ;
@@ -128,7 +129,11 @@ function buildNode(
128129 try {
129130 if ( n . isSVG && name === 'xlink:href' ) {
130131 node . setAttributeNS ( 'http://www.w3.org/1999/xlink' , name , value ) ;
131- } else if ( name == 'onload' || name == 'onclick' || name . substring ( 0 , 7 ) == 'onmouse' ) {
132+ } else if (
133+ name === 'onload' ||
134+ name === 'onclick' ||
135+ name . substring ( 0 , 7 ) === 'onmouse'
136+ ) {
132137 // Rename some of the more common atttributes from https://www.w3schools.com/tags/ref_eventattributes.asp
133138 // as setting them triggers a console.error (which shows up despite the try/catch)
134139 // Assumption: these attributes are not used to css
@@ -220,40 +225,55 @@ export function buildNodeWithSN(
220225 return node as INode ;
221226}
222227
223- function sideEffects ( idNodeMap : idNodeMap ) {
224- for ( let id in idNodeMap ) {
225- const node = idNodeMap [ id ] ;
226- const n = node . __sn ;
227- if ( n . type !== NodeType . Element ) {
228+ function visit ( idNodeMap : idNodeMap , onVisit : ( node : INode ) => void ) {
229+ function walk ( node : INode ) {
230+ onVisit ( node ) ;
231+ }
232+
233+ for ( const key in idNodeMap ) {
234+ if ( idNodeMap [ key ] ) {
235+ walk ( idNodeMap [ key ] ) ;
236+ }
237+ }
238+ }
239+
240+ function handleScroll ( node : INode ) {
241+ const n = node . __sn ;
242+ if ( n . type !== NodeType . Element ) {
243+ return ;
244+ }
245+ const el = ( node as Node ) as HTMLElement ;
246+ for ( const name in n . attributes ) {
247+ if ( ! ( n . attributes . hasOwnProperty ( name ) && name . startsWith ( 'rr_' ) ) ) {
228248 continue ;
229249 }
230- const el = node as Node as HTMLElement ;
231- for ( const name in n . attributes ) {
232- if ( ! ( n . attributes . hasOwnProperty ( name ) && name . startsWith ( 'rr_' ) ) ) {
233- continue ;
234- }
235- const value = n . attributes [ name ] ;
236- if ( name === 'rr_scrollLeft' ) {
237- el . scrollLeft = value as number ;
238- }
239- if ( name === 'rr_scrollTop' ) {
240- el . scrollTop = value as number ;
241- }
250+ const value = n . attributes [ name ] ;
251+ if ( name === 'rr_scrollLeft' ) {
252+ el . scrollLeft = value as number ;
253+ }
254+ if ( name === 'rr_scrollTop' ) {
255+ el . scrollTop = value as number ;
242256 }
243257 }
244258}
245259
246260function rebuild (
247261 n : serializedNodeWithId ,
248262 doc : Document ,
263+ onVisit ?: ( node : INode ) => unknown ,
249264 /**
250265 * This is not a public API yet, just for POC
251266 */
252267 HACK_CSS : boolean = true ,
253268) : [ Node | null , idNodeMap ] {
254269 const idNodeMap : idNodeMap = { } ;
255270 const node = buildNodeWithSN ( n , doc , idNodeMap , false , HACK_CSS ) ;
256- sideEffects ( idNodeMap ) ;
271+ visit ( idNodeMap , ( visitedNode ) => {
272+ if ( onVisit ) {
273+ onVisit ( visitedNode ) ;
274+ }
275+ handleScroll ( visitedNode ) ;
276+ } ) ;
257277 return [ node , idNodeMap ] ;
258278}
259279
0 commit comments