diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js index a82c03266..25d15b0b2 100644 --- a/devtools/shared/css/generated/properties-db.js +++ b/devtools/shared/css/generated/properties-db.js @@ -777,7 +777,8 @@ exports.CSS_PROPERTIES = { "column-gap" ], "supports": [ - 6 + 6, + 8 ], "values": [ "calc", @@ -5421,7 +5422,8 @@ exports.CSS_PROPERTIES = { "column-gap" ], "supports": [ - 6 + 6, + 8 ], "values": [ "calc", diff --git a/layout/base/LayoutConstants.h b/layout/base/LayoutConstants.h new file mode 100644 index 000000000..cd6e1c3f5 --- /dev/null +++ b/layout/base/LayoutConstants.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* constants used throughout the Layout module */ + +#ifndef LayoutConstants_h___ +#define LayoutConstants_h___ + +#include "nsSize.h" // for NS_MAXSIZE + +/** + * Constant used to indicate an unconstrained size. + */ +#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE + +// NOTE: There are assumptions all over that these have the same value, +// namely NS_UNCONSTRAINEDSIZE. +#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE +#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE +#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE + +// +1 is to avoid clamped huge margin values being processed as auto margins +#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) + +#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN + + +#endif // LayoutConstants_h___ diff --git a/layout/base/moz.build b/layout/base/moz.build index 8cfaead22..63cf54cb9 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -34,6 +34,7 @@ XPIDL_MODULE = 'layout_base' EXPORTS += [ 'CaretAssociationHint.h', 'FrameProperties.h', + 'LayoutConstants.h', 'LayoutLogging.h', 'nsArenaMemoryStats.h', 'nsBidi.h', diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 3897218c6..3f6258b66 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -4700,8 +4700,6 @@ GetDefiniteSize(const nsStyleCoord& aStyle, nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) : aPercentageBasis.value().BSize(wm); if (pb == NS_UNCONSTRAINEDSIZE) { - // XXXmats given that we're calculating an intrinsic size here, - // maybe we should back-compute the calc-size using AddPercents? return false; } *aResult = std::max(0, calc->mLength + @@ -4945,12 +4943,9 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, nscoord result = aContentSize; nscoord min = aContentMinSize; nscoord coordOutsideSize = 0; - float pctOutsideSize = 0; - float pctTotal = 0.0f; if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) { coordOutsideSize += aOffsets.hPadding; - pctOutsideSize += aOffsets.hPctPadding; } coordOutsideSize += aOffsets.hBorder; @@ -4958,21 +4953,15 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, if (aBoxSizing == StyleBoxSizing::Border) { min += coordOutsideSize; result = NSCoordSaturatingAdd(result, coordOutsideSize); - pctTotal += pctOutsideSize; coordOutsideSize = 0; - pctOutsideSize = 0.0f; } coordOutsideSize += aOffsets.hMargin; - pctOutsideSize += aOffsets.hPctMargin; min += coordOutsideSize; result = NSCoordSaturatingAdd(result, coordOutsideSize); - pctTotal += pctOutsideSize; - const bool shouldAddPercent = aType == nsLayoutUtils::PREF_ISIZE || - (aFlags & nsLayoutUtils::ADD_PERCENTS); nscoord size; if (aType == nsLayoutUtils::MIN_ISIZE && (((aStyleSize.HasPercent() || aStyleMaxSize.HasPercent()) && @@ -4990,18 +4979,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleSize, aRenderingContext, aFrame, PROP_WIDTH, size)) { result = size + coordOutsideSize; - if (shouldAddPercent) { - result = nsLayoutUtils::AddPercents(result, pctOutsideSize); - } - } else { - // NOTE: We could really do a lot better for percents and for some - // cases of calc() containing percent (certainly including any where - // the coefficient on the percent is positive and there are no max() - // expressions). However, doing better for percents wouldn't be - // backwards compatible. - if (shouldAddPercent) { - result = nsLayoutUtils::AddPercents(result, pctTotal); - } } nscoord maxSize = aFixedMaxSize ? *aFixedMaxSize : 0; @@ -5009,9 +4986,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleMaxSize, aRenderingContext, aFrame, PROP_MAX_WIDTH, maxSize)) { maxSize += coordOutsideSize; - if (shouldAddPercent) { - maxSize = nsLayoutUtils::AddPercents(maxSize, pctOutsideSize); - } if (result > maxSize) { result = maxSize; } @@ -5022,17 +4996,11 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, GetIntrinsicCoord(aStyleMinSize, aRenderingContext, aFrame, PROP_MIN_WIDTH, minSize)) { minSize += coordOutsideSize; - if (shouldAddPercent) { - minSize = nsLayoutUtils::AddPercents(minSize, pctOutsideSize); - } if (result < minSize) { result = minSize; } } - if (shouldAddPercent) { - min = nsLayoutUtils::AddPercents(min, pctTotal); - } if (result < min) { result = min; } @@ -5049,9 +5017,6 @@ AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext, : devSize.width); // GetMinimumWidgetSize() returns a border-box width. themeSize += aOffsets.hMargin; - if (shouldAddPercent) { - themeSize = nsLayoutUtils::AddPercents(themeSize, aOffsets.hPctMargin); - } if (themeSize > result || !canOverride) { result = themeSize; } @@ -5296,9 +5261,19 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, min = aFrame->GetMinISize(aRenderingContext); } + nscoord pmPercentageBasis = NS_UNCONSTRAINEDSIZE; + if (aPercentageBasis.isSome()) { + // The padding/margin percentage basis is the inline-size in the parent's + // writing-mode. + auto childWM = aFrame->GetWritingMode(); + pmPercentageBasis = + aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM) ? + aPercentageBasis->BSize(childWM) : + aPercentageBasis->ISize(childWM); + } nsIFrame::IntrinsicISizeOffsetData offsets = - MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis) + : aFrame->IntrinsicBSizeOffsets(pmPercentageBasis); nscoord contentBoxSize = result; result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType, boxSizing, result, min, styleISize, @@ -5339,11 +5314,12 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext, } /* static */ nscoord -nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, +nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, nsRenderingContext* aRC, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags) + nsIFrame* aFrame, + IntrinsicISizeType aType, + const LogicalSize& aPercentageBasis, + uint32_t aFlags) { MOZ_ASSERT(aFrame); MOZ_ASSERT(aFrame->IsFlexOrGridItem(), @@ -5357,9 +5333,7 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, aWM.IsVertical() ? "vertical" : "horizontal"); #endif - // Note: this method is only meant for grid/flex items which always - // include percentages in their intrinsic size. - aFlags |= nsLayoutUtils::ADD_PERCENTS; + // Note: this method is only meant for grid/flex items. const nsStylePosition* const stylePos = aFrame->StylePosition(); const nsStyleCoord* style = aAxis == eAxisHorizontal ? &stylePos->mMinWidth : &stylePos->mMinHeight; @@ -5404,11 +5378,17 @@ nsLayoutUtils::MinSizeContributionForAxis(PhysicalAxis aAxis, // wrapping inside of it should not apply font size inflation. AutoMaybeDisableFontInflation an(aFrame); - PhysicalAxis ourInlineAxis = - aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + // The padding/margin percentage basis is the inline-size in the parent's + // writing-mode. + auto childWM = aFrame->GetWritingMode(); + nscoord pmPercentageBasis = + aFrame->GetParent()->GetWritingMode().IsOrthogonalTo(childWM) ? + aPercentageBasis.BSize(childWM) : + aPercentageBasis.ISize(childWM); + PhysicalAxis ourInlineAxis = childWM.PhysicalAxis(eLogicalAxisInline); nsIFrame::IntrinsicISizeOffsetData offsets = - ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + ourInlineAxis == aAxis ? aFrame->IntrinsicISizeOffsets(pmPercentageBasis) + : aFrame->IntrinsicBSizeOffsets(pmPercentageBasis); nscoord result = 0; nscoord min = 0; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index b43e5cdb5..4b2e73fc7 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -6,6 +6,7 @@ #ifndef nsLayoutUtils_h__ #define nsLayoutUtils_h__ +#include "LayoutConstants.h" #include "mozilla/MemoryReporting.h" #include "mozilla/ArrayUtils.h" #include "mozilla/Maybe.h" @@ -153,6 +154,7 @@ public: typedef mozilla::ScreenMargin ScreenMargin; typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize; typedef mozilla::StyleGeometryBox StyleGeometryBox; + typedef mozilla::LogicalSize LogicalSize; /** * Finds previously assigned ViewID for the given content element, if any. @@ -1384,7 +1386,8 @@ public: * variations if that's what matches aAxis) and its padding, border and margin * in the corresponding dimension. * @param aPercentageBasis an optional percentage basis (in aFrame's WM). - * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. + * If the basis is indefinite in a given axis, pass a size with + * NS_UNCONSTRAINEDSIZE in that component. * If you pass Nothing() a percentage basis will be calculated from aFrame's * ancestors' computed size in the relevant axis, if needed. * @param aMarginBoxMinSizeClamp make the result fit within this margin-box @@ -1398,14 +1401,13 @@ public: 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 - ADD_PERCENTS = 0x08, // apply AddPercents also for MIN_ISIZE }; static nscoord IntrinsicForAxis(mozilla::PhysicalAxis aAxis, nsRenderingContext* aRenderingContext, nsIFrame* aFrame, IntrinsicISizeType aType, - const mozilla::Maybe& aPercentageBasis = mozilla::Nothing(), + const mozilla::Maybe& aPercentageBasis = mozilla::Nothing(), uint32_t aFlags = 0, nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE); /** @@ -1430,31 +1432,18 @@ public: * calculates the result as if the 'min-' computed value is zero. * Otherwise, return NS_UNCONSTRAINEDSIZE. * + * @param aPercentageBasis the percentage basis (in aFrame's WM). + * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. * @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, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags = 0); - - /** - * This function increases an initial intrinsic size, 'aCurrent', according - * to the given 'aPercent', such that the size-increase makes up exactly - * 'aPercent' percent of the returned value. If 'aPercent' or 'aCurrent' are - * less than or equal to zero the original 'aCurrent' value is returned. - * If 'aPercent' is greater than or equal to 1.0 the value nscoord_MAX is - * returned. - */ - static nscoord AddPercents(nscoord aCurrent, float aPercent) - { - if (aPercent > 0.0f && aCurrent > 0) { - return MOZ_UNLIKELY(aPercent >= 1.0f) ? nscoord_MAX - : NSToCoordRound(float(aCurrent) / (1.0f - aPercent)); - } - return aCurrent; - } + static nscoord + MinSizeContributionForAxis(mozilla::PhysicalAxis aAxis, + nsRenderingContext* aRC, + nsIFrame* aFrame, + IntrinsicISizeType aType, + const LogicalSize& aPercentageBasis, + uint32_t aFlags = 0); /* * Convert nsStyleCoord to nscoord when percentages depend on the @@ -2891,6 +2880,62 @@ public: static nsRect ComputeGeometryBox(nsIFrame* aFrame, StyleGeometryBox aGeometryBox); + /** + * Resolve a CSS value to a definite size. + */ + template + static nscoord ResolveToLength(const nsStyleCoord& aCoord, + nscoord aPercentageBasis) + { + NS_WARNING_ASSERTION(aPercentageBasis >= nscoord(0), "nscoord overflow?"); + + switch (aCoord.GetUnit()) { + case eStyleUnit_Coord: + MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetCoordValue() >= 0, + "This value should have been rejected by the style system"); + return aCoord.GetCoordValue(); + case eStyleUnit_Percent: + if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { + return nscoord(0); + } + MOZ_ASSERT(!clampNegativeResultToZero || aCoord.GetPercentValue() >= 0, + "This value should have been rejected by the style system"); + return NSToCoordFloorClamped(aPercentageBasis * + aCoord.GetPercentValue()); + case eStyleUnit_Calc: { + nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); + nscoord result; + if (aPercentageBasis == NS_UNCONSTRAINEDSIZE) { + result = calc->mLength; + } else { + result = calc->mLength + + NSToCoordFloorClamped(aPercentageBasis * calc->mPercent); + } + if (clampNegativeResultToZero && result < 0) { + return nscoord(0); + } + return result; + } + default: + MOZ_ASSERT_UNREACHABLE("Unexpected unit!"); + return nscoord(0); + } + } + + /** + * Resolve a column-gap/row-gap to a definite size. + * @note This method resolves 'normal' to zero. + * Callers who want different behavior should handle 'normal' on their own. + */ + static nscoord ResolveGapToLength(const nsStyleCoord& aGap, + nscoord aPercentageBasis) + { + if (aGap.GetUnit() == eStyleUnit_Normal) { + return nscoord(0); + } + return ResolveToLength(aGap, aPercentageBasis); + } + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 98f10b896..ddb8bb0cf 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -183,18 +183,15 @@ nsColumnSetFrame::GetAvailableContentBSize(const ReflowInput& aReflowInput) static nscoord GetColumnGap(nsColumnSetFrame* aFrame, - const nsStyleColumn* aColStyle) + const nsStyleColumn* aColStyle, + nscoord aPercentageBasis) { - if (eStyleUnit_Normal == aColStyle->mColumnGap.GetUnit()) + const auto& columnGap = aColStyle->mColumnGap; + if (columnGap.GetUnit() == eStyleUnit_Normal) { return aFrame->StyleFont()->mFont.size; - if (eStyleUnit_Coord == aColStyle->mColumnGap.GetUnit()) { - nscoord colGap = aColStyle->mColumnGap.GetCoordValue(); - NS_ASSERTION(colGap >= 0, "negative column gap"); - return colGap; } - NS_NOTREACHED("Unknown gap type"); - return 0; + return nsLayoutUtils::ResolveGapToLength(columnGap, aPercentageBasis); } nsColumnSetFrame::ReflowConfig @@ -228,7 +225,7 @@ nsColumnSetFrame::ChooseColumnStrategy(const ReflowInput& aReflowInput, colBSize = std::min(colBSize, aReflowInput.ComputedMaxBSize()); } - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, aReflowInput.ComputedISize()); int32_t numColumns = colStyle->mColumnCount; // If column-fill is set to 'balance', then we want to balance the columns. @@ -404,7 +401,7 @@ nsColumnSetFrame::GetMinISize(nsRenderingContext *aRenderingContext) // include n-1 column gaps. colISize = iSize; iSize *= colStyle->mColumnCount; - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); iSize += colGap * (colStyle->mColumnCount - 1); // The multiplication above can make 'width' negative (integer overflow), // so use std::max to protect against that. @@ -425,7 +422,7 @@ nsColumnSetFrame::GetPrefISize(nsRenderingContext *aRenderingContext) nscoord result = 0; DISPLAY_PREF_WIDTH(this, result); const nsStyleColumn* colStyle = StyleColumn(); - nscoord colGap = GetColumnGap(this, colStyle); + nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); nscoord colISize; if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) { diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 72f55dac2..25c01b19d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4610,68 +4610,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak(StyleClear aBreakType) mLineIsEmpty = true; } -static void -AddCoord(const nsStyleCoord& aStyle, - nsIFrame* aFrame, - nscoord* aCoord, float* aPercent, - bool aClampNegativeToZero) +static nscoord +ResolveMargin(const nsStyleCoord& aStyle, nscoord aPercentageBasis) { - switch (aStyle.GetUnit()) { - case eStyleUnit_Coord: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetCoordValue() >= 0, - "unexpected negative value"); - *aCoord += aStyle.GetCoordValue(); - return; - } - case eStyleUnit_Percent: { - NS_ASSERTION(!aClampNegativeToZero || aStyle.GetPercentValue() >= 0.0f, - "unexpected negative value"); - *aPercent += aStyle.GetPercentValue(); - return; - } - case eStyleUnit_Calc: { - const nsStyleCoord::Calc *calc = aStyle.GetCalcValue(); - if (aClampNegativeToZero) { - // This is far from ideal when one is negative and one is positive. - *aCoord += std::max(calc->mLength, 0); - *aPercent += std::max(calc->mPercent, 0.0f); - } else { - *aCoord += calc->mLength; - *aPercent += calc->mPercent; - } - return; - } - default: { - return; - } + if (aStyle.GetUnit() == eStyleUnit_Auto) { + return nscoord(0); } + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); +} + +static nscoord +ResolvePadding(const nsStyleCoord& aStyle, nscoord aPercentageBasis) +{ + return nsLayoutUtils::ResolveToLength(aStyle, aPercentageBasis); } static nsIFrame::IntrinsicISizeOffsetData -IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) +IntrinsicSizeOffsets(nsIFrame* aFrame, nscoord aPercentageBasis, bool aForISize) { nsIFrame::IntrinsicISizeOffsetData result; WritingMode wm = aFrame->GetWritingMode(); - const nsStyleMargin* styleMargin = aFrame->StyleMargin(); + const auto& margin = aFrame->StyleMargin()->mMargin; bool verticalAxis = aForISize == wm.IsVertical(); - AddCoord(verticalAxis ? styleMargin->mMargin.GetTop() - : styleMargin->mMargin.GetLeft(), - aFrame, &result.hMargin, &result.hPctMargin, - false); - AddCoord(verticalAxis ? styleMargin->mMargin.GetBottom() - : styleMargin->mMargin.GetRight(), - aFrame, &result.hMargin, &result.hPctMargin, - false); + if (verticalAxis) { + result.hMargin += ResolveMargin(margin.GetTop(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetBottom(), aPercentageBasis); + } else { + result.hMargin += ResolveMargin(margin.GetLeft(), aPercentageBasis); + result.hMargin += ResolveMargin(margin.GetRight(), aPercentageBasis); + } - const nsStylePadding* stylePadding = aFrame->StylePadding(); - AddCoord(verticalAxis ? stylePadding->mPadding.GetTop() - : stylePadding->mPadding.GetLeft(), - aFrame, &result.hPadding, &result.hPctPadding, - true); - AddCoord(verticalAxis ? stylePadding->mPadding.GetBottom() - : stylePadding->mPadding.GetRight(), - aFrame, &result.hPadding, &result.hPctPadding, - true); + const auto& padding = aFrame->StylePadding()->mPadding; + if (verticalAxis) { + result.hPadding += ResolvePadding(padding.GetTop(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetBottom(), aPercentageBasis); + } else { + result.hPadding += ResolvePadding(padding.GetLeft(), aPercentageBasis); + result.hPadding += ResolvePadding(padding.GetRight(), aPercentageBasis); + } const nsStyleBorder* styleBorder = aFrame->StyleBorder(); if (verticalAxis) { @@ -4701,22 +4677,21 @@ IntrinsicSizeOffsets(nsIFrame* aFrame, bool aForISize) result.hPadding = presContext->DevPixelsToAppUnits(verticalAxis ? padding.TopBottom() : padding.LeftRight()); - result.hPctPadding = 0; } } return result; } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsFrame::IntrinsicISizeOffsets() +nsFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, true); + return IntrinsicSizeOffsets(this, aPercentageBasis, true); } nsIFrame::IntrinsicISizeOffsetData -nsIFrame::IntrinsicBSizeOffsets() +nsIFrame::IntrinsicBSizeOffsets(nscoord aPercentageBasis) { - return IntrinsicSizeOffsets(this, false); + return IntrinsicSizeOffsets(this, aPercentageBasis, false); } /* virtual */ IntrinsicSize diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index ff2479347..c9bf2c376 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -264,7 +264,8 @@ public: InlineMinISizeData *aData) override; void AddInlinePrefISize(nsRenderingContext *aRenderingContext, InlinePrefISizeData *aData) override; - IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData + IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override; mozilla::IntrinsicSize GetIntrinsicSize() override; nsSize GetIntrinsicRatio() override; diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 2e7021eef..2f5da6762 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -8,9 +8,9 @@ #include "nsGridContainerFrame.h" -#include // for std::stable_sort #include #include +#include // for div() #include "mozilla/CSSAlignUtils.h" #include "mozilla/dom/GridBinding.h" #include "mozilla/Maybe.h" @@ -127,43 +127,6 @@ ResolveToDefiniteSize(const nsStyleCoord& aCoord, nscoord aPercentBasis) nsRuleNode::ComputeCoordPercentCalc(aCoord, aPercentBasis)); } -static bool -GetPercentSizeParts(const nsStyleCoord& aCoord, nscoord* aLength, float* aPercent) -{ - switch (aCoord.GetUnit()) { - case eStyleUnit_Percent: - *aLength = 0; - *aPercent = aCoord.GetPercentValue(); - return true; - case eStyleUnit_Calc: { - nsStyleCoord::Calc* calc = aCoord.GetCalcValue(); - *aLength = calc->mLength; - *aPercent = calc->mPercent; - return true; - } - default: - return false; - } -} - -static void -ResolvePercentSizeParts(const nsStyleCoord& aCoord, nscoord aPercentBasis, - nscoord* aLength, float* aPercent) -{ - MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit()); - if (aPercentBasis != NS_UNCONSTRAINEDSIZE) { - *aLength = std::max(nscoord(0), - nsRuleNode::ComputeCoordPercentCalc(aCoord, - aPercentBasis)); - *aPercent = 0.0f; - return; - } - if (!GetPercentSizeParts(aCoord, aLength, aPercent)) { - *aLength = aCoord.ToLength(); - *aPercent = 0.0f; - } -} - // Synthesize a baseline from a border box. For an alphabetical baseline // this is the end edge of the border box. For a central baseline it's // the center of the border box. @@ -1172,7 +1135,7 @@ struct nsGridContainerFrame::TrackSizingFunctions return 1; } nscoord repeatTrackSize = 0; - // Note that the repeat() track size is included in |sum| in this loop. + // Note that one repeat() track size is included in |sum| in this loop. nscoord sum = 0; const nscoord percentBasis = aSize; for (uint32_t i = 0; i < numTracks; ++i) { @@ -1189,54 +1152,31 @@ struct nsGridContainerFrame::TrackSizingFunctions } nscoord trackSize = ::ResolveToDefiniteSize(*coord, percentBasis); if (i == mRepeatAutoStart) { - if (percentBasis != NS_UNCONSTRAINEDSIZE) { - // Use a minimum 1px for the repeat() track-size. - if (trackSize < AppUnitsPerCSSPixel()) { - trackSize = AppUnitsPerCSSPixel(); - } + // Use a minimum 1px for the repeat() track-size. + if (trackSize < AppUnitsPerCSSPixel()) { + trackSize = AppUnitsPerCSSPixel(); } repeatTrackSize = trackSize; } sum += trackSize; } - nscoord gridGap; - float percentSum = 0.0f; - float gridGapPercent; - ResolvePercentSizeParts(aGridGap, percentBasis, &gridGap, &gridGapPercent); + nscoord gridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aSize); if (numTracks > 1) { // Add grid-gaps for all the tracks including the repeat() track. sum += gridGap * (numTracks - 1); - percentSum = gridGapPercent * (numTracks - 1); } // Calculate the max number of tracks that fits without overflow. nscoord available = maxFill != NS_UNCONSTRAINEDSIZE ? maxFill : aMinSize; - nscoord size = nsLayoutUtils::AddPercents(sum, percentSum); - if (available - size < 0) { + nscoord spaceToFill = available - sum; + if (spaceToFill <= 0) { // "if any number of repetitions would overflow, then 1 repetition" return 1; } - uint32_t numRepeatTracks = 1; - bool exactFit = false; - while (true) { - sum += gridGap + repeatTrackSize; - percentSum += gridGapPercent; - nscoord newSize = nsLayoutUtils::AddPercents(sum, percentSum); - if (newSize <= size) { - // Adding more repeat-tracks won't make forward progress. - return numRepeatTracks; - } - size = newSize; - nscoord remaining = available - size; - exactFit = remaining == 0; - if (remaining >= 0) { - ++numRepeatTracks; - } - if (remaining <= 0) { - break; - } - } - - if (!exactFit && maxFill == NS_UNCONSTRAINEDSIZE) { + // Calculate the max number of tracks that fits without overflow. + div_t q = div(spaceToFill, repeatTrackSize + gridGap); + // The +1 here is for the one repeat track we already accounted for above. + uint32_t numRepeatTracks = q.quot + 1; + if (q.rem != 0 && maxFill == NS_UNCONSTRAINEDSIZE) { // "Otherwise, if the grid container has a definite min size in // the relevant axis, the number of repetitions is the largest possible // positive integer that fulfills that minimum requirement." @@ -1882,13 +1822,6 @@ struct nsGridContainerFrame::Tracks WritingMode aWM, const LogicalSize& aContainerSize); - /** - * Return the intrinsic size by back-computing percentages as: - * IntrinsicSize = SumOfCoordSizes / (1 - SumOfPercentages). - */ - nscoord BackComputedIntrinsicSize(const TrackSizingFunctions& aFunctions, - const nsStyleCoord& aGridGap) const; - nscoord GridLineEdge(uint32_t aLine, GridLineSide aSide) const { if (MOZ_UNLIKELY(mSizes.IsEmpty())) { @@ -2198,11 +2131,10 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput } /** - * Calculate our track sizes. If the given aContentBox block-axis size is - * unconstrained, it is assigned to the resulting intrinsic block-axis size. + * Calculate our track sizes. */ void CalculateTrackSizes(const Grid& aGrid, - LogicalSize& aContentBox, + const LogicalSize& aContentBox, SizingConstraint aConstraint); /** @@ -2688,7 +2620,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Grid void nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( const Grid& aGrid, - LogicalSize& aContentBox, + const LogicalSize& aContentBox, SizingConstraint aConstraint) { mCols.Initialize(mColFunctions, mGridStyle->mGridColumnGap, @@ -2706,12 +2638,6 @@ nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( mRows.CalculateSizes(*this, mGridItems, mRowFunctions, aContentBox.BSize(mWM), &GridArea::mRows, aConstraint); - if (aContentBox.BSize(mWM) == NS_AUTOHEIGHT) { - aContentBox.BSize(mWM) = - mRows.BackComputedIntrinsicSize(mRowFunctions, mGridStyle->mGridRowGap); - mRows.mGridGap = - ::ResolveToDefiniteSize(mGridStyle->mGridRowGap, aContentBox.BSize(mWM)); - } } /** @@ -3813,7 +3739,7 @@ nsGridContainerFrame::Tracks::Initialize( aFunctions.MinSizingFor(i), aFunctions.MaxSizingFor(i)); } - mGridGap = ::ResolveToDefiniteSize(aGridGap, aContentBoxSize); + mGridGap = nsLayoutUtils::ResolveGapToLength(aGridGap, aContentBoxSize); mContentBoxSize = aContentBoxSize; } @@ -3894,8 +3820,7 @@ ContentContribution(const GridItemInfo& aGridItem, PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, aPercentageBasis, - aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | - nsLayoutUtils::ADD_PERCENTS, + aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED, aMinSizeClamp); if (size == NS_INTRINSIC_WIDTH_UNKNOWN) { // We need to reflow the child to find its BSize contribution. @@ -3932,15 +3857,7 @@ ContentContribution(const GridItemInfo& aGridItem, LogicalSize availableSize(childWM, availISize, availBSize); size = ::MeasuringReflow(child, aState.mReflowInput, aRC, availableSize, cbSize, iMinSizeClamp, bMinSizeClamp); - nsIFrame::IntrinsicISizeOffsetData offsets = child->IntrinsicBSizeOffsets(); - size += offsets.hMargin; - auto percent = offsets.hPctMargin; - if (availBSize == NS_UNCONSTRAINEDSIZE) { - // We always want to add in percent padding too, unless we already did so - // using a resolved column size above. - percent += offsets.hPctPadding; - } - size = nsLayoutUtils::AddPercents(size, percent); + size += child->GetLogicalUsedMargin(childWM).BStartEnd(childWM); nscoord overflow = size - aMinSizeClamp; if (MOZ_UNLIKELY(overflow > 0)) { nscoord contentSize = child->ContentBSize(childWM); @@ -4045,6 +3962,10 @@ MinSize(const GridItemInfo& aGridItem, return s; } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } + // 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 / @@ -4058,7 +3979,8 @@ MinSize(const GridItemInfo& aGridItem, "baseline offset should be zero when not baseline-aligned"); nscoord sz = aGridItem.mBaselineOffset[aAxis] + nsLayoutUtils::MinSizeContributionForAxis(axis, aRC, child, - nsLayoutUtils::MIN_ISIZE); + nsLayoutUtils::MIN_ISIZE, + *aCache->mPercentageBasis); const nsStyleCoord& style = axis == eAxisHorizontal ? stylePos->mMinWidth : stylePos->mMinHeight; auto unit = style.GetUnit(); @@ -4067,9 +3989,6 @@ MinSize(const GridItemInfo& aGridItem, child->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); - if (aCache->mPercentageBasis.isNothing()) { - aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); - } sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, @@ -4927,8 +4846,8 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks( applyMinMax = false; // https://drafts.csswg.org/css-grid/#algo-flex-tracks // "If using this flex fraction would cause the grid to be smaller than - // the grid container’s min-width/height (or larger than the grid - // container’s max-width/height), then redo this step, treating the free + // the grid container?™s min-width/height (or larger than the grid + // container?™s max-width/height), then redo this step, treating the free // space as definite [...]" nscoord newSize = 0; for (auto& sz : mSizes) { @@ -5097,36 +5016,6 @@ nsGridContainerFrame::Tracks::AlignJustifyContent( MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?"); } -nscoord -nsGridContainerFrame::Tracks::BackComputedIntrinsicSize( - const TrackSizingFunctions& aFunctions, - const nsStyleCoord& aGridGap) const -{ - // Sum up the current sizes (where percentage tracks were treated as 'auto') - // in 'size'. - nscoord size = 0; - for (size_t i = 0, len = mSizes.Length(); i < len; ++i) { - size += mSizes[i].mBase; - } - - // Add grid-gap contributions to 'size' and calculate a 'percent' sum. - float percent = 0.0f; - size_t numTracks = mSizes.Length(); - if (numTracks > 1) { - const size_t gridGapCount = numTracks - 1; - nscoord gridGapLength; - float gridGapPercent; - if (::GetPercentSizeParts(aGridGap, &gridGapLength, &gridGapPercent)) { - percent = gridGapCount * gridGapPercent; - } else { - gridGapLength = aGridGap.ToLength(); - } - size += gridGapCount * gridGapLength; - } - - return std::max(0, nsLayoutUtils::AddPercents(size, percent)); -} - void nsGridContainerFrame::LineRange::ToPositionAndLength( const nsTArray& aTrackSizes, nscoord* aPos, nscoord* aLength) const @@ -6292,7 +6181,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, LogicalSize computedSize(wm, computedISize, computedBSize); nscoord consumedBSize = 0; - nscoord bSize; + nscoord bSize = 0; if (!prevInFlow) { Grid grid; grid.PlaceGridItems(gridReflowInput, aReflowInput.ComputedMinSize(), @@ -6300,7 +6189,12 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, gridReflowInput.CalculateTrackSizes(grid, computedSize, SizingConstraint::eNoConstraint); - bSize = computedSize.BSize(wm); + // Note: we can't use GridLineEdge here since we haven't calculated + // the rows' mPosition yet (happens in AlignJustifyContent below). + for (const auto& sz : gridReflowInput.mRows.mSizes) { + bSize += sz.mBase; + } + bSize += gridReflowInput.mRows.SumOfGridGaps(); } else { consumedBSize = ConsumedBSize(wm); gridReflowInput.InitializeForContinuation(this, consumedBSize); @@ -6699,8 +6593,14 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext, state.mCols.CalculateSizes(state, state.mGridItems, state.mColFunctions, NS_UNCONSTRAINEDSIZE, &GridArea::mCols, constraint); - return state.mCols.BackComputedIntrinsicSize(state.mColFunctions, - state.mGridStyle->mGridColumnGap); + state.mCols.mGridGap = + nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mGridColumnGap, + NS_UNCONSTRAINEDSIZE); + nscoord length = 0; + for (const TrackSize& sz : state.mCols.mSizes) { + length += sz.mBase; + } + return length + state.mCols.SumOfGridGaps(); } nscoord diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index d0ad27e6f..1ea3fd196 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -25,6 +25,7 @@ #include "CaretAssociationHint.h" #include "FrameProperties.h" +#include "LayoutConstants.h" #include "mozilla/layout/FrameChildList.h" #include "mozilla/Maybe.h" #include "mozilla/WritingModes.h" @@ -130,30 +131,12 @@ typedef uint32_t nsSplittableType; #define NS_FRAME_IS_NOT_SPLITTABLE(type)\ (0 == ((type) & NS_FRAME_SPLITTABLE)) -#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN - //---------------------------------------------------------------------- #define NS_SUBTREE_DIRTY(_frame) \ (((_frame)->GetStateBits() & \ (NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0) -/** - * Constant used to indicate an unconstrained size. - * - * @see #Reflow() - */ -#define NS_UNCONSTRAINEDSIZE NS_MAXSIZE - -#define NS_INTRINSICSIZE NS_UNCONSTRAINEDSIZE -#define NS_AUTOHEIGHT NS_UNCONSTRAINEDSIZE -// +1 is to avoid clamped huge margin values being processed as auto margins -#define NS_AUTOMARGIN (NS_UNCONSTRAINEDSIZE + 1) -#define NS_AUTOOFFSET NS_UNCONSTRAINEDSIZE -// NOTE: there are assumptions all over that these have the same value, namely NS_UNCONSTRAINEDSIZE -// if any are changed to be a value other than NS_UNCONSTRAINEDSIZE -// at least update AdjustComputedHeight/Width and test ad nauseum - // 1 million CSS pixels less than our max app unit measure. // For reflowing with an "infinite" available inline space per [css-sizing]. // (reflowing with an NS_UNCONSTRAINEDSIZE available inline size isn't allowed @@ -2095,23 +2078,27 @@ public: /** * Return the horizontal components of padding, border, and margin * that contribute to the intrinsic width that applies to the parent. + * @param aPercentageBasis the percentage basis to use for padding/margin - + * i.e. the Containing Block's inline-size */ struct IntrinsicISizeOffsetData { nscoord hPadding, hBorder, hMargin; - float hPctPadding, hPctMargin; IntrinsicISizeOffsetData() : hPadding(0), hBorder(0), hMargin(0) - , hPctPadding(0.0f), hPctMargin(0.0f) {} }; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() = 0; + virtual IntrinsicISizeOffsetData + IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) = 0; /** * Return the bsize components of padding, border, and margin * that contribute to the intrinsic width that applies to the parent. + * @param aPercentageBasis the percentage basis to use for padding/margin - + * i.e. the Containing Block's inline-size */ - IntrinsicISizeOffsetData IntrinsicBSizeOffsets(); + IntrinsicISizeOffsetData + IntrinsicBSizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE); virtual mozilla::IntrinsicSize GetIntrinsicSize() = 0; diff --git a/layout/reftests/bugs/403519-2-ref.html b/layout/reftests/bugs/403519-2-ref.html index e00fb5e24..72176a89a 100644 --- a/layout/reftests/bugs/403519-2-ref.html +++ b/layout/reftests/bugs/403519-2-ref.html @@ -17,7 +17,7 @@ table { - + diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html index 8858b4ea8..f2c76f78b 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-definite-001-ref.html @@ -65,32 +65,49 @@ b40 { .h.r { height: 42px; width: 42px; - /* This margin-left is 20% of 98px-wide grid area */ - margin-left: 19.6px; - /* This padding-bottom is 10% of 98px wide grid area */ - /* This padding-left is 30% of 98px wide grid area */ - padding: 1px 3px 9.8px 29.4px; + /* 49px is the percentage basis, i.e. the column size */ + margin-left: calc(0.2 * 49px); + padding: 1px 3px calc(0.1 * 49px) calc(0.3 * 49px); } .v.r { height: 42px; width: 42px; - /* This margin-left is 20% of 54px-wide grid area */ - margin-left: 10.8px; - /* This padding-bottom is 10% of 54px wide grid area */ - /* This padding-left is 30% of 54px wide grid area */ - padding: 1px 3px 5.4px 16.2px; + /* 27px is the percentage basis, i.e. the column size */ + margin-left: calc(0.2 * 27px); + padding: 1px 3px calc(0.1 * 27px) calc(0.3 * 27px); } .r { position:relative; } +.t4 { width: 49px; + height: calc(10px /* item min-height */ + + 7px /* item margin-top */ + + 1px /* item padding-top */ + + 1px /* item border-top */ + + calc(0.5 * 49px) /* item margin-bottom */ + + calc(0.1 * 49px) /* item padding-bottom */); + } + .t6 { width:46px; } -.t8 { width:118px; height: 102.5px; } +.t8 { width: 27px; + height: calc(30px /* item min-height */ + + 7px /* item margin-top */ + + 3px /* item padding-top */ + + 1px /* item border-top */ + + calc(0.5 * 27px) /* item margin-bottom */ + + calc(0.1 * 27px) /* item padding-bottom */); + } xx { display: block; background: lime; - padding:32px 32px 16px 32px; - margin: 0 0 32px 16px; + padding: 32px 32px calc(0.2 * 32px) calc(0.4 * 32px); + margin: 0 0 calc(0.4 * 32px) calc(0.2 * 32px); +} +.t9, .t10 { + position: relative; + z-index: 1; + grid: calc(32px + calc(0.4 * 32px) + calc(0.2 * 32px)) 0 / 32px; } @@ -100,15 +117,15 @@ xx {
-
+

-
+
-
-
+
+
diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html index 35f596928..183f00e24 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-002-ref.html @@ -36,7 +36,7 @@ var coltest = [ "min-height:40%", "min-height:40%; max-width:30px" ]; var results = [ -"360px", "360px", "360px", "24px", "24px", "360px", "80px", "24px", "24px", "24px", +"24px", "24px", "24px", "24px", "24px", "24px", "80px", "24px", "24px", "24px", "24px", "24px", "24px" ]; var item_width = [ diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html index caef8b031..6533c97b6 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html index fd2302add..d435f8f3e 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-percent-001-ref.html @@ -54,9 +54,9 @@ br { clear:both; } .c10 { grid-template-columns: minmax(10px,0) 1fr; } #px-border .c10 { grid-template-columns: minmax(30px,0) 1fr; } -#percent-border .c100 { grid-template-columns: 111px 0; } -#percent-border .c100calc100 { grid-template-columns: 100px 11px; } -#percent-border .c10 { grid-template-columns: minmax(11px,0) 0; } +#percent-border .c100 { grid-template-columns: 100px 0; } +#percent-border .c100calc100 { grid-template-columns: 100px 10px; } +#percent-border .c10 { grid-template-columns: minmax(10px,0) 0; } #percent-border .c100100 { grid-template-columns: minmax(100px,0) 150px; } #percent-border .c200 { grid-template-columns: 250px; } @@ -99,7 +99,7 @@ var grids = [ "grid c100", "grid c100", "grid", -"grid c200", +"grid c100", "grid c10", "grid c100", "grid c100", @@ -110,7 +110,7 @@ var grids = [ "grid c100", "grid c100", "grid", -"grid c200", +"grid c100", "grid c10", "grid c100", "grid c100", diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html index 8dcdd563b..528d63bc7 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-002-ref.html @@ -36,7 +36,7 @@ var coltest = [ "min-height:40%", "min-height:40%; max-width:30px" ]; var results = [ -"360px", "360px", "360px", "24px", "24px", "360px", "80px", "24px", "20px", "24px", +"360px", "0px", "0px", "0px", "24px", "360px", "80px", "24px", "20px", "24px", "6px", "24px", "24px" ]; var item_width = [ diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html index 36a2d4920..4eb623b7d 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html b/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html index fb4d15ff8..a55dcc989 100644 --- a/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html +++ b/layout/reftests/css-grid/grid-item-sizing-percent-003-ref.html @@ -69,67 +69,67 @@ a {
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html b/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html index 51f71e662..96365b468 100644 --- a/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html +++ b/layout/reftests/css-grid/grid-item-sizing-percent-004-ref.html @@ -62,71 +62,71 @@ a {
-
-
-
-
+
+
+
+
-
-
-
+
+
+

-
-
-
-
+
+
+
+
-
-
-
+
+
+

-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html b/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html index 945b43b52..7ad85e1e5 100644 --- a/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html +++ b/layout/reftests/css-grid/grid-percent-grid-gap-001-ref.html @@ -65,7 +65,7 @@ br { clear: both; }
-
+
@@ -74,7 +74,7 @@ br { clear: both; }
-
+
@@ -141,12 +141,12 @@ br { clear: both; }
-
-
- - - - +
+
+ + + +
diff --git a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html index a404a0905..682e0ca38 100644 --- a/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html +++ b/layout/reftests/css-grid/grid-repeat-auto-fill-fit-002-ref.html @@ -83,12 +83,16 @@ fill,fit { .zero-progress { grid-row-gap: calc(10px - 1%); - grid-template-rows: [a] 10px repeat(4, [b] minmax(0,auto) [c]) [d]; + grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; } .w50.zero-progress { grid-row-gap: calc(10px - 1%); grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; } +.mw50.zero-progress { + grid-row-gap: calc(10px - 1%); + grid-template-rows: [a] 10px repeat(4, [b] 0 [c]) [d]; +} diff --git a/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html b/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html index 629c0a917..3645fa006 100644 --- a/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html +++ b/layout/reftests/writing-mode/1174450-intrinsic-sizing-ref.html @@ -13,20 +13,20 @@ div.v, div.h { display: block; position: relative; border: 1px dashed silver; - width:92px; - height:60px; + width:74px; + height:24px; } div.h { - width:124px; - height:98px; + width:62px; + height:61.2px; } .h span { - margin: 7px 13px 62px 25px; - padding: 1px 3px 12px 37px; + margin: 7px 13px 32px 12px; + padding: 1px 3px 6px 19px; } .v span { - margin: 7px 13px 30px 12px; - padding: 1px 3px 6px 18px; + margin: 7px 13px 30px 5px; + padding: 1px 3px 2px 7px; } span { diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 77ce3cd9c..f809ede5f 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1510,7 +1510,7 @@ CSS_PROP_COLUMN( CSS_PROPERTY_PARSE_VALUE | CSS_PROPERTY_VALUE_NONNEGATIVE, "", - VARIANT_HL | VARIANT_NORMAL | VARIANT_CALC, + VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC, nullptr, offsetof(nsStyleColumn, mColumnGap), eStyleAnimType_Coord) diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index d81325b63..250c70870 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -3575,7 +3575,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn uint32_t mColumnCount; // [reset] see nsStyleConsts.h nsStyleCoord mColumnWidth; // [reset] coord, auto - nsStyleCoord mColumnGap; // [reset] coord, normal + nsStyleCoord mColumnGap; // [reset] | normal mozilla::StyleComplexColor mColumnRuleColor; // [reset] uint8_t mColumnRuleStyle; // [reset] diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 3ff599e26..d5b8d49cd 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1438,7 +1438,7 @@ var gCSSProperties = { inherited: false, type: CSS_TYPE_LONGHAND, initial_values: [ "normal", "1em", "calc(-2em + 3em)" ], - other_values: [ "2px", "4em", + other_values: [ "2px", "1em", "4em", "3%", "calc(3%)", "calc(1em - 3%)", "calc(2px)", "calc(-2px)", "calc(0px)", @@ -1448,7 +1448,7 @@ var gCSSProperties = { "calc(25px*3)", "calc(3*25px + 5em)", ], - invalid_values: [ "3%", "-1px", "4" ] + invalid_values: [ "-3%", "-1px", "4" ] }, "-moz-column-gap": { domProp: "MozColumnGap", diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index ac7e3e860..6b810f78a 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -796,12 +796,12 @@ nsTableCellFrame::GetPrefISize(nsRenderingContext *aRenderingContext) } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsTableCellFrame::IntrinsicISizeOffsets() +nsTableCellFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + IntrinsicISizeOffsetData result = + nsContainerFrame::IntrinsicISizeOffsets(aPercentageBasis); result.hMargin = 0; - result.hPctMargin = 0; WritingMode wm = GetWritingMode(); result.hBorder = GetBorderWidth(wm).IStartEnd(wm); diff --git a/layout/tables/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h index 6717e1b70..240809850 100644 --- a/layout/tables/nsTableCellFrame.h +++ b/layout/tables/nsTableCellFrame.h @@ -118,7 +118,8 @@ public: virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis = + NS_UNCONSTRAINEDSIZE) override; virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index fbbabe5f9..4305e6cc6 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1598,16 +1598,15 @@ nsTableFrame::GetPrefISize(nsRenderingContext *aRenderingContext) } /* virtual */ nsIFrame::IntrinsicISizeOffsetData -nsTableFrame::IntrinsicISizeOffsets() +nsTableFrame::IntrinsicISizeOffsets(nscoord aPercentageBasis) { - IntrinsicISizeOffsetData result = nsContainerFrame::IntrinsicISizeOffsets(); + IntrinsicISizeOffsetData result = + nsContainerFrame::IntrinsicISizeOffsets(aPercentageBasis); result.hMargin = 0; - result.hPctMargin = 0; if (IsBorderCollapse()) { result.hPadding = 0; - result.hPctPadding = 0; WritingMode wm = GetWritingMode(); LogicalMargin outerBC = GetIncludedOuterBCBorder(wm); diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index f526868e8..f29fadc02 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -317,7 +317,8 @@ public: // border to the results of these functions. virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override; virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override; - virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override; + IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis = + NS_UNCONSTRAINEDSIZE) override; virtual mozilla::LogicalSize ComputeSize(nsRenderingContext* aRenderingContext,
 
 
b