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
});