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