From 6ad6dcd11271bbbd355481b2ab058f0d47507efa Mon Sep 17 00:00:00 2001 From: Ori Riner Date: Tue, 10 Oct 2017 13:54:47 +0300 Subject: [PATCH] Clear previous children when SVG node doesn't have innerHTML (#11108) * clear previous children when SVG node doesn't have innerHTML * remove 'get' handler for appendChild in test node proxy --- src/renderers/dom/shared/setInnerHTML.js | 3 ++ .../utils/__tests__/setInnerHTML-test.js | 37 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/renderers/dom/shared/setInnerHTML.js b/src/renderers/dom/shared/setInnerHTML.js index fd320769d2251..4a749ab3be441 100644 --- a/src/renderers/dom/shared/setInnerHTML.js +++ b/src/renderers/dom/shared/setInnerHTML.js @@ -31,6 +31,9 @@ var setInnerHTML = createMicrosoftUnsafeLocalFunction(function(node, html) { reusableSVGContainer || document.createElement('div'); reusableSVGContainer.innerHTML = '' + html + ''; var svgNode = reusableSVGContainer.firstChild; + while (node.firstChild) { + node.removeChild(node.firstChild); + } while (svgNode.firstChild) { node.appendChild(svgNode.firstChild); } diff --git a/src/renderers/dom/shared/utils/__tests__/setInnerHTML-test.js b/src/renderers/dom/shared/utils/__tests__/setInnerHTML-test.js index fe625a6f0b374..6b2cd5b6ac97c 100644 --- a/src/renderers/dom/shared/utils/__tests__/setInnerHTML-test.js +++ b/src/renderers/dom/shared/utils/__tests__/setInnerHTML-test.js @@ -24,17 +24,25 @@ describe('setInnerHTML', () => { }); describe('when the node does not have an innerHTML property', () => { - // Disabled. JSDOM doesn't seem to remove nodes when using appendChild to - // move existing nodes. - xit('sets innerHTML on it', () => { + var node; + var nodeProxy; + beforeEach(() => { // Create a mock node that looks like an SVG in IE (without innerHTML) - var node = { - namespaceURI: Namespaces.svg, - appendChild: jasmine.createSpy(), - }; + node = document.createElementNS(Namespaces.svg, 'svg'); + nodeProxy = new Proxy(node, { + has: (target, prop) => { + return prop === 'innerHTML' ? false : prop in target; + }, + }); + + spyOn(node, 'appendChild').and.callThrough(); + spyOn(node, 'removeChild').and.callThrough(); + }); + + it('sets innerHTML on it', () => { var html = ''; - setInnerHTML(node, html); + setInnerHTML(nodeProxy, html); expect(node.appendChild.calls.argsFor(0)[0].outerHTML).toBe( '', @@ -43,5 +51,18 @@ describe('setInnerHTML', () => { '', ); }); + + it('clears previous children', () => { + var firstHtml = ''; + var secondHtml = ''; + setInnerHTML(nodeProxy, firstHtml); + + setInnerHTML(nodeProxy, secondHtml); + + expect(node.removeChild.calls.argsFor(0)[0].outerHTML).toBe( + '', + ); + expect(node.innerHTML).toBe(''); + }); }); });