@@ -200,14 +200,26 @@ export function _isBlockedElement(
200200function onceIframeLoaded (
201201 iframeEl : HTMLIFrameElement ,
202202 listener : ( ) => unknown ,
203+ iframeLoadTimeout : number ,
203204) {
204205 const win = iframeEl . contentWindow ;
205206 if ( ! win ) {
206207 return ;
207208 }
208209 // document is loading
210+ let fired = false ;
209211 if ( win . document . readyState !== 'complete' ) {
210- iframeEl . addEventListener ( 'load' , listener ) ;
212+ const timer = setTimeout ( ( ) => {
213+ if ( ! fired ) {
214+ listener ( ) ;
215+ fired = true ;
216+ }
217+ } , iframeLoadTimeout ) ;
218+ iframeEl . addEventListener ( 'load' , ( ) => {
219+ clearTimeout ( timer ) ;
220+ fired = true ;
221+ listener ( ) ;
222+ } ) ;
211223 return ;
212224 }
213225 // check blank frame for Chrome
@@ -519,6 +531,7 @@ export function serializeNodeWithId(
519531 preserveWhiteSpace ?: boolean ;
520532 onSerialize ?: ( n : INode ) => unknown ;
521533 onIframeLoad ?: ( iframeINode : INode , node : serializedNodeWithId ) => unknown ;
534+ iframeLoadTimeout ?: number ;
522535 } ,
523536) : serializedNodeWithId | null {
524537 const {
@@ -533,6 +546,7 @@ export function serializeNodeWithId(
533546 recordCanvas = false ,
534547 onSerialize,
535548 onIframeLoad,
549+ iframeLoadTimeout = 5000 ,
536550 } = options ;
537551 let { preserveWhiteSpace = true } = options ;
538552 const _serializedNode = serializeNode ( n , {
@@ -606,6 +620,7 @@ export function serializeNodeWithId(
606620 preserveWhiteSpace,
607621 onSerialize,
608622 onIframeLoad,
623+ iframeLoadTimeout,
609624 } ) ;
610625 if ( serializedChildNode ) {
611626 serializedNode . childNodes . push ( serializedChildNode ) ;
@@ -617,29 +632,34 @@ export function serializeNodeWithId(
617632 serializedNode . type === NodeType . Element &&
618633 serializedNode . tagName === 'iframe'
619634 ) {
620- onceIframeLoaded ( n as HTMLIFrameElement , ( ) => {
621- const iframeDoc = ( n as HTMLIFrameElement ) . contentDocument ;
622- if ( iframeDoc && onIframeLoad ) {
623- const serializedIframeNode = serializeNodeWithId ( iframeDoc , {
624- doc : iframeDoc ,
625- map,
626- blockClass,
627- blockSelector,
628- skipChild : false ,
629- inlineStylesheet,
630- maskInputOptions,
631- slimDOMOptions,
632- recordCanvas,
633- preserveWhiteSpace,
634- onSerialize,
635- onIframeLoad,
636- } ) ;
637-
638- if ( serializedIframeNode ) {
639- onIframeLoad ( n as INode , serializedIframeNode ) ;
635+ onceIframeLoaded (
636+ n as HTMLIFrameElement ,
637+ ( ) => {
638+ const iframeDoc = ( n as HTMLIFrameElement ) . contentDocument ;
639+ if ( iframeDoc && onIframeLoad ) {
640+ const serializedIframeNode = serializeNodeWithId ( iframeDoc , {
641+ doc : iframeDoc ,
642+ map,
643+ blockClass,
644+ blockSelector,
645+ skipChild : false ,
646+ inlineStylesheet,
647+ maskInputOptions,
648+ slimDOMOptions,
649+ recordCanvas,
650+ preserveWhiteSpace,
651+ onSerialize,
652+ onIframeLoad,
653+ iframeLoadTimeout,
654+ } ) ;
655+
656+ if ( serializedIframeNode ) {
657+ onIframeLoad ( n as INode , serializedIframeNode ) ;
658+ }
640659 }
641- }
642- } ) ;
660+ } ,
661+ iframeLoadTimeout ,
662+ ) ;
643663 }
644664
645665 return serializedNode ;
@@ -657,6 +677,7 @@ function snapshot(
657677 preserveWhiteSpace ?: boolean ;
658678 onSerialize ?: ( n : INode ) => unknown ;
659679 onIframeLoad ?: ( iframeINode : INode , node : serializedNodeWithId ) => unknown ;
680+ iframeLoadTimeout ?: number ;
660681 } ,
661682) : [ serializedNodeWithId | null , idNodeMap ] {
662683 const {
@@ -669,6 +690,7 @@ function snapshot(
669690 preserveWhiteSpace,
670691 onSerialize,
671692 onIframeLoad,
693+ iframeLoadTimeout,
672694 } = options || { } ;
673695 const idNodeMap : idNodeMap = { } ;
674696 const maskInputOptions : MaskInputOptions =
@@ -725,6 +747,7 @@ function snapshot(
725747 preserveWhiteSpace,
726748 onSerialize,
727749 onIframeLoad,
750+ iframeLoadTimeout,
728751 } ) ,
729752 idNodeMap ,
730753 ] ;
0 commit comments