DidMoveToNewDocumentAssertionScope shouldn't be necessary
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Oct 2017 22:02:38 +0000 (22:02 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Oct 2017 22:02:38 +0000 (22:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=178836
<rdar://problem/35008876>

Reviewed by Antti Koivisto.

DidMoveToNewDocumentAssertionScope was introduced in r217972 to replace an existing assertion to make sure
Node::didMoveToNewDocument is always called by its overrides in Node's subclasses. However, we can ensure
better Node::didMoveToNewDocument is always called if we called it directly in Node::moveTreeToNewScope.

Because only subclasses of Element and ShadowRoot override Node::didMoveToNewDocument and we already have
a specialized code path to adopt a ShadowRoot to a new document, this refactoring eliminates the need for
having a virtual function on Node at all.

Hence this patch names Node::didMoveToNewDocument to Node::moveToNewDocument and makes it non-virtual,
splits ShadowRoot::didMoveToNewDocument into moveShadowRootToNewParentScope and moveShadowRootToNewDocument,
and removes DidMoveToNewDocumentAssertionScope completely.

No new tests since there should be no behavioral change.

* dom/Document.cpp:
(WebCore::Document::moveNodeIteratorsToNewDocumentSlowCase): Renamed from moveNodeIteratorsToNewDocument.
* dom/Document.h:
(WebCore::Document::moveNodeIteratorsToNewDocument): Inlined the check for emptiness of m_nodeIterators to
avoid keep calling moveNodeIteratorsToNewDocumentSlowCase on every single node getting moved.
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument): Removed the call to Node::didMoveToNewDocument since this is the
base virtual function now.
* dom/Element.h:
* dom/Node.cpp:
(WebCore::DidMoveToNewDocumentAssertionScope::DidMoveToNewDocumentAssertionScope): Deleted.
(WebCore::DidMoveToNewDocumentAssertionScope::~DidMoveToNewDocumentAssertionScope): Deleted.
(WebCore::DidMoveToNewDocumentAssertionScope::didRecieveCall): Deleted.
(WebCore::moveNodeToNewDocument): Deleted.
(WebCore::Node::moveShadowTreeToNewDocument): Made this a member function of Node since it needs to call
moveNodeToNewDocument, which is private to Node.
(WebCore::Node::moveTreeToNewScope): Removed the release assert for the root node since  the same check
exists inside traverseSubtreeToUpdateTreeScope. Also removed the release assertion for checking that
node's old document matches the old document since document() simply calls treeScope().documentScope()
and we're already release-asserting that the old scope of a node matches the old scope we know of.
We release-assert that the old tree scope's document didn't change after the traversal instead. Finally,
replaced a bunch of RELEASE_ASSERT with RELEASE_ASSERT_WITH_SECURITY_IMPLICATION.
(WebCore::Node::moveNodeToNewDocument): Renamed from didMoveToNewDocument. Moved the code related to
mutation observers inside hasRareData() check, and moved the the code to move event listeners inside
eventTargetData() check both for clarity, and avoid doing the work for every single node being moved.
Finally, call the old didMoveToNewDocument when "this" is an Element.
* dom/Node.h:
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::moveShadowRootToNewParentScope): Added. Extracted from didMoveToNewDocument.
(WebCore::ShadowRoot::moveShadowRootToNewDocument): Renamed from didMoveToNewDocument. We now
release-assert that parent tree scope's document matches the new document if any.
* dom/ShadowRoot.h:

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

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/ShadowRoot.cpp
Source/WebCore/dom/ShadowRoot.h

index 3b318e8..9ab37c7 100644 (file)
@@ -1,3 +1,58 @@
+2017-10-26  Ryosuke Niwa  <rniwa@webkit.org>
+
+        DidMoveToNewDocumentAssertionScope shouldn't be necessary
+        https://bugs.webkit.org/show_bug.cgi?id=178836
+        <rdar://problem/35008876>
+
+        Reviewed by Antti Koivisto.
+
+        DidMoveToNewDocumentAssertionScope was introduced in r217972 to replace an existing assertion to make sure
+        Node::didMoveToNewDocument is always called by its overrides in Node's subclasses. However, we can ensure
+        better Node::didMoveToNewDocument is always called if we called it directly in Node::moveTreeToNewScope.
+
+        Because only subclasses of Element and ShadowRoot override Node::didMoveToNewDocument and we already have
+        a specialized code path to adopt a ShadowRoot to a new document, this refactoring eliminates the need for
+        having a virtual function on Node at all.
+
+        Hence this patch names Node::didMoveToNewDocument to Node::moveToNewDocument and makes it non-virtual,
+        splits ShadowRoot::didMoveToNewDocument into moveShadowRootToNewParentScope and moveShadowRootToNewDocument,
+        and removes DidMoveToNewDocumentAssertionScope completely.
+
+        No new tests since there should be no behavioral change.
+
+        * dom/Document.cpp:
+        (WebCore::Document::moveNodeIteratorsToNewDocumentSlowCase): Renamed from moveNodeIteratorsToNewDocument.
+        * dom/Document.h:
+        (WebCore::Document::moveNodeIteratorsToNewDocument): Inlined the check for emptiness of m_nodeIterators to
+        avoid keep calling moveNodeIteratorsToNewDocumentSlowCase on every single node getting moved.
+        * dom/Element.cpp:
+        (WebCore::Element::didMoveToNewDocument): Removed the call to Node::didMoveToNewDocument since this is the
+        base virtual function now.
+        * dom/Element.h:
+        * dom/Node.cpp:
+        (WebCore::DidMoveToNewDocumentAssertionScope::DidMoveToNewDocumentAssertionScope): Deleted.
+        (WebCore::DidMoveToNewDocumentAssertionScope::~DidMoveToNewDocumentAssertionScope): Deleted.
+        (WebCore::DidMoveToNewDocumentAssertionScope::didRecieveCall): Deleted.
+        (WebCore::moveNodeToNewDocument): Deleted.
+        (WebCore::Node::moveShadowTreeToNewDocument): Made this a member function of Node since it needs to call
+        moveNodeToNewDocument, which is private to Node.
+        (WebCore::Node::moveTreeToNewScope): Removed the release assert for the root node since  the same check
+        exists inside traverseSubtreeToUpdateTreeScope. Also removed the release assertion for checking that
+        node's old document matches the old document since document() simply calls treeScope().documentScope()
+        and we're already release-asserting that the old scope of a node matches the old scope we know of.
+        We release-assert that the old tree scope's document didn't change after the traversal instead. Finally,
+        replaced a bunch of RELEASE_ASSERT with RELEASE_ASSERT_WITH_SECURITY_IMPLICATION.
+        (WebCore::Node::moveNodeToNewDocument): Renamed from didMoveToNewDocument. Moved the code related to
+        mutation observers inside hasRareData() check, and moved the the code to move event listeners inside
+        eventTargetData() check both for clarity, and avoid doing the work for every single node being moved.
+        Finally, call the old didMoveToNewDocument when "this" is an Element.
+        * dom/Node.h:
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::moveShadowRootToNewParentScope): Added. Extracted from didMoveToNewDocument.
+        (WebCore::ShadowRoot::moveShadowRootToNewDocument): Renamed from didMoveToNewDocument. We now
+        release-assert that parent tree scope's document matches the new document if any.
+        * dom/ShadowRoot.h:
+
 2017-10-26  Youenn Fablet  <youenn@apple.com>
 
         Implement ServiceWorkerContainer getRegistration
index a631b9c..d40f99c 100644 (file)
@@ -4048,8 +4048,9 @@ void Document::detachNodeIterator(NodeIterator* ni)
     m_nodeIterators.remove(ni);
 }
 
-void Document::moveNodeIteratorsToNewDocument(Node& node, Document& newDocument)
+void Document::moveNodeIteratorsToNewDocumentSlowCase(Node& node, Document& newDocument)
 {
+    ASSERT(!m_nodeIterators.isEmpty());
     for (auto* it : copyToVector(m_nodeIterators)) {
         if (&it->root() == &node) {
             detachNodeIterator(it);
index 488e12c..19d8b97 100644 (file)
@@ -751,7 +751,11 @@ public:
 
     void attachNodeIterator(NodeIterator*);
     void detachNodeIterator(NodeIterator*);
-    void moveNodeIteratorsToNewDocument(Node&, Document&);
+    void moveNodeIteratorsToNewDocument(Node& node, Document& newDocument)
+    {
+        if (!m_nodeIterators.isEmpty())
+            moveNodeIteratorsToNewDocumentSlowCase(node, newDocument);
+    }
 
     void attachRange(Range*);
     void detachRange(Range*);
@@ -1423,6 +1427,8 @@ private:
 
     void buildAccessKeyMap(TreeScope* root);
 
+    void moveNodeIteratorsToNewDocumentSlowCase(Node&, Document&);
+
     void loadEventDelayTimerFired();
 
     void pendingTasksTimerFired();
index 0b0e8ba..d06b9d1 100644 (file)
@@ -1571,7 +1571,6 @@ void Element::parserDidSetAttributes()
 void Element::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument);
-    Node::didMoveToNewDocument(oldDocument, newDocument);
 
     if (oldDocument.inQuirksMode() != document().inQuirksMode()) {
         // ElementData::m_classNames or ElementData::m_idForStyleResolution need to be updated with the right case.
index bd4d621..91750cf 100644 (file)
@@ -260,6 +260,8 @@ public:
     // Clones all attribute-derived data, including subclass specifics (through copyNonAttributeProperties.)
     void cloneDataFromElement(const Element&);
 
+    virtual void didMoveToNewDocument(Document& oldDocument, Document& newDocument);
+
     bool hasEquivalentAttributes(const Element* other) const;
 
     virtual void copyNonAttributePropertiesFromElement(const Element&) { }
@@ -556,7 +558,6 @@ protected:
     void childrenChanged(const ChildChange&) override;
     void removeAllEventListeners() final;
     virtual void parserDidSetAttributes();
-    void didMoveToNewDocument(Document& oldDocument, Document& newDocument) override;
 
     void clearTabIndexExplicitlyIfNeeded();
     void setTabIndexExplicitly(int);
index 20f84ab..745f003 100644 (file)
@@ -1917,62 +1917,6 @@ 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()
-    {
-        RELEASE_ASSERT(m_called);
-        s_scope = m_previousScope;
-    }
-
-    static void didRecieveCall(Node& node, Document& oldDocument, Document& newDocument)
-    {
-        RELEASE_ASSERT(s_scope);
-        RELEASE_ASSERT(!s_scope->m_called);
-        RELEASE_ASSERT(&s_scope->m_node == &node);
-        RELEASE_ASSERT(&s_scope->m_oldDocument == &oldDocument);
-        RELEASE_ASSERT(&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);
-    RELEASE_ASSERT(&node.document() == &newDocument);
-}
-
 template <typename MoveNodeFunction, typename MoveShadowRootFunction>
 static void traverseSubtreeToUpdateTreeScope(Node& root, MoveNodeFunction moveNode, MoveShadowRootFunction moveShadowRoot)
 {
@@ -1993,12 +1937,13 @@ static void traverseSubtreeToUpdateTreeScope(Node& root, MoveNodeFunction moveNo
     }
 }
 
-static void moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)
+inline void Node::moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDocument, Document& newDocument)
 {
     traverseSubtreeToUpdateTreeScope(shadowRoot, [&oldDocument, &newDocument](Node& node) {
-        moveNodeToNewDocument(node, oldDocument, newDocument);
+        node.moveNodeToNewDocument(oldDocument, newDocument);
     }, [&oldDocument, &newDocument](ShadowRoot& innerShadowRoot) {
-        RELEASE_ASSERT(&innerShadowRoot.document() == &oldDocument);
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&innerShadowRoot.document() == &oldDocument);
+        innerShadowRoot.moveShadowRootToNewDocument(newDocument);
         moveShadowTreeToNewDocument(innerShadowRoot, oldDocument, newDocument);
     });
 }
@@ -2006,7 +1951,6 @@ static void moveShadowTreeToNewDocument(ShadowRoot& shadowRoot, Document& oldDoc
 void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newScope)
 {
     ASSERT(&oldScope != &newScope);
-    RELEASE_ASSERT(&root.treeScope() == &oldScope);
 
     Document& oldDocument = oldScope.documentScope();
     Document& newDocument = newScope.documentScope();
@@ -2014,22 +1958,22 @@ void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newSco
         oldDocument.incrementReferencingNodeCount();
         traverseSubtreeToUpdateTreeScope(root, [&](Node& node) {
             ASSERT(!node.isTreeScope());
-            RELEASE_ASSERT(&node.treeScope() == &oldScope);
-            RELEASE_ASSERT(&node.document() == &oldDocument);
+            RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&node.treeScope() == &oldScope);
             node.setTreeScope(newScope);
-            moveNodeToNewDocument(node, oldDocument, newDocument);
+            node.moveNodeToNewDocument(oldDocument, newDocument);
         }, [&](ShadowRoot& shadowRoot) {
             ASSERT_WITH_SECURITY_IMPLICATION(&shadowRoot.document() == &oldDocument);
-            shadowRoot.setParentTreeScope(newScope);
+            shadowRoot.moveShadowRootToNewParentScope(newScope, newDocument);
             moveShadowTreeToNewDocument(shadowRoot, oldDocument, newDocument);
         });
         oldDocument.decrementReferencingNodeCount();
+        RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&oldScope.documentScope() == &oldDocument && &newScope.documentScope() == &newDocument);
     } else {
         traverseSubtreeToUpdateTreeScope(root, [&](Node& node) {
             ASSERT(!node.isTreeScope());
-            RELEASE_ASSERT(&node.treeScope() == &oldScope);
+            RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&node.treeScope() == &oldScope);
             node.setTreeScope(newScope);
-            if (!node.hasRareData())
+            if (UNLIKELY(!node.hasRareData()))
                 return;
             if (auto* nodeLists = node.rareData()->nodeLists())
                 nodeLists->adoptTreeScope();
@@ -2039,72 +1983,69 @@ void Node::moveTreeToNewScope(Node& root, TreeScope& oldScope, TreeScope& newSco
     }
 }
 
-void Node::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
+void Node::moveNodeToNewDocument(Document& oldDocument, Document& newDocument)
 {
-    RELEASE_ASSERT(&document() == &newDocument);
-    DidMoveToNewDocumentAssertionScope::didRecieveCall(*this, oldDocument, newDocument);
-
     newDocument.incrementReferencingNodeCount();
     oldDocument.decrementReferencingNodeCount();
 
     if (hasRareData()) {
         if (auto* nodeLists = rareData()->nodeLists())
             nodeLists->adoptDocument(oldDocument, newDocument);
+        if (auto* registry = mutationObserverRegistry()) {
+            for (auto& registration : *registry)
+                newDocument.addMutationObserverTypes(registration->mutationTypes());
+        }
+        if (auto* transientRegistry = transientMutationObserverRegistry()) {
+            for (auto& registration : *transientRegistry)
+                newDocument.addMutationObserverTypes(registration->mutationTypes());
+        }
+    } else {
+        ASSERT(!mutationObserverRegistry());
+        ASSERT(!transientMutationObserverRegistry());
     }
 
     oldDocument.moveNodeIteratorsToNewDocument(*this, newDocument);
 
-    if (auto* eventTargetData = this->eventTargetData()) {
-        if (!eventTargetData->eventListenerMap.isEmpty()) {
-            for (auto& type : eventTargetData->eventListenerMap.eventTypes())
-                newDocument.addListenerTypeIfNeeded(type);
-        }
-    }
-
     if (AXObjectCache::accessibilityEnabled()) {
         if (auto* cache = oldDocument.existingAXObjectCache())
             cache->remove(this);
     }
 
-    unsigned numWheelEventHandlers = eventListeners(eventNames().mousewheelEvent).size() + eventListeners(eventNames().wheelEvent).size();
-    for (unsigned i = 0; i < numWheelEventHandlers; ++i) {
-        oldDocument.didRemoveWheelEventHandler(*this);
-        newDocument.didAddWheelEventHandler(*this);
-    }
+    if (auto* eventTargetData = this->eventTargetData()) {
+        if (!eventTargetData->eventListenerMap.isEmpty()) {
+            for (auto& type : eventTargetData->eventListenerMap.eventTypes())
+                newDocument.addListenerTypeIfNeeded(type);
+        }
 
-    unsigned numTouchEventListeners = 0;
-    for (auto& name : eventNames().touchEventNames())
-        numTouchEventListeners += eventListeners(name).size();
+        unsigned numWheelEventHandlers = eventListeners(eventNames().mousewheelEvent).size() + eventListeners(eventNames().wheelEvent).size();
+        for (unsigned i = 0; i < numWheelEventHandlers; ++i) {
+            oldDocument.didRemoveWheelEventHandler(*this);
+            newDocument.didAddWheelEventHandler(*this);
+        }
 
-    for (unsigned i = 0; i < numTouchEventListeners; ++i) {
-        oldDocument.didRemoveTouchEventHandler(*this);
-        newDocument.didAddTouchEventHandler(*this);
+        unsigned numTouchEventListeners = 0;
+        for (auto& name : eventNames().touchEventNames())
+            numTouchEventListeners += eventListeners(name).size();
 
+        for (unsigned i = 0; i < numTouchEventListeners; ++i) {
+            oldDocument.didRemoveTouchEventHandler(*this);
+            newDocument.didAddTouchEventHandler(*this);
 #if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS)
-        oldDocument.removeTouchEventListener(*this);
-        newDocument.addTouchEventListener(*this);
+            oldDocument.removeTouchEventListener(*this);
+            newDocument.addTouchEventListener(*this);
 #endif
-    }
+        }
 
 #if ENABLE(TOUCH_EVENTS) && ENABLE(IOS_GESTURE_EVENTS)
-    unsigned numGestureEventListeners = 0;
-    for (auto& name : eventNames().gestureEventNames())
-        numGestureEventListeners += eventListeners(name).size();
+        unsigned numGestureEventListeners = 0;
+        for (auto& name : eventNames().gestureEventNames())
+            numGestureEventListeners += eventListeners(name).size();
 
-    for (unsigned i = 0; i < numGestureEventListeners; ++i) {
-        oldDocument.removeTouchEventHandler(*this);
-        newDocument.addTouchEventHandler(*this);
-    }
+        for (unsigned i = 0; i < numGestureEventListeners; ++i) {
+            oldDocument.removeTouchEventHandler(*this);
+            newDocument.addTouchEventHandler(*this);
+        }
 #endif
-
-    if (auto* registry = mutationObserverRegistry()) {
-        for (auto& registration : *registry)
-            newDocument.addMutationObserverTypes(registration->mutationTypes());
-    }
-
-    if (auto* transientRegistry = transientMutationObserverRegistry()) {
-        for (auto& registration : *transientRegistry)
-            newDocument.addMutationObserverTypes(registration->mutationTypes());
     }
 
 #if !ASSERT_DISABLED || ENABLE(SECURITY_ASSERTIONS)
@@ -2116,6 +2057,9 @@ void Node::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
     ASSERT_WITH_SECURITY_IMPLICATION(!oldDocument.touchEventTargetsContain(*this));
 #endif
 #endif
+
+    if (is<Element>(*this))
+        downcast<Element>(*this).didMoveToNewDocument(oldDocument, newDocument);
 }
 
 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, Ref<EventListener>&& listener, const EventTarget::AddEventListenerOptions& options)
index 61f866c..0b5cea6 100644 (file)
@@ -491,8 +491,6 @@ 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;
 
@@ -679,7 +677,9 @@ private:
 
     void* opaqueRootSlow() const;
 
+    static void moveShadowTreeToNewDocument(ShadowRoot&, Document& oldDocument, Document& newDocument);
     static void moveTreeToNewScope(Node&, TreeScope& oldScope, TreeScope& newScope);
+    void moveNodeToNewDocument(Document& oldDocument, Document& newDocument);
 
     int m_refCount;
     mutable uint32_t m_nodeFlags;
index dd23ba7..dec7988 100644 (file)
@@ -100,17 +100,20 @@ void ShadowRoot::removedFromAncestor(RemovalType removalType, ContainerNode& old
         document().didRemoveInDocumentShadowRoot(*this);
 }
 
-void ShadowRoot::didMoveToNewDocument(Document& oldDocument, Document& newDocument)
+void ShadowRoot::moveShadowRootToNewParentScope(TreeScope& newScope, Document& newDocument)
+{
+    setParentTreeScope(newScope);
+    moveShadowRootToNewDocument(newDocument);
+}
+
+void ShadowRoot::moveShadowRootToNewDocument(Document& newDocument)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(&document() == &oldDocument || &document() == &newDocument);
     setDocumentScope(newDocument);
-    ASSERT_WITH_SECURITY_IMPLICATION(&document() == &newDocument);
-    ASSERT_WITH_SECURITY_IMPLICATION(&m_styleScope->document() == &oldDocument);
+    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(!parentTreeScope() || &parentTreeScope()->documentScope() == &newDocument);
 
     // Style scopes are document specific.
     m_styleScope = std::make_unique<Style::Scope>(*this);
-
-    DocumentFragment::didMoveToNewDocument(oldDocument, newDocument);
+    RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(&m_styleScope->document() == &newDocument);
 }
 
 Style::Scope& ShadowRoot::styleScope()
index d2a4483..1bf896b 100644 (file)
@@ -81,6 +81,9 @@ public:
 
     const Vector<Node*>* assignedNodesForSlot(const HTMLSlotElement&);
 
+    void moveShadowRootToNewParentScope(TreeScope&, Document&);
+    void moveShadowRootToNewDocument(Document&);
+
 protected:
     ShadowRoot(Document&, ShadowRootMode);
 
@@ -96,7 +99,6 @@ private:
 
     Node::InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) override;
     void removedFromAncestor(RemovalType, ContainerNode& insertionPoint) override;
-    void didMoveToNewDocument(Document& oldDocument, Document& newDocument) override;
 
     bool m_resetStyleInheritance { false };
     ShadowRootMode m_type { ShadowRootMode::UserAgent };