Index: Source/WebCore/rendering/RenderBlock.cpp |
=================================================================== |
--- Source/WebCore/rendering/RenderBlock.cpp (revision 86003) |
+++ Source/WebCore/rendering/RenderBlock.cpp (working copy) |
@@ -77,6 +77,8 @@ |
static int gDelayUpdateScrollInfo = 0; |
static DelayedUpdateScrollInfoSet* gDelayedUpdateScrollInfoSet = 0; |
+bool RenderBlock::s_canPropagateFloatIntoSibling = false; |
+ |
// Our MarginInfo state used when laying out block children. |
RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int beforeBorderPadding, int afterBorderPadding) |
: m_atBeforeSideOfBlock(true) |
@@ -196,6 +198,8 @@ |
void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle) |
{ |
+ s_canPropagateFloatIntoSibling = style() ? !isFloatingOrPositioned() && !avoidsFloats() : false; |
+ |
setReplaced(newStyle->isDisplayInlineType()); |
if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) { |
@@ -259,6 +263,15 @@ |
updateBeforeAfterContent(BEFORE); |
updateBeforeAfterContent(AFTER); |
} |
+ |
+ // 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. |
+ bool canPropagateFloatIntoSibling = !isFloatingOrPositioned() && !avoidsFloats(); |
+ if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) { |
+ markAllDescendantsWithFloatsForLayout(); |
+ markSiblingsWithFloatsForLayout(); |
+ } |
} |
void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId) |
@@ -3798,6 +3811,30 @@ |
} |
} |
+void RenderBlock::markSiblingsWithFloatsForLayout() |
+{ |
+ FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
+ FloatingObjectSetIterator end = floatingObjectSet.end(); |
+ for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { |
+ if (logicalBottomForFloat(*it) > logicalHeight()) { |
+ RenderBox* floatingBox = (*it)->renderer(); |
+ |
+ RenderObject* next = nextSibling(); |
+ while (next) { |
+ if (next->isRenderBlock() && !next->isFloatingOrPositioned() && !toRenderBlock(next)->avoidsFloats()) { |
+ RenderBlock* nextBlock = toRenderBlock(next); |
+ if (nextBlock->containsFloat(floatingBox)) |
+ nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox); |
+ else |
+ break; |
+ } |
+ |
+ next = next->nextSibling(); |
+ } |
+ } |
+ } |
+} |
+ |
int RenderBlock::getClearDelta(RenderBox* child, int yPos) |
{ |
// There is no need to compute clearance if we have no floats. |