Bug 1427608 - [css-grid] Fix span=1 'auto' min-sizing for intrinsic sizing. r=dholbert

When sizing the container under a min- or max-content constraint,
the item's min/max-content contribution needs to be clamped (when
Automatic Minimum Size / clamping applies) if its size is 'auto'.
That'll give the container the right intrinsic size. In Reflow,
we'll size the track initially to the clamped min-content
contribution again (in the Resolve Intrinsic Track Sizes step),
but since the container now has a definite size we'll grow
the track in the Maximize Tracks step up to its limit
(i.e. the clamp size).

For more details on the underlying issue, see:
https://github.com/w3c/csswg-drafts/issues/2303
This commit is contained in:
Mats Palmgren 2018-02-28 03:56:13 +01:00
Родитель 0a3df952cf
Коммит e06a462e0f
2 изменённых файлов: 41 добавлений и 47 удалений

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

@ -5520,22 +5520,11 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
// For -moz-max-content and -moz-min-content, we handle them like
// specified widths, but ignore box-sizing.
boxSizing = StyleBoxSizing::Content;
if (aMarginBoxMinSizeClamp != NS_MAXSIZE &&
styleISize.GetIntValue() == NS_STYLE_WIDTH_MIN_CONTENT) {
// We need |result| to be the 'min-content size' for the clamping below.
result = aFrame->GetMinISize(aRenderingContext);
}
} else if (!styleISize.ConvertsToLength() &&
!(haveFixedMinISize && haveFixedMaxISize && maxISize <= minISize)) {
#ifdef DEBUG_INTRINSIC_WIDTH
++gNoiseIndent;
#endif
if (aType != MIN_ISIZE) {
// At this point, |styleISize| is auto/-moz-fit-content/-moz-available or
// has a percentage. The intrinisic size for those under a max-content
// constraint is the max-content contribution which we shouldn't clamp.
aMarginBoxMinSizeClamp = NS_MAXSIZE;
}
if (MOZ_UNLIKELY(!isInlineAxis)) {
IntrinsicSize intrinsicSize = aFrame->GetIntrinsicSize();
const nsStyleCoord intrinsicBCoord =

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

@ -614,22 +614,22 @@ struct nsGridContainerFrame::GridItemInfo
LogicalAxis aContainerAxis,
nscoord aPercentageBasis) const
{
const auto pos = mFrame->StylePosition();
const auto* pos = mFrame->IsTableWrapperFrame() ?
mFrame->PrincipalChildList().FirstChild()->StylePosition() :
mFrame->StylePosition();
const auto& size = aContainerAxis == eLogicalAxisInline ?
pos->ISize(aContainerWM) : pos->BSize(aContainerWM);
// NOTE: if we have a definite or 'max-content' size then our automatic
// minimum size can't affect our size. Excluding these simplifies applying
// NOTE: if we have a definite size then our automatic minimum size
// can't affect our size. Excluding these simplifies applying
// the clamping in the right cases later.
if (size.GetUnit() == eStyleUnit_Auto ||
::IsPercentOfIndefiniteSize(size, aPercentageBasis) || // same as 'auto'
(size.GetUnit() == eStyleUnit_Enumerated &&
size.GetIntValue() != NS_STYLE_WIDTH_MAX_CONTENT)) {
const auto& minSize = aContainerAxis == eLogicalAxisInline ?
pos->MinISize(aContainerWM) : pos->MinBSize(aContainerWM);
return minSize.GetUnit() == eStyleUnit_Auto &&
mFrame->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE;
if (size.GetUnit() != eStyleUnit_Auto &&
!::IsPercentOfIndefiniteSize(size, aPercentageBasis)) {
return false;
}
return false;
const auto& minSize = aContainerAxis == eLogicalAxisInline ?
pos->MinISize(aContainerWM) : pos->MinBSize(aContainerWM);
return minSize.GetUnit() == eStyleUnit_Auto &&
mFrame->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE;
}
#ifdef DEBUG
@ -3779,33 +3779,25 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1(
TrackSize& sz = mSizes[aRange.mStart];
WritingMode wm = aState.mWM;
// Check if we need to apply "Automatic Minimum Size" and cache it.
if ((sz.mState & TrackSize::eAutoMinSizing) &&
aGridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
aGridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
}
// Calculate data for "Automatic Minimum Size" clamping, if needed.
bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) ||
aConstraint == SizingConstraint::eNoConstraint) &&
(aGridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState)) {
if (sz.mState & TrackSize::eIntrinsicMinSizing) {
auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart);
cache.mMinSizeClamp = maxCoord.ComputeCoordPercentCalc(aPercentageBasis);
}
aGridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
}
// min sizing
gfxContext* rc = &aState.mRenderingContext;
if (sz.mState & TrackSize::eAutoMinSizing) {
nscoord s;
if (aConstraint == SizingConstraint::eMinContent) {
s = MinContentContribution(aGridItem, aState, rc, wm, mAxis, &cache);
} else if (aConstraint == SizingConstraint::eMaxContent) {
s = MaxContentContribution(aGridItem, aState, rc, wm, mAxis, &cache);
// Check if we need to apply "Automatic Minimum Size" and cache it.
if (aGridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
aGridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
// Clamp it if it's spanning a definite track max-sizing function.
if (TrackSize::IsDefiniteMaxSizing(sz.mState)) {
auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart);
cache.mMinSizeClamp = maxCoord.ComputeCoordPercentCalc(aPercentageBasis);
aGridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
}
if (aConstraint != SizingConstraint::eMaxContent) {
s = MinContentContribution(aGridItem, aState, rc, wm, mAxis, &cache);
} else {
s = MaxContentContribution(aGridItem, aState, rc, wm, mAxis, &cache);
}
} else {
MOZ_ASSERT(aConstraint == SizingConstraint::eNoConstraint);
s = MinSize(aGridItem, aState, rc, wm, mAxis, &cache);
}
sz.mBase = std::max(sz.mBase, s);
@ -5073,18 +5065,31 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
// Setup the ClampMarginBoxMinSize reflow flags and property, if needed.
uint32_t flags = 0;
if (aGridItemInfo) {
// Clamp during reflow if we're stretching in that axis.
auto* pos = aChild->StylePosition();
auto j = pos->UsedJustifySelf(StyleContext());
auto a = pos->UsedAlignSelf(StyleContext());
bool stretch[2];
stretch[eLogicalAxisInline] = j == NS_STYLE_JUSTIFY_NORMAL ||
j == NS_STYLE_JUSTIFY_STRETCH;
stretch[eLogicalAxisBlock] = a == NS_STYLE_ALIGN_NORMAL ||
a == NS_STYLE_ALIGN_STRETCH;
auto childIAxis = isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
if (aGridItemInfo->mState[childIAxis] & ItemState::eClampMarginBoxMinSize) {
if (stretch[childIAxis] &&
aGridItemInfo->mState[childIAxis] & ItemState::eClampMarginBoxMinSize) {
flags |= ReflowInput::I_CLAMP_MARGIN_BOX_MIN_SIZE;
}
auto childBAxis = GetOrthogonalAxis(childIAxis);
if (aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) {
if (stretch[childBAxis] &&
aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) {
flags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE;
aChild->SetProperty(BClampMarginBoxMinSizeProperty(),
childCBSize.BSize(childWM));
} else {
aChild->DeleteProperty(BClampMarginBoxMinSizeProperty());
}
if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) {
flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE;
}