|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=650493 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for Bug 650493</title> |
|
8 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
10 </head> |
|
11 <body> |
|
12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650493">Mozilla Bug 650493</a> |
|
13 <p id="display"></p> |
|
14 <div id="content" style="display: none"> |
|
15 |
|
16 </div> |
|
17 <pre id="test"> |
|
18 <script class="testbody" type="text/javascript"> |
|
19 |
|
20 function getNodes() { |
|
21 var walker = document.createTreeWalker($('content'), NodeFilter.SHOW_ALL, null); |
|
22 var nodes = []; |
|
23 do { |
|
24 nodes.push(walker.currentNode); |
|
25 } while(walker.nextNode()); |
|
26 |
|
27 return nodes; |
|
28 } |
|
29 |
|
30 function check() { |
|
31 var current = getNodes(); |
|
32 is(nodes.length, current.length, "length after " + testName); |
|
33 nodes.forEach(function(val, index) { |
|
34 ok(current.indexOf(val) > -1, "nodes[" + index + "] (" + val + ") shouldn't exist after " + testName); |
|
35 }); |
|
36 } |
|
37 |
|
38 var nodes = getNodes(); |
|
39 var testName = "empty"; |
|
40 var mutateCount = 0; |
|
41 |
|
42 check(); |
|
43 |
|
44 // Set up listeners |
|
45 root = $('content'); |
|
46 root.addEventListener("DOMNodeInserted", function(e) { |
|
47 mutateCount++; |
|
48 is(e.isTrusted, true, "untrusted mutation event"); |
|
49 var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null); |
|
50 do { |
|
51 is(nodes.indexOf(w.currentNode), -1, "already have inserted node (" + w.currentNode + ") when " + testName); |
|
52 nodes.push(w.currentNode); |
|
53 } while(w.nextNode()); |
|
54 }, false); |
|
55 root.addEventListener("DOMNodeRemoved", function(e) { |
|
56 mutateCount++; |
|
57 is(e.isTrusted, true, "untrusted mutation event"); |
|
58 var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null); |
|
59 do { |
|
60 var index = nodes.indexOf(w.currentNode); |
|
61 ok(index != -1, "missing removed node (" + w.currentNode + ") when " + testName); |
|
62 nodes.splice(index, 1); |
|
63 } while(w.nextNode()); |
|
64 }, false); |
|
65 |
|
66 testName = "text-only innerHTML"; |
|
67 root.innerHTML = "hello world"; |
|
68 check(); |
|
69 |
|
70 testName = "innerHTML with <b>"; |
|
71 root.innerHTML = "<b>bold</b> world"; |
|
72 check(); |
|
73 |
|
74 testName = "complex innerHTML"; |
|
75 root.innerHTML = "<b>b<span>old</span></b> <strong>world"; |
|
76 check(); |
|
77 |
|
78 testName = "replacing using .textContent"; |
|
79 root.textContent = "i'm just a plain text minding my own business"; |
|
80 check(); |
|
81 |
|
82 testName = "clearing using .textContent"; |
|
83 root.textContent = ""; |
|
84 check(); |
|
85 |
|
86 testName = "inserting using .textContent"; |
|
87 root.textContent = "i'm new text!!"; |
|
88 check(); |
|
89 |
|
90 testName = "inserting using .textContent"; |
|
91 root.textContent = "i'm new text!!"; |
|
92 check(); |
|
93 |
|
94 testName = "preparing to normalize"; |
|
95 root.innerHTML = "<u><b>foo</b></u> "; |
|
96 var u = root.firstChild; |
|
97 is(u.nodeName, "U", "got the right node"); |
|
98 var b = u.firstChild; |
|
99 is(b.nodeName, "B", "got the right node"); |
|
100 b.insertBefore(document.createTextNode(""), b.firstChild); |
|
101 b.insertBefore(document.createTextNode(""), b.firstChild); |
|
102 b.appendChild(document.createTextNode("")); |
|
103 b.appendChild(document.createTextNode("hello")); |
|
104 b.appendChild(document.createTextNode("world")); |
|
105 u.appendChild(document.createTextNode("foo")); |
|
106 u.appendChild(document.createTextNode("")); |
|
107 u.appendChild(document.createTextNode("bar")); |
|
108 check(); |
|
109 |
|
110 testName = "normalizing"; |
|
111 root.normalize(); |
|
112 check(); |
|
113 |
|
114 testName = "self replace firstChild"; |
|
115 mutateCount = 0; |
|
116 root.replaceChild(root.firstChild, root.firstChild); |
|
117 check(); |
|
118 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
119 |
|
120 testName = "self replace second child"; |
|
121 mutateCount = 0; |
|
122 root.replaceChild(root.firstChild.nextSibling, root.firstChild.nextSibling); |
|
123 check(); |
|
124 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
125 |
|
126 testName = "self replace lastChild"; |
|
127 mutateCount = 0; |
|
128 root.replaceChild(root.lastChild, root.lastChild); |
|
129 check(); |
|
130 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
131 |
|
132 testName = "self insertBefore firstChild"; |
|
133 mutateCount = 0; |
|
134 root.insertBefore(root.firstChild, root.firstChild); |
|
135 check(); |
|
136 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
137 |
|
138 testName = "self insertBefore second child"; |
|
139 mutateCount = 0; |
|
140 root.insertBefore(root.firstChild.nextSibling, root.firstChild.nextSibling); |
|
141 check(); |
|
142 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
143 |
|
144 testName = "self insertBefore lastChild"; |
|
145 mutateCount = 0; |
|
146 root.insertBefore(root.lastChild, root.lastChild); |
|
147 check(); |
|
148 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
149 |
|
150 testName = "appendChild last"; |
|
151 mutateCount = 0; |
|
152 root.appendChild(root.lastChild); |
|
153 check(); |
|
154 is(mutateCount, 2, "should remove and reinsert " + testName); |
|
155 |
|
156 testName = "prepare script/style"; |
|
157 script = document.createElement("script"); |
|
158 script.appendChild(document.createTextNode("void(0);")); |
|
159 root.appendChild(script); |
|
160 style = document.createElement("style"); |
|
161 root.appendChild(style); |
|
162 check(); |
|
163 |
|
164 testName = "set something in script"; |
|
165 script.text = "something"; |
|
166 check(); |
|
167 |
|
168 testName = "set something in style"; |
|
169 style.innerHTML = "something { dislay: none; }"; |
|
170 check(); |
|
171 |
|
172 testName = "moving style"; |
|
173 root.insertBefore(style, root.firstChild); |
|
174 check(); |
|
175 |
|
176 testName = "replacing script"; |
|
177 root.replaceChild(b, script); |
|
178 check(); |
|
179 |
|
180 testName = "doc-fragment insert in the middle"; |
|
181 frag = document.createDocumentFragment(); |
|
182 frag.addEventListener("DOMNodeRemoved", function(e) { |
|
183 var index = children.indexOf(e.target); |
|
184 ok(index != -1, "unknown child removed from fragment"); |
|
185 children.splice(index, 1); |
|
186 }, false); |
|
187 var children = []; |
|
188 children.push(document.createTextNode("foo")); |
|
189 children.push(document.createTextNode("bar")); |
|
190 children.push(document.createElement("span")); |
|
191 children.push(document.createElement("b")); |
|
192 children[2].appendChild(document.createElement("i")); |
|
193 children.forEach(function(child) { frag.appendChild(child); }); |
|
194 ok(root.firstChild, "need to have children in order to test inserting before end"); |
|
195 root.replaceChild(frag, root.firstChild); |
|
196 check(); |
|
197 is(children.length, 0, "should have received DOMNodeRemoved for all frag children when inserting"); |
|
198 is(frag.childNodes.length, 0, "fragment should be empty when inserting"); |
|
199 |
|
200 testName = "doc-fragment append at the end"; |
|
201 children.push(document.createTextNode("foo")); |
|
202 children.push(document.createTextNode("bar")); |
|
203 children.push(document.createElement("span")); |
|
204 children.push(document.createElement("b")); |
|
205 children[2].appendChild(document.createElement("i")); |
|
206 children.forEach(function(child) { frag.appendChild(child); }); |
|
207 root.appendChild(frag); |
|
208 check(); |
|
209 is(children.length, 0, "should have received DOMNodeRemoved for all frag children when appending"); |
|
210 is(frag.childNodes.length, 0, "fragment should be empty when appending"); |
|
211 |
|
212 </script> |
|
213 </body> |
|
214 </html> |
|
215 |