Bug 1308876 - Mark lines dirty when we abort their reflow due to page-break-inside:avoid. r=mats

Both of the changes are needed to fix
layout/reftests/w3c-css/submitted/css21/pagination/moz-css21-float-page-break-inside-avoid-4.html
with the primary patch in bug 1308876.

That patch changes the transfer of NS_FRAME_IS_DIRTY from parent to
child so that it happens at the start of the parent's reflow rather than
later at the start of the child's reflow, which means that frames that
are pulled into a dirty frame during reflow are not marked dirty (and
thus forced to reflow all of their lines).  This means that the primary
patch in bug 1308876 introduces the possibility of non-dirty reflows
during printing, which means we exercise non-dirty relayout code in a
number of tests where we did not do so previously.

Note: This patch passes try on its own, on Linux64 debug.

Writing a simple test for this that fails without the primary patch in
bug 1308876 seems difficult.  ColumnSetFrame responds to
nsReflowStatus::NextInFlowNeedsReflow by marking the next-in-flow
*dirty* (which page frames don't), which makes it hard to test in
columns, at least without nesting.  (Colums probably shouldn't do that,
though, but that's a performance fix for another time.)

MozReview-Commit-ID: JZ3qWTSO2lX
This commit is contained in:
L. David Baron 2017-07-12 19:37:11 -07:00
parent af959c6c34
commit 8487157732

View File

@ -3820,6 +3820,9 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
// and we have page-break-inside:avoid, then we need to be pushed to
// our parent's next-in-flow.
aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
// When we reflow in the new position, we need to reflow this
// line again.
aLine->MarkDirty();
} else {
// Push the line that didn't fit and any lines that follow it
// to our next-in-flow.
@ -4711,6 +4714,8 @@ nsBlockFrame::PlaceLine(BlockReflowInput& aState,
ShouldAvoidBreakInside(aState.mReflowInput)) {
aLine->AppendFloats(aState.mCurrentLineFloats);
aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
// Reflow the line again when we reflow at our new position.
aLine->MarkDirty();
return true;
}