| Index: Source/core/layout/LayoutBlock.cpp
|
| diff --git a/Source/core/layout/LayoutBlock.cpp b/Source/core/layout/LayoutBlock.cpp
|
| index f1a16e36f0ccc7825328e57370ca33ba0e78a378..37d35af274b1bbe8ce821c83ed95d5f0739297e6 100644
|
| --- a/Source/core/layout/LayoutBlock.cpp
|
| +++ b/Source/core/layout/LayoutBlock.cpp
|
| @@ -300,8 +300,14 @@ void LayoutBlock::styleDidChange(StyleDifference diff, const ComputedStyle* oldS
|
| {
|
| LayoutBox::styleDidChange(diff, oldStyle);
|
|
|
| - if (isFloatingOrOutOfFlowPositioned() && oldStyle && !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && parent() && parent()->isLayoutBlockFlow())
|
| + if (isFloatingOrOutOfFlowPositioned() && oldStyle && !oldStyle->isFloating() && !oldStyle->hasOutOfFlowPosition() && parent() && parent()->isLayoutBlockFlow()) {
|
| toLayoutBlock(parent())->removeAnonymousWrappersIfRequired();
|
| + // Reparent to an adjacent anonymous block if one is available.
|
| + if (previousSibling() && previousSibling()->isAnonymousBlock())
|
| + toLayoutBlock(parent())->moveChildTo(toLayoutBlock(previousSibling()), this, nullptr, false);
|
| + else if (nextSibling() && nextSibling()->isAnonymousBlock())
|
| + toLayoutBlock(parent())->moveChildTo(toLayoutBlock(nextSibling()), this, nextSibling()->slowFirstChild(), false);
|
| + }
|
|
|
| const ComputedStyle& newStyle = styleRef();
|
|
|
| @@ -477,7 +483,20 @@ void LayoutBlock::addChildIgnoringContinuation(LayoutObject* newChild, LayoutObj
|
| // No suitable existing anonymous box - create a new one.
|
| LayoutBlock* newBox = createAnonymousBlock();
|
| LayoutBox::addChild(newBox, beforeChild);
|
| + // Reparent adjacent floating or out-of-flow siblings to the new box.
|
| + LayoutObject* child = newBox->previousSibling();
|
| + while (child && child->isFloatingOrOutOfFlowPositioned()) {
|
| + LayoutObject* sibling = child->previousSibling();
|
| + moveChildTo(newBox, child, newBox->firstChild(), false);
|
| + child = sibling;
|
| + }
|
| newBox->addChild(newChild);
|
| + child = newBox->nextSibling();
|
| + while (child && child->isFloatingOrOutOfFlowPositioned()) {
|
| + LayoutObject* sibling = child->nextSibling();
|
| + moveChildTo(newBox, child, nullptr, false);
|
| + child = sibling;
|
| + }
|
| return;
|
| }
|
| }
|
| @@ -671,6 +690,20 @@ void LayoutBlock::collapseAnonymousBlockChild(LayoutBlock* parent, LayoutBlock*
|
| child->destroy();
|
| }
|
|
|
| +static inline bool shouldMakeChildrenInline(const LayoutBlock* block)
|
| +{
|
| + if (!block->isLayoutBlockFlow())
|
| + return false;
|
| + LayoutObject* child = block->firstChild();
|
| + while (child) {
|
| + // TODO(rhogan): If we encounter anonymous blocks with inline children we should fold them in here.
|
| + if (!child->isFloatingOrOutOfFlowPositioned())
|
| + return false;
|
| + child = child->nextSibling();
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void LayoutBlock::removeChild(LayoutObject* oldChild)
|
| {
|
| // No need to waste time in merging or removing empty anonymous blocks.
|
| @@ -773,6 +806,9 @@ void LayoutBlock::removeChild(LayoutObject* oldChild)
|
| setContinuation(nullptr);
|
| destroy();
|
| }
|
| + } else if (!beingDestroyed() && !oldChild->isFloatingOrOutOfFlowPositioned() && shouldMakeChildrenInline(this)) {
|
| + // If the child we're removing means that we can now treat all children as inline without the need for anonymous blocks, then do that.
|
| + setChildrenInline(true);
|
| }
|
| }
|
|
|
|
|