| <!DOCTYPE html> | |
| <meta charset=utf-8> | |
| <title>Node.cloneNode</title> | |
| <link rel=help href="https://dom.spec.whatwg.org/#dom-node-clonenode"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <div id=log></div> | |
| <script> | |
| function assert_equal_node(nodeA, nodeB) { | |
| assert_equals(nodeB.nodeType, nodeA.nodeType, "nodeType"); | |
| assert_equals(nodeB.nodeName, nodeA.nodeName, "nodeName"); | |
| if (nodeA.nodeType === Node.ELEMENT_NODE) { | |
| assert_equals(nodeB.prefix, nodeA.prefix, "prefix"); | |
| assert_equals(nodeB.namespaceURI, nodeA.namespaceURI, "namespaceURI"); | |
| assert_equals(nodeB.localName, nodeA.localName, "localName"); | |
| assert_equals(nodeB.tagName, nodeA.tagName, "tagName"); | |
| assert_not_equals(nodeB.attributes != nodeA.attributes, "attributes"); | |
| assert_equals(nodeB.attributes.length, nodeA.attributes.length, | |
| "attributes.length"); | |
| for (var i = 0, il = nodeA.attributes.length; i < il; ++i) { | |
| assert_not_equals(nodeB.attributes[i], nodeA.attributes[i], | |
| "attributes[" + i + "]"); | |
| assert_equals(nodeB.attributes[i].name, nodeA.attributes[i].name, | |
| "attributes[" + i + "].name"); | |
| assert_equals(nodeB.attributes[i].prefix, nodeA.attributes[i].prefix, | |
| "attributes[" + i + "].prefix"); | |
| assert_equals(nodeB.attributes[i].namespaceURI, nodeA.attributes[i].namespaceURI, | |
| "attributes[" + i + "].namespaceURI"); | |
| assert_equals(nodeB.attributes[i].value, nodeA.attributes[i].value, | |
| "attributes[" + i + "].value"); | |
| } | |
| } | |
| } | |
| function check_copy(orig, copy, type) { | |
| assert_not_equals(orig, copy, "Object equality"); | |
| assert_equal_node(orig, copy, "Node equality"); | |
| assert_true(orig instanceof type, "original instanceof " + type); | |
| assert_true(copy instanceof type, "copy instanceof " + type); | |
| } | |
| function create_element_and_check(localName, typeName) { | |
| test(function() { | |
| assert_true(typeName in window, typeName + " is not supported"); | |
| var element = document.createElement(localName); | |
| var copy = element.cloneNode(); | |
| check_copy(element, copy, window[typeName]); | |
| }, "createElement(" + localName + ")"); | |
| } | |
| // test1: createElement | |
| create_element_and_check("a", "HTMLAnchorElement"); | |
| create_element_and_check("abbr", "HTMLElement"); | |
| create_element_and_check("acronym", "HTMLElement"); | |
| create_element_and_check("address", "HTMLElement"); | |
| create_element_and_check("area", "HTMLAreaElement"); | |
| create_element_and_check("article", "HTMLElement"); | |
| create_element_and_check("aside", "HTMLElement"); | |
| create_element_and_check("audio", "HTMLAudioElement"); | |
| create_element_and_check("b", "HTMLElement"); | |
| create_element_and_check("base", "HTMLBaseElement"); | |
| create_element_and_check("bdi", "HTMLElement"); | |
| create_element_and_check("bdo", "HTMLElement"); | |
| create_element_and_check("bgsound", "HTMLElement"); | |
| create_element_and_check("big", "HTMLElement"); | |
| create_element_and_check("blockquote","HTMLElement"); | |
| create_element_and_check("body", "HTMLBodyElement"); | |
| create_element_and_check("br", "HTMLBRElement"); | |
| create_element_and_check("button", "HTMLButtonElement"); | |
| create_element_and_check("canvas", "HTMLCanvasElement"); | |
| create_element_and_check("caption", "HTMLTableCaptionElement"); | |
| create_element_and_check("center", "HTMLElement"); | |
| create_element_and_check("cite", "HTMLElement"); | |
| create_element_and_check("code", "HTMLElement"); | |
| create_element_and_check("col", "HTMLTableColElement"); | |
| create_element_and_check("colgroup", "HTMLTableColElement"); | |
| create_element_and_check("data", "HTMLDataElement"); | |
| create_element_and_check("datalist", "HTMLDataListElement"); | |
| create_element_and_check("dialog", "HTMLDialogElement"); | |
| create_element_and_check("dd", "HTMLElement"); | |
| create_element_and_check("del", "HTMLModElement"); | |
| create_element_and_check("details", "HTMLElement"); | |
| create_element_and_check("dfn", "HTMLElement"); | |
| create_element_and_check("dir", "HTMLDirectoryElement"); | |
| create_element_and_check("div", "HTMLDivElement"); | |
| create_element_and_check("dl", "HTMLDListElement"); | |
| create_element_and_check("dt", "HTMLElement"); | |
| create_element_and_check("embed", "HTMLEmbedElement"); | |
| create_element_and_check("fieldset", "HTMLFieldSetElement"); | |
| create_element_and_check("figcaption","HTMLElement"); | |
| create_element_and_check("figure", "HTMLElement"); | |
| create_element_and_check("font", "HTMLFontElement"); | |
| create_element_and_check("footer", "HTMLElement"); | |
| create_element_and_check("form", "HTMLFormElement"); | |
| create_element_and_check("frame", "HTMLFrameElement"); | |
| create_element_and_check("frameset", "HTMLFrameSetElement"); | |
| create_element_and_check("h1", "HTMLHeadingElement"); | |
| create_element_and_check("h2", "HTMLHeadingElement"); | |
| create_element_and_check("h3", "HTMLHeadingElement"); | |
| create_element_and_check("h4", "HTMLHeadingElement"); | |
| create_element_and_check("h5", "HTMLHeadingElement"); | |
| create_element_and_check("h6", "HTMLHeadingElement"); | |
| create_element_and_check("head", "HTMLHeadElement"); | |
| create_element_and_check("header", "HTMLElement"); | |
| create_element_and_check("hgroup", "HTMLElement"); | |
| create_element_and_check("hr", "HTMLHRElement"); | |
| create_element_and_check("html", "HTMLHtmlElement"); | |
| create_element_and_check("i", "HTMLElement"); | |
| create_element_and_check("iframe", "HTMLIFrameElement"); | |
| create_element_and_check("img", "HTMLImageElement"); | |
| create_element_and_check("input", "HTMLInputElement"); | |
| create_element_and_check("ins", "HTMLModElement"); | |
| create_element_and_check("isindex", "HTMLElement"); | |
| create_element_and_check("kbd", "HTMLElement"); | |
| create_element_and_check("label", "HTMLLabelElement"); | |
| create_element_and_check("legend", "HTMLLegendElement"); | |
| create_element_and_check("li", "HTMLLIElement"); | |
| create_element_and_check("link", "HTMLLinkElement"); | |
| create_element_and_check("main", "HTMLElement"); | |
| create_element_and_check("map", "HTMLMapElement"); | |
| create_element_and_check("mark", "HTMLElement"); | |
| create_element_and_check("marquee", "HTMLElement"); | |
| create_element_and_check("meta", "HTMLMetaElement"); | |
| create_element_and_check("meter", "HTMLMeterElement"); | |
| create_element_and_check("nav", "HTMLElement"); | |
| create_element_and_check("nobr", "HTMLElement"); | |
| create_element_and_check("noframes", "HTMLElement"); | |
| create_element_and_check("noscript", "HTMLElement"); | |
| create_element_and_check("object", "HTMLObjectElement"); | |
| create_element_and_check("ol", "HTMLOListElement"); | |
| create_element_and_check("optgroup", "HTMLOptGroupElement"); | |
| create_element_and_check("option", "HTMLOptionElement"); | |
| create_element_and_check("output", "HTMLOutputElement"); | |
| create_element_and_check("p", "HTMLParagraphElement"); | |
| create_element_and_check("param", "HTMLParamElement"); | |
| create_element_and_check("pre", "HTMLPreElement"); | |
| create_element_and_check("progress", "HTMLProgressElement"); | |
| create_element_and_check("q", "HTMLQuoteElement"); | |
| create_element_and_check("rp", "HTMLElement"); | |
| create_element_and_check("rt", "HTMLElement"); | |
| create_element_and_check("ruby", "HTMLElement"); | |
| create_element_and_check("s", "HTMLElement"); | |
| create_element_and_check("samp", "HTMLElement"); | |
| create_element_and_check("script", "HTMLScriptElement"); | |
| create_element_and_check("section", "HTMLElement"); | |
| create_element_and_check("select", "HTMLSelectElement"); | |
| create_element_and_check("small", "HTMLElement"); | |
| create_element_and_check("source", "HTMLSourceElement"); | |
| create_element_and_check("spacer", "HTMLElement"); | |
| create_element_and_check("span", "HTMLSpanElement"); | |
| create_element_and_check("strike", "HTMLElement"); | |
| create_element_and_check("style", "HTMLStyleElement"); | |
| create_element_and_check("sub", "HTMLElement"); | |
| create_element_and_check("summary", "HTMLElement"); | |
| create_element_and_check("sup", "HTMLElement"); | |
| create_element_and_check("table", "HTMLTableElement"); | |
| create_element_and_check("tbody", "HTMLTableSectionElement"); | |
| create_element_and_check("td", "HTMLTableCellElement"); | |
| create_element_and_check("template", "HTMLTemplateElement"); | |
| create_element_and_check("textarea", "HTMLTextAreaElement"); | |
| create_element_and_check("th", "HTMLTableCellElement"); | |
| create_element_and_check("time", "HTMLTimeElement"); | |
| create_element_and_check("title", "HTMLTitleElement"); | |
| create_element_and_check("tr", "HTMLTableRowElement"); | |
| create_element_and_check("tt", "HTMLElement"); | |
| create_element_and_check("track", "HTMLTrackElement"); | |
| create_element_and_check("u", "HTMLElement"); | |
| create_element_and_check("ul", "HTMLUListElement"); | |
| create_element_and_check("var", "HTMLElement"); | |
| create_element_and_check("video", "HTMLVideoElement"); | |
| create_element_and_check("unknown", "HTMLUnknownElement"); | |
| create_element_and_check("wbr", "HTMLElement"); | |
| test(function() { | |
| var fragment = document.createDocumentFragment(); | |
| var copy = fragment.cloneNode(); | |
| check_copy(fragment, copy, DocumentFragment); | |
| }, "createDocumentFragment"); | |
| test(function() { | |
| var text = document.createTextNode("hello world"); | |
| var copy = text.cloneNode(); | |
| check_copy(text, copy, Text); | |
| assert_equals(text.data, copy.data); | |
| assert_equals(text.wholeText, copy.wholeText); | |
| }, "createTextNode"); | |
| test(function() { | |
| var comment = document.createComment("a comment"); | |
| var copy = comment.cloneNode(); | |
| check_copy(comment, copy, Comment); | |
| assert_equals(comment.data, copy.data); | |
| }, "createComment"); | |
| test(function() { | |
| var el = document.createElement("foo"); | |
| el.setAttribute("a", "b"); | |
| el.setAttribute("c", "d"); | |
| var c = el.cloneNode(); | |
| check_copy(el, c, Element); | |
| }, "createElement with attributes") | |
| test(function() { | |
| var el = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:div"); | |
| var c = el.cloneNode(); | |
| check_copy(el, c, HTMLDivElement); | |
| }, "createElementNS HTML") | |
| test(function() { | |
| var el = document.createElementNS("http://www.example.com/", "foo:div"); | |
| var c = el.cloneNode(); | |
| check_copy(el, c, Element); | |
| }, "createElementNS non-HTML") | |
| test(function() { | |
| var pi = document.createProcessingInstruction("target", "data"); | |
| var copy = pi.cloneNode(); | |
| check_copy(pi, copy, ProcessingInstruction); | |
| assert_equals(pi.data, copy.data, "data"); | |
| assert_equals(pi.target, pi.target, "target"); | |
| }, "createProcessingInstruction"); | |
| test(function() { | |
| var attr = document.createAttribute("class"); | |
| var copy = attr.cloneNode(); | |
| check_copy(attr, copy, Attr); | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy.localName); | |
| assert_equals(attr.value, copy.value); | |
| attr.value = "abc"; | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy.localName); | |
| assert_not_equals(attr.value, copy.value); | |
| var copy2 = attr.cloneNode(); | |
| check_copy(attr, copy2, Attr); | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy2.localName); | |
| assert_equals(attr.value, copy2.value); | |
| }, "createAttribute"); | |
| test(function() { | |
| var attr = document.createAttributeNS("http://www.w3.org/1999/xhtml", "foo:class"); | |
| var copy = attr.cloneNode(); | |
| check_copy(attr, copy, Attr); | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy.localName); | |
| assert_equals(attr.value, copy.value); | |
| attr.value = "abc"; | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy.localName); | |
| assert_not_equals(attr.value, copy.value); | |
| var copy2 = attr.cloneNode(); | |
| check_copy(attr, copy2, Attr); | |
| assert_equals(attr.namespaceURI, copy.namespaceURI); | |
| assert_equals(attr.prefix, copy.prefix); | |
| assert_equals(attr.localName, copy2.localName); | |
| assert_equals(attr.value, copy2.value); | |
| }, "createAttributeNS"); | |
| test(function() { | |
| var doctype = document.implementation.createDocumentType("html", "public", "system"); | |
| var copy = doctype.cloneNode(); | |
| check_copy(doctype, copy, DocumentType); | |
| assert_equals(doctype.name, copy.name, "name"); | |
| assert_equals(doctype.publicId, copy.publicId, "publicId"); | |
| assert_equals(doctype.systemId, copy.systemId, "systemId"); | |
| }, "implementation.createDocumentType"); | |
| test(function() { | |
| var doc = document.implementation.createDocument(null, null); | |
| var copy = doc.cloneNode(); | |
| check_copy(doc, copy, Document); | |
| assert_equals(doc.charset, "UTF-8", "charset value"); | |
| assert_equals(doc.charset, copy.charset, "charset equality"); | |
| assert_equals(doc.contentType, "application/xml", "contentType value"); | |
| assert_equals(doc.contentType, copy.contentType, "contentType equality"); | |
| assert_equals(doc.URL, "about:blank", "URL value") | |
| assert_equals(doc.URL, copy.URL, "URL equality"); | |
| assert_equals(doc.compatMode, "CSS1Compat", "compatMode value"); | |
| assert_equals(doc.compatMode, copy.compatMode, "compatMode equality"); | |
| }, "implementation.createDocument"); | |
| test(function() { | |
| var html = document.implementation.createHTMLDocument("title"); | |
| var copy = html.cloneNode(); | |
| check_copy(html, copy, Document); | |
| assert_equals(copy.title, "", "title value"); | |
| }, "implementation.createHTMLDocument"); | |
| test(function() { | |
| var parent = document.createElement("div"); | |
| var child1 = document.createElement("div"); | |
| var child2 = document.createElement("div"); | |
| var grandChild = document.createElement("div"); | |
| child2.appendChild(grandChild); | |
| parent.appendChild(child1); | |
| parent.appendChild(child2); | |
| var deep = true; | |
| var copy = parent.cloneNode(deep); | |
| check_copy(parent, copy, HTMLDivElement); | |
| assert_equals(copy.childNodes.length, 2, | |
| "copy.childNodes.length with deep copy"); | |
| check_copy(child1, copy.childNodes[0], HTMLDivElement); | |
| assert_equals(copy.childNodes[0].childNodes.length, 0, | |
| "copy.childNodes[0].childNodes.length"); | |
| check_copy(child2, copy.childNodes[1], HTMLDivElement); | |
| assert_equals(copy.childNodes[1].childNodes.length, 1, | |
| "copy.childNodes[1].childNodes.length"); | |
| check_copy(grandChild, copy.childNodes[1].childNodes[0], HTMLDivElement); | |
| deep = false; | |
| copy = parent.cloneNode(deep); | |
| check_copy(parent, copy, HTMLDivElement); | |
| assert_equals(copy.childNodes.length, 0, | |
| "copy.childNodes.length with non-deep copy"); | |
| }, "node with children"); | |
| test(() => { | |
| const proto = Object.create(HTMLElement.prototype), | |
| node = document.createElement("hi"); | |
| Object.setPrototypeOf(node, proto); | |
| assert_true(proto.isPrototypeOf(node)); | |
| const clone = node.cloneNode(); | |
| assert_false(proto.isPrototypeOf(clone)); | |
| assert_true(HTMLUnknownElement.prototype.isPrototypeOf(clone)); | |
| const deepClone = node.cloneNode(true); | |
| assert_false(proto.isPrototypeOf(deepClone)); | |
| assert_true(HTMLUnknownElement.prototype.isPrototypeOf(deepClone)); | |
| }, "Node with custom prototype") | |
| </script> |