summaryrefslogtreecommitdiff
path: root/layout
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-09-28 23:36:05 -0400
committerGaming4JC <g4jc@hyperbola.info>2019-09-28 23:47:05 -0400
commit68bc133c802beabd2b85f9190d560080b529e867 (patch)
tree97e62467bb84625caa59b1c3620c7c5606ebe6cd /layout
parenta6303615be2a6bc6f0a17d7ed8d8f6e4537ee10e (diff)
downloaduxp-68bc133c802beabd2b85f9190d560080b529e867.tar.gz
Issue mcp-graveyard/UXP#1230 - Part 1: Fix Back-computing percentages for intrinsic sizing in Layout CSS-Grid
List of relevant patches applied: 1398537 part 2 - [css-multicol] Implement percentages for 'column-gap' (Gecko part). 1434478 part 1 - [css-grid] Stop back-computing percentage grid gaps when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 2 - Stop back-computing percentage padding/margin when the percentage basis is indefinite. Treat them as zero sized instead. 1434478 part 3 - Remove IntrinsicISizeOffsetData::hPctPadding/hPctMargin members since they are now unused. 1434478 part 4 - Factor out constants like NS_UNCONSTRAINEDSIZE so they can be used in headers without needing nsIFrame.h (idempotent patch). 1434478 part 5 - Create nsLayoutUtils::ResolveToLength for resolving CSS <length-percentage> (idempotent patch). 1434478 part 6 - Propagate a percentage basis to nsIFrame::IntrinsicISizeOffsets for resolving padding/margin. This is needed only for CSS Grid since in other cases we're only using IntrinsicISizeOffsets in the inline-axis and the percentage basis is always indefinite for *intrinsic sizing*. When calculating the intrinsic size of grid items in the grid container's block axis however, we do have a definite size for the grid area in the inline-axis and it should be used per: https://drafts.csswg.org/css-grid/#algo-overview "2. Next, the track sizing algorithm resolves the sizes of the grid rows, using the grid column sizes calculated in the previous step." (Percentage padding/margin for grid items is always resolved against the grid area's inline-size nowadays.)
Diffstat (limited to 'layout')
-rw-r--r--layout/base/LayoutConstants.h31
-rw-r--r--layout/base/moz.build4
-rw-r--r--layout/base/nsLayoutUtils.cpp76
-rw-r--r--layout/base/nsLayoutUtils.h95
-rw-r--r--layout/generic/nsColumnSetFrame.cpp19
-rw-r--r--layout/generic/nsFrame.cpp93
-rw-r--r--layout/generic/nsFrame.h3
-rw-r--r--layout/generic/nsGridContainerFrame.cpp180
-rw-r--r--layout/generic/nsIFrame.h31
-rw-r--r--layout/style/nsCSSPropList.h2
-rw-r--r--layout/style/nsStyleStruct.h2
-rw-r--r--layout/style/test/property_database.js4
-rw-r--r--layout/tables/nsTableCellFrame.cpp6
-rw-r--r--layout/tables/nsTableCellFrame.h3
-rw-r--r--layout/tables/nsTableFrame.cpp7
-rw-r--r--layout/tables/nsTableFrame.h3
16 files changed, 240 insertions, 319 deletions
diff --git a/layout/base/LayoutConstants.h b/layout/base/LayoutConstants.h
new file mode 100644
index 0000000000..cd6e1c3f55
--- /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 4308a6e4d0..afc683665a 100644
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -13,6 +13,9 @@ with Files('Display*'):
with Files('FrameLayerBuilder.*'):
BUG_COMPONENT = ('Core', 'Layout: View Rendering')
+with Files('LayoutConstants.*'):
+ BUG_COMPONENT = ('Core', 'Layout: View Rendering')
+
with Files('LayerState.*'):
BUG_COMPONENT = ('Core', 'Layout: View Rendering')
@@ -63,6 +66,7 @@ EXPORTS += [
'FrameLayerBuilder.h',
'FrameProperties.h',
'LayerState.h',
+ 'LayoutConstants.h',
'LayoutLogging.h',
'nsArenaMemoryStats.h',
'nsBidi.h',
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 06690b208b..21d20c69fa 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4671,8 +4671,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 +
@@ -4916,12 +4914,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;
@@ -4929,21 +4924,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()) &&
@@ -4961,18 +4950,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;
@@ -4980,9 +4957,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;
}
@@ -4993,17 +4967,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;
}
@@ -5020,9 +4988,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;
}
@@ -5267,9 +5232,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,
@@ -5310,11 +5285,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(),
@@ -5328,9 +5304,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;
@@ -5375,11 +5349,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 0a82dbf6a5..bba1f32652 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"
@@ -154,6 +155,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.
@@ -1381,7 +1383,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
@@ -1395,14 +1398,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<mozilla::LogicalSize>& aPercentageBasis = mozilla::Nothing(),
+ const mozilla::Maybe<LogicalSize>& aPercentageBasis = mozilla::Nothing(),
uint32_t aFlags = 0,
nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE);
/**
@@ -1427,31 +1429,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
@@ -2876,6 +2865,62 @@ public:
static nsRect ComputeGeometryBox(nsIFrame* aFrame,
StyleGeometryBox aGeometryBox);
+ /**
+ * Resolve a CSS <length-percentage> value to a definite size.
+ */
+ template<bool clampNegativeResultToZero>
+ 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<true>(aGap, aPercentageBasis);
+ }
+
private:
static uint32_t sFontSizeInflationEmPerLine;
static uint32_t sFontSizeInflationMinTwips;
diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp
index ad36ba1a88..6ea15d4d2f 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
@@ -227,7 +224,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.
@@ -403,7 +400,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.
@@ -424,7 +421,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 bd96f213b0..a531dea07f 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4515,68 +4515,44 @@ nsIFrame::InlinePrefISizeData::ForceBreak()
mSkipWhitespace = true;
}
-static void
-AddCoord(const nsStyleCoord& aStyle,
- nsIFrame* aFrame,
- nscoord* aCoord, float* aPercent,
- bool aClampNegativeToZero)
-{
- 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;
- }
+static nscoord
+ResolveMargin(const nsStyleCoord& aStyle, nscoord aPercentageBasis)
+{
+ if (aStyle.GetUnit() == eStyleUnit_Auto) {
+ return nscoord(0);
}
+ return nsLayoutUtils::ResolveToLength<false>(aStyle, aPercentageBasis);
+}
+
+static nscoord
+ResolvePadding(const nsStyleCoord& aStyle, nscoord aPercentageBasis)
+{
+ return nsLayoutUtils::ResolveToLength<true>(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);
-
- 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);
+ 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 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) {
@@ -4606,22 +4582,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 af1c95ef29..439e398562 100644
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -261,7 +261,8 @@ public:
InlineMinISizeData *aData) override;
virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext,
InlinePrefISizeData *aData) override;
- virtual IntrinsicISizeOffsetData IntrinsicISizeOffsets() override;
+ IntrinsicISizeOffsetData
+ IntrinsicISizeOffsets(nscoord aPercentageBasis = NS_UNCONSTRAINEDSIZE) override;
virtual mozilla::IntrinsicSize GetIntrinsicSize() override;
virtual nsSize GetIntrinsicRatio() override;
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index 054f012978..959061e334 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -8,8 +8,8 @@
#include "nsGridContainerFrame.h"
-#include <algorithm> // for std::stable_sort
#include <limits>
+#include <stdlib.h> // for div()
#include "mozilla/CSSAlignUtils.h"
#include "mozilla/dom/GridBinding.h"
#include "mozilla/Function.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,
@@ -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<TrackSize>& 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 = GetConsumedBSize();
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 ec35684832..57f5c460c2 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
@@ -2050,23 +2033,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/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index 2049f70e88..07db6d3ddc 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1499,7 +1499,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 c8182b8f14..b257c6bb54 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3495,7 +3495,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] <length-percentage> | 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 272931c15e..c75f7b498f 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 316a966134..dea82ea591 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 6717e1b70d..2408098507 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 b9b6ca5fe5..272a77406a 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1564,16 +1564,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 7e56c28c17..c7b92d387e 100644
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -324,7 +324,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,