Chromium Code Reviews| 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 |