Implement iterator for traversing composed ancestors
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Oct 2015 15:12:39 +0000 (15:12 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Oct 2015 15:12:39 +0000 (15:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150162

Reviewed by Andreas Kling.

The existing general purpose ComposedTreeIterator can traverse parent chain but not efficiently
(since it builds stack). Add a separate stackless iterator for ancestor chain traversal.

* WebCore.xcodeproj/project.pbxproj:
* dom/ComposedTreeAncestorIterator.h: Added.
(WebCore::ComposedTreeAncestorIterator::operator*):
(WebCore::ComposedTreeAncestorIterator::operator->):
(WebCore::ComposedTreeAncestorIterator::operator==):
(WebCore::ComposedTreeAncestorIterator::operator!=):
(WebCore::ComposedTreeAncestorIterator::operator++):
(WebCore::ComposedTreeAncestorIterator::get):
(WebCore::ComposedTreeAncestorIterator::ComposedTreeAncestorIterator):
(WebCore::ComposedTreeAncestorIterator::traverseParent):
(WebCore::ComposedTreeAncestorAdapter::ComposedTreeAncestorAdapter):
(WebCore::ComposedTreeAncestorAdapter::begin):
(WebCore::ComposedTreeAncestorAdapter::end):
(WebCore::ComposedTreeAncestorAdapter::first):
(WebCore::composedTreeAncestors):
* dom/ComposedTreeIterator.h:
* dom/ContainerNode.h:
(WebCore::Node::highestAncestor):
(WebCore::Node::isTreeScope):
(WebCore::Node::needsNodeRenderingTraversalSlowPath): Deleted.

    With NodeRenderingTraversal::parent removed this bit is no longer used.

* dom/Element.cpp:
(WebCore::Element::shadowRoot):
(WebCore::Element::addShadowRoot):
(WebCore::shouldUseNodeRenderingTraversalSlowPath): Deleted.
(WebCore::Element::resetNeedsNodeRenderingTraversalSlowPath): Deleted.
* dom/Element.h:
(WebCore::Element::didAddUserAgentShadowRoot):
(WebCore::Element::alwaysCreateUserAgentShadowRoot):
* dom/Node.cpp:
(WebCore::Node::derefEventTarget):
(WebCore::Node::updateAncestorsForStyleRecalc):
(WebCore::traverseStyleParent): Deleted.
(WebCore::traverseFirstStyleParent): Deleted.

    Switch to iterator interface.

* dom/Node.h:
(WebCore::Node::isDocumentFragment):
(WebCore::Node::isShadowRoot):
(WebCore::Node::isNamedFlowContentNode):
(WebCore::Node::hasCustomStyleResolveCallbacks):
(WebCore::Node::setHasCustomStyleResolveCallbacks):
(WebCore::Node::setTreeScope):
(WebCore::Node::setStyleChange):
(WebCore::Node::setNeedsNodeRenderingTraversalSlowPath): Deleted.
* dom/NodeRenderingTraversal.cpp:
(WebCore::NodeRenderingTraversal::traverseParent):
(WebCore::NodeRenderingTraversal::traverseFirstChild):
(WebCore::NodeRenderingTraversal::traverseLastChild):
(WebCore::NodeRenderingTraversal::traversePreviousSibling):
(WebCore::NodeRenderingTraversal::nextInScope):
(WebCore::NodeRenderingTraversal::previousInScope):
(WebCore::NodeRenderingTraversal::parentInScope):
(WebCore::NodeRenderingTraversal::lastChildInScope):
(WebCore::NodeRenderingTraversal::parentSlow): Deleted.
* dom/NodeRenderingTraversal.h:
(WebCore::NodeRenderingTraversal::parent): Deleted.

    No longer used.

* html/HTMLSummaryElement.cpp:
* rendering/RenderNamedFlowThread.cpp:
(WebCore::RenderNamedFlowThread::isChildAllowed):

    Switch to iterator interface.

* style/RenderTreePosition.cpp:
* style/StyleResolveTree.cpp:
(WebCore::Style::updateTextRendererAfterContentChange):

    Switch to iterator interface.

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/ComposedTreeAncestorIterator.h [new file with mode: 0644]
Source/WebCore/dom/ComposedTreeIterator.h
Source/WebCore/dom/ContainerNode.h
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/NodeRenderingTraversal.cpp
Source/WebCore/dom/NodeRenderingTraversal.h
Source/WebCore/html/HTMLSummaryElement.cpp
Source/WebCore/rendering/RenderNamedFlowThread.cpp
Source/WebCore/style/RenderTreePosition.cpp
Source/WebCore/style/StyleResolveTree.cpp

index 71a6d7b..c8b6e87 100644 (file)
@@ -1,3 +1,88 @@
+2015-10-15  Antti Koivisto  <antti@apple.com>
+
+        Implement iterator for traversing composed ancestors
+        https://bugs.webkit.org/show_bug.cgi?id=150162
+
+        Reviewed by Andreas Kling.
+
+        The existing general purpose ComposedTreeIterator can traverse parent chain but not efficiently
+        (since it builds stack). Add a separate stackless iterator for ancestor chain traversal.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/ComposedTreeAncestorIterator.h: Added.
+        (WebCore::ComposedTreeAncestorIterator::operator*):
+        (WebCore::ComposedTreeAncestorIterator::operator->):
+        (WebCore::ComposedTreeAncestorIterator::operator==):
+        (WebCore::ComposedTreeAncestorIterator::operator!=):
+        (WebCore::ComposedTreeAncestorIterator::operator++):
+        (WebCore::ComposedTreeAncestorIterator::get):
+        (WebCore::ComposedTreeAncestorIterator::ComposedTreeAncestorIterator):
+        (WebCore::ComposedTreeAncestorIterator::traverseParent):
+        (WebCore::ComposedTreeAncestorAdapter::ComposedTreeAncestorAdapter):
+        (WebCore::ComposedTreeAncestorAdapter::begin):
+        (WebCore::ComposedTreeAncestorAdapter::end):
+        (WebCore::ComposedTreeAncestorAdapter::first):
+        (WebCore::composedTreeAncestors):
+        * dom/ComposedTreeIterator.h:
+        * dom/ContainerNode.h:
+        (WebCore::Node::highestAncestor):
+        (WebCore::Node::isTreeScope):
+        (WebCore::Node::needsNodeRenderingTraversalSlowPath): Deleted.
+
+            With NodeRenderingTraversal::parent removed this bit is no longer used.
+
+        * dom/Element.cpp:
+        (WebCore::Element::shadowRoot):
+        (WebCore::Element::addShadowRoot):
+        (WebCore::shouldUseNodeRenderingTraversalSlowPath): Deleted.
+        (WebCore::Element::resetNeedsNodeRenderingTraversalSlowPath): Deleted.
+        * dom/Element.h:
+        (WebCore::Element::didAddUserAgentShadowRoot):
+        (WebCore::Element::alwaysCreateUserAgentShadowRoot):
+        * dom/Node.cpp:
+        (WebCore::Node::derefEventTarget):
+        (WebCore::Node::updateAncestorsForStyleRecalc):
+        (WebCore::traverseStyleParent): Deleted.
+        (WebCore::traverseFirstStyleParent): Deleted.
+
+            Switch to iterator interface.
+
+        * dom/Node.h:
+        (WebCore::Node::isDocumentFragment):
+        (WebCore::Node::isShadowRoot):
+        (WebCore::Node::isNamedFlowContentNode):
+        (WebCore::Node::hasCustomStyleResolveCallbacks):
+        (WebCore::Node::setHasCustomStyleResolveCallbacks):
+        (WebCore::Node::setTreeScope):
+        (WebCore::Node::setStyleChange):
+        (WebCore::Node::setNeedsNodeRenderingTraversalSlowPath): Deleted.
+        * dom/NodeRenderingTraversal.cpp:
+        (WebCore::NodeRenderingTraversal::traverseParent):
+        (WebCore::NodeRenderingTraversal::traverseFirstChild):
+        (WebCore::NodeRenderingTraversal::traverseLastChild):
+        (WebCore::NodeRenderingTraversal::traversePreviousSibling):
+        (WebCore::NodeRenderingTraversal::nextInScope):
+        (WebCore::NodeRenderingTraversal::previousInScope):
+        (WebCore::NodeRenderingTraversal::parentInScope):
+        (WebCore::NodeRenderingTraversal::lastChildInScope):
+        (WebCore::NodeRenderingTraversal::parentSlow): Deleted.
+        * dom/NodeRenderingTraversal.h:
+        (WebCore::NodeRenderingTraversal::parent): Deleted.
+
+            No longer used.
+
+        * html/HTMLSummaryElement.cpp:
+        * rendering/RenderNamedFlowThread.cpp:
+        (WebCore::RenderNamedFlowThread::isChildAllowed):
+
+            Switch to iterator interface.
+
+        * style/RenderTreePosition.cpp:
+        * style/StyleResolveTree.cpp:
+        (WebCore::Style::updateTextRendererAfterContentChange):
+
+            Switch to iterator interface.
+
 2015-10-14  Zhuo Li  <zachli@apple.com>
 
         Augment <input type=search>’s recent search history with the time each entry was added,
index 5d30c82..351e4ce 100644 (file)
                E4B65A5A132FAAF90070E7BE /* LegacyTileGrid.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4B65A59132FAAF90070E7BE /* LegacyTileGrid.mm */; };
                E4B65A5C132FACB00070E7BE /* LegacyTileLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B65A5B132FACB00070E7BE /* LegacyTileLayer.h */; };
                E4B65A5E132FADB60070E7BE /* LegacyTileLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4B65A5D132FADB60070E7BE /* LegacyTileLayer.mm */; };
+               E4BA50901BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E4BA508F1BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h */; settings = {ASSET_TAGS = (); }; };
                E4BBED0E14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4BBED0C14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.cpp */; };
                E4BBED0F14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.h in Headers */ = {isa = PBXBuildFile; fileRef = E4BBED0D14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.h */; };
                E4BBED4C14FCDBA1003F0B98 /* StyleRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4BBED4A14FCDBA1003F0B98 /* StyleRule.cpp */; };
                E4B65A59132FAAF90070E7BE /* LegacyTileGrid.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LegacyTileGrid.mm; sourceTree = "<group>"; };
                E4B65A5B132FACB00070E7BE /* LegacyTileLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyTileLayer.h; sourceTree = "<group>"; };
                E4B65A5D132FADB60070E7BE /* LegacyTileLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LegacyTileLayer.mm; sourceTree = "<group>"; };
+               E4BA508F1BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComposedTreeAncestorIterator.h; sourceTree = "<group>"; };
                E4BBED0C14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertySetCSSStyleDeclaration.cpp; sourceTree = "<group>"; };
                E4BBED0D14F4025D003F0B98 /* PropertySetCSSStyleDeclaration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertySetCSSStyleDeclaration.h; sourceTree = "<group>"; };
                E4BBED4A14FCDBA1003F0B98 /* StyleRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleRule.cpp; sourceTree = "<group>"; };
                                6550B697099DF0270090D781 /* Comment.cpp */,
                                6550B698099DF0270090D781 /* Comment.h */,
                                85089CC70A98C22600A275AA /* Comment.idl */,
+                               E4BA508F1BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h */,
                                E44FA1861BCA91560091B6EF /* ComposedTreeIterator.cpp */,
                                E44FA1841BCA6B5A0091B6EF /* ComposedTreeIterator.h */,
                                79F2F59E1091939A000D87CB /* CompositionEvent.cpp */,
                                CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */,
                                FBD6AF8815EF25C9008B7110 /* CSSBasicShapes.h in Headers */,
                                E16A84FA14C85CCC002977DF /* CSSBorderImage.h in Headers */,
+                               E4BA50901BCFBD9500E34EF7 /* ComposedTreeAncestorIterator.h in Headers */,
                                BC274B2F140EBEB200EADFA6 /* CSSBorderImageSliceValue.h in Headers */,
                                49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */,
                                BC6049CC0DB560C200204739 /* CSSCanvasValue.h in Headers */,
                                51F41A681BA73B5B002E053B /* IDBCallbacks.h in Headers */,
                                5185FCB91BB4CBF80012898F /* IDBConnectionToClient.h in Headers */,
                                516D7D721BB5F0BD00AF7C77 /* IDBConnectionToClientDelegate.h in Headers */,
-                               5185FC5B1BB4BE4C0012898F /* IDBConnectionToServer.h in Headers */,
                                516D7D701BB5F0BD00AF7C77 /* IDBConnectionToServerDelegate.h in Headers */,
                                5185FC7B1BB4C4E80012898F /* IDBCursor.h in Headers */,
                                51F41A6A1BA73B5B002E053B /* IDBCursorBackend.h in Headers */,
                                5185FC771BB4C4E80012898F /* IDBAny.cpp in Sources */,
                                C585A66211D4FAC5004C3E4B /* IDBBindingUtilities.cpp in Sources */,
                                516D7D711BB5F0BD00AF7C77 /* IDBConnectionToClient.cpp in Sources */,
-                               516D7D6F1BB5F0BD00AF7C77 /* IDBConnectionToServer.cpp in Sources */,
                                5185FC7A1BB4C4E80012898F /* IDBCursor.cpp in Sources */,
                                51F41A691BA73B5B002E053B /* IDBCursorBackend.cpp in Sources */,
                                51F41A6B1BA73B5B002E053B /* IDBCursorBackendOperations.cpp in Sources */,
                                CDC69DDB16371FD4007C38DF /* WebCoreFullScreenPlaceholderView.mm in Sources */,
                                CDC69DD71632026C007C38DF /* WebCoreFullScreenWarningView.mm in Sources */,
                                CD127DED14F3097D00E84779 /* WebCoreFullScreenWindow.mm in Sources */,
-                               411A90421BBAB47A000CF156 /* WebCoreJSBuiltins.cpp in Sources */,
                                3140379C124BEA7F00AF40E4 /* WebCoreMotionManager.mm in Sources */,
                                934D9BA50B8C116B007B42A9 /* WebCoreNSStringExtras.mm in Sources */,
                                C5B4C24E1509236C00A6EF37 /* WebCoreNSURLExtras.mm in Sources */,
diff --git a/Source/WebCore/dom/ComposedTreeAncestorIterator.h b/Source/WebCore/dom/ComposedTreeAncestorIterator.h
new file mode 100644 (file)
index 0000000..d63ab9e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "HTMLSlotElement.h"
+#include "PseudoElement.h"
+#include "ShadowRoot.h"
+
+#ifndef ComposedTreeAncestorIterator_h
+#define ComposedTreeAncestorIterator_h
+
+namespace WebCore {
+
+class HTMLSlotElement;
+
+class ComposedTreeAncestorIterator {
+public:
+    ComposedTreeAncestorIterator(ContainerNode& root);
+    ComposedTreeAncestorIterator(ContainerNode& root, Node& current);
+
+    ContainerNode& operator*() { return get(); }
+    ContainerNode* operator->() { return &get(); }
+
+    bool operator==(const ComposedTreeAncestorIterator& other) const { return m_current == other.m_current; }
+    bool operator!=(const ComposedTreeAncestorIterator& other) const { return m_current != other.m_current; }
+
+    ComposedTreeAncestorIterator& operator++() { return traverseParent(); }
+
+    ContainerNode& get() { return downcast<ContainerNode>(*m_current); }
+    ComposedTreeAncestorIterator& traverseParent();
+
+private:
+    void traverseParentInShadowTree();
+
+    ContainerNode& m_root;
+    Node* m_current { 0 };
+};
+
+inline ComposedTreeAncestorIterator::ComposedTreeAncestorIterator(ContainerNode& root)
+    : m_root(root)
+{
+    ASSERT(!is<ShadowRoot>(m_root));
+}
+
+inline ComposedTreeAncestorIterator::ComposedTreeAncestorIterator(ContainerNode& root, Node& current)
+    : m_root(root)
+    , m_current(&current)
+{
+    ASSERT(!is<ShadowRoot>(m_root));
+    ASSERT(!is<ShadowRoot>(m_current));
+}
+
+inline ComposedTreeAncestorIterator& ComposedTreeAncestorIterator::traverseParent()
+{
+    if (m_current == &m_root) {
+        m_current = nullptr;
+        return *this;
+    }
+
+    auto* parent = m_current->parentNode();
+    if (!parent) {
+        m_current = nullptr;
+        return *this;
+    }
+    if (is<ShadowRoot>(*parent)) {
+        m_current = downcast<ShadowRoot>(*parent).host();
+        return *this;
+    }
+
+    if (auto* shadowRoot = parent->shadowRoot()) {
+#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
+        m_current = shadowRoot->findAssignedSlot(*m_current);
+#else
+        m_current = nullptr;
+#endif
+        return *this;
+    }
+
+    m_current = parent;
+    return *this;
+}
+
+class ComposedTreeAncestorAdapter {
+public:
+    using iterator = ComposedTreeAncestorIterator;
+
+    ComposedTreeAncestorAdapter(Node& node)
+        : m_node(node)
+    { }
+
+    iterator begin()
+    {
+        if (is<ShadowRoot>(m_node))
+            return iterator(m_node.document(), *downcast<ShadowRoot>(m_node).host());
+        if (is<PseudoElement>(m_node))
+            return iterator(m_node.document(), *downcast<PseudoElement>(m_node).hostElement());
+        return iterator(m_node.document(), m_node).traverseParent();
+    }
+    iterator end()
+    {
+        return iterator(m_node.document());
+    }
+    ContainerNode* first()
+    {
+        auto it = begin();
+        if (it == end())
+            return nullptr;
+        return &it.get();
+    }
+
+private:
+    Node& m_node;
+};
+
+// FIXME: We should have const versions too.
+inline ComposedTreeAncestorAdapter composedTreeAncestors(Node& node)
+{
+    return ComposedTreeAncestorAdapter(node);
+}
+
+}
+
+#endif
index f8d33d7..ae86557 100644 (file)
@@ -23,7 +23,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "HTMLSlotElement.h"
 #include "NodeTraversal.h"
 #include "ShadowRoot.h"
 
index f3a440a..599ed35 100644 (file)
@@ -228,14 +228,6 @@ inline Node* Node::highestAncestor() const
     return highest;
 }
 
-inline bool Node::needsNodeRenderingTraversalSlowPath() const
-{
-    if (getFlag(NeedsNodeRenderingTraversalSlowPathFlag))
-        return true;
-    ContainerNode* parent = parentOrShadowHostNode();
-    return parent && parent->getFlag(NeedsNodeRenderingTraversalSlowPathFlag);
-}
-
 inline bool Node::isTreeScope() const
 {
     return &treeScope().rootNode() == this;
index d47664c..7ec56a6 100644 (file)
@@ -1619,15 +1619,6 @@ ShadowRoot* Element::shadowRoot() const
     return hasRareData() ? elementRareData()->shadowRoot() : 0;
 }
 
-static bool shouldUseNodeRenderingTraversalSlowPath(const Element& element)
-{
-    return element.isShadowRoot() || element.shadowRoot();
-}
-
-void Element::resetNeedsNodeRenderingTraversalSlowPath()
-{
-    setNeedsNodeRenderingTraversalSlowPath(shouldUseNodeRenderingTraversalSlowPath(*this));
-}
 
 void Element::addShadowRoot(Ref<ShadowRoot>&& newShadowRoot)
 {
@@ -1644,8 +1635,6 @@ void Element::addShadowRoot(Ref<ShadowRoot>&& newShadowRoot)
     for (auto& target : postInsertionNotificationTargets)
         target->finishedInsertingSubtree();
 
-    resetNeedsNodeRenderingTraversalSlowPath();
-
     setNeedsStyleRecalc(ReconstructRenderTree);
 
     InspectorInstrumentation::didPushShadowRoot(*this, shadowRoot);
index c0a489f..d253b03 100644 (file)
@@ -519,8 +519,6 @@ private:
     bool isUserActionElementFocused() const;
     bool isUserActionElementHovered() const;
 
-    void resetNeedsNodeRenderingTraversalSlowPath();
-
     virtual void didAddUserAgentShadowRoot(ShadowRoot*) { }
     virtual bool alwaysCreateUserAgentShadowRoot() const { return false; }
 
index edbd37e..6689bb0 100644 (file)
@@ -31,6 +31,7 @@
 #include "ChildListMutationScope.h"
 #include "Chrome.h"
 #include "ChromeClient.h"
+#include "ComposedTreeAncestorIterator.h"
 #include "ContainerNodeAlgorithms.h"
 #include "ContextMenuController.h"
 #include "DOMImplementation.h"
@@ -740,45 +741,26 @@ void Node::derefEventTarget()
     deref();
 }
 
-// FIXME: Factor into iterator.
-static ContainerNode* traverseStyleParent(Node& node)
-{
-    auto* parent = node.parentNode();
-    if (!parent) {
-        if (is<ShadowRoot>(node))
-            return downcast<ShadowRoot>(node).host();
-        return nullptr;
-    }
-#if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT)
-    if (auto* shadowRoot = parent->shadowRoot()) {
-        if (auto* assignedSlot = shadowRoot->findAssignedSlot(node))
-            return assignedSlot;
-    }
-#endif
-    return parent;
-}
-
-static ContainerNode* traverseFirstStyleParent(Node& node)
-{
-    if (is<PseudoElement>(node))
-        return downcast<PseudoElement>(node).hostElement();
-    return traverseStyleParent(node);
-}
-
 inline void Node::updateAncestorsForStyleRecalc()
 {
-    if (auto* ancestor = traverseFirstStyleParent(*this)) {
-        ancestor->setDirectChildNeedsStyleRecalc();
+    auto composedAncestors = composedTreeAncestors(*this);
+    auto it = composedAncestors.begin();
+    auto end = composedAncestors.end();
+    if (it != end) {
+        it->setDirectChildNeedsStyleRecalc();
 
-        if (is<Element>(*ancestor) && downcast<Element>(*ancestor).childrenAffectedByPropertyBasedBackwardPositionalRules()) {
-            if (ancestor->styleChangeType() < FullStyleChange)
-                ancestor->setStyleChange(FullStyleChange);
+        if (is<Element>(*it) && downcast<Element>(*it).childrenAffectedByPropertyBasedBackwardPositionalRules()) {
+            if (it->styleChangeType() < FullStyleChange)
+                it->setStyleChange(FullStyleChange);
         }
 
-        for (; ancestor; ancestor = traverseStyleParent(*ancestor)) {
-            if (ancestor->childNeedsStyleRecalc())
+        for (; it != end; ++it) {
+            // Iterator skips over shadow roots.
+            if (auto* shadowRoot = it->shadowRoot())
+                shadowRoot->setChildNeedsStyleRecalc();
+            if (it->childNeedsStyleRecalc())
                 break;
-            ancestor->setChildNeedsStyleRecalc();
+            it->setChildNeedsStyleRecalc();
         }
     }
 
index a64e0c5..6a193aa 100644 (file)
@@ -267,8 +267,6 @@ public:
     bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
     bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
 
-    bool needsNodeRenderingTraversalSlowPath() const;
-
     bool isNamedFlowContentNode() const { return getFlag(IsNamedFlowContentNodeFlag); }
     bool hasCustomStyleResolveCallbacks() const { return getFlag(HasCustomStyleResolveCallbacksFlag); }
 
@@ -617,7 +615,7 @@ protected:
         HasSyntheticAttrChildNodesFlag = 1 << 19,
         HasCustomStyleResolveCallbacksFlag = 1 << 20,
         HasEventTargetDataFlag = 1 << 21,
-        NeedsNodeRenderingTraversalSlowPathFlag = 1 << 22,
+        // HeyItIsAFreeBit = 1 << 22,
         IsInShadowTreeFlag = 1 << 23,
         IsMathMLFlag = 1 << 24,
 
@@ -644,8 +642,8 @@ protected:
         CreateText = DefaultNodeFlags | IsTextFlag,
         CreateContainer = DefaultNodeFlags | IsContainerFlag, 
         CreateElement = CreateContainer | IsElementFlag, 
-        CreatePseudoElement =  CreateElement | InDocumentFlag | NeedsNodeRenderingTraversalSlowPathFlag,
-        CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | NeedsNodeRenderingTraversalSlowPathFlag | IsInShadowTreeFlag,
+        CreatePseudoElement =  CreateElement | InDocumentFlag,
+        CreateShadowRoot = CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
         CreateDocumentFragment = CreateContainer | IsDocumentFragmentFlag,
         CreateStyledElement = CreateElement | IsStyledElementFlag, 
         CreateHTMLElement = CreateStyledElement | IsHTMLFlag,
@@ -670,8 +668,6 @@ protected:
 
     void setHasCustomStyleResolveCallbacks() { setFlag(true, HasCustomStyleResolveCallbacksFlag); }
 
-    void setNeedsNodeRenderingTraversalSlowPath(bool flag) { setFlag(flag, NeedsNodeRenderingTraversalSlowPathFlag); }
-
     void setTreeScope(TreeScope& scope) { m_treeScope = &scope; }
 
     void setStyleChange(StyleChangeType changeType) { m_nodeFlags = (m_nodeFlags & ~StyleChangeMask) | changeType; }
index 11dc5e0..2e2030a 100644 (file)
@@ -34,45 +34,31 @@ namespace WebCore {
 
 namespace NodeRenderingTraversal {
 
-enum ShadowRootCrossing { CrossShadowRoot, DontCrossShadowRoot };
-
-static ContainerNode* traverseParent(const Node* node, ShadowRootCrossing shadowRootCrossing)
+static ContainerNode* traverseParent(const Node* node)
 {
-    if (shadowRootCrossing == DontCrossShadowRoot  && node->isShadowRoot())
+    if (node->isShadowRoot())
         return nullptr;
 
     ContainerNode* parent = node->parentNode();
     if (parent && parent->shadowRoot())
         return nullptr;
 
-    if (!parent)
-        return nullptr;
-
-    if (is<ShadowRoot>(*parent))
-        return shadowRootCrossing == CrossShadowRoot ? downcast<ShadowRoot>(parent)->host() : parent;
-
     return parent;
 }
 
-static Node* traverseFirstChild(const Node* node, ShadowRootCrossing shadowRootCrossing)
+static Node* traverseFirstChild(const Node* node)
 {
     ASSERT(node);
-    if (node->shadowRoot()) {
-        if (shadowRootCrossing == DontCrossShadowRoot)
-            return nullptr;
-        node = node->shadowRoot();
-    }
+    if (node->shadowRoot())
+        return nullptr;
     return node->firstChild();
 }
 
-static Node* traverseLastChild(const Node* node, ShadowRootCrossing shadowRootCrossing)
+static Node* traverseLastChild(const Node* node)
 {
     ASSERT(node);
-    if (node->shadowRoot()) {
-        if (shadowRootCrossing == DontCrossShadowRoot)
-            return nullptr;
-        node = node->shadowRoot();
-    }
+    if (node->shadowRoot())
+        return nullptr;
     return node->lastChild();
 }
 
@@ -88,43 +74,36 @@ static Node* traversePreviousSibling(const Node* node)
     return node->previousSibling();
 }
 
-ContainerNode* parentSlow(const Node* node)
-{
-    ASSERT(!node->isShadowRoot());
-
-    return traverseParent(node, CrossShadowRoot);
-}
-
 Node* nextInScope(const Node* node)
 {
-    if (Node* next = traverseFirstChild(node, DontCrossShadowRoot))
+    if (Node* next = traverseFirstChild(node))
         return next;
     if (Node* next = traverseNextSibling(node))
         return next;
     const Node* current = node;
     while (current && !traverseNextSibling(current))
-        current = traverseParent(current, DontCrossShadowRoot);
+        current = traverseParent(current);
     return current ? traverseNextSibling(current) : 0;
 }
 
 Node* previousInScope(const Node* node)
 {
     if (Node* current = traversePreviousSibling(node)) {
-        while (Node* child = traverseLastChild(current, DontCrossShadowRoot))
+        while (Node* child = traverseLastChild(current))
             current = child;
         return current;
     }
-    return traverseParent(node, DontCrossShadowRoot);
+    return traverseParent(node);
 }
 
 Node* parentInScope(const Node* node)
 {
-    return traverseParent(node, DontCrossShadowRoot);
+    return traverseParent(node);
 }
 
 Node* lastChildInScope(const Node* node)
 {
-    return traverseLastChild(node, DontCrossShadowRoot);
+    return traverseLastChild(node);
 }
 
 }
index bedd808..f7f6d8e 100644 (file)
@@ -34,25 +34,11 @@ namespace WebCore {
 
 namespace NodeRenderingTraversal {
 
-ContainerNode* parent(const Node*);
-
 Node* nextInScope(const Node*);
 Node* previousInScope(const Node*);
 Node* parentInScope(const Node*);
 Node* lastChildInScope(const Node*);
 
-ContainerNode* parentSlow(const Node*);
-
-inline ContainerNode* parent(const Node* node)
-{
-    ASSERT(!node->isPseudoElement());
-    if (node->needsNodeRenderingTraversalSlowPath())
-        return parentSlow(node);
-
-    ASSERT(node->parentNode() == parentSlow(node));
-    return node->parentNodeGuaranteedHostFree();
-}
-
 }
 
 } // namespace WebCore
index 6a953a4..f59d8c0 100644 (file)
@@ -28,7 +28,6 @@
 #include "HTMLSlotElement.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
-#include "NodeRenderingTraversal.h"
 #include "PlatformMouseEvent.h"
 #include "RenderBlockFlow.h"
 #include "ShadowRoot.h"
index 717cd1b..12b607a 100644 (file)
 #include "config.h"
 #include "RenderNamedFlowThread.h"
 
+#include "ComposedTreeAncestorIterator.h"
 #include "ExceptionCodePlaceholder.h"
 #include "FlowThreadController.h"
 #include "InlineTextBox.h"
 #include "InspectorInstrumentation.h"
-#include "NodeRenderingTraversal.h"
 #include "NodeTraversal.h"
 #include "Position.h"
 #include "Range.h"
@@ -547,7 +547,7 @@ bool RenderNamedFlowThread::isChildAllowed(const RenderObject& child, const Rend
 
     ASSERT(is<Element>(*child.node()));
 
-    Node* originalParent = NodeRenderingTraversal::parent(child.node());
+    auto* originalParent = composedTreeAncestors(*child.node()).first();
     if (!is<Element>(originalParent) || !originalParent->renderer())
         return true;
 
index 22944cb..cb038e8 100644 (file)
@@ -27,7 +27,6 @@
 #include "RenderTreePosition.h"
 
 #include "ComposedTreeIterator.h"
-#include "NodeRenderingTraversal.h"
 #include "PseudoElement.h"
 #include "RenderObject.h"
 #include "ShadowRoot.h"
index bc828fa..2f64992 100644 (file)
@@ -30,6 +30,7 @@
 #include "AnimationController.h"
 #include "AuthorStyleSheets.h"
 #include "CSSFontSelector.h"
+#include "ComposedTreeAncestorIterator.h"
 #include "ComposedTreeIterator.h"
 #include "ElementIterator.h"
 #include "ElementRareData.h"
@@ -39,7 +40,6 @@
 #include "LoaderStrategy.h"
 #include "MainFrame.h"
 #include "NodeRenderStyle.h"
-#include "NodeRenderingTraversal.h"
 #include "NodeTraversal.h"
 #include "PlatformStrategies.h"
 #include "RenderFullScreen.h"
@@ -327,7 +327,7 @@ void detachTextRenderer(Text& textNode)
 
 void updateTextRendererAfterContentChange(Text& textNode, unsigned offsetOfReplacedData, unsigned lengthOfReplacedData)
 {
-    ContainerNode* renderingParentNode = NodeRenderingTraversal::parent(&textNode);
+    auto* renderingParentNode = composedTreeAncestors(textNode).first();
     if (!renderingParentNode || !renderingParentNode->renderer())
         return;