| Index: Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| diff --git a/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| index eb55299f7c228df950acc4daddbf5c9ffd99570a..16203d6ff17d8ed4a43672b7c07237a42d1c4cb3 100644
|
| --- a/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| +++ b/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| @@ -361,6 +361,25 @@ void LayoutMultiColumnFlowThread::columnRuleStyleDidChange()
|
| columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange);
|
| }
|
|
|
| +bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(LayoutBox* spannerObjectInFlowThread)
|
| +{
|
| + ASSERT(spannerObjectInFlowThread->spannerPlaceholder());
|
| + if (descendantIsValidColumnSpanner(spannerObjectInFlowThread))
|
| + return false; // Still a valid spanner.
|
| +
|
| + // No longer a valid spanner. Get rid of the placeholder.
|
| + destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder());
|
| + ASSERT(!spannerObjectInFlowThread->spannerPlaceholder());
|
| +
|
| + // We may have a new containing block, since we're no longer a spanner. Mark it for relayout.
|
| + spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::ColumnsChanged);
|
| +
|
| + // Now generate a column set for this ex-spanner, if needed and none is there for us already.
|
| + flowThreadDescendantWasInserted(spannerObjectInFlowThread);
|
| +
|
| + return true;
|
| +}
|
| +
|
| void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const
|
| {
|
| LayoutBlock* columnBlock = multiColumnBlockFlow();
|
| @@ -458,13 +477,15 @@ void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(LayoutMultiColumnSpa
|
|
|
| bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* descendant) const
|
| {
|
| + // This method needs to behave correctly in the following situations:
|
| + // - When the descendant doesn't have a spanner placeholder but should have one (return true)
|
| + // - When the descendant doesn't have a spanner placeholder and still should not have one (return false)
|
| + // - When the descendant has a spanner placeholder but should no longer have one (return false)
|
| + // - When the descendant has a spanner placeholder and should still have one (return true)
|
| +
|
| // We assume that we're inside the flow thread. This function is not to be called otherwise.
|
| ASSERT(descendant->isDescendantOf(this));
|
|
|
| - // We're evaluating if the descendant should be turned into a proper spanner. It shouldn't
|
| - // already be one.
|
| - ASSERT(!descendant->spannerPlaceholder());
|
| -
|
| // The spec says that column-span only applies to in-flow block-level elements.
|
| if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox() || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned())
|
| return false;
|
| @@ -475,7 +496,7 @@ bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
|
| }
|
|
|
| // This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one.
|
| - for (LayoutBlock* ancestor = descendant->containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
|
| + for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor; ancestor = ancestor->containingBlock()) {
|
| if (ancestor->isLayoutFlowThread()) {
|
| ASSERT(ancestor == this);
|
| return true;
|
| @@ -712,8 +733,27 @@ void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec
|
| // of the multicol is bad.
|
| return;
|
| }
|
| - if (oldStyle.hasOutOfFlowPosition() && !styleRef().hasOutOfFlowPosition())
|
| + if (styleRef().hasOutOfFlowPosition())
|
| + return;
|
| +
|
| + // We're not out of flow.
|
| + if (oldStyle.hasOutOfFlowPosition()) {
|
| + // ... but we used to be out of flow. So we might need to insert a column set (or
|
| + // spanner placeholder, in case this descendant is now a valid column spanner).
|
| flowThreadDescendantWasInserted(descendant);
|
| + return;
|
| + }
|
| + if (descendantIsValidColumnSpanner(descendant)) {
|
| + // We went from being regular column content to becoming a spanner.
|
| + ASSERT(!toLayoutBox(descendant)->spannerPlaceholder());
|
| +
|
| + // First remove this as regular column content. Note that this will walk the entire subtree
|
| + // of |descendant|. There might be spanners there (which won't be spanners anymore, since
|
| + // we're not allowed to nest spanners), whose placeholders must die.
|
| + flowThreadDescendantWillBeRemoved(descendant);
|
| +
|
| + createAndInsertSpannerPlaceholder(toLayoutBox(descendant), nextInPreOrderAfterChildrenSkippingOutOfFlow(this, descendant));
|
| + }
|
| }
|
|
|
| void LayoutMultiColumnFlowThread::computePreferredLogicalWidths()
|
|
|