Index: Source/core/layout/LayoutBlockFlow.cpp |
diff --git a/Source/core/layout/LayoutBlockFlow.cpp b/Source/core/layout/LayoutBlockFlow.cpp |
index 40f01f81436b7517574d9b64912f659e33c9ac2b..7ea7e1082e4f9aa830b125a4e11b13699607b179 100644 |
--- a/Source/core/layout/LayoutBlockFlow.cpp |
+++ b/Source/core/layout/LayoutBlockFlow.cpp |
@@ -475,16 +475,23 @@ inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
updateLogicalHeight(); |
LayoutUnit newHeight = logicalHeight(); |
- if (oldHeight > newHeight && !childrenInline()) { |
+ if (!childrenInline()) { |
+ LayoutBlockFlow* lowestBlock = nullptr; |
+ bool addedOverhangingFloats = false; |
// One of our children's floats may have become an overhanging float for us. |
for (LayoutObject* child = lastChild(); child; child = child->previousSibling()) { |
+ // TODO(robhogan): We should exclude blocks that create formatting contexts, not just out of flow or floating blocks. |
if (child->isLayoutBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) { |
LayoutBlockFlow* block = toLayoutBlockFlow(child); |
- if (block->lowestFloatLogicalBottom() + block->logicalTop() <= newHeight) |
+ lowestBlock = block; |
+ if (oldHeight <= newHeight || block->lowestFloatLogicalBottom() + block->logicalTop() <= newHeight) |
break; |
addOverhangingFloats(block, false); |
+ addedOverhangingFloats = true; |
} |
} |
+ if (!addedOverhangingFloats) |
+ addLowestFloatFromChildren(lowestBlock); |
} |
bool heightChanged = (previousHeight != newHeight); |
@@ -500,6 +507,26 @@ inline bool LayoutBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & |
return true; |
} |
+void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) |
leviw_travelin_and_unemployed
2015/05/22 20:52:02
This is a little weird, as this will bubble up the
rhogan
2015/05/23 11:56:51
Exactly, which would be the case with a genuinely
leviw_travelin_and_unemployed
2015/05/26 23:15:35
I guess I was trying to suggest that we should nam
|
+{ |
+ // TODO(robhogan): Make createsNewFormattingContext an ASSERT. |
+ if (!block || !block->containsFloats() || block->createsNewFormattingContext()) |
+ return; |
+ |
+ FloatingObject* floatingObject = block->m_floatingObjects->lowestFloatObject(); |
+ if (!floatingObject || containsFloat(floatingObject->layoutObject())) |
+ return; |
+ |
+ LayoutUnit childLogicalTop = block->logicalTop(); |
+ LayoutUnit childLogicalLeft = block->logicalLeft(); |
+ LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(-childLogicalLeft, -childLogicalTop) : LayoutSize(-childLogicalTop, -childLogicalLeft); |
+ |
+ if (!m_floatingObjects) |
+ createFloatingObjects(); |
+ FloatingObject* newFloatingObject = m_floatingObjects->add(floatingObject->copyToNewContainer(offset, false, true)); |
+ newFloatingObject->setIsLowestNonOverhangingFloatInChild(true); |
+} |
+ |
void LayoutBlockFlow::determineLogicalLeftPositionForChild(LayoutBox& child) |
{ |
LayoutUnit startPosition = borderStart() + paddingStart(); |
@@ -2586,7 +2613,7 @@ void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, bool makeChil |
// behaves properly). We always want to propagate the desire to paint the float as |
// far out as we can, to the outermost block that overlaps the float, stopping only |
// if we hit a self-painting layer boundary. |
- if (floatingObject->layoutObject()->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer()) { |
+ if (floatingObject->layoutObject()->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer() && !floatingObject->isLowestNonOverhangingFloatInChild()) { |
floatingObject->setShouldPaint(false); |
shouldPaint = true; |
} |
@@ -2597,7 +2624,7 @@ void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, bool makeChil |
m_floatingObjects->add(floatingObject->copyToNewContainer(offset, shouldPaint, true)); |
} |
} else { |
- if (makeChildPaintOtherFloats && !floatingObject->shouldPaint() && !floatingObject->layoutObject()->hasSelfPaintingLayer() |
+ if (makeChildPaintOtherFloats && !floatingObject->shouldPaint() && !floatingObject->layoutObject()->hasSelfPaintingLayer() && !floatingObject->isLowestNonOverhangingFloatInChild() |
&& floatingObject->layoutObject()->isDescendantOf(child) && floatingObject->layoutObject()->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) { |
// The float is not overhanging from this block, so if it is a descendant of the child, the child should |
// paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing |