add keepIframeSrcFn option (#81)

* add allowIframe option to snapshot

* rename allowIframe to keepIframeSrcFn
This commit is contained in:
bachmanity1
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 61074a2303
commit 9110664ca2
5 changed files with 20 additions and 5 deletions

View File

@@ -154,9 +154,7 @@ function buildNode(
node.appendChild(child); node.appendChild(child);
continue; continue;
} }
if (tagName === 'iframe' && name === 'src') {
continue;
}
try { try {
if (n.isSVG && name === 'xlink:href') { if (n.isSVG && name === 'xlink:href') {
node.setAttributeNS('http://www.w3.org/1999/xlink', name, value); node.setAttributeNS('http://www.w3.org/1999/xlink', name, value);

View File

@@ -8,6 +8,7 @@ import {
MaskInputOptions, MaskInputOptions,
SlimDOMOptions, SlimDOMOptions,
MaskTextFn, MaskTextFn,
KeepIframeSrcFn,
} from './types'; } from './types';
import { isElement, isShadowRoot } from './utils'; import { isElement, isShadowRoot } from './utils';
@@ -348,6 +349,7 @@ function serializeNode(
maskInputOptions: MaskInputOptions; maskInputOptions: MaskInputOptions;
maskTextFn: MaskTextFn | undefined; maskTextFn: MaskTextFn | undefined;
recordCanvas: boolean; recordCanvas: boolean;
keepIframeSrcFn: KeepIframeSrcFn;
}, },
): serializedNode | false { ): serializedNode | false {
const { const {
@@ -360,6 +362,7 @@ function serializeNode(
maskInputOptions = {}, maskInputOptions = {},
maskTextFn, maskTextFn,
recordCanvas, recordCanvas,
keepIframeSrcFn
} = options; } = options;
// Only record root id when document object is not the base document // Only record root id when document object is not the base document
let rootId: number | undefined; let rootId: number | undefined;
@@ -483,7 +486,7 @@ function serializeNode(
}; };
} }
// iframe // iframe
if (tagName === 'iframe') { if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src as string)) {
delete attributes.src; delete attributes.src;
} }
return { return {
@@ -648,6 +651,7 @@ export function serializeNodeWithId(
maskInputOptions?: MaskInputOptions; maskInputOptions?: MaskInputOptions;
maskTextFn: MaskTextFn | undefined; maskTextFn: MaskTextFn | undefined;
slimDOMOptions: SlimDOMOptions; slimDOMOptions: SlimDOMOptions;
keepIframeSrcFn?: KeepIframeSrcFn;
recordCanvas?: boolean; recordCanvas?: boolean;
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
@@ -671,6 +675,7 @@ export function serializeNodeWithId(
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout = 5000, iframeLoadTimeout = 5000,
keepIframeSrcFn = () => false,
} = options; } = options;
let { preserveWhiteSpace = true } = options; let { preserveWhiteSpace = true } = options;
const _serializedNode = serializeNode(n, { const _serializedNode = serializeNode(n, {
@@ -683,6 +688,7 @@ export function serializeNodeWithId(
maskInputOptions, maskInputOptions,
maskTextFn, maskTextFn,
recordCanvas, recordCanvas,
keepIframeSrcFn,
}); });
if (!_serializedNode) { if (!_serializedNode) {
// TODO: dev only // TODO: dev only
@@ -750,6 +756,7 @@ export function serializeNodeWithId(
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout, iframeLoadTimeout,
keepIframeSrcFn,
}; };
for (const childN of Array.from(n.childNodes)) { for (const childN of Array.from(n.childNodes)) {
const serializedChildNode = serializeNodeWithId(childN, bypassOptions); const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
@@ -800,6 +807,7 @@ export function serializeNodeWithId(
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout, iframeLoadTimeout,
keepIframeSrcFn,
}); });
if (serializedIframeNode) { if (serializedIframeNode) {
@@ -830,6 +838,7 @@ function snapshot(
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number; iframeLoadTimeout?: number;
keepIframeSrcFn?: KeepIframeSrcFn;
}, },
): [serializedNodeWithId | null, idNodeMap] { ): [serializedNodeWithId | null, idNodeMap] {
const { const {
@@ -846,6 +855,7 @@ function snapshot(
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout, iframeLoadTimeout,
keepIframeSrcFn = () => false,
} = options || {}; } = options || {};
const idNodeMap: idNodeMap = {}; const idNodeMap: idNodeMap = {};
const maskInputOptions: MaskInputOptions = const maskInputOptions: MaskInputOptions =
@@ -909,6 +919,7 @@ function snapshot(
onSerialize, onSerialize,
onIframeLoad, onIframeLoad,
iframeLoadTimeout, iframeLoadTimeout,
keepIframeSrcFn,
}), }),
idNodeMap, idNodeMap,
]; ];

View File

@@ -108,3 +108,6 @@ export type SlimDOMOptions = Partial<{
}>; }>;
export type MaskTextFn = (text: string) => string; export type MaskTextFn = (text: string) => string;
export type KeepIframeSrcFn = (src: string) => boolean;

View File

@@ -1,4 +1,4 @@
import { serializedNodeWithId, INode, idNodeMap, MaskInputOptions, SlimDOMOptions, MaskTextFn } from './types'; import { serializedNodeWithId, INode, idNodeMap, MaskInputOptions, SlimDOMOptions, MaskTextFn, KeepIframeSrcFn } from './types';
export declare const IGNORED_NODE = -2; export declare const IGNORED_NODE = -2;
export declare function absoluteToStylesheet(cssText: string | null, href: string): string; export declare function absoluteToStylesheet(cssText: string | null, href: string): string;
export declare function absoluteToDoc(doc: Document, attributeValue: string): string; export declare function absoluteToDoc(doc: Document, attributeValue: string): string;
@@ -17,6 +17,7 @@ export declare function serializeNodeWithId(n: Node | INode, options: {
maskInputOptions?: MaskInputOptions; maskInputOptions?: MaskInputOptions;
maskTextFn: MaskTextFn | undefined; maskTextFn: MaskTextFn | undefined;
slimDOMOptions: SlimDOMOptions; slimDOMOptions: SlimDOMOptions;
keepIframeSrcFn?: KeepIframeSrcFn;
recordCanvas?: boolean; recordCanvas?: boolean;
preserveWhiteSpace?: boolean; preserveWhiteSpace?: boolean;
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
@@ -37,6 +38,7 @@ declare function snapshot(n: Document, options?: {
onSerialize?: (n: INode) => unknown; onSerialize?: (n: INode) => unknown;
onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown;
iframeLoadTimeout?: number; iframeLoadTimeout?: number;
keepIframeSrcFn?: KeepIframeSrcFn;
}): [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;

1
typings/types.d.ts vendored
View File

@@ -88,3 +88,4 @@ export declare type SlimDOMOptions = Partial<{
headMetaVerification: boolean; headMetaVerification: boolean;
}>; }>;
export declare type MaskTextFn = (text: string) => string; export declare type MaskTextFn = (text: string) => string;
export declare type KeepIframeSrcFn = (src: string) => boolean;