cloneNode(true) does not clone nested template elements' contents
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Dec 2014 22:19:38 +0000 (22:19 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Dec 2014 22:19:38 +0000 (22:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137755

Reviewed by Darin Adler.

Source/WebCore:

The bug was caused by cloneChildNodes not copying template element's content.

Fixed the bug by adding the third behavior (CloneContent) to the polymorphic
cloneNodeInternal, which copies template element's content but not its children,
in addition to the existing CloneSelf (deep=false) and CloneChildren (deep=true).

Test: fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html

* dom/Attr.cpp:
(WebCore::Attr::cloneNodeInternal): Renamed from cloneNode.
* dom/Attr.h:
* dom/CDATASection.cpp:
(WebCore::CDATASection::cloneNodeInternal): Renamed from cloneNode.
* dom/CDATASection.h:
* dom/Comment.cpp:
(WebCore::Comment::cloneNodeInternal): Renamed from cloneNode.
* dom/Comment.h:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::cloneChildNodes): Calls cloneNode with CloneContent.
* dom/Document.cpp:
(WebCore::Document::cloneNodeInternal): Renamed from cloneNode.
* dom/Document.h:
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::cloneNodeInternal): Renamed from cloneNode.
* dom/DocumentFragment.h:
* dom/DocumentType.cpp:
(WebCore::DocumentType::cloneNodeInternal): Renamed from cloneNode.
* dom/DocumentType.h:
* dom/Element.cpp:
(WebCore::Element::cloneNodeInternal): Renamed from cloneNode.
* dom/Element.h:
* dom/EntityReference.cpp:
(WebCore::EntityReference::cloneNodeInternal): Renamed from cloneNode.
* dom/EntityReference.h:
* dom/Node.h:
(WebCore::Node::cloneNode): Added. It calls cloneNodeInternal with CloneSelf or CloneChildren.
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::cloneNodeInternal): Renamed from cloneNode.
* dom/ProcessingInstruction.h:
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::cloneNodeInternal): Renamed from cloneNode. Also moved from ShadowRoot.h.
* dom/ShadowRoot.h:
* dom/Text.cpp:
(WebCore::Text::cloneNodeInternal): Renamed from cloneNode.
* dom/Text.h:
* html/HTMLTemplateElement.cpp:
(WebCore::HTMLTemplateElement::cloneNodeInternal): Renamed from cloneNode. This is the only
function in which CloneContent results in a different behavior from CloneSelf.
* html/HTMLTemplateElement.h:

LayoutTests:

Added a regression test.

* fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt: Added.
* fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177314 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Attr.cpp
Source/WebCore/dom/Attr.h
Source/WebCore/dom/CDATASection.cpp
Source/WebCore/dom/CDATASection.h
Source/WebCore/dom/Comment.cpp
Source/WebCore/dom/Comment.h
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/DocumentFragment.cpp
Source/WebCore/dom/DocumentFragment.h
Source/WebCore/dom/DocumentType.cpp
Source/WebCore/dom/DocumentType.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/EntityReference.cpp
Source/WebCore/dom/EntityReference.h
Source/WebCore/dom/Node.h
Source/WebCore/dom/ProcessingInstruction.cpp
Source/WebCore/dom/ProcessingInstruction.h
Source/WebCore/dom/ShadowRoot.cpp
Source/WebCore/dom/ShadowRoot.h
Source/WebCore/dom/Text.cpp
Source/WebCore/dom/Text.h
Source/WebCore/html/HTMLTemplateElement.cpp
Source/WebCore/html/HTMLTemplateElement.h

index 7aaf599c93ef7bf55ad74eba78e59eeffcf0d277..8d73edd88f443ea435f773317d0eb062d55278cf 100644 (file)
@@ -1,3 +1,15 @@
+2014-12-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        cloneNode(true) does not clone nested template elements' contents
+        https://bugs.webkit.org/show_bug.cgi?id=137755
+
+        Reviewed by Darin Adler.
+
+        Added a regression test.
+
+        * fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt: Added.
+        * fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html: Added.
+
 2014-12-15  Benjamin Poulain  <bpoulain@apple.com>
 
         Unify the various serialization of selector list
diff --git a/LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt b/LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates-expected.txt
new file mode 100644 (file)
index 0000000..579c1e3
--- /dev/null
@@ -0,0 +1,19 @@
+Test that template contents are not cloned when the template element is cloned
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+clonedOuterTemplate = outerTemplate.cloneNode(true)
+PASS clonedOuterTemplate.content is not outerTemplate.content
+PASS clonedOuterTemplate.content.childNodes.length is 1
+innerTemplate = outerTemplate.content.firstChild
+clonedInnerTemplate = clonedOuterTemplate.content.firstChild
+PASS clonedInnerTemplate.outerHTML is innerTemplate.outerHTML
+PASS clonedInnerTemplate.content is not innerTemplate.content
+PASS innerTemplate.content.childNodes.length is 1
+PASS clonedInnerTemplate.content.childNodes.length is 1
+PASS innerTemplate.content.firstChild.outerHTML is clonedInnerTemplate.content.firstChild.outerHTML
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html b/LayoutTests/fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html
new file mode 100644 (file)
index 0000000..2dace15
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<body>
+<template id="outerTemplate"><template id="innerTemplate"><span>Contents</span></template></template>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+
+description('Test that template contents are not cloned when the template element is cloned');
+
+if (!window.HTMLTemplateElement)
+    testFailed('This test requires ENABLE(TEMPLATE_ELEMENT)');
+
+var outerTemplate = document.getElementById('outerTemplate');
+evalAndLog('clonedOuterTemplate = outerTemplate.cloneNode(true)');
+shouldNotBe('clonedOuterTemplate.content', 'outerTemplate.content');
+shouldBe('clonedOuterTemplate.content.childNodes.length', '1');
+evalAndLog('innerTemplate = outerTemplate.content.firstChild');
+evalAndLog('clonedInnerTemplate = clonedOuterTemplate.content.firstChild');
+shouldBe('clonedInnerTemplate.outerHTML', 'innerTemplate.outerHTML');
+shouldNotBe('clonedInnerTemplate.content', 'innerTemplate.content');
+shouldBe('innerTemplate.content.childNodes.length', '1');
+shouldBe('clonedInnerTemplate.content.childNodes.length', '1');
+shouldBe('innerTemplate.content.firstChild.outerHTML', 'clonedInnerTemplate.content.firstChild.outerHTML');
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 77ff982efeab2f77ed58644eebba52d77d67253b..08219b1f5561b128c3d406d9f26c6e22f86c2e20 100644 (file)
@@ -1,3 +1,60 @@
+2014-12-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        cloneNode(true) does not clone nested template elements' contents
+        https://bugs.webkit.org/show_bug.cgi?id=137755
+
+        Reviewed by Darin Adler.
+
+        The bug was caused by cloneChildNodes not copying template element's content.
+
+        Fixed the bug by adding the third behavior (CloneContent) to the polymorphic
+        cloneNodeInternal, which copies template element's content but not its children,
+        in addition to the existing CloneSelf (deep=false) and CloneChildren (deep=true).
+
+        Test: fast/dom/HTMLTemplateElement/cloneNode-nested-templates.html
+
+        * dom/Attr.cpp:
+        (WebCore::Attr::cloneNodeInternal): Renamed from cloneNode.
+        * dom/Attr.h:
+        * dom/CDATASection.cpp:
+        (WebCore::CDATASection::cloneNodeInternal): Renamed from cloneNode.
+        * dom/CDATASection.h:
+        * dom/Comment.cpp:
+        (WebCore::Comment::cloneNodeInternal): Renamed from cloneNode.
+        * dom/Comment.h:
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::cloneChildNodes): Calls cloneNode with CloneContent.
+        * dom/Document.cpp:
+        (WebCore::Document::cloneNodeInternal): Renamed from cloneNode.
+        * dom/Document.h:
+        * dom/DocumentFragment.cpp:
+        (WebCore::DocumentFragment::cloneNodeInternal): Renamed from cloneNode.
+        * dom/DocumentFragment.h:
+        * dom/DocumentType.cpp:
+        (WebCore::DocumentType::cloneNodeInternal): Renamed from cloneNode.
+        * dom/DocumentType.h:
+        * dom/Element.cpp:
+        (WebCore::Element::cloneNodeInternal): Renamed from cloneNode.
+        * dom/Element.h:
+        * dom/EntityReference.cpp:
+        (WebCore::EntityReference::cloneNodeInternal): Renamed from cloneNode.
+        * dom/EntityReference.h:
+        * dom/Node.h:
+        (WebCore::Node::cloneNode): Added. It calls cloneNodeInternal with CloneSelf or CloneChildren.
+        * dom/ProcessingInstruction.cpp:
+        (WebCore::ProcessingInstruction::cloneNodeInternal): Renamed from cloneNode.
+        * dom/ProcessingInstruction.h:
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::cloneNodeInternal): Renamed from cloneNode. Also moved from ShadowRoot.h.
+        * dom/ShadowRoot.h:
+        * dom/Text.cpp:
+        (WebCore::Text::cloneNodeInternal): Renamed from cloneNode.
+        * dom/Text.h:
+        * html/HTMLTemplateElement.cpp:
+        (WebCore::HTMLTemplateElement::cloneNodeInternal): Renamed from cloneNode. This is the only
+        function in which CloneContent results in a different behavior from CloneSelf.
+        * html/HTMLTemplateElement.h:
+
 2014-12-15  Benjamin Poulain  <bpoulain@apple.com>
 
         Unify the various serialization of selector list
index e6b4d7b45954a6aebd1383cb69d6ea3802e5bf88..0706fd6ba6f83764564410baffaed79e60f8bd85 100644 (file)
@@ -137,7 +137,7 @@ void Attr::setNodeValue(const String& v, ExceptionCode& ec)
     setValue(v, ec);
 }
 
-RefPtr<Node> Attr::cloneNode(bool /*deep*/)
+RefPtr<Node> Attr::cloneNodeInternal(CloningOperation)
 {
     RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
     cloneChildNodes(clone.get());
index c10fcfa9e09f5e3100f28a0a6d88af867923d702..3254414bbe25fd9bb5d65d07da5a5d9694b66c7d 100644 (file)
@@ -80,7 +80,7 @@ private:
 
     virtual String nodeValue() const override { return value(); }
     virtual void setNodeValue(const String&, ExceptionCode&) override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
 
     virtual bool isAttributeNode() const override { return true; }
     virtual bool childTypeAllowed(NodeType) const override;
index c3127066eba1eec995ac58de1d0d7bb85a3a20f7..9f94384dc488e6a3fa26ed24b110eb60ee604551 100644 (file)
@@ -46,7 +46,7 @@ Node::NodeType CDATASection::nodeType() const
     return CDATA_SECTION_NODE;
 }
 
-RefPtr<Node> CDATASection::cloneNode(bool /*deep*/)
+RefPtr<Node> CDATASection::cloneNodeInternal(CloningOperation)
 {
     return create(document(), data());
 }
index de52f3b5753d2a96b715ce6035df64e26c380220..b38d2065160c36b36fb5bf91944d3f31eb01e9f9 100644 (file)
@@ -36,7 +36,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
     virtual RefPtr<Text> virtualCreate(const String&) override;
 };
index de2df46bcad1ecbb5d57d5baf29b070b3cf23519..769434a76ca88a7ba4b2a15decf6c067938746ae 100644 (file)
@@ -51,7 +51,7 @@ Node::NodeType Comment::nodeType() const
     return COMMENT_NODE;
 }
 
-RefPtr<Node> Comment::cloneNode(bool /*deep*/)
+RefPtr<Node> Comment::cloneNodeInternal(CloningOperation)
 {
     return create(document(), data());
 }
index 5668bd786e7a07c286f2a7e671e3ac4b3abf78f4..b1254ba8e1bb862c5de778fc0c66ea0a60ad0db1 100644 (file)
@@ -37,7 +37,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 };
 
index 960960742b5f24dd2d79fda1396fbee592fe7144..d2e7b87a9a7155461c64ee645efd0c754fab2883 100644 (file)
@@ -769,7 +769,7 @@ void ContainerNode::cloneChildNodes(ContainerNode *clone)
 {
     ExceptionCode ec = 0;
     for (Node* child = firstChild(); child && !ec; child = child->nextSibling()) {
-        RefPtr<Node> clonedChild = child->cloneNode(false);
+        RefPtr<Node> clonedChild = child->cloneNodeInternal(CloningOperation::SelfWithTemplateContent);
         clone->appendChild(clonedChild, ec);
 
         if (!ec && is<ContainerNode>(child))
index 3700e1e9f29f4af2d82692bf49eba41fcf3a7043..fac54d6e51e03e48b248e19dddf29ded0e0b0db9 100644 (file)
@@ -3183,12 +3183,18 @@ bool Document::canReplaceChild(Node* newChild, Node* oldChild)
     return true;
 }
 
-RefPtr<Node> Document::cloneNode(bool deep)
+RefPtr<Node> Document::cloneNodeInternal(CloningOperation type)
 {
     RefPtr<Document> clone = cloneDocumentWithoutChildren();
     clone->cloneDataFromDocument(*this);
-    if (deep)
+    switch (type) {
+    case CloningOperation::OnlySelf:
+    case CloningOperation::SelfWithTemplateContent:
+        break;
+    case CloningOperation::Everything:
         cloneChildNodes(clone.get());
+        break;
+    }
     return clone;
 }
 
index f54d9d5c8f5b6df2c6e0330d63272d60771921e5..f328616a3942bd6d6f95cd4d8017d12f9cea3505 100644 (file)
@@ -1308,7 +1308,7 @@ private:
     virtual String nodeName() const override final;
     virtual NodeType nodeType() const override final;
     virtual bool childTypeAllowed(NodeType) const override final;
-    virtual RefPtr<Node> cloneNode(bool deep) override final;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override final;
     void cloneDataFromDocument(const Document&);
 
     virtual void refScriptExecutionContext() override final { ref(); }
index 8af4750055480884d87d7206f3efc46ae79ba0bf..31870c39ce613e2e2345a20911514f72211266fa 100644 (file)
@@ -71,11 +71,17 @@ bool DocumentFragment::childTypeAllowed(NodeType type) const
     }
 }
 
-RefPtr<Node> DocumentFragment::cloneNode(bool deep)
+RefPtr<Node> DocumentFragment::cloneNodeInternal(CloningOperation type)
 {
     RefPtr<DocumentFragment> clone = create(document());
-    if (deep)
+    switch (type) {
+    case CloningOperation::OnlySelf:
+    case CloningOperation::SelfWithTemplateContent:
+        break;
+    case CloningOperation::Everything:
         cloneChildNodes(clone.get());
+        break;
+    }
     return clone;
 }
 
index 10fca51c0467b0e19cac8d8397e8760f3949238c..a3d9deb403b1edf9ad0175d79193efd1f8c00526 100644 (file)
@@ -48,7 +48,7 @@ protected:
 
 private:
     virtual NodeType nodeType() const override final;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 };
 
index 2921f30ed1102d0b6407a0062372b67fe27f719e..e4d096d8b2dae135b0cc1ccbe56d5683b6bf5121 100644 (file)
@@ -51,7 +51,7 @@ Node::NodeType DocumentType::nodeType() const
     return DOCUMENT_TYPE_NODE;
 }
 
-RefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
+RefPtr<Node> DocumentType::cloneNodeInternal(CloningOperation)
 {
     return create(document(), m_name, m_publicId, m_systemId);
 }
index d9215f457743daea74e2c342f5b807643f52d79a..4c0a16d086ce047ce824f19606ac0eee711f4e1b 100644 (file)
@@ -52,7 +52,7 @@ private:
     virtual URL baseURI() const override;
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
 
     String m_name;
     String m_publicId;
index 3eb72c86518a17fcb8c26d64763985ad93d4426e..0768c26305fd55cbfc5b20324d4d49a93e6b6277 100644 (file)
@@ -289,9 +289,17 @@ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
 
-RefPtr<Node> Element::cloneNode(bool deep)
+RefPtr<Node> Element::cloneNodeInternal(CloningOperation type)
 {
-    return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
+    switch (type) {
+    case CloningOperation::OnlySelf:
+    case CloningOperation::SelfWithTemplateContent:
+        return cloneElementWithoutChildren();
+    case CloningOperation::Everything:
+        return cloneElementWithChildren();
+    }
+    ASSERT_NOT_REACHED();
+    return nullptr;
 }
 
 RefPtr<Element> Element::cloneElementWithChildren()
index de45052594e343dcc777cd8095f36f282d9ce049..a4b0e3bd3afbd39efebf0844bf3751f9483569b1 100644 (file)
@@ -632,7 +632,7 @@ private:
 
     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
     // are used instead.
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren();
 
     void addShadowRoot(PassRefPtr<ShadowRoot>);
index e7b2f97f553986597acc8804290322d689bccea4..bf6a3327c9ac94d7a78a6c4a0773b4781caea031 100644 (file)
@@ -46,7 +46,7 @@ Node::NodeType EntityReference::nodeType() const
     return ENTITY_REFERENCE_NODE;
 }
 
-RefPtr<Node> EntityReference::cloneNode(bool)
+RefPtr<Node> EntityReference::cloneNodeInternal(CloningOperation)
 {
     return create(document(), m_entityName);
 }
index 6164b9adf8e825860e5ae6ef9edd6428e1926700..a56347a8e494804d79bdb128a77b9d149b1b9966 100644 (file)
@@ -35,7 +35,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
 
     String m_entityName;
 };
index f2684753b8e6444b1ba67da1394f7ee229777e55..af19de1a4d20acc6df0826c2e4c5503de6d88388 100644 (file)
@@ -203,7 +203,15 @@ public:
 
     WEBCORE_EXPORT void remove(ExceptionCode&);
     bool hasChildNodes() const { return firstChild(); }
-    virtual RefPtr<Node> cloneNode(bool deep) = 0;
+
+    enum class CloningOperation {
+        OnlySelf,
+        SelfWithTemplateContent,
+        Everything,
+    };
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) = 0;
+    RefPtr<Node> cloneNode(bool deep) { return cloneNodeInternal(deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
+
     virtual const AtomicString& localName() const;
     virtual const AtomicString& namespaceURI() const;
     virtual const AtomicString& prefix() const;
index b4dffd10e9a9df70b83a9801009c99ed2913875f..f0ef9dc1637638565f83bc6b45a73645d079fdcc 100644 (file)
@@ -79,7 +79,7 @@ Node::NodeType ProcessingInstruction::nodeType() const
     return PROCESSING_INSTRUCTION_NODE;
 }
 
-RefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
+RefPtr<Node> ProcessingInstruction::cloneNodeInternal(CloningOperation)
 {
     // FIXME: Is it a problem that this does not copy m_localHref?
     // What about other data members?
index 0e4e8b8dbe89ff3232a9f95201211ffe5f8f2a8d..05b0cfa489cc6af42ffa9b88479447e0f277b902 100644 (file)
@@ -58,7 +58,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
 
     virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
     virtual void removedFrom(ContainerNode&) override;
index 5bfeb79550eb2fb67b0c58f1a0f84d7b14ec6816..67764373ec0fc10d2c44120fd1306df9b045f516 100644 (file)
@@ -131,6 +131,11 @@ void ShadowRoot::childrenChanged(const ChildChange& change)
     invalidateDistribution();
 }
 
+RefPtr<Node> ShadowRoot::cloneNodeInternal(CloningOperation)
+{
+    return nullptr; // ShadowRoots should never be cloned.
+}
+
 void ShadowRoot::removeAllEventListeners()
 {
     DocumentFragment::removeAllEventListeners();
index aa11e8044efd354efbc1d4a4d1b3cad0644e0a33..5eea892a73f4c4013b065317eb86c072b6eaf87b 100644 (file)
@@ -76,8 +76,7 @@ private:
     virtual bool childTypeAllowed(NodeType) const override;
     virtual void childrenChanged(const ChildChange&) override;
 
-    // ShadowRoots should never be cloned.
-    virtual RefPtr<Node> cloneNode(bool) override { return 0; }
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
 
     // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
     bool isOrphan() const { return !hostElement(); }
index b9b8c0666d1d73bb0351475643c443f215e14034..d0f3a7107ccc63339105b872f0ed601974ba88eb 100644 (file)
@@ -169,7 +169,7 @@ Node::NodeType Text::nodeType() const
     return TEXT_NODE;
 }
 
-RefPtr<Node> Text::cloneNode(bool /*deep*/)
+RefPtr<Node> Text::cloneNodeInternal(CloningOperation)
 {
     return create(document(), data());
 }
index f6793b5259ab7b862c8fae6bdf120b51943495e3..532bd3c8f3faf581abd61be10b89c80ae914f205 100644 (file)
@@ -64,7 +64,7 @@ protected:
 private:
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 
     virtual RefPtr<Text> virtualCreate(const String&);
index 320de86ff2eb3e2b4b551dfceac01f4bbf189b05..dc752eeeaf7e08a6821fd60c859816797716e4ee 100644 (file)
@@ -68,12 +68,19 @@ DocumentFragment* HTMLTemplateElement::content() const
     return m_content.get();
 }
 
-RefPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
+RefPtr<Node> HTMLTemplateElement::cloneNodeInternal(CloningOperation type)
 {
-    if (!deep)
+    RefPtr<Node> clone;
+    switch (type) {
+    case CloningOperation::OnlySelf:
         return cloneElementWithoutChildren();
-
-    RefPtr<Node> clone = cloneElementWithChildren();
+    case CloningOperation::SelfWithTemplateContent:
+        clone = cloneElementWithoutChildren();
+        break;
+    case CloningOperation::Everything:
+        clone = cloneElementWithChildren();
+        break;
+    }
     if (m_content)
         content()->cloneChildNodes(downcast<HTMLTemplateElement>(clone.get())->content());
     return clone.release();
index aa1e221cffa1b3a77d89d9284c351ce76019041b..d96d69ae389423b983353c71d9b2176031642d6e 100644 (file)
@@ -50,7 +50,7 @@ public:
 private:
     HTMLTemplateElement(const QualifiedName&, Document&);
 
-    virtual RefPtr<Node> cloneNode(bool deep) override;
+    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
     virtual void didMoveToNewDocument(Document* oldDocument) override;
 
     mutable RefPtr<TemplateContentDocumentFragment> m_content;