Nested template contents are not cloned by document.importNode
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 19:08:54 +0000 (19:08 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 16 Dec 2014 19:08:54 +0000 (19:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137619

Reviewed by Andreas Kling.

Source/WebCore:

The bug was caused by Document.importNode not cloning HTMLTemplateElement's content.

Fixed the bug by sharing code between Document::importNode and Node::cloneNode by
generalizing Node::cloneNodeInternal, added in r177314, by taking the owner document
as an argument. The most of code changes are the result of adding this argument.

Document::importNode is the only function in which the actual logic changes.
Note that the code to import TEXT_NODE, CDATA_SECTION_NODE, ENTITY_REFERENCE_NODE,
PROCESSING_INSTRUCTION_NODE and COMMENT_NODE nodes are identical to that of cloneNode.

This patch removes the call to hasValidNamespaceForElements in ELEMENT_NODE but this
should not introduce an observable behavior change since all instantiated elements
should have a valid namespace in the first place.

Because DOCUMENT_NODE and DOCUMENT_TYPE_NODE cannot be imported and DOCUMENT_TYPE_NODE
can only appear as a direct child of DOCUMENT_NODE, neither nodes nor unimplemented
XPATH_NAMESPACE_NODE and XPATH_NAMESPACE_NODE can appear inside the recursive calls
for ELEMENT_NODE and DOCUMENT_FRAGMENT_NODE nodes.

While importNode behaves differently from cloneNode for ATTRIBUTE_NODE, namely that
it merges all of its child nodes, this behavior isn't present when recursing inside
ELEMENT_NODE and DOCUMENT_FRAGMENT_NODE since we are using cloneDataFromElement.

Thus there should be no observable behavior changes for DOCUMENT_FRAGMENT_NODE and
ELEMENT_NODE nodes either.

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

* dom/Attr.cpp:
(WebCore::Attr::cloneNodeInternal):
* dom/Attr.h:
* dom/CDATASection.cpp:
(WebCore::CDATASection::cloneNodeInternal):
* dom/CDATASection.h:
* dom/Comment.cpp:
(WebCore::Comment::cloneNodeInternal):
* dom/Comment.h:
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::cloneChildNodes):
* dom/Document.cpp:
(WebCore::Document::importNode):
(WebCore::Document::cloneNodeInternal):
* dom/Document.h:
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::cloneNodeInternal):
* dom/DocumentFragment.h:
* dom/DocumentType.cpp:
(WebCore::DocumentType::cloneNodeInternal):
* dom/DocumentType.h:
* dom/Element.cpp:
(WebCore::Element::cloneNodeInternal):
(WebCore::Element::cloneElementWithChildren):
(WebCore::Element::cloneElementWithoutChildren):
(WebCore::Element::cloneElementWithoutAttributesAndChildren):
* dom/Element.h:
* dom/EntityReference.cpp:
(WebCore::EntityReference::cloneNodeInternal):
* dom/EntityReference.h:
* dom/Node.h:
(WebCore::Node::cloneNode):
* dom/ProcessingInstruction.cpp:
(WebCore::ProcessingInstruction::cloneNodeInternal):
* dom/ProcessingInstruction.h:
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::cloneNodeInternal):
* dom/ShadowRoot.h:
* dom/Text.cpp:
(WebCore::Text::cloneNodeInternal):
* dom/Text.h:
* editing/ApplyStyleCommand.cpp:
(WebCore::ApplyStyleCommand::pushDownInlineStyleAroundNode):
(WebCore::ApplyStyleCommand::applyInlineStyleChange):
* editing/BreakBlockquoteCommand.cpp:
(WebCore::BreakBlockquoteCommand::doApply):
* editing/InsertParagraphSeparatorCommand.cpp:
(WebCore::InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock):
(WebCore::InsertParagraphSeparatorCommand::doApply):
* editing/ModifySelectionListLevel.cpp:
(WebCore::IncreaseSelectionListLevelCommand::doApply):
* editing/SplitElementCommand.cpp:
(WebCore::SplitElementCommand::doApply):
* editing/markup.cpp:
(WebCore::createFragmentFromText):
* html/HTMLKeygenElement.cpp:
* html/HTMLScriptElement.cpp:
(WebCore::HTMLScriptElement::cloneElementWithoutAttributesAndChildren):
* html/HTMLScriptElement.h:
* html/HTMLTemplateElement.cpp:
(WebCore::HTMLTemplateElement::cloneNodeInternal):
* html/HTMLTemplateElement.h:
* html/shadow/SliderThumbElement.cpp:
(WebCore::SliderThumbElement::cloneElementWithoutAttributesAndChildren):
* html/shadow/SliderThumbElement.h:
* html/track/WebVTTElement.cpp:
(WebCore::WebVTTElement::cloneElementWithoutAttributesAndChildren):
* html/track/WebVTTElement.h:
* svg/SVGScriptElement.cpp:
(WebCore::SVGScriptElement::cloneElementWithoutAttributesAndChildren):
* svg/SVGScriptElement.h:
* svg/SVGUseElement.cpp:
(WebCore::SVGUseElement::buildShadowTree):
(WebCore::SVGUseElement::expandUseElementsInShadowTree):

LayoutTests:

Added a regression test.

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

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

46 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLTemplateElement/importNode-nested-templates-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLTemplateElement/importNode-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/editing/ApplyStyleCommand.cpp
Source/WebCore/editing/BreakBlockquoteCommand.cpp
Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp
Source/WebCore/editing/ModifySelectionListLevel.cpp
Source/WebCore/editing/SplitElementCommand.cpp
Source/WebCore/editing/markup.cpp
Source/WebCore/html/HTMLKeygenElement.cpp
Source/WebCore/html/HTMLScriptElement.cpp
Source/WebCore/html/HTMLScriptElement.h
Source/WebCore/html/HTMLTemplateElement.cpp
Source/WebCore/html/HTMLTemplateElement.h
Source/WebCore/html/shadow/SliderThumbElement.cpp
Source/WebCore/html/shadow/SliderThumbElement.h
Source/WebCore/html/track/WebVTTElement.cpp
Source/WebCore/html/track/WebVTTElement.h
Source/WebCore/svg/SVGScriptElement.cpp
Source/WebCore/svg/SVGScriptElement.h
Source/WebCore/svg/SVGUseElement.cpp

index 22a495b..1cab148 100644 (file)
@@ -1,3 +1,15 @@
+2014-12-16  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Nested template contents are not cloned by document.importNode
+        https://bugs.webkit.org/show_bug.cgi?id=137619
+
+        Reviewed by Andreas Kling.
+
+        Added a regression test.
+
+        * fast/dom/HTMLTemplateElement/importNode-nested-templates-expected.txt: Added.
+        * fast/dom/HTMLTemplateElement/importNode-nested-templates.html: Added.
+
 2014-12-16  Alexey Proskuryakov  <ap@apple.com>
 
         WebKit2 test expectations gardening.
diff --git a/LayoutTests/fast/dom/HTMLTemplateElement/importNode-nested-templates-expected.txt b/LayoutTests/fast/dom/HTMLTemplateElement/importNode-nested-templates-expected.txt
new file mode 100644 (file)
index 0000000..35d40dc
--- /dev/null
@@ -0,0 +1,22 @@
+Test that template contents are cloned when the template element is imported via importNode
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+importedOuterTemplate = anotherDocument.importNode(outerTemplate, true)
+PASS outerTemplate.ownerDocument is document
+PASS importedOuterTemplate.ownerDocument is anotherDocument
+PASS importedOuterTemplate.content is not outerTemplate.content
+PASS importedOuterTemplate.content.childNodes.length is 1
+innerTemplate = outerTemplate.content.firstChild
+importedInnerTemplate = importedOuterTemplate.content.firstChild
+PASS importedInnerTemplate.outerHTML is innerTemplate.outerHTML
+PASS innerTemplate.ownerDocument is not importedInnerTemplate.ownerDocument
+PASS importedInnerTemplate.content is not innerTemplate.content
+PASS innerTemplate.content.childNodes.length is 1
+PASS importedInnerTemplate.content.childNodes.length is 1
+PASS innerTemplate.content.firstChild.outerHTML is importedInnerTemplate.content.firstChild.outerHTML
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/HTMLTemplateElement/importNode-nested-templates.html b/LayoutTests/fast/dom/HTMLTemplateElement/importNode-nested-templates.html
new file mode 100644 (file)
index 0000000..e9136bf
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<body>
+<template id="outerTemplate"><template id="innerTemplate"><span>Contents</span></template></template>
+<iframe></iframe>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+
+description('Test that template contents are cloned when the template element is imported via importNode');
+
+if (!window.HTMLTemplateElement)
+    testFailed('This test requires ENABLE(TEMPLATE_ELEMENT)');
+
+var anotherDocument = document.querySelector('iframe').contentDocument;
+
+var outerTemplate = document.getElementById('outerTemplate');
+evalAndLog('importedOuterTemplate = anotherDocument.importNode(outerTemplate, true)');
+shouldBe('outerTemplate.ownerDocument', 'document');
+shouldBe('importedOuterTemplate.ownerDocument', 'anotherDocument');
+shouldNotBe('importedOuterTemplate.content', 'outerTemplate.content');
+shouldBe('importedOuterTemplate.content.childNodes.length', '1');
+evalAndLog('innerTemplate = outerTemplate.content.firstChild');
+evalAndLog('importedInnerTemplate = importedOuterTemplate.content.firstChild');
+shouldBe('importedInnerTemplate.outerHTML', 'innerTemplate.outerHTML');
+shouldNotBe('innerTemplate.ownerDocument', 'importedInnerTemplate.ownerDocument');
+shouldNotBe('importedInnerTemplate.content', 'innerTemplate.content');
+shouldBe('innerTemplate.content.childNodes.length', '1');
+shouldBe('importedInnerTemplate.content.childNodes.length', '1');
+shouldBe('innerTemplate.content.firstChild.outerHTML', 'importedInnerTemplate.content.firstChild.outerHTML');
+
+var successfullyParsed = true;
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 87191da..c92709f 100644 (file)
@@ -1,3 +1,113 @@
+2014-12-16  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Nested template contents are not cloned by document.importNode
+        https://bugs.webkit.org/show_bug.cgi?id=137619
+
+        Reviewed by Andreas Kling.
+
+        The bug was caused by Document.importNode not cloning HTMLTemplateElement's content.
+
+        Fixed the bug by sharing code between Document::importNode and Node::cloneNode by
+        generalizing Node::cloneNodeInternal, added in r177314, by taking the owner document
+        as an argument. The most of code changes are the result of adding this argument.
+
+        Document::importNode is the only function in which the actual logic changes.
+        Note that the code to import TEXT_NODE, CDATA_SECTION_NODE, ENTITY_REFERENCE_NODE,
+        PROCESSING_INSTRUCTION_NODE and COMMENT_NODE nodes are identical to that of cloneNode.
+
+        This patch removes the call to hasValidNamespaceForElements in ELEMENT_NODE but this
+        should not introduce an observable behavior change since all instantiated elements
+        should have a valid namespace in the first place.
+
+        Because DOCUMENT_NODE and DOCUMENT_TYPE_NODE cannot be imported and DOCUMENT_TYPE_NODE
+        can only appear as a direct child of DOCUMENT_NODE, neither nodes nor unimplemented
+        XPATH_NAMESPACE_NODE and XPATH_NAMESPACE_NODE can appear inside the recursive calls
+        for ELEMENT_NODE and DOCUMENT_FRAGMENT_NODE nodes.
+
+        While importNode behaves differently from cloneNode for ATTRIBUTE_NODE, namely that
+        it merges all of its child nodes, this behavior isn't present when recursing inside
+        ELEMENT_NODE and DOCUMENT_FRAGMENT_NODE since we are using cloneDataFromElement.
+
+        Thus there should be no observable behavior changes for DOCUMENT_FRAGMENT_NODE and
+        ELEMENT_NODE nodes either.
+
+        Test: fast/dom/HTMLTemplateElement/importNode-nested-templates.html
+
+        * dom/Attr.cpp:
+        (WebCore::Attr::cloneNodeInternal):
+        * dom/Attr.h:
+        * dom/CDATASection.cpp:
+        (WebCore::CDATASection::cloneNodeInternal):
+        * dom/CDATASection.h:
+        * dom/Comment.cpp:
+        (WebCore::Comment::cloneNodeInternal):
+        * dom/Comment.h:
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::cloneChildNodes):
+        * dom/Document.cpp:
+        (WebCore::Document::importNode):
+        (WebCore::Document::cloneNodeInternal):
+        * dom/Document.h:
+        * dom/DocumentFragment.cpp:
+        (WebCore::DocumentFragment::cloneNodeInternal):
+        * dom/DocumentFragment.h:
+        * dom/DocumentType.cpp:
+        (WebCore::DocumentType::cloneNodeInternal):
+        * dom/DocumentType.h:
+        * dom/Element.cpp:
+        (WebCore::Element::cloneNodeInternal):
+        (WebCore::Element::cloneElementWithChildren):
+        (WebCore::Element::cloneElementWithoutChildren):
+        (WebCore::Element::cloneElementWithoutAttributesAndChildren):
+        * dom/Element.h:
+        * dom/EntityReference.cpp:
+        (WebCore::EntityReference::cloneNodeInternal):
+        * dom/EntityReference.h:
+        * dom/Node.h:
+        (WebCore::Node::cloneNode):
+        * dom/ProcessingInstruction.cpp:
+        (WebCore::ProcessingInstruction::cloneNodeInternal):
+        * dom/ProcessingInstruction.h:
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::cloneNodeInternal):
+        * dom/ShadowRoot.h:
+        * dom/Text.cpp:
+        (WebCore::Text::cloneNodeInternal):
+        * dom/Text.h:
+        * editing/ApplyStyleCommand.cpp:
+        (WebCore::ApplyStyleCommand::pushDownInlineStyleAroundNode):
+        (WebCore::ApplyStyleCommand::applyInlineStyleChange):
+        * editing/BreakBlockquoteCommand.cpp:
+        (WebCore::BreakBlockquoteCommand::doApply):
+        * editing/InsertParagraphSeparatorCommand.cpp:
+        (WebCore::InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock):
+        (WebCore::InsertParagraphSeparatorCommand::doApply):
+        * editing/ModifySelectionListLevel.cpp:
+        (WebCore::IncreaseSelectionListLevelCommand::doApply):
+        * editing/SplitElementCommand.cpp:
+        (WebCore::SplitElementCommand::doApply):
+        * editing/markup.cpp:
+        (WebCore::createFragmentFromText):
+        * html/HTMLKeygenElement.cpp:
+        * html/HTMLScriptElement.cpp:
+        (WebCore::HTMLScriptElement::cloneElementWithoutAttributesAndChildren):
+        * html/HTMLScriptElement.h:
+        * html/HTMLTemplateElement.cpp:
+        (WebCore::HTMLTemplateElement::cloneNodeInternal):
+        * html/HTMLTemplateElement.h:
+        * html/shadow/SliderThumbElement.cpp:
+        (WebCore::SliderThumbElement::cloneElementWithoutAttributesAndChildren):
+        * html/shadow/SliderThumbElement.h:
+        * html/track/WebVTTElement.cpp:
+        (WebCore::WebVTTElement::cloneElementWithoutAttributesAndChildren):
+        * html/track/WebVTTElement.h:
+        * svg/SVGScriptElement.cpp:
+        (WebCore::SVGScriptElement::cloneElementWithoutAttributesAndChildren):
+        * svg/SVGScriptElement.h:
+        * svg/SVGUseElement.cpp:
+        (WebCore::SVGUseElement::buildShadowTree):
+        (WebCore::SVGUseElement::expandUseElementsInShadowTree):
+
 2014-12-16  Tibor Meszaros  <tmeszaros.u-szeged@partner.samsung.com>
 
         Document.contentType implementation
index 0706fd6..afa6eb3 100644 (file)
@@ -137,9 +137,9 @@ void Attr::setNodeValue(const String& v, ExceptionCode& ec)
     setValue(v, ec);
 }
 
-RefPtr<Node> Attr::cloneNodeInternal(CloningOperation)
+RefPtr<Node> Attr::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
-    RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
+    RefPtr<Attr> clone = adoptRef(new Attr(targetDocument, qualifiedName(), value()));
     cloneChildNodes(clone.get());
     return clone.release();
 }
index 3254414..c7a94f9 100644 (file)
@@ -80,7 +80,7 @@ private:
 
     virtual String nodeValue() const override { return value(); }
     virtual void setNodeValue(const String&, ExceptionCode&) override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
 
     virtual bool isAttributeNode() const override { return true; }
     virtual bool childTypeAllowed(NodeType) const override;
index 9f94384..52b9faf 100644 (file)
@@ -46,9 +46,9 @@ Node::NodeType CDATASection::nodeType() const
     return CDATA_SECTION_NODE;
 }
 
-RefPtr<Node> CDATASection::cloneNodeInternal(CloningOperation)
+RefPtr<Node> CDATASection::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
-    return create(document(), data());
+    return create(targetDocument, data());
 }
 
 bool CDATASection::childTypeAllowed(NodeType) const
index b38d206..c78ea8a 100644 (file)
@@ -36,7 +36,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
     virtual RefPtr<Text> virtualCreate(const String&) override;
 };
index 769434a..e0fb717 100644 (file)
@@ -51,9 +51,9 @@ Node::NodeType Comment::nodeType() const
     return COMMENT_NODE;
 }
 
-RefPtr<Node> Comment::cloneNodeInternal(CloningOperation)
+RefPtr<Node> Comment::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
-    return create(document(), data());
+    return create(targetDocument, data());
 }
 
 bool Comment::childTypeAllowed(NodeType) const
index b1254ba..c692806 100644 (file)
@@ -37,7 +37,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 };
 
index d2e7b87..e75087e 100644 (file)
@@ -765,11 +765,12 @@ void ContainerNode::childrenChanged(const ChildChange& change)
     invalidateNodeListAndCollectionCachesInAncestors();
 }
 
-void ContainerNode::cloneChildNodes(ContainerNode *clone)
+void ContainerNode::cloneChildNodes(ContainerNodeclone)
 {
     ExceptionCode ec = 0;
+    Document& targetDocument = clone->document();
     for (Node* child = firstChild(); child && !ec; child = child->nextSibling()) {
-        RefPtr<Node> clonedChild = child->cloneNodeInternal(CloningOperation::SelfWithTemplateContent);
+        RefPtr<Node> clonedChild = child->cloneNodeInternal(targetDocument, CloningOperation::SelfWithTemplateContent);
         clone->appendChild(clonedChild, ec);
 
         if (!ec && is<ContainerNode>(child))
index 8ebe4b7..c3a6f37 100644 (file)
@@ -923,78 +923,32 @@ RefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
 
 RefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec)
 {
-    ec = 0;
-    
     if (!importedNode) {
         ec = NOT_SUPPORTED_ERR;
         return nullptr;
     }
 
     switch (importedNode->nodeType()) {
+    case ELEMENT_NODE:
     case TEXT_NODE:
-        return createTextNode(importedNode->nodeValue());
     case CDATA_SECTION_NODE:
-        return createCDATASection(importedNode->nodeValue(), ec);
     case ENTITY_REFERENCE_NODE:
-        return createEntityReference(importedNode->nodeName(), ec);
     case PROCESSING_INSTRUCTION_NODE:
-        return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec);
     case COMMENT_NODE:
-        return createComment(importedNode->nodeValue());
-    case ELEMENT_NODE: {
-        Element& oldElement = downcast<Element>(*importedNode);
-        // FIXME: The following check might be unnecessary. Is it possible that
-        // oldElement has mismatched prefix/namespace?
-        if (!hasValidNamespaceForElements(oldElement.tagQName())) {
-            ec = NAMESPACE_ERR;
-            return nullptr;
-        }
-
-        RefPtr<Element> newElement = createElement(oldElement.tagQName(), false);
-        newElement->cloneDataFromElement(oldElement);
-
-        if (deep) {
-            for (Node* oldChild = oldElement.firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
-                RefPtr<Node> newChild = importNode(oldChild, true, ec);
-                if (ec)
-                    return nullptr;
-                newElement->appendChild(newChild.release(), ec);
-                if (ec)
-                    return nullptr;
-            }
-        }
+    case DOCUMENT_FRAGMENT_NODE:
+        return importedNode->cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf);
 
-        return newElement.release();
-    }
     case ATTRIBUTE_NODE:
+        // FIXME: This will "Attr::normalize" child nodes of Attr.
         return Attr::create(*this, QualifiedName(nullAtom, downcast<Attr>(*importedNode).name(), nullAtom), downcast<Attr>(*importedNode).value());
-    case DOCUMENT_FRAGMENT_NODE: {
-        if (importedNode->isShadowRoot()) {
-            // ShadowRoot nodes should not be explicitly importable.
-            // Either they are imported along with their host node, or created implicitly.
-            break;
-        }
-        DocumentFragment& oldFragment = downcast<DocumentFragment>(*importedNode);
-        RefPtr<DocumentFragment> newFragment = createDocumentFragment();
-        if (deep) {
-            for (Node* oldChild = oldFragment.firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
-                RefPtr<Node> newChild = importNode(oldChild, true, ec);
-                if (ec)
-                    return nullptr;
-                newFragment->appendChild(newChild.release(), ec);
-                if (ec)
-                    return nullptr;
-            }
-        }
-        
-        return newFragment.release();
-    }
+
+    case DOCUMENT_NODE: // Can't import a document into another document.
+    case DOCUMENT_TYPE_NODE: // FIXME: Support cloning a DocumentType node per DOM4.
+        break;
+
     case ENTITY_NODE:
-        // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
-        // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
-    case DOCUMENT_NODE:
-    case DOCUMENT_TYPE_NODE:
     case XPATH_NAMESPACE_NODE:
+        ASSERT_NOT_REACHED(); // These two types of DOM nodes are not implemented.
         break;
     }
     ec = NOT_SUPPORTED_ERR;
@@ -3207,7 +3161,7 @@ bool Document::canReplaceChild(Node* newChild, Node* oldChild)
     return true;
 }
 
-RefPtr<Node> Document::cloneNodeInternal(CloningOperation type)
+RefPtr<Node> Document::cloneNodeInternal(Document&, CloningOperation type)
 {
     RefPtr<Document> clone = cloneDocumentWithoutChildren();
     clone->cloneDataFromDocument(*this);
index e53a7d8..4a7fef2 100644 (file)
@@ -1311,7 +1311,7 @@ private:
     virtual String nodeName() const override final;
     virtual NodeType nodeType() const override final;
     virtual bool childTypeAllowed(NodeType) const override final;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override final;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override final;
     void cloneDataFromDocument(const Document&);
 
     virtual void refScriptExecutionContext() override final { ref(); }
index 31870c3..6fe0378 100644 (file)
@@ -71,9 +71,9 @@ bool DocumentFragment::childTypeAllowed(NodeType type) const
     }
 }
 
-RefPtr<Node> DocumentFragment::cloneNodeInternal(CloningOperation type)
+RefPtr<Node> DocumentFragment::cloneNodeInternal(Document& targetDocument, CloningOperation type)
 {
-    RefPtr<DocumentFragment> clone = create(document());
+    RefPtr<DocumentFragment> clone = create(targetDocument);
     switch (type) {
     case CloningOperation::OnlySelf:
     case CloningOperation::SelfWithTemplateContent:
index a3d9deb..a9d4e69 100644 (file)
@@ -48,7 +48,7 @@ protected:
 
 private:
     virtual NodeType nodeType() const override final;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 };
 
index e4d096d..67e3d53 100644 (file)
@@ -51,9 +51,9 @@ Node::NodeType DocumentType::nodeType() const
     return DOCUMENT_TYPE_NODE;
 }
 
-RefPtr<Node> DocumentType::cloneNodeInternal(CloningOperation)
+RefPtr<Node> DocumentType::cloneNodeInternal(Document& documentTarget, CloningOperation)
 {
-    return create(document(), m_name, m_publicId, m_systemId);
+    return create(documentTarget, m_name, m_publicId, m_systemId);
 }
 
 }
index 4c0a16d..63f9128 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> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
 
     String m_name;
     String m_publicId;
index 0768c26..8e22f88 100644 (file)
@@ -289,29 +289,29 @@ DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, error);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, focus);
 DEFINE_VIRTUAL_ATTRIBUTE_EVENT_LISTENER(Element, load);
 
-RefPtr<Node> Element::cloneNodeInternal(CloningOperation type)
+RefPtr<Node> Element::cloneNodeInternal(Document& targetDocument, CloningOperation type)
 {
     switch (type) {
     case CloningOperation::OnlySelf:
     case CloningOperation::SelfWithTemplateContent:
-        return cloneElementWithoutChildren();
+        return cloneElementWithoutChildren(targetDocument);
     case CloningOperation::Everything:
-        return cloneElementWithChildren();
+        return cloneElementWithChildren(targetDocument);
     }
     ASSERT_NOT_REACHED();
     return nullptr;
 }
 
-RefPtr<Element> Element::cloneElementWithChildren()
+RefPtr<Element> Element::cloneElementWithChildren(Document& targetDocument)
 {
-    RefPtr<Element> clone = cloneElementWithoutChildren();
+    RefPtr<Element> clone = cloneElementWithoutChildren(targetDocument);
     cloneChildNodes(clone.get());
     return clone.release();
 }
 
-RefPtr<Element> Element::cloneElementWithoutChildren()
+RefPtr<Element> Element::cloneElementWithoutChildren(Document& targetDocument)
 {
-    RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
+    RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren(targetDocument);
     // This will catch HTML elements in the wrong namespace that are not correctly copied.
     // This is a sanity check as HTML overloads some of the DOM methods.
     ASSERT(isHTMLElement() == clone->isHTMLElement());
@@ -320,9 +320,9 @@ RefPtr<Element> Element::cloneElementWithoutChildren()
     return clone.release();
 }
 
-RefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> Element::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
 {
-    return document().createElement(tagQName(), false);
+    return targetDocument.createElement(tagQName(), false);
 }
 
 RefPtr<Attr> Element::detachAttribute(unsigned index)
index a4b0e3b..1a7e1ca 100644 (file)
@@ -267,8 +267,8 @@ public:
 
     virtual String nodeName() const override;
 
-    RefPtr<Element> cloneElementWithChildren();
-    RefPtr<Element> cloneElementWithoutChildren();
+    RefPtr<Element> cloneElementWithChildren(Document&);
+    RefPtr<Element> cloneElementWithoutChildren(Document&);
 
     void normalizeAttributes();
     String nodeNamePreservingCase() const;
@@ -632,8 +632,8 @@ private:
 
     // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
     // are used instead.
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren();
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&);
 
     void addShadowRoot(PassRefPtr<ShadowRoot>);
     void removeShadowRoot();
index bf6a332..88ad688 100644 (file)
@@ -46,9 +46,9 @@ Node::NodeType EntityReference::nodeType() const
     return ENTITY_REFERENCE_NODE;
 }
 
-RefPtr<Node> EntityReference::cloneNodeInternal(CloningOperation)
+RefPtr<Node> EntityReference::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
-    return create(document(), m_entityName);
+    return create(targetDocument, m_entityName);
 }
 
 } // namespace
index a56347a..5e8da8d 100644 (file)
@@ -35,7 +35,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
 
     String m_entityName;
 };
index af19de1..cc18cd7 100644 (file)
@@ -209,8 +209,8 @@ public:
         SelfWithTemplateContent,
         Everything,
     };
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) = 0;
-    RefPtr<Node> cloneNode(bool deep) { return cloneNodeInternal(deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) = 0;
+    RefPtr<Node> cloneNode(bool deep) { return cloneNodeInternal(document(), deep ? CloningOperation::Everything : CloningOperation::OnlySelf); }
 
     virtual const AtomicString& localName() const;
     virtual const AtomicString& namespaceURI() const;
index f0ef9dc..ec8fa19 100644 (file)
@@ -79,11 +79,11 @@ Node::NodeType ProcessingInstruction::nodeType() const
     return PROCESSING_INSTRUCTION_NODE;
 }
 
-RefPtr<Node> ProcessingInstruction::cloneNodeInternal(CloningOperation)
+RefPtr<Node> ProcessingInstruction::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
     // FIXME: Is it a problem that this does not copy m_localHref?
     // What about other data members?
-    return create(document(), m_target, data());
+    return create(targetDocument, m_target, data());
 }
 
 void ProcessingInstruction::checkStyleSheet()
index 05b0cfa..ab82f26 100644 (file)
@@ -58,7 +58,7 @@ private:
 
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
 
     virtual InsertionNotificationRequest insertedInto(ContainerNode&) override;
     virtual void removedFrom(ContainerNode&) override;
index 6776437..ebfa4ca 100644 (file)
@@ -131,7 +131,7 @@ void ShadowRoot::childrenChanged(const ChildChange& change)
     invalidateDistribution();
 }
 
-RefPtr<Node> ShadowRoot::cloneNodeInternal(CloningOperation)
+RefPtr<Node> ShadowRoot::cloneNodeInternal(Document&, CloningOperation)
 {
     return nullptr; // ShadowRoots should never be cloned.
 }
index 5eea892..e1f88a6 100644 (file)
@@ -76,7 +76,7 @@ private:
     virtual bool childTypeAllowed(NodeType) const override;
     virtual void childrenChanged(const ChildChange&) override;
 
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
 
     // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
     bool isOrphan() const { return !hostElement(); }
index d0f3a71..70697a4 100644 (file)
@@ -169,9 +169,9 @@ Node::NodeType Text::nodeType() const
     return TEXT_NODE;
 }
 
-RefPtr<Node> Text::cloneNodeInternal(CloningOperation)
+RefPtr<Node> Text::cloneNodeInternal(Document& targetDocument, CloningOperation)
 {
-    return create(document(), data());
+    return create(targetDocument, data());
 }
 
 static bool isSVGShadowText(Text* text)
index 532bd3c..2b3d407 100644 (file)
@@ -64,7 +64,7 @@ protected:
 private:
     virtual String nodeName() const override;
     virtual NodeType nodeType() const override;
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
     virtual bool childTypeAllowed(NodeType) const override;
 
     virtual RefPtr<Text> virtualCreate(const String&);
index 1117874..5ccf92d 100644 (file)
@@ -1060,7 +1060,7 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(EditingStyle* style, Node*
                 continue;
             if (!child.contains(targetNode) && elementsToPushDown.size()) {
                 for (size_t i = 0; i < elementsToPushDown.size(); i++) {
-                    RefPtr<Element> wrapper = elementsToPushDown[i]->cloneElementWithoutChildren();
+                    RefPtr<Element> wrapper = elementsToPushDown[i]->cloneElementWithoutChildren(document());
                     wrapper->removeAttribute(styleAttr);
                     surroundNodeRangeWithElement(&child, &child, wrapper);
                 }
@@ -1504,7 +1504,7 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
         surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), supTag));
 
     if (m_styledInlineElement && addStyledElement == AddStyledElement)
-        surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElementWithoutChildren());
+        surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElementWithoutChildren(document()));
 }
 
 float ApplyStyleCommand::computedFontSize(Node* node)
index 294adb6..f6fb4aa 100644 (file)
@@ -131,7 +131,7 @@ void BreakBlockquoteCommand::doApply()
         ancestors.append(node);
     
     // Insert a clone of the top blockquote after the break.
-    RefPtr<Element> clonedBlockquote = downcast<Element>(*topBlockquote).cloneElementWithoutChildren();
+    RefPtr<Element> clonedBlockquote = downcast<Element>(*topBlockquote).cloneElementWithoutChildren(document());
     insertNodeAfter(clonedBlockquote.get(), breakNode.get());
     
     // Clone startNode's ancestors into the cloned blockquote.
@@ -140,7 +140,7 @@ void BreakBlockquoteCommand::doApply()
     // or clonedBlockquote if ancestors is empty).
     RefPtr<Element> clonedAncestor = clonedBlockquote;
     for (size_t i = ancestors.size(); i != 0; --i) {
-        RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
+        RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren(document());
         // Preserve list item numbering in cloned lists.
         if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) {
             Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode;
index 606117b..82ec534 100644 (file)
@@ -136,7 +136,7 @@ PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock
     // Make clones of ancestors in between the start node and the start block.
     RefPtr<Element> parent = blockToInsert;
     for (size_t i = ancestors.size(); i != 0; --i) {
-        RefPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren();
+        RefPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren(document());
         // It should always be okay to remove id from the cloned elements, since the originals are not deleted.
         child->removeAttribute(idAttr);
         appendNode(child, parent);
@@ -207,7 +207,7 @@ void InsertParagraphSeparatorCommand::doApply()
     } else if (shouldUseDefaultParagraphElement(startBlock.get())) 
         blockToInsert = createDefaultParagraphElement(document());
     else
-        blockToInsert = startBlock->cloneElementWithoutChildren();
+        blockToInsert = startBlock->cloneElementWithoutChildren(document());
 
     //---------------------------------------------------------------------
     // Handle case when position is in the last visible position in its block,
index dfce553..837ab68 100644 (file)
@@ -187,7 +187,7 @@ void IncreaseSelectionListLevelCommand::doApply()
             case InheritedListType:
                 newParent = startListChild->parentElement();
                 if (newParent)
-                    newParent = newParent->cloneElementWithoutChildren();
+                    newParent = newParent->cloneElementWithoutChildren(document());
                 break;
             case OrderedList:
                 newParent = createOrderedListElement(document());
index 92e3b93..09beb85 100644 (file)
@@ -70,7 +70,7 @@ void SplitElementCommand::executeApply()
     
 void SplitElementCommand::doApply()
 {
-    m_element1 = m_element2->cloneElementWithoutChildren();
+    m_element1 = m_element2->cloneElementWithoutChildren(document());
     
     executeApply();
 }
index 9623c28..e8dd860 100644 (file)
@@ -798,7 +798,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range& context, const String
             fillContainerFromString(fragment.get(), s);
         } else {
             if (useClonesOfEnclosingBlock)
-                element = block->cloneElementWithoutChildren();
+                element = block->cloneElementWithoutChildren(document);
             else
                 element = createDefaultParagraphElement(document);
             fillContainerFromString(element.get(), s);
index 86f9a6c..d398ead 100644 (file)
@@ -58,9 +58,9 @@ protected:
     }
 
 private:
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document& targetDocument) override
     {
-        return create(document());
+        return create(targetDocument);
     }
 };
 
index a67eb18..6832668 100644 (file)
@@ -168,9 +168,9 @@ void HTMLScriptElement::dispatchLoadEvent()
     dispatchEvent(Event::create(eventNames().loadEvent, false, false));
 }
 
-RefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
 {
-    return adoptRef(new HTMLScriptElement(tagQName(), document(), false, alreadyStarted()));
+    return adoptRef(new HTMLScriptElement(tagQName(), targetDocument, false, alreadyStarted()));
 }
 
 }
index e0ee7b9..acf609b 100644 (file)
@@ -64,7 +64,7 @@ private:
 
     virtual void dispatchLoadEvent() override;
 
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
 };
 
 } //namespace
index dc752ee..a42016f 100644 (file)
@@ -68,17 +68,17 @@ DocumentFragment* HTMLTemplateElement::content() const
     return m_content.get();
 }
 
-RefPtr<Node> HTMLTemplateElement::cloneNodeInternal(CloningOperation type)
+RefPtr<Node> HTMLTemplateElement::cloneNodeInternal(Document& targetDocument, CloningOperation type)
 {
     RefPtr<Node> clone;
     switch (type) {
     case CloningOperation::OnlySelf:
-        return cloneElementWithoutChildren();
+        return cloneElementWithoutChildren(targetDocument);
     case CloningOperation::SelfWithTemplateContent:
-        clone = cloneElementWithoutChildren();
+        clone = cloneElementWithoutChildren(targetDocument);
         break;
     case CloningOperation::Everything:
-        clone = cloneElementWithChildren();
+        clone = cloneElementWithChildren(targetDocument);
         break;
     }
     if (m_content)
index d96d69a..f79646b 100644 (file)
@@ -50,7 +50,7 @@ public:
 private:
     HTMLTemplateElement(const QualifiedName&, Document&);
 
-    virtual RefPtr<Node> cloneNodeInternal(CloningOperation) override;
+    virtual RefPtr<Node> cloneNodeInternal(Document&, CloningOperation) override;
     virtual void didMoveToNewDocument(Document* oldDocument) override;
 
     mutable RefPtr<TemplateContentDocumentFragment> m_content;
index b4c6ae0..5470165 100644 (file)
@@ -598,9 +598,9 @@ const AtomicString& SliderThumbElement::shadowPseudoId() const
     }
 }
 
-RefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
 {
-    return create(document());
+    return create(targetDocument);
 }
 
 // --------------------------------
index 721cec3..85a6e3d 100644 (file)
@@ -62,7 +62,7 @@ private:
     SliderThumbElement(Document&);
 
     virtual RenderPtr<RenderElement> createElementRenderer(Ref<RenderStyle>&&) override;
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
     virtual bool isDisabledFormControl() const override;
     virtual bool matchesReadWritePseudoClass() const override;
     virtual Element* focusDelegate() override;
index a947955..485acbb 100644 (file)
@@ -80,9 +80,9 @@ PassRefPtr<WebVTTElement> WebVTTElement::create(WebVTTNodeType nodeType, Documen
     return adoptRef(new WebVTTElement(nodeType, document));
 }
 
-RefPtr<Element> WebVTTElement::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> WebVTTElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
 {
-    RefPtr<WebVTTElement> clone = create(static_cast<WebVTTNodeType>(m_webVTTNodeType), document());
+    RefPtr<WebVTTElement> clone = create(static_cast<WebVTTNodeType>(m_webVTTNodeType), targetDocument);
     clone->setLanguage(m_language);
     return clone;
 }
index 42a75fa..15965c8 100644 (file)
@@ -46,7 +46,7 @@ public:
     static PassRefPtr<WebVTTElement> create(const WebVTTNodeType, Document&);
     PassRefPtr<HTMLElement> createEquivalentHTMLElement(Document&);
 
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
 
     void setWebVTTNodeType(WebVTTNodeType type) { m_webVTTNodeType = static_cast<unsigned>(type); }
     WebVTTNodeType webVTTNodeType() const { return static_cast<WebVTTNodeType>(m_webVTTNodeType); }
index b33dbf7..b7fddda 100644 (file)
@@ -192,9 +192,9 @@ bool SVGScriptElement::hasSourceAttribute() const
     return hasAttribute(XLinkNames::hrefAttr);
 }
 
-RefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
 {
-    return adoptRef(new SVGScriptElement(tagQName(), document(), false, alreadyStarted()));
+    return adoptRef(new SVGScriptElement(tagQName(), targetDocument, false, alreadyStarted()));
 }
 
 #ifndef NDEBUG
index aac99c6..7761e8c 100644 (file)
@@ -65,7 +65,7 @@ private:
 
     virtual void dispatchLoadEvent() override { SVGExternalResourcesRequired::dispatchLoadEvent(this); }
 
-    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
+    virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
     virtual bool rendererIsNeeded(const RenderStyle&) override { return false; }
 
     // SVGExternalResourcesRequired
index 7ce3add..cef15bf 100644 (file)
@@ -685,7 +685,7 @@ void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targ
     if (isDisallowedElement(*target))
         return;
 
-    RefPtr<SVGElement> newChild = static_pointer_cast<SVGElement>(targetInstance->correspondingElement()->cloneElementWithChildren());
+    RefPtr<SVGElement> newChild = static_pointer_cast<SVGElement>(targetInstance->correspondingElement()->cloneElementWithChildren(document()));
 
     // We don't walk the target tree element-by-element, and clone each element,
     // but instead use cloneElementWithChildren(). This is an optimization for the common
@@ -727,7 +727,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
         transferUseAttributesToReplacedElement(&use, cloneParent.get());
 
         if (target && !isDisallowedElement(*target)) {
-            RefPtr<Element> newChild = target->cloneElementWithChildren();
+            RefPtr<Element> newChild = target->cloneElementWithChildren(document());
             ASSERT(newChild->isSVGElement());
             cloneParent->appendChild(newChild.release());
         }