add iframe load timeout

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent 59c849e429
commit a5d77ea4f0
2 changed files with 47 additions and 22 deletions

View File

@@ -200,14 +200,26 @@ export function _isBlockedElement(
function onceIframeLoaded( function onceIframeLoaded(
iframeEl: HTMLIFrameElement, iframeEl: HTMLIFrameElement,
listener: () => unknown, listener: () => unknown,
iframeLoadTimeout: number,
) { ) {
const win = iframeEl.contentWindow; const win = iframeEl.contentWindow;
if (!win) { if (!win) {
return; return;
} }
// document is loading // document is loading
let fired = false;
if (win.document.readyState !== 'complete') { if (win.document.readyState !== 'complete') {
iframeEl.addEventListener('load', listener); const timer = setTimeout(() => {
if (!fired) {
listener();
fired = true;
}
}, iframeLoadTimeout);
iframeEl.addEventListener('load', () => {
clearTimeout(timer);
fired = true;
listener();
});
return; return;
} }
// check blank frame for Chrome // check blank frame for Chrome
@@ -519,6 +531,7 @@ export function serializeNodeWithId(
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number;
}, },
): serializedNodeWithId | null { ): serializedNodeWithId | null {
const { const {
@@ -533,6 +546,7 @@ export function serializeNodeWithId(
recordCanvas = false, recordCanvas = false,
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout = 5000,
} = options; } = options;
let { preserveWhiteSpace = true } = options; let { preserveWhiteSpace = true } = options;
const _serializedNode = serializeNode(n, { const _serializedNode = serializeNode(n, {
@@ -606,6 +620,7 @@ export function serializeNodeWithId(
preserveWhiteSpace, preserveWhiteSpace,
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout,
}); });
if (serializedChildNode) { if (serializedChildNode) {
serializedNode.childNodes.push(serializedChildNode); serializedNode.childNodes.push(serializedChildNode);
@@ -617,29 +632,34 @@ export function serializeNodeWithId(
serializedNode.type === NodeType.Element && serializedNode.type === NodeType.Element &&
serializedNode.tagName === 'iframe' serializedNode.tagName === 'iframe'
) { ) {
onceIframeLoaded(n as HTMLIFrameElement, () => { onceIframeLoaded(
const iframeDoc = (n as HTMLIFrameElement).contentDocument; n as HTMLIFrameElement,
if (iframeDoc && onIframeLoad) { () => {
const serializedIframeNode = serializeNodeWithId(iframeDoc, { const iframeDoc = (n as HTMLIFrameElement).contentDocument;
doc: iframeDoc, if (iframeDoc && onIframeLoad) {
map, const serializedIframeNode = serializeNodeWithId(iframeDoc, {
blockClass, doc: iframeDoc,
blockSelector, map,
skipChild: false, blockClass,
inlineStylesheet, blockSelector,
maskInputOptions, skipChild: false,
slimDOMOptions, inlineStylesheet,
recordCanvas, maskInputOptions,
preserveWhiteSpace, slimDOMOptions,
onSerialize, recordCanvas,
onIframeLoad, preserveWhiteSpace,
}); onSerialize,
onIframeLoad,
iframeLoadTimeout,
});
if (serializedIframeNode) { if (serializedIframeNode) {
onIframeLoad(n as INode, serializedIframeNode); onIframeLoad(n as INode, serializedIframeNode);
}
} }
} },
}); iframeLoadTimeout,
);
} }
return serializedNode; return serializedNode;
@@ -657,6 +677,7 @@ function snapshot(
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number;
}, },
): [serializedNodeWithId | null, idNodeMap] { ): [serializedNodeWithId | null, idNodeMap] {
const { const {
@@ -669,6 +690,7 @@ function snapshot(
preserveWhiteSpace, preserveWhiteSpace,
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout,
} = options || {}; } = options || {};
const idNodeMap: idNodeMap = {}; const idNodeMap: idNodeMap = {};
const maskInputOptions: MaskInputOptions = const maskInputOptions: MaskInputOptions =
@@ -725,6 +747,7 @@ function snapshot(
preserveWhiteSpace, preserveWhiteSpace,
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout,
}), }),
idNodeMap, idNodeMap,
]; ];

View File

@@ -17,6 +17,7 @@ export declare function serializeNodeWithId(n: Node | INode, options: {
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number;
}): serializedNodeWithId | null; }): serializedNodeWithId | null;
declare function snapshot(n: Document, options?: { declare function snapshot(n: Document, options?: {
blockClass?: string | RegExp; blockClass?: string | RegExp;
@@ -28,6 +29,7 @@ declare function snapshot(n: Document, options?: {
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number;
}): [serializedNodeWithId | null, idNodeMap]; }): [serializedNodeWithId | null, idNodeMap];
export declare function visitSnapshot(node: serializedNodeWithId, onVisit: (node: serializedNodeWithId) => unknown): void; export declare function visitSnapshot(node: serializedNodeWithId, onVisit: (node: serializedNodeWithId) => unknown): void;
export declare function cleanupSnapshot(): void; export declare function cleanupSnapshot(): void;