Chromium Code Reviews

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBox.cpp

Issue 1762983002: Only honor break-* values when appropriate. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update some unit tests too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
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;
}
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBox.h ('k') | third_party/WebKit/Source/core/layout/PaginationTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine