| Index: third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| index cc04c00db8e6b756d1ace3ef12bb78a19a4dfe4f..fbc996b507e046373021b1d64e4c87efff5f9faa 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
|
| @@ -81,6 +81,22 @@ static inline bool isMultiColumnContainer(const LayoutObject& object)
|
| return toLayoutBlockFlow(object).multiColumnFlowThread();
|
| }
|
|
|
| +static inline bool canContainSpannerInParentFragmentationContext(const LayoutObject& object)
|
| +{
|
| + if (!object.isLayoutBlockFlow())
|
| + return false;
|
| + const LayoutBlockFlow& blockFlow = toLayoutBlockFlow(object);
|
| + return !blockFlow.createsNewFormattingContext()
|
| + && blockFlow.paginationBreakability() != LayoutBox::ForbidBreaks
|
| + && !isMultiColumnContainer(blockFlow);
|
| +}
|
| +
|
| +static inline bool hasAnyColumnSpanners(const LayoutMultiColumnFlowThread& flowThread)
|
| +{
|
| + LayoutBox* firstBox = flowThread.firstMultiColumnBox();
|
| + return firstBox && (firstBox != flowThread.lastMultiColumnBox() || firstBox->isLayoutMultiColumnSpannerPlaceholder());
|
| +}
|
| +
|
| // Find the next layout object that has the multicol container in its containing block chain, skipping nested multicol containers.
|
| static LayoutObject* nextInPreOrderAfterChildrenSkippingOutOfFlow(LayoutMultiColumnFlowThread* flowThread, LayoutObject* descendant)
|
| {
|
| @@ -211,10 +227,7 @@ LayoutMultiColumnSpannerPlaceholder* LayoutMultiColumnFlowThread::containingColu
|
| {
|
| ASSERT(descendant->isDescendantOf(this));
|
|
|
| - // Before we spend time on searching the ancestry, see if there's a quick way to determine
|
| - // whether there might be any spanners at all.
|
| - LayoutBox* firstBox = firstMultiColumnBox();
|
| - if (!firstBox || (firstBox == lastMultiColumnBox() && firstBox->isLayoutMultiColumnSet()))
|
| + if (!hasAnyColumnSpanners(*this))
|
| return nullptr;
|
|
|
| // We have spanners. See if the layoutObject in question is one or inside of one then.
|
| @@ -596,10 +609,7 @@ bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d
|
| ASSERT(ancestor == this);
|
| return true;
|
| }
|
| - if (!ancestor->isLayoutBlockFlow())
|
| - return false;
|
| - const LayoutBlockFlow& ancestorBlockFlow = *toLayoutBlockFlow(ancestor);
|
| - if (ancestorBlockFlow.createsNewFormattingContext() || ancestorBlockFlow.paginationBreakability() == ForbidBreaks)
|
| + if (!canContainSpannerInParentFragmentationContext(*ancestor))
|
| return false;
|
| }
|
| ASSERT_NOT_REACHED();
|
| @@ -931,4 +941,27 @@ void LayoutMultiColumnFlowThread::contentWasLaidOut(LayoutUnit logicalBottomInFl
|
| appendNewFragmentainerGroupIfNeeded(logicalBottomInFlowThreadAfterPagination);
|
| }
|
|
|
| +bool LayoutMultiColumnFlowThread::canSkipLayout(const LayoutBox& root) const
|
| +{
|
| + // Objects containing spanners is all we need to worry about, so if there are no spanners at all
|
| + // in this multicol container, we can just return the good news right away.
|
| + if (!hasAnyColumnSpanners(*this))
|
| + return true;
|
| +
|
| + LayoutObject* next;
|
| + for (const LayoutObject* object = &root; object; object = next) {
|
| + if (object->isColumnSpanAll()) {
|
| + // A spanner potentially ends one fragmentainer group and begins a new one, and thus
|
| + // determines the flow thread portion bottom and top of adjacent fragmentainer
|
| + // groups. It's just too hard to guess these values without laying out.
|
| + return false;
|
| + }
|
| + if (canContainSpannerInParentFragmentationContext(*object))
|
| + next = object->nextInPreOrder(&root);
|
| + else
|
| + next = object->nextInPreOrderAfterChildren(&root);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| } // namespace blink
|
|
|