Add lineageOfType renderer iterator and start using it.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Jan 2014 23:19:40 +0000 (23:19 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 Jan 2014 23:19:40 +0000 (23:19 +0000)
<https://webkit.org/b/126456>

Add a convenient way to iterate over a renderers ancestry *including*
the starting point renderer (if it meets the type criteria.)

This works just like lineageOfType for Elements.

Reviewed by Geoffrey Garen.

* rendering/RenderAncestorIterator.h:
(WebCore::lineageOfType):

    Added. Returns an adapter for walking a renderer's entire lineage
    matching any renderer of the given type.

* rendering/RenderBoxModelObject.h:
* rendering/RenderLayerModelObject.h:

    Add the requisite isRendererOfType<T> helpers.

* rendering/RenderBox.cpp:
(WebCore::RenderBox::enclosingFloatPaintingLayer):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::enclosingLayer):
(WebCore::RenderObject::enclosingBox):
(WebCore::RenderObject::enclosingBoxModelObject):

    Simplify with lineageOfType. Added some FIXMEs about functions
    that should return references instead of pointers.

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderAncestorIterator.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBoxModelObject.h
Source/WebCore/rendering/RenderLayerModelObject.h
Source/WebCore/rendering/RenderObject.cpp

index abecaea66594c6f39bcf33ee8fe52f312d4a5e51..3882c17457a394b0bcdc28dedafc9ecc786bb997 100644 (file)
@@ -1,3 +1,36 @@
+2014-01-03  Andreas Kling  <akling@apple.com>
+
+        Add lineageOfType renderer iterator and start using it.
+        <https://webkit.org/b/126456>
+
+        Add a convenient way to iterate over a renderers ancestry *including*
+        the starting point renderer (if it meets the type criteria.)
+
+        This works just like lineageOfType for Elements.
+
+        Reviewed by Geoffrey Garen.
+
+        * rendering/RenderAncestorIterator.h:
+        (WebCore::lineageOfType):
+
+            Added. Returns an adapter for walking a renderer's entire lineage
+            matching any renderer of the given type.
+
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderLayerModelObject.h:
+
+            Add the requisite isRendererOfType<T> helpers.
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::enclosingFloatPaintingLayer):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::enclosingLayer):
+        (WebCore::RenderObject::enclosingBox):
+        (WebCore::RenderObject::enclosingBoxModelObject):
+
+            Simplify with lineageOfType. Added some FIXMEs about functions
+            that should return references instead of pointers.
+
 2014-01-03  Martin Robinson  <mrobinson@igalia.com>
 
         Small build fix for the GTK+ CMake port
index 7d2fd6edfd17f02c5bc1a920db094dbb75771112..39dd05e725213391e190c17a633f9accb4ef2581 100644 (file)
@@ -72,6 +72,8 @@ private:
 
 template <typename T> RenderAncestorIteratorAdapter<T> ancestorsOfType(RenderObject&);
 template <typename T> RenderAncestorConstIteratorAdapter<T> ancestorsOfType(const RenderObject&);
+template <typename T> RenderAncestorIteratorAdapter<T> lineageOfType(RenderObject&);
+template <typename T> RenderAncestorConstIteratorAdapter<T> lineageOfType(const RenderObject&);
 
 // RenderAncestorIterator
 
@@ -181,6 +183,22 @@ inline RenderAncestorConstIteratorAdapter<T> ancestorsOfType(const RenderObject&
     return RenderAncestorConstIteratorAdapter<T>(first);
 }
 
+template <typename T>
+inline RenderAncestorIteratorAdapter<T> lineageOfType(RenderObject& first)
+{
+    if (isRendererOfType<const T>(first))
+        return RenderAncestorIteratorAdapter<T>(static_cast<T*>(&first));
+    return ancestorsOfType<T>(first);
+}
+
+template <typename T>
+inline RenderAncestorConstIteratorAdapter<T> lineageOfType(const RenderObject& first)
+{
+    if (isRendererOfType<const T>(first))
+        return RenderAncestorConstIteratorAdapter<T>(static_cast<const T*>(&first));
+    return ancestorsOfType<T>(first);
+}
+
 }
 
 #endif
index c6f9f719e72c36036431d94659c326902cb31ff5..1be2f1026b6f60e954031f3c3c148e33a86fc13e 100644 (file)
@@ -4485,14 +4485,11 @@ int RenderBox::baselinePosition(FontBaseline baselineType, bool /*firstLine*/, L
 
 RenderLayer* RenderBox::enclosingFloatPaintingLayer() const
 {
-    const RenderElement* curr = this;
-    while (curr) {
-        RenderLayer* layer = curr->hasLayer() && curr->isBox() ? toRenderBox(curr)->layer() : 0;
-        if (layer && layer->isSelfPaintingLayer())
-            return layer;
-        curr = curr->parent();
+    for (auto& box : lineageOfType<RenderBox>(*this)) {
+        if (box.layer() && box.layer()->isSelfPaintingLayer())
+            return box.layer();
     }
-    return 0;
+    return nullptr;
 }
 
 LayoutRect RenderBox::logicalVisualOverflowRectForPropagation(RenderStyle* parentStyle) const
index b3e37bed2a6e1acf073705c673571d540cf4970e..22c319f34a0fdc3e83bda9f21677fad9ee731717 100644 (file)
@@ -345,6 +345,8 @@ private:
     void paintMaskForTextFillBox(ImageBuffer*, const IntRect&, InlineFlowBox*, const LayoutRect&, RenderRegion*);
 };
 
+template <> inline bool isRendererOfType<const RenderBoxModelObject>(const RenderObject& renderer) { return renderer.isBoxModelObject(); }
+
 RENDER_OBJECT_TYPE_CASTS(RenderBoxModelObject, isBoxModelObject())
 
 } // namespace WebCore
index 3b03d69e352f2b472b76d34db031cbf4dc85ef7d..6c75b37f4162274aa2ef9fdabfa9d6f981d819ca 100644 (file)
@@ -67,6 +67,8 @@ private:
     static bool s_layerWasSelfPainting;
 };
 
+template <> inline bool isRendererOfType<const RenderLayerModelObject>(const RenderObject& renderer) { return renderer.isRenderLayerModelObject(); }
+
 RENDER_OBJECT_TYPE_CASTS(RenderLayerModelObject, isRenderLayerModelObject())
 
 } // namespace WebCore
index 73a8e33adebc04ee600ce5c9510386ae8caba297..f3c730ff6fa1016684329a7dae15c6c6923d425e 100644 (file)
@@ -49,6 +49,7 @@
 #include "RenderFlowThread.h"
 #include "RenderGeometryMap.h"
 #include "RenderInline.h"
+#include "RenderIterator.h"
 #include "RenderLayer.h"
 #include "RenderLayerBacking.h"
 #include "RenderNamedFlowThread.h"
@@ -472,14 +473,11 @@ void RenderObject::resetTextAutosizing()
 
 RenderLayer* RenderObject::enclosingLayer() const
 {
-    const RenderObject* curr = this;
-    while (curr) {
-        RenderLayer* layer = curr->hasLayer() ? toRenderLayerModelObject(curr)->layer() : 0;
-        if (layer)
-            return layer;
-        curr = curr->parent();
+    for (auto& renderer : lineageOfType<RenderLayerModelObject>(*this)) {
+        if (renderer.layer())
+            return renderer.layer();
     }
-    return 0;
+    return nullptr;
 }
 
 bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
@@ -494,28 +492,14 @@ bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlign
 
 RenderBox* RenderObject::enclosingBox() const
 {
-    RenderObject* curr = const_cast<RenderObject*>(this);
-    while (curr) {
-        if (curr->isBox())
-            return toRenderBox(curr);
-        curr = curr->parent();
-    }
-    
-    ASSERT_NOT_REACHED();
-    return 0;
+    // FIXME: This should return a reference; it can always find the root RenderView.
+    return lineageOfType<RenderBox>(const_cast<RenderObject&>(*this)).first();
 }
 
 RenderBoxModelObject* RenderObject::enclosingBoxModelObject() const
 {
-    RenderObject* curr = const_cast<RenderObject*>(this);
-    while (curr) {
-        if (curr->isBoxModelObject())
-            return toRenderBoxModelObject(curr);
-        curr = curr->parent();
-    }
-
-    ASSERT_NOT_REACHED();
-    return 0;
+    // FIXME: This should return a reference; it can always find the root RenderView.
+    return lineageOfType<RenderBoxModelObject>(const_cast<RenderObject&>(*this)).first();
 }
 
 bool RenderObject::fixedPositionedWithNamedFlowContainingBlock() const