Bug 1308876 - Avoid initiating special-height reflow as a result of new paginated non-dirty reflows. r=dholbert

Previously, in paginated mode, all reflows were dirty reflows, since
tables do not split outside of printing, and prior to the primary patch
in bug 1308876, all reflows during printing are dirty reflows.  (The
isPaginated test here is actually for real pages, not fragmentation in
general.  However, the use here is appropriate for the meaning of
whether it's possible for the table to fragment.)

The fact that all reflows were dirty reflows meant that the
NS_FRAME_CONTAINS_RELATIVE_BSIZE flag was always cleared immediately
before reflow in ReflowInput::InitResizeFlags (which might also have set
the flag on *ancestors*).  This meant that, prior to the primary patch
in bug 1308876, the initial value of needToInitiateSpecialReflow that
was initialized from the presence of the
NS_FRAME_CONTAINS_RELATIVE_BSIZE flag was always false.  This patch
preserves that initialization in the presence of the change in the
primary patch in bug 1308876.

This caused a failure in a single test in our test suite, and in a
rather complicated way.  The test was
layout/base/crashtests/470851-1.xhtml, in which there was both a
difference in assertion count (due to the bogus assertion "data loss -
incomplete row needed more height than available, on top of page" in
nsTableRowGroupFrame::SplitRowGroup, whose companion assertion "data
loss - complete row needed more height than available, on top of page"
is already just an NS_WARNING) that caused a test failure, and a
difference in layout (the test split across 3 pages rather than 2) that
did not cause a test failure.

This patch fixes the difference in layout.  The immediate cause of the
layout difference was that a cell (the second outermost) on the second
page had a height, computed in CalcUnpaginatedBSize, that was large
enough to cause it to need to continue onto the third page.  This height
came (via nsTableRowFrame::GetUnpaginatedBSize) from the
UnpaginatedHeightProperty stored on the first-in-flow of its row, on the
first page, stored by CacheRowBSizesForPrinting called in
nsTableRowGroupFrame::ReflowChildren during the reflow of its row group
on the first page, in a special height reflow initiated during the
second-pass constrained-height reflow of the table (still,
second-outermost) on the first page, due to the change being fixed in
this patch.

MozReview-Commit-ID: 3E84VwdXuPs

--HG--
extra : transplant_source : m%DF%D2L%7B%E7%DD%98.zzI%07%14w%8A%15J%F5%16
This commit is contained in:
L. David Baron 2017-06-27 15:17:21 -07:00
Родитель 35982ed74f
Коммит d6baba5dd5
4 изменённых файлов: 64 добавлений и 9 удалений

Просмотреть файл

@ -75,3 +75,4 @@ fuzzy-if(skiaContent,1,23) == resize-reflow-001.html resize-reflow-001.ref.html
# == table-caption-splitaftercaption-11.html blank.html # bug 672654
== column-balancing-break-inside-avoid-2.html column-balancing-break-inside-avoid-2-ref.html
fails-if(styloVsGecko||stylo) == combobox-page-break-inside.html combobox-page-break-inside-ref.html
== table-nested-1308876-1.xhtml table-nested-1308876-1-ref.html

Просмотреть файл

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<html class="reftest-print">
<!--
This reference matches our current rendering, which isn't necessarily
correct, but I'd at least like to know about it if it changes, given how
little test coverage of this we currently have.
-->
<style>
html, body { margin: 0; padding: 0; }
</style>
<div id="page1" style="border: 2px solid black; background: yellow; height: 2in; box-sizing: border-box; padding: 3px; width: -moz-min-content">
<div style="background: orange; height: calc(2in - 16px); padding: 3px;">
<div style="background: brown; color: black;padding: 1px;">A</div>
</div>
</div>
<div id="page2" style="border: 2px solid black; background: yellow; height: 2in; box-sizing: border-box; padding: 3px; border-bottom: none; padding-bottom: 0; width: -moz-min-content">
<div style="background: orange; height: calc(2in - 8px); padding: 3px 3px 0 3px">
<div style="border: 1px solid fuchsia; background: aqua; height: calc(2in - 9px); border-bottom: none; color: transparent">B</div>
</div>
</div>

Просмотреть файл

@ -0,0 +1,29 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-print">
<!--
Reduced from layout/base/crashtests/470851-1.xhtml and turned into a reftest.
-->
<table style="background: black">
<tbody>
<tr>
<td style="background: yellow">
<table>
<tbody style="top: 10%; position: relative; overflow: scroll">
<tr>
<td style="background: orange">
<table>
<tbody style="background: brown">
<tr><td>A</td></tr>
</tbody>
<tbody style="background: fuchsia">
<tr><td><div style="background: aqua; line-height: 4in">B</div></td></tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</html>

Просмотреть файл

@ -2071,16 +2071,21 @@ nsTableFrame::Reflow(nsPresContext* aPresContext,
SetGeometryDirty();
}
bool needToInitiateSpecialReflow =
HasAnyStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
// see if an extra reflow will be necessary in pagination mode
// when there is a specified table bsize
if (isPaginated && !GetPrevInFlow() && (NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableBSize())) {
nscoord tableSpecifiedBSize = CalcBorderBoxBSize(aReflowInput);
if ((tableSpecifiedBSize > 0) &&
(tableSpecifiedBSize != NS_UNCONSTRAINEDSIZE)) {
needToInitiateSpecialReflow = true;
bool needToInitiateSpecialReflow = false;
if (isPaginated) {
// see if an extra reflow will be necessary in pagination mode
// when there is a specified table bsize
if (!GetPrevInFlow() &&
NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableBSize()) {
nscoord tableSpecifiedBSize = CalcBorderBoxBSize(aReflowInput);
if ((tableSpecifiedBSize > 0) &&
(tableSpecifiedBSize != NS_UNCONSTRAINEDSIZE)) {
needToInitiateSpecialReflow = true;
}
}
} else {
needToInitiateSpecialReflow =
HasAnyStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
}
nsIFrame* lastChildReflowed = nullptr;