From 03d52a065972a063dbec9f9a26d5d576722f157d Mon Sep 17 00:00:00 2001 From: Anthony Gubler Date: Tue, 6 Nov 2018 00:01:35 +0000 Subject: [PATCH] Remove nodes that could not be merged --- src/widget-core/vdom.ts | 16 +++++++++++++--- tests/widget-core/unit/vdom.ts | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/widget-core/vdom.ts b/src/widget-core/vdom.ts index a387de300..3cb27dcb2 100644 --- a/src/widget-core/vdom.ts +++ b/src/widget-core/vdom.ts @@ -379,6 +379,7 @@ export function renderer(renderer: () => WNode | VNode): Renderer { let _afterRenderCallbacks: Function[] = []; let _deferredRenderCallbacks: Function[] = []; let parentInvalidate: () => void; + let _allMergedNodes: Node[] = []; function nodeOperation( propName: string, @@ -724,6 +725,10 @@ export function renderer(renderer: () => WNode | VNode): Renderer { }); _runProcessQueue(); _mountOptions.merge = false; + let mergedNode: Node | undefined; + while ((mergedNode = _allMergedNodes.pop())) { + mergedNode.parentNode && mergedNode.parentNode.removeChild(mergedNode); + } _runDomInstructionQueue(); _runCallbacks(); } @@ -892,6 +897,10 @@ export function renderer(renderer: () => WNode | VNode): Renderer { for (let i = 0; i < mergeNodes.length; i++) { const domElement = mergeNodes[i] as Element; if (tag.toUpperCase() === (domElement.tagName || '')) { + const mergeNodeIndex = _allMergedNodes.indexOf(domElement); + if (mergeNodeIndex !== -1) { + _allMergedNodes.splice(mergeNodeIndex, 1); + } mergeNodes.splice(i, 1); next.domNode = domElement; break; @@ -1099,12 +1108,13 @@ export function renderer(renderer: () => WNode | VNode): Renderer { } } } else { - next.merged = true; - } - if (next.domNode) { if (_mountOptions.merge) { mergeNodes = arrayFrom(next.domNode.childNodes); + _allMergedNodes = [..._allMergedNodes, ...mergeNodes]; } + next.merged = true; + } + if (next.domNode) { if (next.node.children) { next.childrenWrappers = renderedToWrapper(next.node.children, next, null); } diff --git a/tests/widget-core/unit/vdom.ts b/tests/widget-core/unit/vdom.ts index 02dab2be9..374b4faec 100644 --- a/tests/widget-core/unit/vdom.ts +++ b/tests/widget-core/unit/vdom.ts @@ -2415,7 +2415,7 @@ jsdomDescribe('vdom', () => { document.body.removeChild(iframe); }); - it('Skips unknown nodes when merging', () => { + it('Removes unknown nodes when merging', () => { const iframe = document.createElement('iframe'); document.body.appendChild(iframe); iframe.contentDocument.write(` @@ -2497,11 +2497,11 @@ jsdomDescribe('vdom', () => { childElementCount, 'should have the same number of children' ); - assert.strictEqual(label, root.childNodes[1], 'should have been reused'); - assert.strictEqual(select, root.childNodes[3], 'should have been reused'); - assert.strictEqual(button, root.childNodes[5], 'should have been reused'); - assert.strictEqual(span, root.childNodes[7], 'should have been reused'); - assert.strictEqual(div, root.childNodes[9], 'should have been reused'); + assert.strictEqual(label, root.childNodes[0], 'should have been reused'); + assert.strictEqual(select, root.childNodes[1], 'should have been reused'); + assert.strictEqual(button, root.childNodes[2], 'should have been reused'); + assert.strictEqual(span, root.childNodes[3], 'should have been reused'); + assert.strictEqual(div, root.childNodes[4], 'should have been reused'); assert.isFalse(select.disabled, 'select should be enabled'); assert.isFalse(button.disabled, 'button should be enabled'); @@ -4459,7 +4459,7 @@ jsdomDescribe('vdom', () => { assert.isTrue(onclickListener.called, 'onclickListener should have been called'); document.body.removeChild(iframe); }); - it('Skips unknown nodes when merging', () => { + it('Removes unknown nodes when merging', () => { const iframe = document.createElement('iframe'); document.body.appendChild(iframe); iframe.contentDocument.write(` @@ -4531,11 +4531,11 @@ jsdomDescribe('vdom', () => { r.mount({ domNode: iframe.contentDocument.body }); assert.strictEqual(root.className, 'foo bar', 'should have added bar class'); assert.strictEqual(root.childElementCount, childElementCount, 'should have the same number of children'); - assert.strictEqual(label, root.childNodes[1], 'should have been reused'); - assert.strictEqual(select, root.childNodes[3], 'should have been reused'); - assert.strictEqual(button, root.childNodes[5], 'should have been reused'); - assert.strictEqual(span, root.childNodes[7], 'should have been reused'); - assert.strictEqual(div, root.childNodes[9], 'should have been reused'); + assert.strictEqual(label, root.childNodes[0], 'should have been reused'); + assert.strictEqual(select, root.childNodes[1], 'should have been reused'); + assert.strictEqual(button, root.childNodes[2], 'should have been reused'); + assert.strictEqual(span, root.childNodes[3], 'should have been reused'); + assert.strictEqual(div, root.childNodes[4], 'should have been reused'); assert.isFalse(select.disabled, 'select should be enabled'); assert.isFalse(button.disabled, 'button should be enabled'); assert.strictEqual(select.value, 'foo', 'foo should be selected');