From 19eca4da6da82b4455f0e0226fc0b8370abe2fc8 Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 1 Apr 2026 12:00:00 +0800 Subject: [PATCH] use document object from params instead of the one in the current scope --- index.d.ts | 2 +- src/rebuild.ts | 22 +++++++++++----------- test/integration.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/index.d.ts b/index.d.ts index bfd03d96..9f2eda37 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,7 +2,7 @@ import { serializedNodeWithId, idNodeMap } from './src/types'; export * from './src/types'; export function snapshot(n: Document): [serializedNodeWithId | null, idNodeMap]; -export function rebuild(n: serializedNodeWithId): Node | null; +export function rebuild(n: serializedNodeWithId, doc: Document): Node | null; export function serializeNodeWithId( n: Node, doc: Document, diff --git a/src/rebuild.ts b/src/rebuild.ts index 4e61283e..c53cf72b 100644 --- a/src/rebuild.ts +++ b/src/rebuild.ts @@ -11,19 +11,19 @@ function getTagName(n: elementNode): string { return tagName; } -function buildNode(n: serializedNodeWithId): Node | null { +function buildNode(n: serializedNodeWithId, doc: Document): Node | null { switch (n.type) { case NodeType.Document: - return document.implementation.createDocument(null, '', null); + return doc.implementation.createDocument(null, '', null); case NodeType.DocumentType: - return document.implementation.createDocumentType( + return doc.implementation.createDocumentType( n.name, n.publicId, n.systemId, ); case NodeType.Element: const tagName = getTagName(n); - const node = document.createElement(tagName); + const node = doc.createElement(tagName); const extraChildIndexes: number[] = []; for (const name in n.attributes) { if (n.attributes.hasOwnProperty(name)) { @@ -32,7 +32,7 @@ function buildNode(n: serializedNodeWithId): Node | null { const isTextarea = tagName === 'textarea' && name === 'value'; const isRemoteCss = tagName === 'style' && name === '_cssText'; if (isTextarea || isRemoteCss) { - const child = document.createTextNode(value); + const child = doc.createTextNode(value); // identify the extra child DOM we added when rebuild extraChildIndexes.push(node.childNodes.length); node.appendChild(child); @@ -53,18 +53,18 @@ function buildNode(n: serializedNodeWithId): Node | null { } return node; case NodeType.Text: - return document.createTextNode(n.textContent); + return doc.createTextNode(n.textContent); case NodeType.CDATA: - return document.createCDATASection(n.textContent); + return doc.createCDATASection(n.textContent); case NodeType.Comment: - return document.createComment(n.textContent); + return doc.createComment(n.textContent); default: return null; } } -function rebuild(n: serializedNodeWithId): Node | null { - const root = buildNode(n); +function rebuild(n: serializedNodeWithId, doc: Document): Node | null { + const root = buildNode(n, doc); if (!root) { return null; } @@ -73,7 +73,7 @@ function rebuild(n: serializedNodeWithId): Node | null { } if (n.type === NodeType.Document || n.type === NodeType.Element) { for (const childN of n.childNodes) { - const childNode = rebuild(childN); + const childNode = rebuild(childN, doc); if (!childNode) { console.warn('Failed to rebuild', childN); } else { diff --git a/test/integration.ts b/test/integration.ts index 700469f2..d2a74aca 100644 --- a/test/integration.ts +++ b/test/integration.ts @@ -101,7 +101,7 @@ describe('integration tests', () => { const rebuildHtml = (await page.evaluate(`${this.code} const x = new XMLSerializer(); const [snap] = rrweb.snapshot(document); - x.serializeToString(rrweb.rebuild(snap)); + x.serializeToString(rrweb.rebuild(snap, document)); `)).replace(/\n\n/g, ''); const result = matchSnapshot(rebuildHtml, __filename, title); assert(result.pass, result.pass ? '' : result.report());