e8ba496cd01121db2ad1a251f7f3d132e5e98fb7
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / dom / nodes / Node-replaceChild.html
1 <!DOCTYPE html>
2 <meta charset=utf-8>
3 <title>Node.replaceChild</title>
4 <script src="/resources/testharness.js"></script>
5 <script src="/resources/testharnessreport.js"></script>
6 <body><a><b></b><c></c></a>
7 <div id="log"></div>
8 <script>
9 // IDL.
10 test(function() {
11   var a = document.createElement("div");
12   assert_throws(new TypeError(), function() {
13     a.replaceChild(null, null);
14   });
15
16   var b = document.createElement("div");
17   assert_throws(new TypeError(), function() {
18     a.replaceChild(b, null);
19   });
20   assert_throws(new TypeError(), function() {
21     a.replaceChild(null, b);
22   });
23 }, "Passing null to replaceChild should throw a TypeError.")
24
25 // Step 1.
26 test(function() {
27   var a = document.createElement("div");
28   var b = document.createElement("div");
29   var c = document.createElement("div");
30   assert_throws("NotFoundError", function() {
31     a.replaceChild(b, c);
32   });
33
34   var d = document.createElement("div");
35   d.appendChild(b);
36   assert_throws("NotFoundError", function() {
37     a.replaceChild(b, c);
38   });
39   assert_throws("NotFoundError", function() {
40     a.replaceChild(b, a);
41   });
42 }, "If child's parent is not the context node, a NotFoundError exception should be thrown")
43 test(function() {
44   var nodes = [
45     document.implementation.createDocumentType("html", "", ""),
46     document.createTextNode("text"),
47     document.implementation.createDocument(null, "foo", null).createProcessingInstruction("foo", "bar"),
48     document.createComment("comment")
49   ];
50
51   var a = document.createElement("div");
52   var b = document.createElement("div");
53   nodes.forEach(function(node) {
54     assert_throws("HierarchyRequestError", function() {
55       node.replaceChild(a, b);
56     });
57   });
58 }, "If the context node is not a node that can contain children, a NotFoundError exception should be thrown")
59
60 // Step 2.
61 test(function() {
62   var a = document.createElement("div");
63   var b = document.createElement("div");
64
65   assert_throws("HierarchyRequestError", function() {
66     a.replaceChild(a, a);
67   });
68
69   a.appendChild(b);
70   assert_throws("HierarchyRequestError", function() {
71     a.replaceChild(a, b);
72   });
73
74   var c = document.createElement("div");
75   c.appendChild(a);
76   assert_throws("HierarchyRequestError", function() {
77     a.replaceChild(c, b);
78   });
79 }, "If node is an inclusive ancestor of the context node, a HierarchyRequestError should be thrown.")
80
81 // Step 3.1.
82 test(function() {
83   var doc = document.implementation.createHTMLDocument("title");
84   var doc2 = document.implementation.createHTMLDocument("title2");
85   assert_throws("HierarchyRequestError", function() {
86     doc.replaceChild(doc2, doc.documentElement);
87   });
88
89   assert_throws("HierarchyRequestError", function() {
90     doc.replaceChild(doc.createTextNode("text"), doc.documentElement);
91   });
92 }, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
93
94 // Step 3.2.1.
95 test(function() {
96   var doc = document.implementation.createHTMLDocument("title");
97
98   var df = doc.createDocumentFragment();
99   df.appendChild(doc.createElement("a"));
100   df.appendChild(doc.createElement("b"));
101   assert_throws("HierarchyRequestError", function() {
102     doc.replaceChild(df, doc.documentElement);
103   });
104
105   df = doc.createDocumentFragment();
106   df.appendChild(doc.createTextNode("text"));
107   assert_throws("HierarchyRequestError", function() {
108     doc.replaceChild(df, doc.documentElement);
109   });
110
111   df = doc.createDocumentFragment();
112   df.appendChild(doc.createComment("comment"));
113   df.appendChild(doc.createTextNode("text"));
114   assert_throws("HierarchyRequestError", function() {
115     doc.replaceChild(df, doc.documentElement);
116   });
117 }, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
118 test(function() {
119   var doc = document.implementation.createHTMLDocument("title");
120   doc.removeChild(doc.documentElement);
121
122   var df = doc.createDocumentFragment();
123   df.appendChild(doc.createElement("a"));
124   df.appendChild(doc.createElement("b"));
125   assert_throws("HierarchyRequestError", function() {
126     doc.replaceChild(df, doc.doctype);
127   });
128 }, "If the context node is a document (without element children), inserting a DocumentFragment that contains multiple elements should throw a HierarchyRequestError.")
129
130 // Step 3.2.2.
131 test(function() {
132   // The context node has an element child that is not /child/.
133   var doc = document.implementation.createHTMLDocument("title");
134   var comment = doc.appendChild(doc.createComment("foo"));
135   assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
136
137   var df = doc.createDocumentFragment();
138   df.appendChild(doc.createElement("a"));
139   assert_throws("HierarchyRequestError", function() {
140     doc.replaceChild(df, comment);
141   });
142   assert_throws("HierarchyRequestError", function() {
143     doc.replaceChild(df, doc.doctype);
144   });
145 }, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
146 test(function() {
147   // A doctype is following /child/.
148   var doc = document.implementation.createHTMLDocument("title");
149   var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
150   doc.removeChild(doc.documentElement);
151   assert_array_equals(doc.childNodes, [comment, doc.doctype]);
152
153   var df = doc.createDocumentFragment();
154   df.appendChild(doc.createElement("a"));
155   assert_throws("HierarchyRequestError", function() {
156     doc.replaceChild(df, comment);
157   });
158 }, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
159
160 // Step 3.3.
161 test(function() {
162   var doc = document.implementation.createHTMLDocument("title");
163   var comment = doc.appendChild(doc.createComment("foo"));
164   assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
165
166   var a = doc.createElement("a");
167   assert_throws("HierarchyRequestError", function() {
168     doc.replaceChild(a, comment);
169   });
170   assert_throws("HierarchyRequestError", function() {
171     doc.replaceChild(a, doc.doctype);
172   });
173 }, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
174 test(function() {
175   var doc = document.implementation.createHTMLDocument("title");
176   var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
177   doc.removeChild(doc.documentElement);
178   assert_array_equals(doc.childNodes, [comment, doc.doctype]);
179
180   var a = doc.createElement("a");
181   assert_throws("HierarchyRequestError", function() {
182     doc.replaceChild(a, comment);
183   });
184 }, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
185
186 // Step 3.4.
187 test(function() {
188   var doc = document.implementation.createHTMLDocument("title");
189   var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
190   assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
191
192   var doctype = document.implementation.createDocumentType("html", "", "");
193   assert_throws("HierarchyRequestError", function() {
194     doc.replaceChild(doctype, comment);
195   });
196   assert_throws("HierarchyRequestError", function() {
197     doc.replaceChild(doctype, doc.documentElement);
198   });
199 }, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
200 test(function() {
201   var doc = document.implementation.createHTMLDocument("title");
202   var comment = doc.appendChild(doc.createComment("foo"));
203   doc.removeChild(doc.doctype);
204   assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
205
206   var doctype = document.implementation.createDocumentType("html", "", "");
207   assert_throws("HierarchyRequestError", function() {
208     doc.replaceChild(doctype, comment);
209   });
210 }, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
211
212 // Step 4.
213 test(function() {
214   var df = document.createDocumentFragment();
215   var a = df.appendChild(document.createElement("a"));
216
217   var doc = document.implementation.createHTMLDocument("title");
218   assert_throws("HierarchyRequestError", function() {
219     df.replaceChild(doc, a);
220   });
221
222   var doctype = document.implementation.createDocumentType("html", "", "");
223   assert_throws("HierarchyRequestError", function() {
224     df.replaceChild(doctype, a);
225   });
226 }, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
227 test(function() {
228   var el = document.createElement("div");
229   var a = el.appendChild(document.createElement("a"));
230
231   var doc = document.implementation.createHTMLDocument("title");
232   assert_throws("HierarchyRequestError", function() {
233     el.replaceChild(doc, a);
234   });
235
236   var doctype = document.implementation.createDocumentType("html", "", "");
237   assert_throws("HierarchyRequestError", function() {
238     el.replaceChild(doctype, a);
239   });
240 }, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
241
242 // Step 6.
243 test(function() {
244   var a = document.createElement("div");
245   var b = document.createElement("div");
246   var c = document.createElement("div");
247   a.appendChild(b);
248   a.appendChild(c);
249   assert_array_equals(a.childNodes, [b, c]);
250   assert_equals(a.replaceChild(c, b), b);
251   assert_array_equals(a.childNodes, [c]);
252 }, "Replacing a node with its next sibling should work (2 children)");
253 test(function() {
254   var a = document.createElement("div");
255   var b = document.createElement("div");
256   var c = document.createElement("div");
257   var d = document.createElement("div");
258   var e = document.createElement("div");
259   a.appendChild(b);
260   a.appendChild(c);
261   a.appendChild(d);
262   a.appendChild(e);
263   assert_array_equals(a.childNodes, [b, c, d, e]);
264   assert_equals(a.replaceChild(d, c), c);
265   assert_array_equals(a.childNodes, [b, d, e]);
266 }, "Replacing a node with its next sibling should work (4 children)");
267 test(function() {
268   var a = document.createElement("div");
269   var b = document.createElement("div");
270   var c = document.createElement("div");
271   a.appendChild(b);
272   a.appendChild(c);
273   assert_array_equals(a.childNodes, [b, c]);
274   assert_equals(a.replaceChild(b, b), b);
275   assert_array_equals(a.childNodes, [b, c]);
276   assert_equals(a.replaceChild(c, c), c);
277   assert_array_equals(a.childNodes, [b, c]);
278 }, "Replacing a node with itself should not move the node");
279
280 // Step 7.
281 test(function() {
282   var doc = document.implementation.createHTMLDocument("title");
283   var doctype = doc.doctype;
284   assert_array_equals(doc.childNodes, [doctype, doc.documentElement]);
285
286   var doc2 = document.implementation.createHTMLDocument("title2");
287   var doctype2 = doc2.doctype;
288   assert_array_equals(doc2.childNodes, [doctype2, doc2.documentElement]);
289
290   doc.replaceChild(doc2.doctype, doc.doctype);
291   assert_array_equals(doc.childNodes, [doctype2, doc.documentElement]);
292   assert_array_equals(doc2.childNodes, [doc2.documentElement]);
293   assert_equals(doctype.parentNode, null);
294   assert_equals(doctype.ownerDocument, doc);
295   assert_equals(doctype2.parentNode, doc);
296   assert_equals(doctype2.ownerDocument, doc);
297 }, "If the context node is a document, inserting a new doctype should work.")
298
299 // Bugs.
300 test(function() {
301   var doc = document.implementation.createHTMLDocument("title");
302   var df = doc.createDocumentFragment();
303   var a = df.appendChild(doc.createElement("a"));
304   assert_equals(doc.documentElement, doc.replaceChild(df, doc.documentElement));
305   assert_array_equals(doc.childNodes, [doc.doctype, a]);
306 }, "Replacing the document element with a DocumentFragment containing a single element should work.");
307 test(function() {
308   var doc = document.implementation.createHTMLDocument("title");
309   var df = doc.createDocumentFragment();
310   var a = df.appendChild(doc.createComment("a"));
311   var b = df.appendChild(doc.createElement("b"));
312   var c = df.appendChild(doc.createComment("c"));
313   assert_equals(doc.documentElement, doc.replaceChild(df, doc.documentElement));
314   assert_array_equals(doc.childNodes, [doc.doctype, a, b, c]);
315 }, "Replacing the document element with a DocumentFragment containing a single element and comments should work.");
316 test(function() {
317   var doc = document.implementation.createHTMLDocument("title");
318   var a = doc.createElement("a");
319   assert_equals(doc.documentElement, doc.replaceChild(a, doc.documentElement));
320   assert_array_equals(doc.childNodes, [doc.doctype, a]);
321 }, "Replacing the document element with a single element should work.");
322 test(function() {
323   document.addEventListener("DOMNodeRemoved", function(e) {
324     document.body.appendChild(document.createElement("x"));
325   }, false);
326   var a = document.body.firstChild, b = a.firstChild, c = b.nextSibling;
327   assert_equals(a.replaceChild(c, b), b);
328   assert_equals(b.parentNode, null);
329   assert_equals(a.firstChild, c);
330   assert_equals(c.parentNode, a);
331 }, "replaceChild should work in the presence of mutation events.")
332 test(function() {
333   var TEST_ID = "findme";
334   var gBody = document.getElementsByTagName("body")[0];
335   var parent = document.createElement("div");
336   gBody.appendChild(parent);
337   var child = document.createElement("div");
338   parent.appendChild(child);
339   var df = document.createDocumentFragment();
340   var fragChild = df.appendChild(document.createElement("div"));
341   fragChild.setAttribute("id", TEST_ID);
342   parent.replaceChild(df, child);
343   assert_equals(document.getElementById(TEST_ID), fragChild, "should not be null");
344 }, "Replacing an element with a DocumentFragment should allow a child of the DocumentFragment to be found by Id.")
345 </script>