Move TreeScope::adoptIfNeeded to Node and rename it to setTreeScopeRecursively
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jun 2017 08:59:22 +0000 (08:59 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 9 Jun 2017 08:59:22 +0000 (08:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=173129

Reviewed by Antti Koivisto.

Renamed TreeScope::adoptIfNeeded to setTreeScopeRecursively and moved to Node.

The old name was really confusing because due to the existence of Document::adoptNode, a DOM API,
which removes the adopted node from its parent if there was one before adopting the node.
Most confusingly, this function called TreeScope::adoptIfNeeded.

Also inlined the tree scope check to avoid calling to moveTreeToNewScope when there is nothing to do.

This patch effectively reverts r104528.

No new tests. Existing tests cover this.

* dom/Attr.cpp:
(WebCore::Attr::detachFromElementWithValue):
(WebCore::Attr::attachToElement):
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::takeAllChildrenFrom):
(WebCore::ContainerNode::insertBefore):
(WebCore::ContainerNode::replaceChild):
(WebCore::ContainerNode::removeBetween):
(WebCore::ContainerNode::replaceAllChildren):
(WebCore::ContainerNode::appendChildWithoutPreInsertionValidityCheck):
(WebCore::ContainerNode::parserAppendChild):
* dom/ContainerNodeAlgorithms.cpp:
(WebCore::addChildNodesToDeletionQueue):
* dom/Document.cpp:
(WebCore::Document::adoptNode):
* dom/Element.cpp:
(WebCore::Element::ensureAttr):
* dom/Node.cpp:
(WebCore::DidMoveToNewDocumentAssertionScope): Added. The old assertion wasn't sufficient when
HTMLTemplateElement made a recursive call to setTreeScopeRecursively.
(WebCore::DidMoveToNewDocumentAssertionScope::DidMoveToNewDocumentAssertionScope):
(WebCore::DidMoveToNewDocumentAssertionScope::~DidMoveToNewDocumentAssertionScope):
(WebCore::DidMoveToNewDocumentAssertionScope::didRecieveCall):
(WebCore::moveNodeToNewDocument): Moved from TreeScope. Calls to incrementReferencingNodeCount
and decrementReferencingNodeCount to Node::didMoveToNewDocument. This function is now eliminated
in a release build.
(WebCore::moveShadowTreeToNewDocument): Moved from TreeScope.
(WebCore::Node::moveTreeToNewScope): Ditto.
(WebCore::Node::didMoveToNewDocument): See the description for moveNodeToNewDocument above.
* dom/Node.h:
(WebCore::Node::isParsingChildrenFinished): Moved to avoid having its own protected section.
(WebCore::Node::setIsParsingChildrenFinished): Ditto.
(WebCore::Node::clearIsParsingChildrenFinished): Ditto.
(WebCore::Node::setTreeScopeRecursively): Moved from TreeScope::adoptIfNeeded.
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::~ShadowRoot):
* dom/TreeScope.cpp:
(WebCore::TreeScope::adoptIfNeeded): Deleted.
(WebCore::TreeScope::moveTreeToNewScope): Deleted.
(WebCore::TreeScope::ensureDidMoveToNewDocumentWasCalled): Deleted.
(WebCore::TreeScope::moveNodeToNewDocument): Deleted.
(WebCore::TreeScope::moveShadowTreeToNewDocument): Deleted.
* dom/TreeScope.h:
* html/HTMLTemplateElement.cpp:
(WebCore::HTMLTemplateElement::didMoveToNewDocument):

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

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Attr.cpp
Source/WebCore/dom/ContainerNode.cpp
Source/WebCore/dom/ContainerNodeAlgorithms.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/ShadowRoot.cpp
Source/WebCore/dom/TreeScope.cpp
Source/WebCore/dom/TreeScope.h
Source/WebCore/html/HTMLTemplateElement.cpp

index 1cf3b75..ab7c3f6 100644 (file)
@@ -1,3 +1,68 @@
+2017-06-08  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Move TreeScope::adoptIfNeeded to Node and rename it to setTreeScopeRecursively
+        https://bugs.webkit.org/show_bug.cgi?id=173129
+
+        Reviewed by Antti Koivisto.
+
+        Renamed TreeScope::adoptIfNeeded to setTreeScopeRecursively and moved to Node.
+
+        The old name was really confusing because due to the existence of Document::adoptNode, a DOM API,
+        which removes the adopted node from its parent if there was one before adopting the node.
+        Most confusingly, this function called TreeScope::adoptIfNeeded.
+
+        Also inlined the tree scope check to avoid calling to moveTreeToNewScope when there is nothing to do.
+
+        This patch effectively reverts r104528.
+
+        No new tests. Existing tests cover this.
+
+        * dom/Attr.cpp:
+        (WebCore::Attr::detachFromElementWithValue):
+        (WebCore::Attr::attachToElement):
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::takeAllChildrenFrom):
+        (WebCore::ContainerNode::insertBefore):
+        (WebCore::ContainerNode::replaceChild):
+        (WebCore::ContainerNode::removeBetween):
+        (WebCore::ContainerNode::replaceAllChildren):
+        (WebCore::ContainerNode::appendChildWithoutPreInsertionValidityCheck):
+        (WebCore::ContainerNode::parserAppendChild):
+        * dom/ContainerNodeAlgorithms.cpp:
+        (WebCore::addChildNodesToDeletionQueue):
+        * dom/Document.cpp:
+        (WebCore::Document::adoptNode):
+        * dom/Element.cpp:
+        (WebCore::Element::ensureAttr):
+        * dom/Node.cpp:
+        (WebCore::DidMoveToNewDocumentAssertionScope): Added. The old assertion wasn't sufficient when
+        HTMLTemplateElement made a recursive call to setTreeScopeRecursively.
+        (WebCore::DidMoveToNewDocumentAssertionScope::DidMoveToNewDocumentAssertionScope):
+        (WebCore::DidMoveToNewDocumentAssertionScope::~DidMoveToNewDocumentAssertionScope):
+        (WebCore::DidMoveToNewDocumentAssertionScope::didRecieveCall):
+        (WebCore::moveNodeToNewDocument): Moved from TreeScope. Calls to incrementReferencingNodeCount
+        and decrementReferencingNodeCount to Node::didMoveToNewDocument. This function is now eliminated
+        in a release build.
+        (WebCore::moveShadowTreeToNewDocument): Moved from TreeScope.
+        (WebCore::Node::moveTreeToNewScope): Ditto.
+        (WebCore::Node::didMoveToNewDocument): See the description for moveNodeToNewDocument above.
+        * dom/Node.h:
+        (WebCore::Node::isParsingChildrenFinished): Moved to avoid having its own protected section.
+        (WebCore::Node::setIsParsingChildrenFinished): Ditto.
+        (WebCore::Node::clearIsParsingChildrenFinished): Ditto.
+        (WebCore::Node::setTreeScopeRecursively): Moved from TreeScope::adoptIfNeeded.
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::~ShadowRoot):
+        * dom/TreeScope.cpp:
+        (WebCore::TreeScope::adoptIfNeeded): Deleted.
+        (WebCore::TreeScope::moveTreeToNewScope): Deleted.
+        (WebCore::TreeScope::ensureDidMoveToNewDocumentWasCalled): Deleted.
+        (WebCore::TreeScope::moveNodeToNewDocument): Deleted.
+        (WebCore::TreeScope::moveShadowTreeToNewDocument): Deleted.
+        * dom/TreeScope.h:
+        * html/HTMLTemplateElement.cpp:
+        (WebCore::HTMLTemplateElement::didMoveToNewDocument):
+
 2017-06-09  Adrien Plazas  <aplazas@igalia.com>
 
         [GTK] Add kinetic scrolling
index c0cbdc3..2e1e64e 100644 (file)
@@ -135,7 +135,7 @@ void Attr::detachFromElementWithValue(const AtomicString& value)
     ASSERT(m_standaloneValue.isNull());
     m_standaloneValue = value;
     m_element = nullptr;
-    document().adoptIfNeeded(*this);
+    setTreeScopeRecursively(document());
 }
 
 void Attr::attachToElement(Element& element)
@@ -143,7 +143,7 @@ void Attr::attachToElement(Element& element)
     ASSERT(!m_element);
     m_element = &element;
     m_standaloneValue = nullAtom;
-    element.treeScope().adoptIfNeeded(*this);
+    setTreeScopeRecursively(element.treeScope());
 }
 
 }
index e9ed30d..b6c5483 100644 (file)
@@ -150,7 +150,7 @@ void ContainerNode::takeAllChildrenFrom(ContainerNode* oldParent)
     for (auto& child : children) {
         RELEASE_ASSERT(!child->parentNode() && &child->treeScope() == &treeScope());
         ASSERT(!ensurePreInsertionValidity(child, nullptr).hasException());
-        treeScope().adoptIfNeeded(child);
+        child->setTreeScopeRecursively(treeScope());
         parserAppendChild(child);
     }
 }
@@ -290,7 +290,7 @@ ExceptionOr<void> ContainerNode::insertBefore(Node& newChild, Node* refChild)
         {
             NoEventDispatchAssertion assertNoEventDispatch;
 
-            treeScope().adoptIfNeeded(child);
+            child->setTreeScopeRecursively(treeScope());
             insertBeforeCommon(next, child);
         }
 
@@ -466,7 +466,7 @@ ExceptionOr<void> ContainerNode::replaceChild(Node& newChild, Node& oldChild)
 
         {
             NoEventDispatchAssertion assertNoEventDispatch;
-            treeScope().adoptIfNeeded(child);
+            child->setTreeScopeRecursively(treeScope());
             if (refChild)
                 insertBeforeCommon(*refChild, child.get());
             else
@@ -587,7 +587,7 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
     ASSERT(!oldChild.nextSibling());
     oldChild.setParentNode(nullptr);
 
-    document().adoptIfNeeded(oldChild);
+    oldChild.setTreeScopeRecursively(document());
 }
 
 void ContainerNode::parserRemoveChild(Node& oldChild)
@@ -641,7 +641,7 @@ void ContainerNode::replaceAllChildren(Ref<Node>&& node)
     ChildListMutationScope mutation(*this);
 
     // If node is not null, adopt node into parent's node document.
-    treeScope().adoptIfNeeded(node);
+    node->setTreeScopeRecursively(treeScope());
 
     // Remove all parent's children, in tree order.
     willRemoveChildren(*this);
@@ -756,7 +756,7 @@ ExceptionOr<void> ContainerNode::appendChildWithoutPreInsertionValidityCheck(Nod
         // Append child to the end of the list
         {
             NoEventDispatchAssertion assertNoEventDispatch;
-            treeScope().adoptIfNeeded(child);
+            child->setTreeScopeRecursively(treeScope());
             appendChildCommon(child);
         }
 
@@ -780,7 +780,7 @@ void ContainerNode::parserAppendChild(Node& newChild)
             document().adoptNode(newChild);
 
         appendChildCommon(newChild);
-        treeScope().adoptIfNeeded(newChild);
+        newChild.setTreeScopeRecursively(treeScope());
     }
 
     newChild.updateAncestorConnectedSubframeCountForInsertion();
index bb75784..646dc29 100644 (file)
@@ -179,7 +179,7 @@ void addChildNodesToDeletionQueue(Node*& head, Node*& tail, ContainerNode& conta
             tail = node;
         } else {
             Ref<Node> protect(*node); // removedFromDocument may remove remove all references to this node.
-            container.document().adoptIfNeeded(*node);
+            node->setTreeScopeRecursively(container.document());
             if (node->isInTreeScope())
                 notifyChildNodeRemoved(container, *node);
             ASSERT_WITH_SECURITY_IMPLICATION(!node->isInTreeScope());
index 8ed6434..12b35ae 100644 (file)
@@ -991,7 +991,7 @@ ExceptionOr<Ref<Node>> Document::adoptNode(Node& source)
         ASSERT_WITH_SECURITY_IMPLICATION(!source.parentNode());
     }
 
-    adoptIfNeeded(source);
+    source.setTreeScopeRecursively(*this);
 
     return Ref<Node> { source };
 }
index e28d60d..82e4027 100644 (file)
@@ -3412,7 +3412,7 @@ Ref<Attr> Element::ensureAttr(const QualifiedName& name)
     RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
     if (!attrNode) {
         attrNode = Attr::create(*this, name);
-        treeScope().adoptIfNeeded(*attrNode);
+        attrNode->setTreeScopeRecursively(treeScope());
         attrNodeList.append(attrNode);
     }
     return attrNode.releaseNonNull();
index 103e47a..74db8b7 100644 (file)
@@ -1922,10 +1922,127 @@ EventTargetInterface Node::eventTargetInterface() const
     return NodeEventTargetInterfaceType;
 }
 
+#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
+class DidMoveToNewDocumentAssertionScope {
+public:
+    DidMoveToNewDocumentAssertionScope(Node& node, Document& oldDocument, Document& newDocument)
+        : m_node(node)
+        , m_oldDocument(oldDocument)
+        , m_newDocument(newDocument)
+        , m_previousScope(s_scope)
+    {
+        s_scope = this;
+    }
+
+    ~DidMoveToNewDocumentAssertionScope()
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(m_called);
+        s_scope = m_previousScope;
+    }
+
+    static void didRecieveCall(Node& node, Document& oldDocument, Document& newDocument)
+    {
+        ASSERT_WITH_SECURITY_IMPLICATION(s_scope);
+        ASSERT_WITH_SECURITY_IMPLICATION(!s_scope->m_called);
+        ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_node == &node);
+        ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_oldDocument == &oldDocument);
+        ASSERT_WITH_SECURITY_IMPLICATION(&s_scope->m_newDocument == &newDocument);
+        s_scope->m_called = true;
+    }
+
+private:
+    Node& m_node;
+    Document& m_oldDocument;
+    Document& m_newDocument;
+    bool m_called { false };
+    DidMoveToNewDocumentAssertionScope* m_previousScope;
+
+    static DidMoveToNewDocumentAssertionScope* s_scope;
+};
+
+DidMoveToNewDocumentAssertionScope* DidMoveToNewDocumentAssertionScope::s_scope = nullptr;
+
+#else
+class DidMoveToNewDocumentAssertionScope {
+public:
+    DidMoveToNewDocumentAssertionScope(Node&, Document&, Document&) { }
+    static void didRecieveCall(Node&, Document&, Document&) { }
+};
+#endif
+
+static ALWAYS_INLINE void moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument)
+{
+    ASSERT(!node.isConnected() || &oldDocument != &newDocument);
+    DidMoveToNewDocumentAssertionScope scope(node, oldDocument, newDocument);
+    node.didMoveToNewDocument(oldDocument, newDocument);
+}
+
+static void moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)
+{
+    for (Node* node = &shadowRoot; node; node = NodeTraversal::next(*node, &shadowRoot)) {
+        moveNodeToNewDocument(*node, oldDocument, newDocument);
+        if (auto* shadow = node->shadowRoot())
+            moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);
+    }
+}
+
+void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope)
+{
+    ASSERT(&oldScope != &newScope);
+    ASSERT_WITH_SECURITY_IMPLICATION(&root.treeScope() == &oldScope);
+
+    // If an element is moved from a document and then eventually back again the collection cache for
+    // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
+    // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
+    // we ensure that the collection cache will be invalidated as needed when the element is moved back.
+    Document& oldDocument = oldScope.documentScope();
+    Document& newDocument = newScope.documentScope();
+    bool shouldUpdateDocumentScope = &oldDocument != &newDocument;
+    if (shouldUpdateDocumentScope) {
+        oldDocument.incrementReferencingNodeCount();
+        oldDocument.incDOMTreeVersion();
+    }
+
+    for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+        ASSERT(!node->isTreeScope());
+        ASSERT(&node->treeScope() == &oldScope);
+        node->setTreeScope(newScope);
+
+        if (shouldUpdateDocumentScope)
+            moveNodeToNewDocument(*node, oldDocument, newDocument);
+        else if (node->hasRareData()) {
+            if (auto* nodeLists = node->rareData()->nodeLists())
+                nodeLists->adoptTreeScope();
+        }
+
+        if (!is<Element>(*node))
+            continue;
+        Element& element = downcast<Element>(*node);
+
+        if (element.hasSyntheticAttrChildNodes()) {
+            for (auto& attr : element.attrNodeList())
+                moveTreeToNewScope(*attr, oldScope, newScope);
+        }
+
+        if (auto* shadow = element.shadowRoot()) {
+            ASSERT_WITH_SECURITY_IMPLICATION(&shadow->document() == &oldDocument);
+            shadow->setParentTreeScope(newScope);
+            if (shouldUpdateDocumentScope)
+                moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);
+        }
+    }
+
+    if (shouldUpdateDocumentScope)
+        oldDocument.decrementReferencingNodeCount();
+}
+
 void Node::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument);
-    TreeScope::ensureDidMoveToNewDocumentWasCalled(oldDocument);
+    DidMoveToNewDocumentAssertionScope::didRecieveCall(*this, oldDocument, newDocument);
+
+    newDocument.incrementReferencingNodeCount();
+    oldDocument.decrementReferencingNodeCount();
 
     if (hasRareData()) {
         if (auto* nodeLists = rareData()->nodeLists())
index c18b818..23dc9db 100644 (file)
@@ -369,6 +369,7 @@ public:
         ASSERT(m_treeScope);
         return *m_treeScope;
     }
+    void setTreeScopeRecursively(TreeScope&);
     static ptrdiff_t treeScopeMemoryOffset() { return OBJECT_OFFSETOF(Node, m_treeScope); }
 
     // Returns true if this node is associated with a document and is in its associated document's
@@ -490,6 +491,8 @@ public:
     EventTargetInterface eventTargetInterface() const override;
     ScriptExecutionContext* scriptExecutionContext() const final; // Implemented in Document.h
 
+    virtual void didMoveToNewDocument(Document& oldDocument, Document& newDocument);
+
     bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
     bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
 
@@ -614,6 +617,10 @@ protected:
     void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; } 
     void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
 
+    bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
+    void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
+    void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
+
     enum ConstructionType {
         CreateOther = DefaultNodeFlags,
         CreateText = DefaultNodeFlags | IsTextFlag,
@@ -631,8 +638,6 @@ protected:
     };
     Node(Document&, ConstructionType);
 
-    virtual void didMoveToNewDocument(Document& oldDocument, Document& newDocument);
-    
     virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const { }
 
     bool hasRareData() const { return getFlag(HasRareDataFlag); }
@@ -671,9 +676,11 @@ private:
     HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
 
     void adjustStyleValidity(Style::Validity, Style::InvalidationMode);
-    
+
     void* opaqueRootSlow() const;
 
+    static void moveTreeToNewScope(Node&, TreeScope& oldScope, TreeScope& newScope);
+
     int m_refCount;
     mutable uint32_t m_nodeFlags;
 
@@ -686,11 +693,6 @@ private:
         RenderObject* m_renderer;
         NodeRareDataBase* m_rareData;
     } m_data { nullptr };
-
-protected:
-    bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
-    void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
-    void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
 };
 
 #ifndef NDEBUG
@@ -790,6 +792,14 @@ inline void Node::setHasValidStyle()
     clearFlag(StyleResolutionShouldRecompositeLayerFlag);
 }
 
+inline void Node::setTreeScopeRecursively(TreeScope& newTreeScope)
+{
+    ASSERT(!isDocumentNode());
+    ASSERT(!m_deletionHasBegun);
+    if (m_treeScope != &newTreeScope)
+        moveTreeToNewScope(*this, *m_treeScope, newTreeScope);
+}
+
 } // namespace WebCore
 
 #if ENABLE(TREE_DEBUGGING)
index fe11930..3d00d94 100644 (file)
@@ -81,7 +81,7 @@ ShadowRoot::~ShadowRoot()
     willBeDeletedFrom(document());
 
     // We must remove all of our children first before the TreeScope destructor
-    // runs so we don't go through TreeScope::adoptIfNeeded for each child with a
+    // runs so we don't go through Node::setTreeScopeRecursively for each child with a
     // destructed tree scope in each descendant.
     removeDetachedChildren();
 }
index 7798b24..3a08513 100644 (file)
@@ -368,101 +368,6 @@ Element* TreeScope::findAnchor(const String& name)
     return nullptr;
 }
 
-void TreeScope::adoptIfNeeded(Node& node)
-{
-    ASSERT(!node.isDocumentNode());
-    ASSERT(!node.m_deletionHasBegun);
-    TreeScope& treeScopeOfNode = node.treeScope();
-    if (this != &treeScopeOfNode)
-        moveTreeToNewScope(node, treeScopeOfNode, *this);
-}
-
-void TreeScope::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope)
-{
-    ASSERT(&oldScope != &newScope);
-    ASSERT_WITH_SECURITY_IMPLICATION(&root.treeScope() == &oldScope);
-
-    // If an element is moved from a document and then eventually back again the collection cache for
-    // that element may contain stale data as changes made to it will have updated the DOMTreeVersion
-    // of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
-    // we ensure that the collection cache will be invalidated as needed when the element is moved back.
-    Document& oldDocument = oldScope.documentScope();
-    Document& newDocument = newScope.documentScope();
-    bool willMoveToNewDocument = &oldDocument != &newDocument;
-    if (willMoveToNewDocument) {
-        oldDocument.incrementReferencingNodeCount();
-        oldDocument.incDOMTreeVersion();
-    }
-
-    for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
-        ASSERT(!node->isTreeScope());
-        ASSERT(&node->treeScope() == &oldScope);
-        node->setTreeScope(newScope);
-
-        if (willMoveToNewDocument)
-            moveNodeToNewDocument(*node, oldDocument, newDocument);
-        else if (node->hasRareData()) {
-            if (auto* nodeLists = node->rareData()->nodeLists())
-                nodeLists->adoptTreeScope();
-        }
-
-        if (!is<Element>(*node))
-            continue;
-
-        if (node->hasSyntheticAttrChildNodes()) {
-            for (auto& attr : downcast<Element>(*node).attrNodeList())
-                moveTreeToNewScope(*attr, oldScope, newScope);
-        }
-
-        if (auto* shadow = node->shadowRoot()) {
-            ASSERT_WITH_SECURITY_IMPLICATION(&shadow->document() == &oldDocument);
-            shadow->setParentTreeScope(newScope);
-            if (willMoveToNewDocument)
-                moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);
-        }
-    }
-
-    if (willMoveToNewDocument)
-        oldDocument.decrementReferencingNodeCount();
-}
-
-#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
-static bool didMoveToNewDocumentWasCalled = false;
-static Document* oldDocumentDidMoveToNewDocumentWasCalledWith = nullptr;
-
-void TreeScope::ensureDidMoveToNewDocumentWasCalled(Document& oldDocument)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!didMoveToNewDocumentWasCalled);
-    ASSERT_WITH_SECURITY_IMPLICATION(&oldDocument == oldDocumentDidMoveToNewDocumentWasCalledWith);
-    didMoveToNewDocumentWasCalled = true;
-}
-#endif
-
-void TreeScope::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument)
-{
-    ASSERT(!node.isConnected() || &oldDocument != &newDocument);
-
-    newDocument.incrementReferencingNodeCount();
-    oldDocument.decrementReferencingNodeCount();
-
-#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
-    didMoveToNewDocumentWasCalled = false;
-    oldDocumentDidMoveToNewDocumentWasCalledWith = &oldDocument;
-#endif
-
-    node.didMoveToNewDocument(oldDocument, newDocument);
-    ASSERT_WITH_SECURITY_IMPLICATION(didMoveToNewDocumentWasCalled);
-}
-
-void TreeScope::moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)
-{
-    for (Node* node = &shadowRoot; node; node = NodeTraversal::next(*node, &shadowRoot)) {
-        moveNodeToNewDocument(*node, oldDocument, newDocument);
-        if (auto* shadow = node->shadowRoot())
-            moveShadowTreeToNewDocument(*shadow, oldDocument, newDocument);
-    }
-}
-
 static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
 {
     for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
index 80b7ce9..ddefbe3 100644 (file)
@@ -96,14 +96,6 @@ public:
     // quirks mode for historical compatibility reasons.
     Element* findAnchor(const String& name);
 
-    // Used by the basic DOM mutation methods (e.g., appendChild()).
-    void adoptIfNeeded(Node&);
-#if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
-    static void ensureDidMoveToNewDocumentWasCalled(Document& oldDocument);
-#else
-    static void ensureDidMoveToNewDocumentWasCalled(Document&) { }
-#endif
-
     ContainerNode& rootNode() const { return m_rootNode; }
 
     IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
@@ -122,9 +114,6 @@ protected:
     Node* nodeFromPoint(const LayoutPoint& clientPoint, LayoutPoint* localPoint);
 
 private:
-    void moveTreeToNewScope(Node&, TreeScope& oldScope, TreeScope& newScope);
-    void moveNodeToNewDocument(Node&, Document& oldDocument, Document& newDocument);
-    void moveShadowTreeToNewDocument(ShadowRoot&, Document& oldDocument, Document& newDocument);
 
     ContainerNode& m_rootNode;
     std::reference_wrapper<Document> m_documentScope;
index c930364..3a297ed 100644 (file)
@@ -88,7 +88,7 @@ void HTMLTemplateElement::didMoveToNewDocument(Document& oldDocument, Document&
     if (!m_content)
         return;
     ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument);
-    newDocument.ensureTemplateDocument().adoptIfNeeded(*m_content);
+    m_content->setTreeScopeRecursively(newDocument.ensureTemplateDocument());
 }
 
 } // namespace WebCore