| <!DOCTYPE html> | |
| <title>Node.insertBefore</title> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <div id="log"></div> | |
| <script> | |
| function testLeafNode(nodeName, createNodeFunction) { | |
| test(function() { | |
| var node = createNodeFunction(); | |
| assert_throws(new TypeError(), function() { node.insertBefore(null, null) }) | |
| }, "Calling insertBefore with a non-Node first argument on a leaf node " + nodeName + " must throw TypeError.") | |
| test(function() { | |
| var node = createNodeFunction(); | |
| assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(document.createTextNode("fail"), null) }) | |
| // Would be step 2. | |
| assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(node, null) }) | |
| // Would be step 3. | |
| assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(node, document.createTextNode("child")) }) | |
| }, "Calling insertBefore an a leaf node " + nodeName + " must throw HIERARCHY_REQUEST_ERR.") | |
| } | |
| test(function() { | |
| // WebIDL. | |
| assert_throws(new TypeError(), function() { document.body.insertBefore(null, null) }) | |
| assert_throws(new TypeError(), function() { document.body.insertBefore(null, document.body.firstChild) }) | |
| assert_throws(new TypeError(), function() { document.body.insertBefore({'a':'b'}, document.body.firstChild) }) | |
| }, "Calling insertBefore with a non-Node first argument must throw TypeError.") | |
| testLeafNode("DocumentType", function () { return document.doctype; } ) | |
| testLeafNode("Text", function () { return document.createTextNode("Foo") }) | |
| testLeafNode("Comment", function () { return document.createComment("Foo") }) | |
| testLeafNode("ProcessingInstruction", function () { return document.createProcessingInstruction("foo", "bar") }) | |
| test(function() { | |
| // Step 2. | |
| assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.body, document.getElementById("log")) }) | |
| assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.documentElement, document.getElementById("log")) }) | |
| }, "Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY_REQUEST_ERR.") | |
| // Step 3. | |
| test(function() { | |
| var a = document.createElement("div"); | |
| var b = document.createElement("div"); | |
| var c = document.createElement("div"); | |
| assert_throws("NotFoundError", function() { | |
| a.insertBefore(b, c); | |
| }); | |
| }, "Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError.") | |
| // Step 4.1. | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var doc2 = document.implementation.createHTMLDocument("title2"); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doc2, doc.documentElement); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doc.createTextNode("text"), doc.documentElement); | |
| }); | |
| }, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.") | |
| // Step 4.2.1. | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| doc.removeChild(doc.documentElement); | |
| var df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createElement("a")); | |
| df.appendChild(doc.createElement("b")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, null); | |
| }); | |
| df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createTextNode("text")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, null); | |
| }); | |
| df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createComment("comment")); | |
| df.appendChild(doc.createTextNode("text")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, null); | |
| }); | |
| }, "If the context node is a document, appending a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.") | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| doc.removeChild(doc.documentElement); | |
| var df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createElement("a")); | |
| df.appendChild(doc.createElement("b")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.firstChild); | |
| }); | |
| df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createTextNode("text")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.firstChild); | |
| }); | |
| df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createComment("comment")); | |
| df.appendChild(doc.createTextNode("text")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.firstChild); | |
| }); | |
| }, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.") | |
| // Step 4.2.2. | |
| test(function() { | |
| // The context node has an element child. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.appendChild(doc.createComment("foo")); | |
| assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]); | |
| var df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createElement("a")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.doctype); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.documentElement); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, comment); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, null); | |
| }); | |
| }, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.") | |
| test(function() { | |
| // /child/ is a doctype. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild); | |
| doc.removeChild(doc.documentElement); | |
| assert_array_equals(doc.childNodes, [comment, doc.doctype]); | |
| var df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createElement("a")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, doc.doctype); | |
| }); | |
| }, "If the context node is a document and a doctype is following the reference child, inserting a DocumentFragment with an element should throw a HierarchyRequestError.") | |
| test(function() { | |
| // /child/ is not null and a doctype is following /child/. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild); | |
| doc.removeChild(doc.documentElement); | |
| assert_array_equals(doc.childNodes, [comment, doc.doctype]); | |
| var df = doc.createDocumentFragment(); | |
| df.appendChild(doc.createElement("a")); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(df, comment); | |
| }); | |
| }, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.") | |
| // Step 4.3. | |
| test(function() { | |
| // The context node has an element child. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.appendChild(doc.createComment("foo")); | |
| assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]); | |
| var a = doc.createElement("a"); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, doc.doctype); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, doc.documentElement); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, comment); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, null); | |
| }); | |
| }, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.") | |
| test(function() { | |
| // /child/ is a doctype. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild); | |
| doc.removeChild(doc.documentElement); | |
| assert_array_equals(doc.childNodes, [comment, doc.doctype]); | |
| var a = doc.createElement("a"); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, doc.doctype); | |
| }); | |
| }, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.") | |
| test(function() { | |
| // /child/ is not null and a doctype is following /child/. | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild); | |
| doc.removeChild(doc.documentElement); | |
| assert_array_equals(doc.childNodes, [comment, doc.doctype]); | |
| var a = doc.createElement("a"); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(a, comment); | |
| }); | |
| }, "If the context node is a document and a doctype is following the reference child, inserting an element should throw a HierarchyRequestError.") | |
| // Step 4.4. | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild); | |
| assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]); | |
| var doctype = document.implementation.createDocumentType("html", "", ""); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, comment); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, doc.doctype); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, doc.documentElement); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, null); | |
| }); | |
| }, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.") | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.appendChild(doc.createComment("foo")); | |
| doc.removeChild(doc.doctype); | |
| assert_array_equals(doc.childNodes, [doc.documentElement, comment]); | |
| var doctype = document.implementation.createDocumentType("html", "", ""); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, comment); | |
| }); | |
| }, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.") | |
| test(function() { | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| var comment = doc.appendChild(doc.createComment("foo")); | |
| doc.removeChild(doc.doctype); | |
| assert_array_equals(doc.childNodes, [doc.documentElement, comment]); | |
| var doctype = document.implementation.createDocumentType("html", "", ""); | |
| assert_throws("HierarchyRequestError", function() { | |
| doc.insertBefore(doctype, null); | |
| }); | |
| }, "If the context node is a document with and element child, appending a doctype should throw a HierarchyRequestError.") | |
| // Step 5. | |
| test(function() { | |
| var df = document.createDocumentFragment(); | |
| var a = df.appendChild(document.createElement("a")); | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| assert_throws("HierarchyRequestError", function() { | |
| df.insertBefore(doc, a); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| df.insertBefore(doc, null); | |
| }); | |
| var doctype = document.implementation.createDocumentType("html", "", ""); | |
| assert_throws("HierarchyRequestError", function() { | |
| df.insertBefore(doctype, a); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| df.insertBefore(doctype, null); | |
| }); | |
| }, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.") | |
| test(function() { | |
| var el = document.createElement("div"); | |
| var a = el.appendChild(document.createElement("a")); | |
| var doc = document.implementation.createHTMLDocument("title"); | |
| assert_throws("HierarchyRequestError", function() { | |
| el.insertBefore(doc, a); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| el.insertBefore(doc, null); | |
| }); | |
| var doctype = document.implementation.createDocumentType("html", "", ""); | |
| assert_throws("HierarchyRequestError", function() { | |
| el.insertBefore(doctype, a); | |
| }); | |
| assert_throws("HierarchyRequestError", function() { | |
| el.insertBefore(doctype, null); | |
| }); | |
| }, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.") | |
| // Step 7. | |
| test(function() { | |
| var a = document.createElement("div"); | |
| var b = document.createElement("div"); | |
| var c = document.createElement("div"); | |
| a.appendChild(b); | |
| a.appendChild(c); | |
| assert_array_equals(a.childNodes, [b, c]); | |
| assert_equals(a.insertBefore(b, b), b); | |
| assert_array_equals(a.childNodes, [b, c]); | |
| assert_equals(a.insertBefore(c, c), c); | |
| assert_array_equals(a.childNodes, [b, c]); | |
| }, "Inserting a node before itself should not move the node"); | |
| </script> |