From c52368fd915450cbdb8ecf0f060da633342c9c22 Mon Sep 17 00:00:00 2001 From: Justin Halsall Date: Wed, 1 Apr 2026 12:00:00 +0800 Subject: [PATCH] Remove children of Document even if doc not in mirror (#923) * Remove children of Document even if doc not in mirror * fix flaky test * Update packages/rrdom/test/diff.test.ts Co-authored-by: Yun Feng Co-authored-by: Yun Feng --- packages/rrdom/src/diff.ts | 2 +- packages/rrdom/test/diff.test.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/rrdom/src/diff.ts b/packages/rrdom/src/diff.ts index 73850d64..c3c9acd5 100644 --- a/packages/rrdom/src/diff.ts +++ b/packages/rrdom/src/diff.ts @@ -316,7 +316,7 @@ function diffChildren( * We should delete it before insert a serialized one. Otherwise, an error 'Only one element on document allowed' will be thrown. */ if ( - replayer.mirror.getMeta(parentNode)?.type === RRNodeType.Document && + parentNode.nodeName === '#document' && replayer.mirror.getMeta(newNode)?.type === RRNodeType.Element && (parentNode as Document).documentElement ) { diff --git a/packages/rrdom/test/diff.test.ts b/packages/rrdom/test/diff.test.ts index bb4544e8..efb5aaaa 100644 --- a/packages/rrdom/test/diff.test.ts +++ b/packages/rrdom/test/diff.test.ts @@ -1056,6 +1056,24 @@ describe('diff algorithm for rrdom', () => { expect(element.tagName).toBe('DIV'); expect(mirror.getId(element)).toEqual(2); }); + + it('should remove children from document before adding new nodes', () => { + document.write(''); // old document with elements that need removing + + const rrDocument = new RRDocument(); + const docType = rrDocument.createDocumentType('html', '', ''); + rrDocument.mirror.add(docType, getDefaultSN(docType, 1)); + rrDocument.appendChild(docType); + const htmlEl = rrDocument.createElement('html'); + rrDocument.mirror.add(htmlEl, getDefaultSN(htmlEl, 2)); + rrDocument.appendChild(htmlEl); + + diff(document, rrDocument, replayer); + expect(document.childNodes.length).toBe(2); + const element = document.childNodes[0] as HTMLElement; + expect(element.nodeType).toBe(element.DOCUMENT_TYPE_NODE); + expect(mirror.getId(element)).toEqual(1); + }); }); describe('create or get a Node', () => {