| Index: third_party/WebKit/Source/core/layout/LayoutBox.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
|
| index 5eb6a702dc5e7dbd5f93fa1fbe618b4a728366b8..8bae979d47947e5126617202f7de3be316298a20 100644
|
| --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
|
| @@ -1842,44 +1842,102 @@ void LayoutBox::setPaginationStrut(LayoutUnit strut)
|
| ensureRareData().m_paginationStrut = strut;
|
| }
|
|
|
| -static bool isForcedBreakAllowed(const LayoutBox* child)
|
| +bool LayoutBox::isBreakBetweenControllable(EBreak breakValue) const
|
| {
|
| - // We currently only support forced breaks on in-flow block level elements, which is the minimum
|
| - // requirement according to the spec.
|
| - if (child->isInline() || child->isFloatingOrOutOfFlowPositioned())
|
| + if (breakValue == BreakAuto)
|
| + return true;
|
| + // We currently only support non-auto break-before and break-after values on in-flow block
|
| + // level elements, which is the minimum requirement according to the spec.
|
| + if (isInline() || isFloatingOrOutOfFlowPositioned())
|
| return false;
|
| - const LayoutBlock* curr = child->containingBlock();
|
| + const LayoutBlock* curr = containingBlock();
|
| if (!curr || !curr->isLayoutBlockFlow())
|
| return false;
|
| - const LayoutView* layoutView = child->view();
|
| - while (curr && curr != layoutView) {
|
| - if (curr->isLayoutFlowThread())
|
| - return true;
|
| + const LayoutView* layoutView = view();
|
| + bool viewIsPaginated = layoutView->fragmentationContext();
|
| + if (!viewIsPaginated && !flowThreadContainingBlock())
|
| + return false;
|
| + while (curr) {
|
| + if (curr == layoutView)
|
| + return viewIsPaginated && breakValue != BreakColumn && breakValue != BreakAvoidColumn;
|
| + if (curr->isLayoutFlowThread()) {
|
| + if (breakValue == BreakAvoid) // Valid in any kind of fragmentation context.
|
| + return true;
|
| + bool isMulticolValue = breakValue == BreakColumn || breakValue == BreakAvoidColumn;
|
| + if (toLayoutFlowThread(curr)->isLayoutPagedFlowThread())
|
| + return !isMulticolValue;
|
| + if (isMulticolValue)
|
| + return true;
|
| + // If this is a flow thread for a multicol container, and we have a break value for
|
| + // paged, we need to keep looking.
|
| + }
|
| if (curr->isFloatingOrOutOfFlowPositioned())
|
| return false;
|
| curr = curr->containingBlock();
|
| }
|
| - return true;
|
| + ASSERT_NOT_REACHED();
|
| + return false;
|
| +}
|
| +
|
| +bool LayoutBox::isBreakInsideControllable(EBreak breakValue) const
|
| +{
|
| + ASSERT(!isForcedFragmentainerBreakValue(breakValue));
|
| + if (breakValue == BreakAuto)
|
| + return true;
|
| + // First check multicol.
|
| + const LayoutFlowThread* flowThread = flowThreadContainingBlock();
|
| + // 'avoid-column' is only valid in a multicol context.
|
| + if (breakValue == BreakAvoidColumn)
|
| + return flowThread && !flowThread->isLayoutPagedFlowThread();
|
| + // 'avoid' is valid in any kind of fragmentation context.
|
| + if (breakValue == BreakAvoid && flowThread)
|
| + return true;
|
| + ASSERT(breakValue == BreakAvoidPage || breakValue == BreakAvoid);
|
| + if (view()->fragmentationContext())
|
| + return true; // The view is paginated, probably because we're printing.
|
| + if (!flowThread)
|
| + return false; // We're not inside any pagination context
|
| + // We're inside a flow thread. We need to be contained by a flow thread for paged overflow in
|
| + // order for pagination values to be valid, though.
|
| + for (const LayoutBlock* ancestor = flowThread; ancestor; ancestor = ancestor->containingBlock()) {
|
| + if (ancestor->isLayoutFlowThread() && toLayoutFlowThread(ancestor)->isLayoutPagedFlowThread())
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +EBreak LayoutBox::breakAfter() const
|
| +{
|
| + EBreak breakValue = style()->breakAfter();
|
| + if (breakValue == BreakAuto || isBreakBetweenControllable(breakValue))
|
| + return breakValue;
|
| + return BreakAuto;
|
| +}
|
| +
|
| +EBreak LayoutBox::breakBefore() const
|
| +{
|
| + EBreak breakValue = style()->breakBefore();
|
| + if (breakValue == BreakAuto || isBreakBetweenControllable(breakValue))
|
| + return breakValue;
|
| + return BreakAuto;
|
| +}
|
| +
|
| +EBreak LayoutBox::breakInside() const
|
| +{
|
| + EBreak breakValue = style()->breakInside();
|
| + if (breakValue == BreakAuto || isBreakInsideControllable(breakValue))
|
| + return breakValue;
|
| + return BreakAuto;
|
| }
|
|
|
| bool LayoutBox::hasForcedBreakBefore() const
|
| {
|
| - LayoutFlowThread* flowThread = flowThreadContainingBlock();
|
| - bool checkColumnBreaks = flowThread;
|
| - bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight(); // TODO(mstensho): Once columns can print, we have to check this.
|
| - bool checkBeforeAlways = (checkColumnBreaks && style()->breakBefore() == BreakColumn)
|
| - || (checkPageBreaks && style()->breakBefore() == BreakPage);
|
| - return checkBeforeAlways && isForcedBreakAllowed(this);
|
| + return isForcedFragmentainerBreakValue(breakBefore());
|
| }
|
|
|
| bool LayoutBox::hasForcedBreakAfter() const
|
| {
|
| - LayoutFlowThread* flowThread = flowThreadContainingBlock();
|
| - bool checkColumnBreaks = flowThread;
|
| - bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight(); // TODO(mstensho): Once columns can print, we have to check this.
|
| - bool checkAfterAlways = (checkColumnBreaks && style()->breakAfter() == BreakColumn)
|
| - || (checkPageBreaks && style()->breakAfter() == BreakPage);
|
| - return checkAfterAlways && isForcedBreakAllowed(this);
|
| + return isForcedFragmentainerBreakValue(breakAfter());
|
| }
|
|
|
| LayoutRect LayoutBox::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const
|
| @@ -4182,12 +4240,8 @@ LayoutBox::PaginationBreakability LayoutBox::paginationBreakability() const
|
| || (isOutOfFlowPositioned() && style()->position() == FixedPosition))
|
| return ForbidBreaks;
|
|
|
| - bool checkColumnBreaks = flowThreadContainingBlock();
|
| - bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight();
|
| - EBreak breakInside = style()->breakInside();
|
| - bool isUnsplittable = (checkColumnBreaks && (breakInside == BreakAvoid || breakInside == BreakAvoidColumn))
|
| - || (checkPageBreaks && (breakInside == BreakAvoid || breakInside == BreakAvoidPage));
|
| - if (isUnsplittable)
|
| + EBreak breakValue = breakInside();
|
| + if (breakValue == BreakAvoid || breakValue == BreakAvoidPage || breakValue == BreakAvoidColumn)
|
| return AvoidBreaks;
|
| return AllowAnyBreaks;
|
| }
|
|
|