Bug 1827582 - Fix flex container's reflow status when unbreakable flex items consume all content block-size in current fragment. r=dholbert

The bug occurs in `PopulateReflowOutput()` when we change the reflow status of
an auto-height flex container to "complete" because unbreakable tall flex items
have consumed all the theoretical/unfragmented content block-size. Later in
`PopulateReflowOutput()`, we'll change the reflow status [1] to "overflow
incomplete," which cause the next-in-flow to become an overflow container.

It is possible that the container's block-size will grow due to pushed items.
However, `nsSplittableFrame::CalcAndCacheConsumedBSize()` [2] doesn't consider
the overflow container's block-size, so we never correctly consume the extra
block-size growth in later fragments due to pushed items. We end up creating
infinite columns.

[1] https://searchfox.org/mozilla-central/rev/54c533e94ae786056a43231f230c7d9b0773cb80/layout/generic/nsFlexContainerFrame.cpp#5623-5626
[2] https://searchfox.org/mozilla-central/rev/54c533e94ae786056a43231f230c7d9b0773cb80/layout/generic/nsSplittableFrame.cpp#201-204

Differential Revision: https://phabricator.services.mozilla.com/D175543
This commit is contained in:
Ting-Yu Lin 2023-04-19 21:53:24 +00:00
Родитель 1fe9277420
Коммит 05e90a8a3e
3 изменённых файлов: 89 добавлений и 3 удалений

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

@ -5538,9 +5538,24 @@ void nsFlexContainerFrame::PopulateReflowOutput(
desiredSizeInFlexWM.BSize(flexWM) = std::min(
effectiveContentBSizeWithBStartBP, aMaxBlockEndEdgeOfChildren);
if (aMaxBlockEndEdgeOfChildren >= effectiveContentBSizeWithBStartBP) {
// Some unbreakable children force us to consume all of our content
// block-size, and make us complete.
if ((aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE ||
!aAnyChildIncomplete) &&
aMaxBlockEndEdgeOfChildren >= effectiveContentBSizeWithBStartBP) {
// We have some tall unbreakable child that's sticking off the end of
// our fragment, *and* forcing us to consume all of our remaining
// content block-size and call ourselves complete.
//
// - If we have a definite block-size: we get here if the tall child
// makes us reach that block-size.
// - If we have a content-based block-size: we get here if the tall
// child makes us reach the content-based block-size from a
// theoretical unfragmented layout, *and* all our children are
// complete. (Note that if we have some incomplete child, then we
// instead prefer to return an incomplete status, so we can get a
// next-in-flow to include that child's requested next-in-flow, in the
// spirit of having a block-size that fits the content.)
//
// TODO: the auto-height case might need more subtlety; see bug 1828977.
isStatusIncomplete = false;
// We also potentially need to get the unskipped block-end border and

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

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
<style>
.multicol {
column-count: 2;
column-gap: 0;
column-fill: auto;
width: 200px;
border: 5px solid gray;
height: 0px;
}
.flexbox {
position: relative
}
.flexbox > div {
position: absolute;
width: 50px;
contain: size;
}
</style>
<div class="multicol">
<div class="flexbox">
<div style="height: 10px; background: pink; left: 100px;"></div>
<div style="height: 20px; background: orange; left: 50px;"></div>
</div>
</div>
</html>

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

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>Test that the first flex item is pushed to the second column due to insufficient space, and the browser shouldn't create infinite columns.</title>
<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#pagination">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1827582">
<link rel="match" href="single-line-row-flex-fragmentation-044-ref.html">
<style>
.multicol {
column-count: 2;
column-gap: 0;
column-fill: auto;
width: 200px;
border: 5px solid gray;
height: 0px;
}
.flexbox {
display: flex;
width: 100px;
}
.flexbox > div {
width: 50px;
contain: size;
}
</style>
<div class="multicol">
<div class="flexbox">
<!-- To reproduce the bug, the first item should have margin-top, and its
block-end should be smaller than the second item's block-end. -->
<div style="height: 10px; background: pink; margin-top: 5px;"></div>
<div style="height: 20px; background: orange"></div>
</div>
</div>
</html>