Make loops in RenderObject::containingBlock homogeneous in their forms to simplify
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Apr 2013 19:58:08 +0000 (19:58 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Apr 2013 19:58:08 +0000 (19:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=114853

Reviewed by David Hyatt.

This patch prepares us to avoid computing containing blocks during a depth-first traversal of the render tree.

Extracted inline functions out of RenderBlock::containingBlock to make the code simpler. Also moved the code
to obtain the nearest containing block out of the loop for a relatively positioned inline.

* rendering/RenderObject.cpp:
(WebCore::isNonReplacedInlineInFlowPosition): Extracted.
(WebCore::isContainingBlockCandidateForAbsolutelyPositionedObject): Extracted.
(WebCore::isNonRenderBlockInline): Extracted.
(WebCore::RenderObject::containingBlock): Refactored as stated above.

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderObject.cpp

index c53c41dc229d78f9fa8295c79b61dde9cb3355e0..9ce418da33293da3861b06ceb13cb5d00febabef 100644 (file)
@@ -1,3 +1,21 @@
+2013-04-18  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make loops in RenderObject::containingBlock homogeneous in their forms to simplify
+        https://bugs.webkit.org/show_bug.cgi?id=114853
+
+        Reviewed by David Hyatt.
+
+        This patch prepares us to avoid computing containing blocks during a depth-first traversal of the render tree.
+
+        Extracted inline functions out of RenderBlock::containingBlock to make the code simpler. Also moved the code
+        to obtain the nearest containing block out of the loop for a relatively positioned inline.
+
+        * rendering/RenderObject.cpp:
+        (WebCore::isNonReplacedInlineInFlowPosition): Extracted.
+        (WebCore::isContainingBlockCandidateForAbsolutelyPositionedObject): Extracted.
+        (WebCore::isNonRenderBlockInline): Extracted.
+        (WebCore::RenderObject::containingBlock): Refactored as stated above.
+
 2013-04-19  Tim Horton  <timothy_horton@apple.com>
 
         WebKit should not decode or support PDF favicons
 2013-04-19  Tim Horton  <timothy_horton@apple.com>
 
         WebKit should not decode or support PDF favicons
index 3660f0a34a054e7ef0114846521e6a589465cbaa..95fb75cd6fdeae7a103212b5e55b2ade1e05f024 100644 (file)
@@ -768,48 +768,46 @@ void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
     toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
 }
 
     toRenderLayerModelObject(this)->layer()->setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
 }
 
+static inline bool isContainingBlockCandidateForAbsolutelyPositionedObject(RenderObject* object)
+{
+    return object->style()->position() != StaticPosition
+        || (object->hasTransform() && object->isRenderBlock())
+#if ENABLE(SVG)
+        || object->isSVGForeignObject()
+#endif
+        || object->isRenderView();
+}
+
+static inline bool isNonRenderBlockInline(RenderObject* object)
+{
+    return (object->isInline() && !object->isReplaced()) || !object->isRenderBlock();
+}
+
 RenderBlock* RenderObject::containingBlock() const
 {
     RenderObject* o = parent();
     if (!o && isRenderScrollbarPart())
         o = toRenderScrollbarPart(this)->rendererOwningScrollbar();
 RenderBlock* RenderObject::containingBlock() const
 {
     RenderObject* o = parent();
     if (!o && isRenderScrollbarPart())
         o = toRenderScrollbarPart(this)->rendererOwningScrollbar();
+
     if (!isText() && m_style->position() == FixedPosition) {
     if (!isText() && m_style->position() == FixedPosition) {
-        while (o) {
-            if (o->canContainFixedPositionObjects())
-                break;
+        while (o && !o->canContainFixedPositionObjects())
             o = o->parent();
             o = o->parent();
-        }
         ASSERT(!o || !o->isAnonymousBlock());
     } else if (!isText() && m_style->position() == AbsolutePosition) {
         ASSERT(!o || !o->isAnonymousBlock());
     } else if (!isText() && m_style->position() == AbsolutePosition) {
-        while (o) {
-            // For relpositioned inlines, we return the nearest non-anonymous enclosing block. We don't try
-            // to return the inline itself.  This allows us to avoid having a positioned objects
-            // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result
-            // from this method.  The container() method can actually be used to obtain the
-            // inline directly.
-            if (o->style()->position() != StaticPosition && (!o->isInline() || o->isReplaced()))
-                break;
-            if (o->isRenderView())
-                break;
-            if (o->hasTransform() && o->isRenderBlock())
-                break;
-
-            if (o->style()->hasInFlowPosition() && o->isInline() && !o->isReplaced()) {
-                o = o->containingBlock();
-                break;
-            }
-#if ENABLE(SVG)
-            if (o->isSVGForeignObject()) //foreignObject is the containing block for contents inside it
-                break;
-#endif
-
+        while (o && !isContainingBlockCandidateForAbsolutelyPositionedObject(o))
             o = o->parent();
             o = o->parent();
-        }
+
+        // For a relatively positioned inline, return its nearest non-anonymous containing block,
+        // not the inline itself, to avoid having a positioned objects list in all RenderInlines
+        // and use RenderBlock* as this function's return type.
+        // Use RenderBlock::container() to obtain the inline.
+        if (o->isRenderInline())
+            o = o->containingBlock();
 
         while (o && o->isAnonymousBlock())
             o = o->containingBlock();
     } else {
 
         while (o && o->isAnonymousBlock())
             o = o->containingBlock();
     } else {
-        while (o && ((o->isInline() && !o->isReplaced()) || !o->isRenderBlock()))
+        while (o && isNonRenderBlockInline(o))
             o = o->parent();
     }
 
             o = o->parent();
     }