OSDN Git Service

Cherry-pick WebKit change 89165 to fix a crash due to floats not being removed
authorSteve Block <steveblock@google.com>
Fri, 14 Oct 2011 10:30:59 +0000 (11:30 +0100)
committerSteve Block <steveblock@google.com>
Fri, 14 Oct 2011 14:54:54 +0000 (15:54 +0100)
This is part 1 of 2 of the fix.

See http://trac.webkit.org/changeset/89165

Bug: 5249309
Change-Id: I1159aab70e1fa6d3025761423c4164682dc97b64

Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h

index 792b809..4df6066 100644 (file)
@@ -269,12 +269,33 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
     }
 
     // After our style changed, if we lose our ability to propagate floats into next sibling
-    // blocks, then we need to mark our descendants with floats for layout and clear all floats
-    // from next sibling blocks that exist in our floating objects list. See bug 56299.
+    // blocks, then we need to find the top most parent containing that overhanging float and
+    // then mark its descendants with floats for layout and clear all floats from its next
+    // sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
     bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats();
     if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
-        markAllDescendantsWithFloatsForLayout();
-        markSiblingsWithFloatsForLayout();
+        RenderBlock* parentBlock = this;
+        FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+        FloatingObjectSetIterator end = floatingObjectSet.end();
+
+        for (RenderObject* curr = parent(); curr && !curr->isRenderView(); curr = curr->parent()) {
+            if (curr->isRenderBlock()) {
+                RenderBlock* currBlock = toRenderBlock(curr);
+
+                if (currBlock->hasOverhangingFloats()) {
+                    for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
+                        RenderBox* renderer = (*it)->renderer();
+                        if (currBlock->hasOverhangingFloat(renderer)) {
+                            parentBlock = currBlock;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+              
+        parentBlock->markAllDescendantsWithFloatsForLayout();
+        parentBlock->markSiblingsWithFloatsForLayout();
     }
 }
 
@@ -3738,6 +3759,19 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int logicalLeftOffset,
     return lowestFloatLogicalBottom;
 }
 
+bool RenderBlock::hasOverhangingFloat(RenderBox* renderer)
+{
+    if (!m_floatingObjects || hasColumns() || !parent())
+        return false;
+
+    FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
+    FloatingObjectSetIterator it = floatingObjectSet.find<RenderBox*, FloatingObjectHashTranslator>(renderer);
+    if (it == floatingObjectSet.end())
+        return false;
+
+    return logicalBottomForFloat(*it) > logicalHeight();
+}
+
 void RenderBlock::addIntrudingFloats(RenderBlock* prev, int logicalLeftOffset, int logicalTopOffset)
 {
     // If the parent or previous sibling doesn't have any floats to add, don't bother.
index d45ab66..7ca13c6 100644 (file)
@@ -542,6 +542,7 @@ private:
     virtual bool avoidsFloats() const;
 
     bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
+    bool hasOverhangingFloat(RenderBox*);
     void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
     int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats);