@samitouri / QOS-React / commits / 6ad6dcd112

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

Ori Riner committed Oct 10, 2017 at 13:54 UTC 6ad6dcd11271bbbd355481b2ab058f0d47507efa
2 files changed +32 -8
src/renderers/dom/shared/setInnerHTML.js
+3
@@ -31,6 +31,9 @@ var setInnerHTML = createMicrosoftUnsafeLocalFunction(function(node, html) {
31 reusableSVGContainer || document.createElement('div');
32 reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
33 var svgNode = reusableSVGContainer.firstChild;
34 + while (node.firstChild) {
35 + node.removeChild(node.firstChild);
36 + }
37 while (svgNode.firstChild) {
38 node.appendChild(svgNode.firstChild);
39 }
src/renderers/dom/shared/utils/__tests__/setInnerHTML-test.js
+29 -8
@@ -24,17 +24,25 @@ describe('setInnerHTML', () => {
24 });
25
26 describe('when the node does not have an innerHTML property', () => {
27 - // Disabled. JSDOM doesn't seem to remove nodes when using appendChild to
28 - // move existing nodes.
29 - xit('sets innerHTML on it', () => {
27 + var node;
28 + var nodeProxy;
29 + beforeEach(() => {
30 // Create a mock node that looks like an SVG in IE (without innerHTML)
31 - var node = {
32 - namespaceURI: Namespaces.svg,
33 - appendChild: jasmine.createSpy(),
34 - };
31 + node = document.createElementNS(Namespaces.svg, 'svg');
32
33 + nodeProxy = new Proxy(node, {
34 + has: (target, prop) => {
35 + return prop === 'innerHTML' ? false : prop in target;
36 + },
37 + });
38 +
39 + spyOn(node, 'appendChild').and.callThrough();
40 + spyOn(node, 'removeChild').and.callThrough();
41 + });
42 +
43 + it('sets innerHTML on it', () => {
44 var html = '<circle></circle><rect></rect>';
37 - setInnerHTML(node, html);
45 + setInnerHTML(nodeProxy, html);
46
47 expect(node.appendChild.calls.argsFor(0)[0].outerHTML).toBe(
48 '<circle></circle>',
@@ -43,5 +51,18 @@ describe('setInnerHTML', () => {
51 '<rect></rect>',
52 );
53 });
54 +
55 + it('clears previous children', () => {
56 + var firstHtml = '<rect></rect>';
57 + var secondHtml = '<circle></circle>';
58 + setInnerHTML(nodeProxy, firstHtml);
59 +
60 + setInnerHTML(nodeProxy, secondHtml);
61 +
62 + expect(node.removeChild.calls.argsFor(0)[0].outerHTML).toBe(
63 + '<rect></rect>',
64 + );
65 + expect(node.innerHTML).toBe('<circle></circle>');
66 + });
67 });
68 });