OLD | NEW |
| (Empty) |
1 <!DOCTYPE html> | |
2 <html> | |
3 <link rel="import" href="../resources/chai.html" /> | |
4 <link rel="import" href="../resources/mocha.html" /> | |
5 <script> | |
6 describe('MutationObserver.observe on a subtree', function() { | |
7 it('should handle basic aspects of subtree observation', function(done) { | |
8 var observer; | |
9 var subDiv; | |
10 var mutations; | |
11 | |
12 function start() { | |
13 var div = document.createElement('div'); | |
14 subDiv = div.appendChild(document.createElement('div')); | |
15 subDiv.textContent = 'hello, world'; | |
16 observer = new MutationObserver(function(records) { | |
17 mutations = records; | |
18 }); | |
19 | |
20 observer.observe(div, {attributes: true, characterData: true, subtree: tru
e}); | |
21 subDiv.setAttribute('foo', 'bar'); | |
22 subDiv.firstChild.textContent = 'goodbye!'; | |
23 setTimeout(finish, 0); | |
24 } | |
25 | |
26 function finish() { | |
27 // ...attribute and characterData changes in subtree | |
28 assert.equal(mutations.length, 2); | |
29 assert.equal(mutations[0].type, "attributes"); | |
30 assert.equal(mutations[0].target, subDiv); | |
31 assert.equal(mutations[0].attributeName, "foo"); | |
32 assert.equal(mutations[1].type, "characterData"); | |
33 assert.equal(mutations[1].target, subDiv.firstChild); | |
34 observer.disconnect(); | |
35 done(); | |
36 } | |
37 | |
38 start(); | |
39 }); | |
40 | |
41 it('should handle two observers at different depths', function(done) { | |
42 var observer; | |
43 var observer2; | |
44 var mutations; | |
45 var mutations2; | |
46 var subDiv; | |
47 | |
48 function start() { | |
49 var div = document.createElement('div'); | |
50 subDiv = div.appendChild(document.createElement('div')); | |
51 observer = new MutationObserver(function(records) { | |
52 mutations = records; | |
53 }); | |
54 observer2 = new MutationObserver(function(records) { | |
55 mutations2 = records; | |
56 }); | |
57 | |
58 observer.observe(div, {attributes: true, subtree: true}); | |
59 observer2.observe(subDiv, {attributes: true}); | |
60 subDiv.setAttribute('foo', 'bar'); | |
61 setTimeout(finish, 0); | |
62 } | |
63 | |
64 function finish() { | |
65 assert.equal(mutations.length, 1); | |
66 assert.equal(mutations[0].type, "attributes"); | |
67 assert.equal(mutations[0].target, subDiv); | |
68 assert.equal(mutations[0].attributeName, "foo"); | |
69 assert.equal(mutations2.length, 1); | |
70 assert.equal(mutations2[0].type, "attributes"); | |
71 assert.equal(mutations2[0].target, subDiv); | |
72 assert.equal(mutations2[0].attributeName, "foo"); | |
73 observer.disconnect(); | |
74 observer2.disconnect(); | |
75 done(); | |
76 } | |
77 | |
78 start(); | |
79 }); | |
80 | |
81 it('should handle one observer at two different depths', function(done) { | |
82 var observer; | |
83 var mutations; | |
84 var calls = 0; | |
85 var subDiv; | |
86 | |
87 function start() { | |
88 var div = document.createElement('div'); | |
89 subDiv = div.appendChild(document.createElement('div')); | |
90 observer = new MutationObserver(function(records) { | |
91 mutations = records; | |
92 ++calls; | |
93 }); | |
94 | |
95 observer.observe(div, {attributes: true, subtree: true}); | |
96 observer.observe(subDiv, {attributes: true, subtree: true}); | |
97 subDiv.setAttribute('foo', 'bar'); | |
98 setTimeout(finish, 0); | |
99 } | |
100 | |
101 function finish() { | |
102 assert.equal(calls, 1); | |
103 assert.equal(mutations.length, 1); | |
104 assert.equal(mutations[0].type, "attributes"); | |
105 assert.equal(mutations[0].target, subDiv); | |
106 assert.equal(mutations[0].attributeName, "foo"); | |
107 observer.disconnect(); | |
108 done(); | |
109 } | |
110 | |
111 start(); | |
112 }); | |
113 | |
114 // FIXME(sky): This test is huge, it should be broken up. | |
115 it('should handle transiently detached nodes are still observed via subtree',
function(done) { | |
116 var observer; | |
117 var mutations; | |
118 var div; | |
119 var subDiv; | |
120 | |
121 function start() { | |
122 div = document.createElement('div'); | |
123 subDiv = div.appendChild(document.createElement('div')); | |
124 subDiv.textContent = 'hello, world'; | |
125 observer = new MutationObserver(function(records) { | |
126 mutations = records; | |
127 }); | |
128 | |
129 observer.observe(div, {attributes: true, characterData: true, subtree: tru
e}); | |
130 subDiv.setAttribute('foo', 'bar'); | |
131 div.removeChild(subDiv); | |
132 subDiv.setAttribute('test', 'test'); | |
133 setTimeout(checkDeliveredAndChangeAgain, 0); | |
134 } | |
135 | |
136 function checkDeliveredAndChangeAgain() { | |
137 // ...both changes should be received. Change detached subDiv again. | |
138 | |
139 assert.equal(mutations.length, 2); | |
140 assert.equal(mutations[0].type, "attributes"); | |
141 assert.equal(mutations[0].target, subDiv); | |
142 assert.equal(mutations[0].attributeName, "foo"); | |
143 assert.equal(mutations[1].type, "attributes"); | |
144 assert.equal(mutations[1].target, subDiv); | |
145 assert.equal(mutations[1].attributeName, "test"); | |
146 | |
147 mutations = null; | |
148 subDiv.setAttribute('foo', 'baz'); | |
149 | |
150 setTimeout(checkNotDeliveredAndReattach, 0); | |
151 } | |
152 | |
153 function checkNotDeliveredAndReattach() { | |
154 // ...transient subtree observation was stopped after delivery, so subDiv
change should not be received. Reattach and change again. | |
155 | |
156 assert.equal(mutations, null); | |
157 | |
158 mutations = null | |
159 div.appendChild(subDiv); | |
160 subDiv.setAttribute('foo', 'bat'); | |
161 | |
162 setTimeout(checkDeliveredAndReobserve, 0); | |
163 } | |
164 | |
165 function checkDeliveredAndReobserve() { | |
166 //...reattached subtree should now be observable. Try detaching and re-obs
erving. | |
167 | |
168 assert.equal(mutations.length, 1); | |
169 assert.equal(mutations[0].type, "attributes"); | |
170 assert.equal(mutations[0].target, subDiv); | |
171 assert.equal(mutations[0].attributeName, "foo"); | |
172 | |
173 mutations = null; | |
174 div.removeChild(subDiv); | |
175 subDiv.firstChild.textContent = 'badbye'; | |
176 observer.observe(div, {attributes: true, characterData: true, subtree: tru
e}); | |
177 subDiv.setAttribute('foo', 'boo'); | |
178 | |
179 setTimeout(finish, 0); | |
180 } | |
181 | |
182 function finish() { | |
183 // ...The change made before re-observing should be received, but not the
one after. | |
184 | |
185 assert.equal(mutations.length, 1); | |
186 assert.equal(mutations[0].type, "characterData"); | |
187 assert.equal(mutations[0].target, subDiv.firstChild); | |
188 | |
189 observer.disconnect(); | |
190 done(); | |
191 } | |
192 | |
193 start(); | |
194 }); | |
195 | |
196 it('should have correct behavior of transient observation with complex movemen
t', function(done) { | |
197 var observer; | |
198 var subDiv; | |
199 var mutations; | |
200 | |
201 function start() { | |
202 var div = document.createElement('div'); | |
203 subDiv = div.appendChild(document.createElement('div')); | |
204 subDiv2 = subDiv.appendChild(document.createElement('div')); | |
205 subDiv2.textContent = 'hello, world'; | |
206 subDiv3 = document.createElement('div'); | |
207 | |
208 observer = new MutationObserver(function(records) { | |
209 mutations = records; | |
210 }); | |
211 | |
212 observer.observe(div, {attributes: true, characterData: true, subtree: tru
e}); | |
213 div.removeChild(subDiv); | |
214 subDiv.removeChild(subDiv2); | |
215 text = subDiv2.removeChild(subDiv2.firstChild); | |
216 | |
217 subDiv.setAttribute('a', 'a'); | |
218 subDiv2.setAttribute('b', 'b'); | |
219 text.textContent = 'c'; | |
220 subDiv3.appendChild(subDiv2); | |
221 subDiv3.setAttribute('d', 'd'); | |
222 subDiv2.setAttribute('e', 'e'); | |
223 div.appendChild(subDiv3); | |
224 subDiv3.setAttribute('f', 'f'); | |
225 subDiv2.setAttribute('g', 'g'); | |
226 | |
227 setTimeout(finish, 0); | |
228 } | |
229 | |
230 function finish() { | |
231 // ...All changes should be received except for setting the "d" attribute
on subDiv3 before it was reachable from div. | |
232 | |
233 assert.equal(mutations.length, 6); | |
234 assert.equal(mutations[0].type, "attributes"); | |
235 assert.equal(mutations[0].target, subDiv); | |
236 assert.equal(mutations[0].attributeName, "a"); | |
237 | |
238 assert.equal(mutations[1].type, "attributes"); | |
239 assert.equal(mutations[1].target, subDiv2); | |
240 assert.equal(mutations[1].attributeName, "b"); | |
241 | |
242 assert.equal(mutations[2].type, "characterData"); | |
243 assert.equal(mutations[2].target, text); | |
244 | |
245 assert.equal(mutations[3].type, "attributes"); | |
246 assert.equal(mutations[3].target, subDiv2); | |
247 assert.equal(mutations[3].attributeName, "e"); | |
248 | |
249 assert.equal(mutations[4].type, "attributes"); | |
250 assert.equal(mutations[4].target, subDiv3); | |
251 assert.equal(mutations[4].attributeName, "f"); | |
252 | |
253 assert.equal(mutations[5].type, "attributes"); | |
254 assert.equal(mutations[5].target, subDiv2); | |
255 assert.equal(mutations[5].attributeName, "g"); | |
256 | |
257 observer.disconnect(); | |
258 done(); | |
259 } | |
260 start(); | |
261 }); | |
262 }); | |
263 </script> | |
264 </html> | |
OLD | NEW |