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: https://svn.webkit.org/repository/webkit/trunk@177372
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+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.
--- /dev/null
+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
+
--- /dev/null
+<!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>
+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
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();
}
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;
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
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;
};
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
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;
};
invalidateNodeListAndCollectionCachesInAncestors();
}
-void ContainerNode::cloneChildNodes(ContainerNode *clone)
+void ContainerNode::cloneChildNodes(ContainerNode* clone)
{
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))
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;
return true;
}
-RefPtr<Node> Document::cloneNodeInternal(CloningOperation type)
+RefPtr<Node> Document::cloneNodeInternal(Document&, CloningOperation type)
{
RefPtr<Document> clone = cloneDocumentWithoutChildren();
clone->cloneDataFromDocument(*this);
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(); }
}
}
-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:
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;
};
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);
}
}
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;
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());
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)
virtual String nodeName() const override;
- RefPtr<Element> cloneElementWithChildren();
- RefPtr<Element> cloneElementWithoutChildren();
+ RefPtr<Element> cloneElementWithChildren(Document&);
+ RefPtr<Element> cloneElementWithoutChildren(Document&);
void normalizeAttributes();
String nodeNamePreservingCase() const;
// 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();
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
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;
};
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;
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()
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;
invalidateDistribution();
}
-RefPtr<Node> ShadowRoot::cloneNodeInternal(CloningOperation)
+RefPtr<Node> ShadowRoot::cloneNodeInternal(Document&, CloningOperation)
{
return nullptr; // ShadowRoots should never be cloned.
}
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(); }
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)
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&);
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);
}
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)
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.
// 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;
// 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);
} 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,
case InheritedListType:
newParent = startListChild->parentElement();
if (newParent)
- newParent = newParent->cloneElementWithoutChildren();
+ newParent = newParent->cloneElementWithoutChildren(document());
break;
case OrderedList:
newParent = createOrderedListElement(document());
void SplitElementCommand::doApply()
{
- m_element1 = m_element2->cloneElementWithoutChildren();
+ m_element1 = m_element2->cloneElementWithoutChildren(document());
executeApply();
}
fillContainerFromString(fragment.get(), s);
} else {
if (useClonesOfEnclosingBlock)
- element = block->cloneElementWithoutChildren();
+ element = block->cloneElementWithoutChildren(document);
else
element = createDefaultParagraphElement(document);
fillContainerFromString(element.get(), s);
}
private:
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override
+ virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document& targetDocument) override
{
- return create(document());
+ return create(targetDocument);
}
};
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()));
}
}
virtual void dispatchLoadEvent() override;
- virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren() override;
+ virtual RefPtr<Element> cloneElementWithoutAttributesAndChildren(Document&) override;
};
} //namespace
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)
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;
}
}
-RefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
+RefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
{
- return create(document());
+ return create(targetDocument);
}
// --------------------------------
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;
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;
}
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); }
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
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
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
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());
}