mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1176775 part 1 - [css-grid] Implement "Implied Minimum Size of Grid Items" (special min-width/height:auto behavior). r=dholbert
This commit is contained in:
parent
c834243397
commit
d6729d7bd3
@ -4546,10 +4546,15 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis,
|
||||
const nsStylePosition* stylePos = aFrame->StylePosition();
|
||||
uint8_t boxSizing = stylePos->mBoxSizing;
|
||||
|
||||
const nsStyleCoord& styleISize =
|
||||
horizontalAxis ? stylePos->mWidth : stylePos->mHeight;
|
||||
const nsStyleCoord& styleMinISize =
|
||||
horizontalAxis ? stylePos->mMinWidth : stylePos->mMinHeight;
|
||||
const nsStyleCoord& styleISize =
|
||||
(aFlags & MIN_INTRINSIC_ISIZE) ? styleMinISize :
|
||||
(horizontalAxis ? stylePos->mWidth : stylePos->mHeight);
|
||||
MOZ_ASSERT(!(aFlags & MIN_INTRINSIC_ISIZE) ||
|
||||
styleISize.GetUnit() == eStyleUnit_Auto ||
|
||||
styleISize.GetUnit() == eStyleUnit_Enumerated,
|
||||
"should only use MIN_INTRINSIC_ISIZE for intrinsic values");
|
||||
const nsStyleCoord& styleMaxISize =
|
||||
horizontalAxis ? stylePos->mMaxWidth : stylePos->mMaxHeight;
|
||||
|
||||
@ -4765,9 +4770,9 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
|
||||
IntrinsicISizeType aType,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "null frame");
|
||||
NS_PRECONDITION(aFrame->GetParent(),
|
||||
"MinSizeContributionForAxis called on frame not in tree");
|
||||
MOZ_ASSERT(aFrame);
|
||||
MOZ_ASSERT(aFrame->IsFlexOrGridItem(),
|
||||
"only grid/flex items have this behavior currently");
|
||||
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
nsFrame::IndentBy(stderr, gNoiseIndent);
|
||||
@ -4777,6 +4782,46 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
|
||||
aWM.IsVertical() ? "vertical" : "horizontal");
|
||||
#endif
|
||||
|
||||
const nsStylePosition* const stylePos = aFrame->StylePosition();
|
||||
const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth
|
||||
: &stylePos->mMinHeight;
|
||||
nscoord minSize;
|
||||
nscoord* fixedMinSize = nullptr;
|
||||
auto minSizeUnit = style->GetUnit();
|
||||
if (minSizeUnit == eStyleUnit_Auto) {
|
||||
if (aFrame->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE) {
|
||||
style = aAxis == eAxisHorizontal ? &stylePos->mWidth
|
||||
: &stylePos->mHeight;
|
||||
if (GetAbsoluteCoord(*style, minSize)) {
|
||||
// We have a definite width/height. This is the "specified size" in:
|
||||
// https://drafts.csswg.org/css-grid/#min-size-auto
|
||||
fixedMinSize = &minSize;
|
||||
}
|
||||
// XXX the "transferred size" piece is missing (bug 1218178)
|
||||
} else {
|
||||
// min-[width|height]:auto with overflow != visible computes to zero.
|
||||
minSize = 0;
|
||||
fixedMinSize = &minSize;
|
||||
}
|
||||
} else if (GetAbsoluteCoord(*style, minSize)) {
|
||||
fixedMinSize = &minSize;
|
||||
} else if (minSizeUnit != eStyleUnit_Enumerated) {
|
||||
MOZ_ASSERT(style->HasPercent());
|
||||
minSize = 0;
|
||||
fixedMinSize = &minSize;
|
||||
}
|
||||
|
||||
if (!fixedMinSize) {
|
||||
// Let the caller deal with the "content size" cases.
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
nsFrame::IndentBy(stderr, gNoiseIndent);
|
||||
static_cast<nsFrame*>(aFrame)->ListTag(stderr);
|
||||
printf_stderr(" %s min-isize is indefinite.\n",
|
||||
aType == MIN_ISIZE ? "min" : "pref");
|
||||
#endif
|
||||
return NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
|
||||
// If aFrame is a container for font size inflation, then shrink
|
||||
// wrapping inside of it should not apply font size inflation.
|
||||
AutoMaybeDisableFontInflation an(aFrame);
|
||||
@ -4788,18 +4833,13 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis,
|
||||
: aFrame->IntrinsicBSizeOffsets();
|
||||
nscoord result = 0;
|
||||
nscoord min = 0;
|
||||
const nsStylePosition* stylePos = aFrame->StylePosition();
|
||||
uint8_t boxSizing = stylePos->mBoxSizing;
|
||||
const nsStyleCoord& style = aAxis == eAxisHorizontal ? stylePos->mMinWidth
|
||||
: stylePos->mMinHeight;
|
||||
nscoord minSize;
|
||||
nscoord* fixedMinSize = nullptr;
|
||||
if (GetAbsoluteCoord(style, minSize)) {
|
||||
fixedMinSize = &minSize;
|
||||
}
|
||||
result = AddIntrinsicSizeOffset(aRC, aFrame, offsets, aType, boxSizing,
|
||||
result, min, style, fixedMinSize,
|
||||
style, fixedMinSize, style, aFlags, aAxis);
|
||||
|
||||
const nsStyleCoord& maxISize =
|
||||
aAxis == eAxisHorizontal ? stylePos->mMaxWidth : stylePos->mMaxHeight;
|
||||
result = AddIntrinsicSizeOffset(aRC, aFrame, offsets, aType,
|
||||
stylePos->mBoxSizing,
|
||||
result, min, *style, fixedMinSize,
|
||||
*style, nullptr, maxISize, aFlags, aAxis);
|
||||
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
nsFrame::IndentBy(stderr, gNoiseIndent);
|
||||
|
@ -1324,10 +1324,13 @@ public:
|
||||
* variations if that's what matches aAxis) and its padding, border and margin
|
||||
* in the corresponding dimension.
|
||||
*/
|
||||
enum IntrinsicISizeType { MIN_ISIZE, PREF_ISIZE };
|
||||
enum class IntrinsicISizeType { MIN_ISIZE, PREF_ISIZE };
|
||||
static const auto MIN_ISIZE = IntrinsicISizeType::MIN_ISIZE;
|
||||
static const auto PREF_ISIZE = IntrinsicISizeType::PREF_ISIZE;
|
||||
enum {
|
||||
IGNORE_PADDING = 0x01,
|
||||
BAIL_IF_REFLOW_NEEDED = 0x02, // returns NS_INTRINSIC_WIDTH_UNKNOWN if so
|
||||
MIN_INTRINSIC_ISIZE = 0x04, // use min-width/height instead of width/height
|
||||
};
|
||||
static nscoord IntrinsicForAxis(mozilla::PhysicalAxis aAxis,
|
||||
nsRenderingContext* aRenderingContext,
|
||||
@ -1343,10 +1346,20 @@ public:
|
||||
uint32_t aFlags = 0);
|
||||
|
||||
/**
|
||||
* Get the contribution of aFrame for the given physical axis.
|
||||
* Get the definite size contribution of aFrame for the given physical axis.
|
||||
* This considers the child's 'min-width' property (or 'min-height' if the
|
||||
* given axis is vertical), and its padding, border, and margin in the
|
||||
* corresponding dimension.
|
||||
* corresponding dimension. If the 'min-' property is 'auto' (and 'overflow'
|
||||
* is 'visible') and the corresponding 'width'/'height' is definite it returns
|
||||
* the "specified / transferred size" for:
|
||||
* https://drafts.csswg.org/css-grid/#min-size-auto
|
||||
* Note that any percentage in 'width'/'height' makes it count as indefinite.
|
||||
* If the 'min-' property is 'auto' and 'overflow' is not 'visible', then it
|
||||
* calculates the result as if the 'min-' computed value is zero.
|
||||
* Otherwise, return NS_UNCONSTRAINEDSIZE.
|
||||
*
|
||||
* @note this behavior is specific to Grid/Flexbox (currently) so aFrame
|
||||
* should be a grid/flex item.
|
||||
*/
|
||||
static nscoord MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis,
|
||||
nsRenderingContext* aRC,
|
||||
|
@ -4300,6 +4300,9 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
const LogicalSize& aPadding,
|
||||
ComputeSizeFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(GetIntrinsicRatio() == nsSize(0,0),
|
||||
"Please override this method and call "
|
||||
"nsLayoutUtils::ComputeSizeWithIntrinsicDimensions instead.");
|
||||
LogicalSize result = ComputeAutoSize(aRenderingContext, aWM,
|
||||
aCBSize, aAvailableISize,
|
||||
aMargin, aBorder, aPadding,
|
||||
@ -4321,9 +4324,12 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
const nsStyleCoord* inlineStyleCoord = &stylePos->ISize(aWM);
|
||||
const nsStyleCoord* blockStyleCoord = &stylePos->BSize(aWM);
|
||||
|
||||
bool isFlexItem = IsFlexItem();
|
||||
nsIAtom* parentFrameType = GetParent() ? GetParent()->GetType() : nullptr;
|
||||
bool isGridItem = (parentFrameType == nsGkAtoms::gridContainerFrame &&
|
||||
!(GetStateBits() & NS_FRAME_OUT_OF_FLOW));
|
||||
bool isFlexItem = (parentFrameType == nsGkAtoms::flexContainerFrame &&
|
||||
!(GetStateBits() & NS_FRAME_OUT_OF_FLOW));
|
||||
bool isInlineFlexItem = false;
|
||||
|
||||
if (isFlexItem) {
|
||||
// Flex items use their "flex-basis" property in place of their main-size
|
||||
// property (e.g. "width") for sizing purposes, *unless* they have
|
||||
@ -4365,14 +4371,14 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
*inlineStyleCoord);
|
||||
}
|
||||
|
||||
const nsStyleCoord& maxISizeCoord = stylePos->MaxISize(aWM);
|
||||
|
||||
// Flex items ignore their min & max sizing properties in their
|
||||
// flex container's main-axis. (Those properties get applied later in
|
||||
// the flexbox algorithm.)
|
||||
const nsStyleCoord& maxISizeCoord = stylePos->MaxISize(aWM);
|
||||
nscoord maxISize = NS_UNCONSTRAINEDSIZE;
|
||||
if (maxISizeCoord.GetUnit() != eStyleUnit_None &&
|
||||
!(isFlexItem && isInlineFlexItem)) {
|
||||
nscoord maxISize =
|
||||
maxISize =
|
||||
nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
|
||||
aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
|
||||
maxISizeCoord);
|
||||
@ -4380,7 +4386,6 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
}
|
||||
|
||||
const nsStyleCoord& minISizeCoord = stylePos->MinISize(aWM);
|
||||
|
||||
nscoord minISize;
|
||||
if (minISizeCoord.GetUnit() != eStyleUnit_Auto &&
|
||||
!(isFlexItem && isInlineFlexItem)) {
|
||||
@ -4388,6 +4393,13 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
|
||||
aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
|
||||
minISizeCoord);
|
||||
} else if (MOZ_UNLIKELY(isGridItem)) {
|
||||
// This implements "Implied Minimum Size of Grid Items".
|
||||
// https://drafts.csswg.org/css-grid/#min-size-auto
|
||||
minISize = std::min(maxISize, GetMinISize(aRenderingContext));
|
||||
if (inlineStyleCoord->IsCoordPercentCalcUnit()) {
|
||||
minISize = std::min(minISize, result.ISize(aWM));
|
||||
}
|
||||
} else {
|
||||
// Treat "min-width: auto" as 0.
|
||||
// NOTE: Technically, "auto" is supposed to behave like "min-content" on
|
||||
|
@ -1938,15 +1938,6 @@ nsGridContainerFrame::Tracks::Initialize(
|
||||
}
|
||||
}
|
||||
|
||||
static nscoord
|
||||
MinSize(nsIFrame* aChild, nsRenderingContext* aRC, WritingMode aCBWM,
|
||||
LogicalAxis aAxis, nsLayoutUtils::IntrinsicISizeType aConstraint)
|
||||
{
|
||||
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
|
||||
return nsLayoutUtils::MinSizeContributionForAxis(axis, aRC, aChild,
|
||||
aConstraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the [min|max]-content contribution of aChild to its parent (i.e.
|
||||
* the child's margin-box) in aAxis.
|
||||
@ -1957,11 +1948,12 @@ ContentContribution(nsIFrame* aChild,
|
||||
nsRenderingContext* aRC,
|
||||
WritingMode aCBWM,
|
||||
LogicalAxis aAxis,
|
||||
nsLayoutUtils::IntrinsicISizeType aConstraint)
|
||||
nsLayoutUtils::IntrinsicISizeType aConstraint,
|
||||
uint32_t aFlags = 0)
|
||||
{
|
||||
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
|
||||
nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, aChild, aConstraint,
|
||||
nsLayoutUtils::BAIL_IF_REFLOW_NEEDED);
|
||||
aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED);
|
||||
if (size == NS_INTRINSIC_WIDTH_UNKNOWN) {
|
||||
// We need to reflow the child to find its BSize contribution.
|
||||
WritingMode wm = aChild->GetWritingMode();
|
||||
@ -2025,6 +2017,39 @@ MaxContentContribution(nsIFrame* aChild,
|
||||
nsLayoutUtils::PREF_ISIZE);
|
||||
}
|
||||
|
||||
static nscoord
|
||||
MinSize(nsIFrame* aChild,
|
||||
const nsHTMLReflowState* aRS,
|
||||
nsRenderingContext* aRC,
|
||||
WritingMode aCBWM,
|
||||
LogicalAxis aAxis)
|
||||
{
|
||||
PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis));
|
||||
const nsStylePosition* stylePos = aChild->StylePosition();
|
||||
const nsStyleCoord& style = axis == eAxisHorizontal ? stylePos->mMinWidth
|
||||
: stylePos->mMinHeight;
|
||||
// https://drafts.csswg.org/css-grid/#min-size-auto
|
||||
// This calculates the min-content contribution from either a definite
|
||||
// min-width (or min-height depending on aAxis), or the "specified /
|
||||
// transferred size" for min-width:auto if overflow == visible (as min-width:0
|
||||
// otherwise), or NS_UNCONSTRAINEDSIZE for other min-width intrinsic values
|
||||
// (which results in always taking the "content size" part below).
|
||||
nscoord sz =
|
||||
nsLayoutUtils::MinSizeContributionForAxis(axis, aRC, aChild,
|
||||
nsLayoutUtils::MIN_ISIZE);
|
||||
auto unit = style.GetUnit();
|
||||
if (unit == eStyleUnit_Enumerated ||
|
||||
(unit == eStyleUnit_Auto &&
|
||||
aChild->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) {
|
||||
// Now calculate the "content size" part and return whichever is smaller.
|
||||
MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE);
|
||||
sz = std::min(sz, ContentContribution(aChild, aRS, aRC, aCBWM, aAxis,
|
||||
nsLayoutUtils::MIN_ISIZE,
|
||||
nsLayoutUtils::MIN_INTRINSIC_ISIZE));
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
void
|
||||
nsGridContainerFrame::Tracks::CalculateSizes(
|
||||
GridReflowState& aState,
|
||||
@ -2112,7 +2137,7 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1(
|
||||
const nsHTMLReflowState* rs = aState.mReflowState;
|
||||
nsRenderingContext* rc = &aState.mRenderingContext;
|
||||
if (sz.mState & TrackSize::eAutoMinSizing) {
|
||||
nscoord s = MinSize(aGridItem, rc, wm, mAxis, aConstraint);
|
||||
nscoord s = MinSize(aGridItem, rs, rc, wm, mAxis);
|
||||
sz.mBase = std::max(sz.mBase, s);
|
||||
} else if ((sz.mState & TrackSize::eMinContentMinSizing) ||
|
||||
(aConstraint == nsLayoutUtils::MIN_ISIZE &&
|
||||
@ -2217,7 +2242,7 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize(
|
||||
stateBitsPerSpan[span] |= state;
|
||||
nscoord minSize = 0;
|
||||
if (state & (flexMin | TrackSize::eIntrinsicMinSizing)) { // for 2.1
|
||||
minSize = MinSize(child, rc, wm, mAxis, aConstraint);
|
||||
minSize = MinSize(child, aState.mReflowState, rc, wm, mAxis);
|
||||
}
|
||||
nscoord minContent = 0;
|
||||
if (state & (flexMin | TrackSize::eMinOrMaxContentMinSizing | // for 2.2
|
||||
|
Loading…
Reference in New Issue
Block a user