|
1 <html> |
|
2 <!-- |
|
3 https://bugzilla.mozilla.org/show_bug.cgi?id=588990 |
|
4 --> |
|
5 <head> |
|
6 <title>Test for Bug 588990</title> |
|
7 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body> |
|
11 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=588990">Mozilla Bug 588990</a> |
|
12 <!-- DOM to muck around with for tests --> |
|
13 <p id="root"> |
|
14 <img name="n1"> |
|
15 <img name="n2"> |
|
16 <img name="n2"> |
|
17 <img name="n3"> |
|
18 <img name="n3"> |
|
19 <img name="n3"> |
|
20 </p> |
|
21 |
|
22 <pre id="test"> |
|
23 <script class="testbody" type="text/javascript"> |
|
24 |
|
25 root = $('root'); |
|
26 i1_1 = root.children[0]; |
|
27 i2_1 = root.children[1]; |
|
28 i2_2 = root.children[2]; |
|
29 i3_1 = root.children[3]; |
|
30 i3_2 = root.children[4]; |
|
31 i3_3 = root.children[5]; |
|
32 |
|
33 function checkHasName(test) { |
|
34 // Check name first to avoid flushes from hiding problems |
|
35 checkHasNameNoDocProp(test); |
|
36 |
|
37 is(document.n1, i1_1, "i1_1 doc.name " + test); |
|
38 is(document.n2[0], i2_1, "i2_1 doc.name " + test); |
|
39 is(document.n2[1], i2_2, "i2_2 doc.name " + test); |
|
40 is(document.n2.length, 2, "doc.name.length " + test); |
|
41 is(document.n3[0], i3_1, "i3_1 doc.name " + test); |
|
42 is(document.n3[1], i3_2, "i3_2 doc.name " + test); |
|
43 is(document.n3[2], i3_3, "i3_3 doc.name " + test); |
|
44 is(document.n3.length, 3, "doc.name.length " + test); |
|
45 } |
|
46 |
|
47 function checkHasNameNoDocProp(test) { |
|
48 is(i1_1.name, "n1", "i1_1 name " + test); |
|
49 is(i2_1.name, "n2", "i2_1 name " + test); |
|
50 is(i2_2.name, "n2", "i2_2 name " + test); |
|
51 is(i3_1.name, "n3", "i3_1 name " + test); |
|
52 is(i3_2.name, "n3", "i3_2 name " + test); |
|
53 is(i3_3.name, "n3", "i3_3 name " + test); |
|
54 } |
|
55 |
|
56 function checkHasNoName(removed, test) { |
|
57 is(i1_1.name, "", "i1_1 name " + test); |
|
58 is(i2_1.name, "", "i2_1 name " + test); |
|
59 is(i2_2.name, "", "i2_2 name " + test); |
|
60 is(i3_1.name, "", "i3_1 name " + test); |
|
61 is(i3_2.name, "", "i3_2 name " + test); |
|
62 is(i3_3.name, "", "i3_3 name " + test); |
|
63 |
|
64 var attrValue = removed ? null : ""; |
|
65 is(i1_1.getAttribute("name"), attrValue, "i1_1 getAttribute " + test); |
|
66 is(i2_1.getAttribute("name"), attrValue, "i2_1 getAttribute " + test); |
|
67 is(i2_2.getAttribute("name"), attrValue, "i2_2 getAttribute " + test); |
|
68 is(i3_1.getAttribute("name"), attrValue, "i3_1 getAttribute " + test); |
|
69 is(i3_2.getAttribute("name"), attrValue, "i3_2 getAttribute " + test); |
|
70 is(i3_3.getAttribute("name"), attrValue, "i3_3 getAttribute " + test); |
|
71 |
|
72 is(document.n1, undefined, "doc.n1 " + test); |
|
73 is(document.n2, undefined, "doc.n2 " + test); |
|
74 is(document.n3, undefined, "doc.n3 " + test); |
|
75 } |
|
76 |
|
77 // Check that dynamic modifications of attribute work |
|
78 |
|
79 checkHasName("in markup"); |
|
80 |
|
81 i1_1.name = ""; |
|
82 i2_1.name = ""; |
|
83 i2_2.name = ""; |
|
84 i3_1.name = ""; |
|
85 i3_2.name = ""; |
|
86 i3_3.name = ""; |
|
87 |
|
88 checkHasNoName(false, "set to empty"); |
|
89 |
|
90 i1_1.name = "n1"; |
|
91 i2_1.name = "n2"; |
|
92 i2_2.name = "n2"; |
|
93 i3_1.name = "n3"; |
|
94 i3_2.name = "n3"; |
|
95 i3_3.name = "n3"; |
|
96 |
|
97 checkHasName("set using .name"); |
|
98 |
|
99 i1_1.setAttribute("name", ""); |
|
100 i2_1.setAttribute("name", ""); |
|
101 i2_2.setAttribute("name", ""); |
|
102 i3_1.setAttribute("name", ""); |
|
103 i3_2.setAttribute("name", ""); |
|
104 i3_3.setAttribute("name", ""); |
|
105 |
|
106 checkHasNoName(false, "setAttribute to empty"); |
|
107 |
|
108 i1_1.name = "n1"; |
|
109 i2_1.name = "n2"; |
|
110 i2_2.name = "n2"; |
|
111 i3_1.name = "n3"; |
|
112 i3_2.name = "n3"; |
|
113 i3_3.name = "n3"; |
|
114 |
|
115 checkHasName("set again using .name"); |
|
116 |
|
117 i1_1.removeAttribute("name"); |
|
118 i2_1.removeAttribute("name"); |
|
119 i2_2.removeAttribute("name"); |
|
120 i3_1.removeAttribute("name"); |
|
121 i3_2.removeAttribute("name"); |
|
122 i3_3.removeAttribute("name"); |
|
123 |
|
124 checkHasNoName(true, "removed attribute"); |
|
125 |
|
126 i1_1.setAttribute("name", "n1"); |
|
127 i2_1.setAttribute("name", "n2"); |
|
128 i2_2.setAttribute("name", "n2"); |
|
129 i3_1.setAttribute("name", "n3"); |
|
130 i3_2.setAttribute("name", "n3"); |
|
131 i3_3.setAttribute("name", "n3"); |
|
132 |
|
133 checkHasName("set using setAttribute"); |
|
134 |
|
135 t1 = document.createElement("img"); |
|
136 t1.name = "n1"; |
|
137 t2 = document.createElement("img"); |
|
138 t2.name = "n2"; |
|
139 t3 = document.createElement("img"); |
|
140 t3.name = "n2"; |
|
141 t4 = document.createElement("img"); |
|
142 t4.name = "n3"; |
|
143 t5 = document.createElement("img"); |
|
144 t5.name = "n3"; |
|
145 t6 = document.createElement("img"); |
|
146 t6.name = "n3"; |
|
147 |
|
148 // Check that inserting elements before/after existing work |
|
149 |
|
150 function insertAfter(newChild, existing) { |
|
151 existing.parentNode.insertBefore(newChild, existing.nextSibling); |
|
152 } |
|
153 function insertBefore(newChild, existing) { |
|
154 existing.parentNode.insertBefore(newChild, existing); |
|
155 } |
|
156 function removeNode(child) { |
|
157 child.parentNode.removeChild(child); |
|
158 } |
|
159 |
|
160 insertAfter(t1, i1_1); |
|
161 insertAfter(t2, i2_1); |
|
162 insertAfter(t3, i2_2); |
|
163 insertAfter(t4, i3_1); |
|
164 insertAfter(t5, i3_2); |
|
165 insertAfter(t6, i3_3); |
|
166 |
|
167 checkHasNameNoDocProp("inserted after"); |
|
168 is(document.n1[0], i1_1, "i1_1 doc.name inserted after"); |
|
169 is(document.n1[1], t1, "t1 doc.name inserted after"); |
|
170 is(document.n1.length, 2, "doc.name1.length inserted after"); |
|
171 is(document.n2[0], i2_1, "i2_1 doc.name inserted after"); |
|
172 todo_is(document.n2[1], t2, "This is where t2 should show up. The elements in here should be in order-in-document rather than order-of-insertion"); |
|
173 is(document.n2[1], i2_2, "i2_2 doc.name inserted after"); |
|
174 is(document.n2[2], t2, "t2 doc.name inserted after"); |
|
175 is(document.n2[3], t3, "t3 doc.name inserted after"); |
|
176 is(document.n2.length, 4, "doc.name2.length inserted after"); |
|
177 is(document.n3[0], i3_1, "i3_1 doc.name inserted after"); |
|
178 is(document.n3[1], i3_2, "i3_3 doc.name inserted after"); |
|
179 is(document.n3[2], i3_3, "i3_2 doc.name inserted after"); |
|
180 is(document.n3[3], t4, "t4 doc.name inserted after"); |
|
181 is(document.n3[4], t5, "t5 doc.name inserted after"); |
|
182 is(document.n3[5], t6, "t6 doc.name inserted after"); |
|
183 is(document.n3.length, 6, "doc.name3.length inserted after"); |
|
184 |
|
185 |
|
186 insertBefore(t1, i1_1); |
|
187 insertBefore(t2, i2_1); |
|
188 insertBefore(t3, i2_2); |
|
189 insertBefore(t4, i3_1); |
|
190 insertBefore(t5, i3_2); |
|
191 insertBefore(t6, i3_3); |
|
192 |
|
193 checkHasNameNoDocProp("inserted before"); |
|
194 is(document.n1[0], i1_1, "i1_1 doc.name inserted before"); |
|
195 is(document.n1[1], t1, "t1 doc.name inserted before"); |
|
196 is(document.n1.length, 2, "doc.name1.length inserted before"); |
|
197 is(document.n2[0], i2_1, "i2_1 doc.name inserted before"); |
|
198 is(document.n2[1], i2_2, "i2_2 doc.name inserted before"); |
|
199 is(document.n2[2], t2, "t2 doc.name inserted before"); |
|
200 is(document.n2[3], t3, "t3 doc.name inserted before"); |
|
201 is(document.n2.length, 4, "doc.name2.length inserted before"); |
|
202 is(document.n3[0], i3_1, "i3_1 doc.name inserted before"); |
|
203 is(document.n3[1], i3_2, "i3_3 doc.name inserted before"); |
|
204 is(document.n3[2], i3_3, "i3_2 doc.name inserted before"); |
|
205 is(document.n3[3], t4, "t4 doc.name inserted before"); |
|
206 is(document.n3[4], t5, "t5 doc.name inserted before"); |
|
207 is(document.n3[5], t6, "t6 doc.name inserted before"); |
|
208 is(document.n3.length, 6, "doc.name3.length inserted before"); |
|
209 |
|
210 t1.removeAttribute("name"); |
|
211 t2.removeAttribute("name"); |
|
212 t3.removeAttribute("name"); |
|
213 t4.removeAttribute("name"); |
|
214 t5.removeAttribute("name"); |
|
215 t6.removeAttribute("name"); |
|
216 |
|
217 checkHasName("removed tx attribute"); |
|
218 |
|
219 t1.setAttribute("name", "n1"); |
|
220 t2.setAttribute("name", "n2"); |
|
221 t3.setAttribute("name", "n2"); |
|
222 t4.setAttribute("name", "n3"); |
|
223 t5.setAttribute("name", "n3"); |
|
224 t6.setAttribute("name", "n3"); |
|
225 |
|
226 checkHasNameNoDocProp("inserted before"); |
|
227 is(document.n1[0], i1_1, "i1_1 doc.name inserted before"); |
|
228 is(document.n1[1], t1, "t1 doc.name inserted before"); |
|
229 is(document.n1.length, 2, "doc.name1.length inserted before"); |
|
230 is(document.n2[0], i2_1, "i2_1 doc.name inserted before"); |
|
231 is(document.n2[1], i2_2, "i2_2 doc.name inserted before"); |
|
232 is(document.n2[2], t2, "t2 doc.name inserted before"); |
|
233 is(document.n2[3], t3, "t3 doc.name inserted before"); |
|
234 is(document.n2.length, 4, "doc.name2.length inserted before"); |
|
235 is(document.n3[0], i3_1, "i3_1 doc.name inserted before"); |
|
236 is(document.n3[1], i3_2, "i3_3 doc.name inserted before"); |
|
237 is(document.n3[2], i3_3, "i3_2 doc.name inserted before"); |
|
238 is(document.n3[3], t4, "t4 doc.name inserted before"); |
|
239 is(document.n3[4], t5, "t5 doc.name inserted before"); |
|
240 is(document.n3[5], t6, "t6 doc.name inserted before"); |
|
241 is(document.n3.length, 6, "doc.name3.length inserted before"); |
|
242 |
|
243 removeNode(t1); |
|
244 removeNode(t2); |
|
245 removeNode(t3); |
|
246 removeNode(t4); |
|
247 removeNode(t5); |
|
248 removeNode(t6); |
|
249 |
|
250 checkHasName("removed temporaries"); |
|
251 |
|
252 removeNode(i1_1); |
|
253 removeNode(i2_1); |
|
254 removeNode(i2_2); |
|
255 removeNode(i3_1); |
|
256 removeNode(i3_2); |
|
257 removeNode(i3_3); |
|
258 |
|
259 checkHasNameNoDocProp("removed node"); |
|
260 |
|
261 // Check that removing an element during UnsetAttr works |
|
262 is(i1_1.name, "n1", "i1_1 has name set"); |
|
263 var mutateFired = false; |
|
264 root.appendChild(i1_1); |
|
265 i1_1.addEventListener("DOMAttrModified", function(e) { |
|
266 i1_1.removeEventListener("DOMAttrModified", arguments.callee, false); |
|
267 is(e.target, i1_1, "target is i1_1"); |
|
268 is(i1_1.name, "", "i1_1 no longer has name"); |
|
269 is(i1_1.getAttribute("name"), null, "i1_1 no longer has name attr"); |
|
270 removeNode(i1_1); |
|
271 is(i1_1.parentNode, null, "i1_1 was removed"); |
|
272 mutateFired = true; |
|
273 }, false); |
|
274 i1_1.removeAttribute("name"); |
|
275 ok(mutateFired, "mutation event fired"); |
|
276 SpecialPowers.gc(); |
|
277 |
|
278 // Check that removing an element during SetAttr works |
|
279 i2_1.name = ""; |
|
280 mutateFired = false; |
|
281 root.appendChild(i2_1); |
|
282 i2_1.addEventListener("DOMAttrModified", function(e) { |
|
283 i2_1.removeEventListener("DOMAttrModified", arguments.callee, false); |
|
284 is(e.target, i2_1, "target is i2_1"); |
|
285 is(i2_1.name, "n2", "i2_1 no longer has name"); |
|
286 is(i2_1.getAttribute("name"), "n2", "i2_1 no longer has name attr"); |
|
287 removeNode(i2_1); |
|
288 is(i2_1.parentNode, null, "i2_1 was removed"); |
|
289 mutateFired = true; |
|
290 }, false); |
|
291 i2_1.name = "n2"; |
|
292 ok(mutateFired, "mutation event fired"); |
|
293 SpecialPowers.gc(); |
|
294 |
|
295 // Re-add the name inside a mutation event on a HTML element |
|
296 is(i2_2.name, "n2", "i2_2 has name set"); |
|
297 root.appendChild(i2_2); |
|
298 mutateFired = false; |
|
299 root.appendChild(i2_2); |
|
300 i2_2.addEventListener("DOMAttrModified", function(e) { |
|
301 i2_2.removeEventListener("DOMAttrModified", arguments.callee, false); |
|
302 is(e.target, i2_2, "target is i2_2"); |
|
303 is(i2_2.name, "", "i2_2 no longer has name"); |
|
304 is(i2_2.getAttribute("name"), "", "i2_2 has empty name attr"); |
|
305 i2_2.name = "n2"; |
|
306 mutateFired = true; |
|
307 }, false); |
|
308 i2_2.name = ""; |
|
309 ok(mutateFired, "mutation event fired"); |
|
310 is(document.n2, i2_2, "named was readded during mutation"); |
|
311 removeNode(i2_2); |
|
312 SpecialPowers.gc(); |
|
313 |
|
314 // Re-remove the name inside a mutation event on a HTML element |
|
315 i3_1.name = ""; |
|
316 root.appendChild(i3_1); |
|
317 mutateFired = false; |
|
318 root.appendChild(i3_1); |
|
319 i3_1.addEventListener("DOMAttrModified", function(e) { |
|
320 i3_1.removeEventListener("DOMAttrModified", arguments.callee, false); |
|
321 is(e.target, i3_1, "target is i3_1"); |
|
322 is(i3_1.name, "n3", "i3_1 no longer has name"); |
|
323 is(i3_1.getAttribute("name"), "n3", "i3_1 has empty name attr"); |
|
324 i3_1.removeAttribute("name"); |
|
325 mutateFired = true; |
|
326 }, false); |
|
327 i3_1.name = "n3"; |
|
328 ok(mutateFired, "mutation event fired"); |
|
329 is(document.n3, undefined, "named was readded during mutation"); |
|
330 removeNode(i3_1); |
|
331 SpecialPowers.gc(); |
|
332 |
|
333 </script> |
|
334 </pre> |
|
335 </body> |
|
336 </html> |