15
var ReactDOM;
16
var ReactDOMServer;
17
18
+// In standard React, TextComponent keeps track of different Text templates
19
+// using comments. However, in React Fiber, those comments are not outputted due
20
+// to the way Fiber keeps track of the templates.
21
+// This function "Normalizes" childNodes lists to avoid the presence of comments
22
+// and make the child list identical in standard React and Fiber
23
+function filterOutComments(nodeList) {
24
+ return [].slice.call(nodeList).filter(node => !(node instanceof Comment));
25
+}
26
+
27
describe('ReactDOMTextComponent', () => {
28
beforeEach(() => {
29
React = require('React');
34
it('updates a mounted text component in place', () => {
35
var el = document.createElement('div');
36
var inst = ReactDOM.render(<div><span />{'foo'}{'bar'}</div>, el);
37
+ let nodes = filterOutComments(ReactDOM.findDOMNode(inst).childNodes);
38
29
- var foo = ReactDOM.findDOMNode(inst).childNodes[2];
30
- var bar = ReactDOM.findDOMNode(inst).childNodes[5];
39
+ let foo = nodes[1];
40
+ let bar = nodes[2];
41
expect(foo.data).toBe('foo');
42
expect(bar.data).toBe('bar');
43
44
inst = ReactDOM.render(<div><span />{'baz'}{'qux'}</div>, el);
45
// After the update, the text nodes should have stayed in place (as opposed
46
// to getting unmounted and remounted)
37
- expect(ReactDOM.findDOMNode(inst).childNodes[2]).toBe(foo);
38
- expect(ReactDOM.findDOMNode(inst).childNodes[5]).toBe(bar);
47
+ nodes = filterOutComments(ReactDOM.findDOMNode(inst).childNodes);
48
+ expect(nodes[1]).toBe(foo);
49
+ expect(nodes[2]).toBe(bar);
50
expect(foo.data).toBe('baz');
51
expect(bar.data).toBe('qux');
52
});
56
var inst = ReactDOM.render(<div>{'foo'}<div />{'bar'}</div>, el);
57
58
var container = ReactDOM.findDOMNode(inst);
48
- var childDiv = container.childNodes[3];
49
- var childNodes;
59
+ let childNodes = filterOutComments(container.childNodes);
60
+ let childDiv = childNodes[1];
61
62
inst = ReactDOM.render(<div>{null}<div />{null}</div>, el);
63
container = ReactDOM.findDOMNode(inst);
53
- childNodes = container.childNodes;
64
+ childNodes = filterOutComments(container.childNodes);
65
expect(childNodes.length).toBe(1);
66
expect(childNodes[0]).toBe(childDiv);
67
68
inst = ReactDOM.render(<div>{'foo'}<div />{'bar'}</div>, el);
69
container = ReactDOM.findDOMNode(inst);
59
- childNodes = container.childNodes;
60
- expect(childNodes.length).toBe(7);
61
- expect(childNodes[1].data).toBe('foo');
62
- expect(childNodes[3]).toBe(childDiv);
63
- expect(childNodes[5].data).toBe('bar');
70
+ childNodes = filterOutComments(container.childNodes);
71
+ expect(childNodes.length).toBe(3);
72
+ expect(childNodes[0].data).toBe('foo');
73
+ expect(childNodes[1]).toBe(childDiv);
74
+ expect(childNodes[2].data).toBe('bar');
75
+ });
76
+
77
+ it('can reconcile text merged by Node.normalize() alongside other elements', () => {
78
+ var el = document.createElement('div');
79
+ var inst = ReactDOM.render(<div>{'foo'}{'bar'}{'baz'}<span />{'qux'}</div>, el);
80
+
81
+ var container = ReactDOM.findDOMNode(inst);
82
+ container.normalize();
83
+
84
+ inst = ReactDOM.render(<div>{'bar'}{'baz'}{'qux'}<span />{'foo'}</div>, el);
85
+ container = ReactDOM.findDOMNode(inst);
86
+ expect(container.textContent).toBe('barbazquxfoo');
87
});
88
89
it('can reconcile text merged by Node.normalize()', () => {
118
var inst = ReactDOM.render(<div><span />{'foobarbaz'}</div>, el);
119
120
var container = ReactDOM.findDOMNode(inst);
98
- var childNodes = container.childNodes;
99
- var textNode = childNodes[2];
121
+ let childNodes = filterOutComments(ReactDOM.findDOMNode(inst).childNodes);
122
+ let textNode = childNodes[1];
123
textNode.textContent = 'foo';
101
- container.insertBefore(document.createTextNode('bar'), childNodes[3]);
102
- container.insertBefore(document.createTextNode('baz'), childNodes[3]);
124
+ container.insertBefore(document.createTextNode('bar'), childNodes[1].nextSibling);
125
+ container.insertBefore(document.createTextNode('baz'), childNodes[1].nextSibling);
126
127
inst = ReactDOM.render(<div><span />{'barbazqux'}</div>, el);
128
container = ReactDOM.findDOMNode(inst);
129
expect(container.textContent).toBe('barbazqux');
130
});
131
+
132
+ it('can reconcile text arbitrarily split into multiple nodes on some substitutions only', () => {
133
+ var el = document.createElement('div');
134
+ var inst = ReactDOM.render(<div><span />{'bar'}<span />{'foobarbaz'}{'foo'}{'barfoo'}<span/></div>, el);
135
+
136
+ var container = ReactDOM.findDOMNode(inst);
137
+ let childNodes = filterOutComments(ReactDOM.findDOMNode(inst).childNodes);
138
+ let textNode = childNodes[3];
139
+ textNode.textContent = 'foo';
140
+ container.insertBefore(document.createTextNode('bar'), childNodes[3].nextSibling);
141
+ container.insertBefore(document.createTextNode('baz'), childNodes[3].nextSibling);
142
+ let secondTextNode = childNodes[5];
143
+ secondTextNode.textContent = 'bar';
144
+ container.insertBefore(document.createTextNode('foo'), childNodes[5].nextSibling);
145
+
146
+ inst = ReactDOM.render(<div><span />{'baz'}<span />{'barbazqux'}{'bar'}{'bazbar'}<span/></div>, el);
147
+ container = ReactDOM.findDOMNode(inst);
148
+ expect(container.textContent).toBe('bazbarbazquxbarbazbar');
149
+ });
150
});