Fix incorrect grid cell sizing to min/max space.

This commit is contained in:
Fedor 2020-11-26 22:45:24 +02:00
parent b1896615b1
commit 2f3d0d90d2
3 changed files with 77 additions and 29 deletions

View File

@ -4822,14 +4822,14 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks(
: ri->ComputedMaxISize(); : ri->ComputedMaxISize();
} }
Maybe<nsTArray<TrackSize>> origSizes; Maybe<nsTArray<TrackSize>> origSizes;
bool applyMinMax = (minSize != 0 || maxSize != NS_UNCONSTRAINEDSIZE) &&
aAvailableSize == NS_UNCONSTRAINEDSIZE;
// We iterate twice at most. The 2nd time if the grid size changed after // We iterate twice at most. The 2nd time if the grid size changed after
// applying a min/max-size (can only occur if aAvailableSize is indefinite). // applying a min/max-size (can only occur if aAvailableSize is indefinite).
while (true) { while (true) {
float fr = FindUsedFlexFraction(aState, aGridItems, flexTracks, float fr = FindUsedFlexFraction(aState, aGridItems, flexTracks,
aFunctions, aAvailableSize); aFunctions, aAvailableSize);
if (fr != 0.0f) { if (fr != 0.0f) {
bool applyMinMax = (minSize != 0 || maxSize != NS_UNCONSTRAINEDSIZE) &&
aAvailableSize == NS_UNCONSTRAINEDSIZE;
for (uint32_t i : flexTracks) { for (uint32_t i : flexTracks) {
float flexFactor = aFunctions.MaxSizingFor(i).GetFlexFractionValue(); float flexFactor = aFunctions.MaxSizingFor(i).GetFlexFractionValue();
nscoord flexLength = NSToCoordRound(flexFactor * fr); nscoord flexLength = NSToCoordRound(flexFactor * fr);
@ -4841,36 +4841,36 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks(
base = flexLength; base = flexLength;
} }
} }
if (applyMinMax && origSizes.isSome()) { }
// https://drafts.csswg.org/css-grid/#algo-flex-tracks if (applyMinMax) {
// "If using this flex fraction would cause the grid to be smaller than applyMinMax = false;
// the grid containers min-width/height (or larger than the grid // https://drafts.csswg.org/css-grid/#algo-flex-tracks
// containers max-width/height), then redo this step, treating the free // "If using this flex fraction would cause the grid to be smaller than
// space as definite [...]" // the grid containers min-width/height (or larger than the grid
nscoord newSize = 0; // containers max-width/height), then redo this step, treating the free
for (auto& sz : mSizes) { // space as definite [...]"
newSize += sz.mBase; nscoord newSize = 0;
} for (auto& sz : mSizes) {
const auto sumOfGridGaps = SumOfGridGaps(); newSize += sz.mBase;
newSize += sumOfGridGaps; }
if (newSize > maxSize) { const auto sumOfGridGaps = SumOfGridGaps();
aAvailableSize = maxSize; newSize += sumOfGridGaps;
} else if (newSize < minSize) { if (newSize > maxSize) {
aAvailableSize = minSize; aAvailableSize = maxSize;
} } else if (newSize < minSize) {
if (aAvailableSize != NS_UNCONSTRAINEDSIZE) { aAvailableSize = minSize;
// Reset min/max-size to ensure 'applyMinMax' becomes false next time. }
minSize = 0; if (aAvailableSize != NS_UNCONSTRAINEDSIZE) {
maxSize = NS_UNCONSTRAINEDSIZE; aAvailableSize = std::max(0, aAvailableSize - sumOfGridGaps);
aAvailableSize = std::max(0, aAvailableSize - sumOfGridGaps); // Restart with the original track sizes and definite aAvailableSize.
// Restart with the original track sizes and definite aAvailableSize. if (origSizes.isSome()) {
mSizes = Move(*origSizes); mSizes = Move(*origSizes);
origSizes.reset(); origSizes.reset();
if (aAvailableSize == 0) { } // else, no mSizes[].mBase were changed above so it's still correct
break; // zero available size wouldn't change any sizes though... if (aAvailableSize == 0) {
} break; // zero available size wouldn't change any sizes though...
continue;
} }
continue;
} }
} }
break; break;

View File

@ -107,4 +107,28 @@
<div class="item"></div> <div class="item"></div>
</div> </div>
<pre>The first 6 grids should look the same:</pre>
<div class="grid rows" style="grid: 1fr / 30px; height:83px">
<div class="item"></div>
</div>
<div class="grid rows" style="grid: 10px 1fr / 30px; height:83px">
<div class="item" style="grid-row:span 2"></div>
</div>
<div class="grid rows" style="grid: 1fr / 30px; height:83px">
<div class="item"></div>
</div>
<div class="grid rows" style="grid: 1fr 1fr / 30px; height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 1fr auto / 30px; height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 10px 1fr / 30px; height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 1fr 1fr / 30px; grid-row-gap:10px; height:83px">
<div class="item" style="grid-row:span 2"><div style="height:40px"></div></div>
<div class="item"><div style="height:40px"></div></div>
</div>
</body></html> </body></html>

View File

@ -105,4 +105,28 @@
<div class="item"></div> <div class="item"></div>
</div> </div>
<pre>The first 6 grids should look the same:</pre>
<div class="grid rows" style="grid: 1fr / 30px; min-height:83px">
<div class="item"></div>
</div>
<div class="grid rows" style="grid: 10px 1fr / 30px; min-height:83px">
<div class="item" style="grid-row:span 2"></div>
</div>
<div class="grid rows" style="grid: 1fr / 30px; max-height:30px; min-height:83px">
<div class="item"></div>
</div>
<div class="grid rows" style="grid: 1fr 1fr / 30px; max-height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 1fr auto / 30px; max-height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 10px 1fr / 30px; max-height:83px">
<div class="item" style="grid-row:span 2"><div style="height:90px"></div></div>
</div>
<div class="grid rows" style="grid: 1fr 1fr / 30px; grid-row-gap:10px; max-height:83px">
<div class="item" style="grid-row:span 2"><div style="height:40px"></div></div>
<div class="item"><div style="height:40px"></div></div>
</div>
</body></html> </body></html>