diff options
author | Matt A. Tobin <email@mattatobin.com> | 2022-04-02 12:13:12 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2022-04-02 12:13:12 -0500 |
commit | d4d548b757218feb9628f39ae4e601342ba96642 (patch) | |
tree | d681229bf3bc5bd228b6863fb94011b697a03c86 /layout | |
parent | 7d9902261cc16bb264e57b568609370c8e8c1644 (diff) | |
download | aura-central-d4d548b757218feb9628f39ae4e601342ba96642.tar.gz |
[Layout/CSS] Support updated box alignment spec on gap properties
Mozilla Bugs 1398492 1398482 1398483 145482 1473044 1473047 1612401 1639627 1458902
Diffstat (limited to 'layout')
40 files changed, 1509 insertions, 867 deletions
diff --git a/layout/base/crashtests/1156588.html b/layout/base/crashtests/1156588.html index ed0098f79..b48bc3af2 100644 --- a/layout/base/crashtests/1156588.html +++ b/layout/base/crashtests/1156588.html @@ -2,9 +2,6 @@ <html> <head> <meta charset="UTF-8"> -<!-- -user_pref("layout.css.grid.enabled", true); ---> <script> function boom() diff --git a/layout/base/crashtests/crashtests.list b/layout/base/crashtests/crashtests.list index 1a3bf667b..1c8e2713a 100644 --- a/layout/base/crashtests/crashtests.list +++ b/layout/base/crashtests/crashtests.list @@ -467,7 +467,7 @@ load 1116104.html load 1127198-1.html load 1140198.html load 1143535.html -pref(layout.css.grid.enabled,true) load 1156588.html +load 1156588.html load 1162813.xul load 1163583.html load 1234622-1.html diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 01d75c1cf..732068ac2 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -141,7 +141,6 @@ using namespace mozilla::layers; using namespace mozilla::layout; using namespace mozilla::gfx; -#define GRID_ENABLED_PREF_NAME "layout.css.grid.enabled" #define GRID_TEMPLATE_SUBGRID_ENABLED_PREF_NAME "layout.css.grid-template-subgrid-value.enabled" #define WEBKIT_PREFIXES_ENABLED_PREF_NAME "layout.css.prefixes.webkit" #define DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME "layout.css.display-flow-root.enabled" @@ -194,51 +193,6 @@ static ContentMap& GetContentMap() { return *sContentMap; } -// When the pref "layout.css.grid.enabled" changes, this function is invoked -// to let us update kDisplayKTable, to selectively disable or restore the -// entries for "grid" and "inline-grid" in that table. -static void -GridEnabledPrefChangeCallback(const char* aPrefName, void* aClosure) -{ - MOZ_ASSERT(strncmp(aPrefName, GRID_ENABLED_PREF_NAME, - ArrayLength(GRID_ENABLED_PREF_NAME)) == 0, - "We only registered this callback for a single pref, so it " - "should only be called for that pref"); - - static int32_t sIndexOfGridInDisplayTable; - static int32_t sIndexOfInlineGridInDisplayTable; - static bool sAreGridKeywordIndicesInitialized; // initialized to false - - bool isGridEnabled = - Preferences::GetBool(GRID_ENABLED_PREF_NAME, false); - if (!sAreGridKeywordIndicesInitialized) { - // First run: find the position of "grid" and "inline-grid" in - // kDisplayKTable. - sIndexOfGridInDisplayTable = - nsCSSProps::FindIndexOfKeyword(eCSSKeyword_grid, - nsCSSProps::kDisplayKTable); - MOZ_ASSERT(sIndexOfGridInDisplayTable >= 0, - "Couldn't find grid in kDisplayKTable"); - sIndexOfInlineGridInDisplayTable = - nsCSSProps::FindIndexOfKeyword(eCSSKeyword_inline_grid, - nsCSSProps::kDisplayKTable); - MOZ_ASSERT(sIndexOfInlineGridInDisplayTable >= 0, - "Couldn't find inline-grid in kDisplayKTable"); - sAreGridKeywordIndicesInitialized = true; - } - - // OK -- now, stomp on or restore the "grid" entries in kDisplayKTable, - // depending on whether the grid pref is enabled vs. disabled. - if (sIndexOfGridInDisplayTable >= 0) { - nsCSSProps::kDisplayKTable[sIndexOfGridInDisplayTable].mKeyword = - isGridEnabled ? eCSSKeyword_grid : eCSSKeyword_UNKNOWN; - } - if (sIndexOfInlineGridInDisplayTable >= 0) { - nsCSSProps::kDisplayKTable[sIndexOfInlineGridInDisplayTable].mKeyword = - isGridEnabled ? eCSSKeyword_inline_grid : eCSSKeyword_UNKNOWN; - } -} - // When the pref "layout.css.prefixes.webkit" changes, this function is invoked // to let us update kDisplayKTable, to selectively disable or restore the // entries for "-webkit-box" and "-webkit-inline-box" in that table. @@ -7561,8 +7515,6 @@ struct PrefCallbacks PrefChangedFunc func; }; static const PrefCallbacks kPrefCallbacks[] = { - { GRID_ENABLED_PREF_NAME, - GridEnabledPrefChangeCallback }, { WEBKIT_PREFIXES_ENABLED_PREF_NAME, WebkitPrefixEnabledPrefChangeCallback }, { TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME, diff --git a/layout/generic/crashtests/1015562.html b/layout/generic/crashtests/1015562.html index 8975e64f2..353ae40e3 100644 --- a/layout/generic/crashtests/1015562.html +++ b/layout/generic/crashtests/1015562.html @@ -3,10 +3,6 @@ <head> <script> -/* -user_pref("layout.css.grid.enabled", true); -*/ - function boom() { document.getElementById("r").appendChild(document.createTextNode("B")); diff --git a/layout/generic/crashtests/1156257.html b/layout/generic/crashtests/1156257.html index e58c1ba5d..479992629 100644 --- a/layout/generic/crashtests/1156257.html +++ b/layout/generic/crashtests/1156257.html @@ -2,9 +2,6 @@ <html> <head> <meta charset="UTF-8"> -<!-- -user_pref("layout.css.grid.enabled", true); ---> <script> function boom() { diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index c8fb84feb..4d9a5de0f 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -566,7 +566,7 @@ load 986899.html load 1001233.html load 1001258-1.html load 1003441.xul -pref(layout.css.grid.enabled,true) load 1015562.html +load 1015562.html asserts(1-2) load 1015563-1.html asserts(1-2) load 1015563-2.html asserts(0-300) load 1015844.html # bug 574889 @@ -589,7 +589,7 @@ load 1146107.html load 1146114.html load 1153695.html load 1156222.html -pref(layout.css.grid.enabled,true) load 1156257.html +load 1156257.html load 1157011.html load 1169420-1.html load 1169420-2.html @@ -601,9 +601,9 @@ load 1222783.xhtml load 1223568-1.html load 1223568-2.html load 1224230-1.html -pref(layout.css.grid.enabled,true) load 1225118.html -pref(layout.css.grid.enabled,true) load 1225376.html -pref(layout.css.grid.enabled,true) load 1225592.html +load 1225118.html +load 1225376.html +load 1225592.html load 1229437-1.html load 1229437-2.html pref(dom.details_element.enabled,true) load details-containing-only-text.html diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 90d425ccf..99733c549 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -183,15 +183,15 @@ nsColumnSetFrame::GetAvailableContentBSize(const ReflowInput& aReflowInput) static nscoord GetColumnGap(nsColumnSetFrame* aFrame, - const nsStyleColumn* aColStyle, nscoord aPercentageBasis) { - const auto& columnGap = aColStyle->mColumnGap; - if (columnGap.GetUnit() == eStyleUnit_Normal) { + const nsStylePosition* positionData = aFrame->StylePosition(); + if (positionData->mColumnGap.GetUnit() == eStyleUnit_Normal) { return aFrame->StyleFont()->mFont.size; } - return nsLayoutUtils::ResolveGapToLength(columnGap, aPercentageBasis); + return nsLayoutUtils::ResolveGapToLength(positionData->mColumnGap, + aPercentageBasis); } nsColumnSetFrame::ReflowConfig @@ -224,7 +224,7 @@ nsColumnSetFrame::ChooseColumnStrategy(const ReflowInput& aReflowInput, colBSize = std::min(colBSize, aReflowInput.ComputedMaxBSize()); } - nscoord colGap = GetColumnGap(this, colStyle, aReflowInput.ComputedISize()); + nscoord colGap = GetColumnGap(this, aReflowInput.ComputedISize()); int32_t numColumns = colStyle->mColumnCount; // If column-fill is set to 'balance', then we want to balance the columns. @@ -400,7 +400,7 @@ nsColumnSetFrame::GetMinISize(nsRenderingContext *aRenderingContext) // include n-1 column gaps. colISize = iSize; iSize *= colStyle->mColumnCount; - nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); + nscoord colGap = GetColumnGap(this, NS_UNCONSTRAINEDSIZE); iSize += colGap * (colStyle->mColumnCount - 1); // The multiplication above can make 'width' negative (integer overflow), // so use std::max to protect against that. @@ -421,7 +421,7 @@ nsColumnSetFrame::GetPrefISize(nsRenderingContext *aRenderingContext) nscoord result = 0; DISPLAY_PREF_WIDTH(this, result); const nsStyleColumn* colStyle = StyleColumn(); - nscoord colGap = GetColumnGap(this, colStyle, NS_UNCONSTRAINEDSIZE); + nscoord colGap = GetColumnGap(this, NS_UNCONSTRAINEDSIZE); nscoord colISize; if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) { diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 8a393c3fe..4429111e4 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -34,6 +34,7 @@ typedef nsFlexContainerFrame::FlexboxAxisTracker FlexboxAxisTracker; typedef nsFlexContainerFrame::StrutInfo StrutInfo; typedef nsFlexContainerFrame::CachedMeasuringReflowResult CachedMeasuringReflowResult; +typedef nsLayoutUtils::IntrinsicISizeType IntrinsicISizeType; static mozilla::LazyLogModule gFlexContainerLog("nsFlexContainerFrame"); @@ -811,17 +812,23 @@ protected: class nsFlexContainerFrame::FlexLine : public LinkedListElement<FlexLine> { public: - FlexLine() + explicit FlexLine(nscoord aMainGapSize) : mNumItems(0), mNumFrozenItems(0), mTotalInnerHypotheticalMainSize(0), mTotalOuterHypotheticalMainSize(0), mLineCrossSize(0), mFirstBaselineOffset(nscoord_MIN), - mLastBaselineOffset(nscoord_MIN) + mLastBaselineOffset(nscoord_MIN), + mMainGapSize(aMainGapSize) {} - // Returns the sum of our FlexItems' outer hypothetical main sizes. + nscoord GetSumOfGaps() const { + return mNumItems > 0 ? (mNumItems - 1) * mMainGapSize : 0; + } + + // Returns the sum of our FlexItems' outer hypothetical main sizes + // and the sum of the main axis {row,column}-gaps between items. // ("outer" = margin-box, and "hypothetical" = before flexing) nscoord GetTotalOuterHypotheticalMainSize() const { return mTotalOuterHypotheticalMainSize; @@ -890,8 +897,16 @@ public: if (aItem->IsFrozen()) { mNumFrozenItems++; } - mTotalInnerHypotheticalMainSize += aItemInnerHypotheticalMainSize; + + mTotalInnerHypotheticalMainSize += (aItemOuterHypotheticalMainSize - + aItemInnerHypotheticalMainSize); mTotalOuterHypotheticalMainSize += aItemOuterHypotheticalMainSize; + + // If the item added was not the first item in the line, we add in + // any gap space as needed. + if (mNumItems >= 2) { + mTotalOuterHypotheticalMainSize += mMainGapSize; + } } // Computes the cross-size and baseline position of this FlexLine, based on @@ -935,6 +950,22 @@ public: return mLastBaselineOffset; } + /** + * Returns the number of items held in this line. Used for total gap + * calculations. + */ + uint32_t GetNumItems() const { + return mNumItems; + } + + /** + * Returns the gap size in the main axis for this line. Used for gap + * calculations. + */ + nscoord GetMainGapSize() const { + return mMainGapSize; + } + // Runs the "Resolving Flexible Lengths" algorithm from section 9.7 of the // CSS flexbox spec to distribute aFlexContainerMainSize among our flex items. void ResolveFlexibleLengths(nscoord aFlexContainerMainSize); @@ -973,6 +1004,9 @@ private: nscoord mLineCrossSize; nscoord mFirstBaselineOffset; nscoord mLastBaselineOffset; + + // Maintain size of each {row,column}-gap in the main axis + const nscoord mMainGapSize; }; // Information about a strut left behind by a FlexItem that's been collapsed @@ -2241,6 +2275,9 @@ public: "miscounted the number of auto margins"); } + // Advances past the gap space (if any) between two flex items + void TraverseGap(nscoord aGapSize) { mPosition += aGapSize; } + // Advances past the packing space (if any) between two flex items void TraversePackingSpace(); @@ -2266,7 +2303,11 @@ public: const ReflowInput& aReflowInput, nscoord aContentBoxCrossSize, bool aIsCrossSizeDefinite, - const FlexboxAxisTracker& aAxisTracker); + const FlexboxAxisTracker& aAxisTracker, + const nscoord aCrossGapSize); + + // Advances past the gap (if any) between two flex lines + void TraverseGap() { mPosition += mCrossGapSize; } // Advances past the packing space (if any) between two flex lines void TraversePackingSpace(); @@ -2288,6 +2329,8 @@ private: uint32_t mNumPackingSpacesRemaining; // XXX this should be uint16_t when we add explicit fallback handling uint8_t mAlignContent; + + const nscoord mCrossGapSize; }; // Utility class for managing our position along the cross axis, *within* a @@ -2581,14 +2624,12 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize) } MOZ_ASSERT(!IsEmpty(), "empty lines should take the early-return above"); - // Subtract space occupied by our items' margins/borders/padding, so we can - // just be dealing with the space available for our flex items' content - // boxes. - nscoord spaceReservedForMarginBorderPadding = - mTotalOuterHypotheticalMainSize - mTotalInnerHypotheticalMainSize; - + // Subtract space occupied by our items' margins/borders/padding/gaps, so + // we can just be dealing with the space available for our flex items' + // content boxes. nscoord spaceAvailableForFlexItemsContentBoxes = - aFlexContainerMainSize - spaceReservedForMarginBorderPadding; + aFlexContainerMainSize - (mTotalInnerHypotheticalMainSize + + GetSumOfGaps()); nscoord origAvailableFreeSpace; bool isOrigAvailFreeSpaceInitialized = false; @@ -2867,6 +2908,9 @@ MainAxisPositionTracker:: mNumAutoMarginsInMainAxis += item->GetNumAutoMarginsInAxis(mAxis); } + // Subtract space required for row/col gap from the remaining packing space + mPackingSpaceRemaining -= aLine->GetSumOfGaps(); + if (mPackingSpaceRemaining <= 0) { // No available packing space to use for resolving auto margins. mNumAutoMarginsInMainAxis = 0; @@ -3014,12 +3058,14 @@ CrossAxisPositionTracker:: const ReflowInput& aReflowInput, nscoord aContentBoxCrossSize, bool aIsCrossSizeDefinite, - const FlexboxAxisTracker& aAxisTracker) + const FlexboxAxisTracker& aAxisTracker, + const nscoord aCrossGapSize) : PositionTracker(aAxisTracker.GetCrossAxis(), aAxisTracker.IsCrossAxisReversed()), mPackingSpaceRemaining(0), mNumPackingSpacesRemaining(0), - mAlignContent(aReflowInput.mStylePosition->mAlignContent) + mAlignContent(aReflowInput.mStylePosition->mAlignContent), + mCrossGapSize(aCrossGapSize) { MOZ_ASSERT(aFirstLine, "null first line pointer"); @@ -3072,6 +3118,11 @@ CrossAxisPositionTracker:: numLines++; } + // Subtract space required for row/col gap from the remaining packing space + MOZ_ASSERT(numLines >= 1, + "GenerateFlexLines should've produced at least 1 line"); + mPackingSpaceRemaining -= aCrossGapSize * (numLines - 1); + // If packing space is negative, 'space-between' and 'stretch' behave like // 'flex-start', and 'space-around' and 'space-evenly' behave like 'center'. // In those cases, it's simplest to just pretend we have a different @@ -3673,9 +3724,10 @@ FlexboxAxisTracker::InitAxesFromModernProps( // back depending on aShouldInsertAtFront), and returns a pointer to it. static FlexLine* AddNewFlexLineToList(LinkedList<FlexLine>& aLines, - bool aShouldInsertAtFront) + bool aShouldInsertAtFront, + nscoord aMainGapSize) { - FlexLine* newLine = new FlexLine(); + FlexLine* newLine = new FlexLine(aMainGapSize); if (aShouldInsertAtFront) { aLines.insertFront(newLine); } else { @@ -3692,6 +3744,7 @@ nsFlexContainerFrame::GenerateFlexLines( nscoord aAvailableBSizeForContent, const nsTArray<StrutInfo>& aStruts, const FlexboxAxisTracker& aAxisTracker, + nscoord aMainGapSize, nsTArray<nsIFrame*>& aPlaceholders, /* out */ LinkedList<FlexLine>& aLines /* out */) { @@ -3710,7 +3763,8 @@ nsFlexContainerFrame::GenerateFlexLines( // We have at least one FlexLine. Even an empty flex container has a single // (empty) flex line. - FlexLine* curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront); + FlexLine* curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, + aMainGapSize); nscoord wrapThreshold; if (isSingleLine) { @@ -3759,7 +3813,8 @@ nsFlexContainerFrame::GenerateFlexLines( // Honor "page-break-before", if we're multi-line and this line isn't empty: if (!isSingleLine && !curLine->IsEmpty() && childFrame->StyleDisplay()->mBreakBefore) { - curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront); + curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, + aMainGapSize); } UniquePtr<FlexItem> item; @@ -3782,11 +3837,16 @@ nsFlexContainerFrame::GenerateFlexLines( // Check if we need to wrap |item| to a new line // (i.e. check if its outer hypothetical main size pushes our line over // the threshold) - if (wrapThreshold != NS_UNCONSTRAINEDSIZE && - !curLine->IsEmpty() && // No need to wrap at start of a line. - wrapThreshold < (curLine->GetTotalOuterHypotheticalMainSize() + - itemOuterHypotheticalMainSize)) { - curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront); + // Don't wrap if unconstrained and if this will be line's first item. + if (wrapThreshold != NS_UNCONSTRAINEDSIZE && !curLine->IsEmpty()) { + nscoord newOuterSize = curLine->GetTotalOuterHypotheticalMainSize() + + itemOuterHypotheticalMainSize; + // Account for gap between this line's previous item and this item + newOuterSize += aMainGapSize; + if (newOuterSize == nscoord_MAX || newOuterSize > wrapThreshold) { + curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, + aMainGapSize); + } } // Add item to current flex line (and update the line's bookkeeping about @@ -3798,7 +3858,8 @@ nsFlexContainerFrame::GenerateFlexLines( // Honor "page-break-after", if we're multi-line and have more children: if (!isSingleLine && childFrame->GetNextSibling() && childFrame->StyleDisplay()->mBreakAfter) { - curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront); + curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront, + aMainGapSize); } itemIdxInContainer++; } @@ -3990,6 +4051,9 @@ FlexLine::PositionItemsInMainAxis(uint8_t aJustifyContent, mainAxisPosnTracker.ExitChildFrame(itemMainBorderBoxSize); mainAxisPosnTracker.ExitMargin(item->GetMargin()); mainAxisPosnTracker.TraversePackingSpace(); + if (item->getNext()) { + mainAxisPosnTracker.TraverseGap(mMainGapSize); + } } } @@ -4178,16 +4242,37 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext, nscoord contentBoxMainSize = GetMainSizeFromReflowInput(aReflowInput, axisTracker); + // Calculate gap size for main and cross axis + nscoord mainGapSize; + nscoord crossGapSize; + if (axisTracker.IsRowOriented()) { + mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap, + contentBoxMainSize); + crossGapSize = + nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, + GetEffectiveComputedBSize(aReflowInput)); + } else { + mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, + contentBoxMainSize); + NS_WARNING_ASSERTION(aReflowInput.ComputedISize() != NS_UNCONSTRAINEDSIZE, + "Unconstrained inline size; this should only result " + "from huge sizes (not intrinsic sizing w/ orthogonal " + "flows)"); + crossGapSize = + nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap, + aReflowInput.ComputedISize()); + } + AutoTArray<StrutInfo, 1> struts; DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus, contentBoxMainSize, availableBSizeForContent, - struts, axisTracker); + struts, axisTracker, mainGapSize, crossGapSize); if (!struts.IsEmpty()) { // We're restarting flex layout, with new knowledge of collapsed items. DoFlexLayout(aPresContext, aDesiredSize, aReflowInput, aStatus, contentBoxMainSize, availableBSizeForContent, - struts, axisTracker); + struts, axisTracker, mainGapSize, crossGapSize); } } @@ -4312,7 +4397,9 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, nscoord aContentBoxMainSize, nscoord aAvailableBSizeForContent, nsTArray<StrutInfo>& aStruts, - const FlexboxAxisTracker& aAxisTracker) + const FlexboxAxisTracker& aAxisTracker, + nscoord aMainGapSize, + nscoord aCrossGapSize) { aStatus = NS_FRAME_COMPLETE; @@ -4324,6 +4411,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, aContentBoxMainSize, aAvailableBSizeForContent, aStruts, aAxisTracker, + aMainGapSize, placeholderKids, lines); if (lines.getFirst()->IsEmpty() && @@ -4385,6 +4473,11 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, // Now that we've finished with this line's items, size the line itself: line->ComputeCrossSizeAndBaseline(aAxisTracker); sumLineCrossSizes += line->GetLineCrossSize(); + + // Add the cross axis gap space if this is not the last line + if (line->getNext()) { + sumLineCrossSizes += aCrossGapSize; + } } bool isCrossSizeDefinite; @@ -4397,7 +4490,8 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, CrossAxisPositionTracker crossAxisPosnTracker(lines.getFirst(), aReflowInput, contentBoxCrossSize, - isCrossSizeDefinite, aAxisTracker); + isCrossSizeDefinite, aAxisTracker, + aCrossGapSize); // Now that we know the cross size of each line (including // "align-content:stretch" adjustments, from the CrossAxisPositionTracker @@ -4447,6 +4541,10 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, aAxisTracker); crossAxisPosnTracker.TraverseLine(*line); crossAxisPosnTracker.TraversePackingSpace(); + + if (line->getNext()) { + crossAxisPosnTracker.TraverseGap(); + } } // If the container should derive its baseline from the last FlexLine, @@ -4817,33 +4915,70 @@ nsFlexContainerFrame::ReflowPlaceholders(nsPresContext* aPresContext, } } -/* virtual */ nscoord -nsFlexContainerFrame::GetMinISize(nsRenderingContext* aRenderingContext) +nscoord +nsFlexContainerFrame::GetIntrinsicISize(nsRenderingContext* aRenderingContext, + IntrinsicISizeType aType) { - nscoord minISize = 0; - DISPLAY_MIN_WIDTH(this, minISize); - + nscoord containerISize = 0; RenumberList(); const nsStylePosition* stylePos = StylePosition(); const FlexboxAxisTracker axisTracker(this, GetWritingMode()); + nscoord mainGapSize; + if (axisTracker.IsRowOriented()) { + mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mColumnGap, + NS_UNCONSTRAINEDSIZE); + } else { + mainGapSize = nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, + NS_UNCONSTRAINEDSIZE); + } + + // The loop below sets aside space for a gap before each item besides the + // first. This bool helps us handle that special-case. + bool onFirstChild = true; + for (nsIFrame* childFrame : mFrames) { - nscoord childMinISize = - nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame, - nsLayoutUtils::MIN_ISIZE); - // For a horizontal single-line flex container, the intrinsic min - // isize is the sum of its items' min isizes. - // For a column-oriented flex container, or for a multi-line row- - // oriented flex container, the intrinsic min isize is the max of - // its items' min isizes. + // Skip out-of-flow children because they don't participate in flex layout. + if (childFrame->GetType() == nsGkAtoms::placeholderFrame) { + continue; + } + + nscoord childISize = nsLayoutUtils::IntrinsicForContainer( + aRenderingContext, childFrame, aType); + // * For a row-oriented single-line flex container, the intrinsic + // {min/pref}-isize is the sum of its items' {min/pref}-isizes and + // (n-1) column gaps. + // * For a column-oriented flex container, the intrinsic min isize + // is the max of its items' min isizes. + // * For a row-oriented multi-line flex container, the intrinsic + // pref isize is former (sum), and its min isize is the latter (max). + bool isSingleLine = (NS_STYLE_FLEX_WRAP_NOWRAP == stylePos->mFlexWrap); if (axisTracker.IsRowOriented() && - NS_STYLE_FLEX_WRAP_NOWRAP == stylePos->mFlexWrap) { - minISize += childMinISize; + (isSingleLine || aType == nsLayoutUtils::PREF_ISIZE)) { + containerISize += childISize; + if (!onFirstChild) { + containerISize += mainGapSize; + } + onFirstChild = false; } else { - minISize = std::max(minISize, childMinISize); + // col-oriented, or MIN_ISIZE for multi-line row flex container + containerISize = std::max(containerISize, childISize); } } + + return containerISize; +} + +/* virtual */ nscoord +nsFlexContainerFrame::GetMinISize(nsRenderingContext* aRenderingContext) +{ + nscoord minISize = 0; + DISPLAY_MIN_WIDTH(this, minISize); + + // TODO: See bug 1454822 + minISize = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::MIN_ISIZE); + return minISize; } @@ -4853,24 +4988,8 @@ nsFlexContainerFrame::GetPrefISize(nsRenderingContext* aRenderingContext) nscoord prefISize = 0; DISPLAY_PREF_WIDTH(this, prefISize); - RenumberList(); - - // XXXdholbert Optimization: We could cache our intrinsic widths like - // nsBlockFrame does (and return it early from this function if it's set). - // Whenever anything happens that might change it, set it to - // NS_INTRINSIC_WIDTH_UNKNOWN (like nsBlockFrame::MarkIntrinsicISizesDirty - // does) - const FlexboxAxisTracker axisTracker(this, GetWritingMode()); + // TODO: See bug 1454822 + prefISize = GetIntrinsicISize(aRenderingContext, nsLayoutUtils::PREF_ISIZE); - for (nsIFrame* childFrame : mFrames) { - nscoord childPrefISize = - nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame, - nsLayoutUtils::PREF_ISIZE); - if (axisTracker.IsRowOriented()) { - prefISize += childPrefISize; - } else { - prefISize = std::max(prefISize, childPrefISize); - } - } return prefISize; } diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index 9edcb8797..39de79b57 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -72,6 +72,9 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + nscoord GetIntrinsicISize(nsRenderingContext* aRenderingContext, + nsLayoutUtils::IntrinsicISizeType aType); + virtual nscoord GetMinISize(nsRenderingContext* aRenderingContext) override; virtual nscoord @@ -160,7 +163,9 @@ protected: nscoord aContentBoxMainSize, nscoord aAvailableBSizeForContent, nsTArray<StrutInfo>& aStruts, - const FlexboxAxisTracker& aAxisTracker); + const FlexboxAxisTracker& aAxisTracker, + nscoord aMainGapSize, + nscoord aCrossGapSize); /** * Checks whether our child-frame list "mFrames" is sorted, using the given @@ -244,6 +249,7 @@ protected: nscoord aAvailableBSizeForContent, const nsTArray<StrutInfo>& aStruts, const FlexboxAxisTracker& aAxisTracker, + nscoord aMainGapSize, nsTArray<nsIFrame*>& aPlaceholders, mozilla::LinkedList<FlexLine>& aLines); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 0af05be50..0a953d6ff 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -2622,9 +2622,9 @@ nsGridContainerFrame::GridReflowInput::CalculateTrackSizes( const LogicalSize& aContentBox, SizingConstraint aConstraint) { - mCols.Initialize(mColFunctions, mGridStyle->mGridColumnGap, + mCols.Initialize(mColFunctions, mGridStyle->mColumnGap, aGrid.mGridColEnd, aContentBox.ISize(mWM)); - mRows.Initialize(mRowFunctions, mGridStyle->mGridRowGap, + mRows.Initialize(mRowFunctions, mGridStyle->mRowGap, aGrid.mGridRowEnd, aContentBox.BSize(mWM)); mCols.CalculateSizes(*this, mGridItems, mColFunctions, @@ -3378,7 +3378,7 @@ nsGridContainerFrame::Grid::PlaceGridItems(GridReflowInput& aState, // to a 0,0 based grid after placing definite lines. auto areas = gridStyle->mGridTemplateAreas.get(); uint32_t numRepeatCols = aState.mColFunctions.InitRepeatTracks( - gridStyle->mGridColumnGap, + gridStyle->mColumnGap, aComputedMinSize.ISize(aState.mWM), aComputedSize.ISize(aState.mWM), aComputedMaxSize.ISize(aState.mWM)); @@ -3387,7 +3387,7 @@ nsGridContainerFrame::Grid::PlaceGridItems(GridReflowInput& aState, LineNameMap colLineNameMap(gridStyle->mGridTemplateColumns, numRepeatCols); uint32_t numRepeatRows = aState.mRowFunctions.InitRepeatTracks( - gridStyle->mGridRowGap, + gridStyle->mRowGap, aComputedMinSize.BSize(aState.mWM), aComputedSize.BSize(aState.mWM), aComputedMaxSize.BSize(aState.mWM)); @@ -6214,6 +6214,11 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, computedISize, bSize); if (!prevInFlow) { + if (computedBSize == NS_AUTOHEIGHT && stylePos->mRowGap.HasPercent()) { + // Re-resolve the row-gap now that we know our intrinsic block-size. + gridReflowInput.mRows.mGridGap = + nsLayoutUtils::ResolveGapToLength(stylePos->mRowGap, bSize); + } // Apply 'align/justify-content' to the grid. // CalculateTrackSizes did the columns. gridReflowInput.mRows.AlignJustifyContent(stylePos, wm, contentArea.Size(wm)); @@ -6585,7 +6590,7 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext, if (grid.mGridColEnd == 0) { return 0; } - state.mCols.Initialize(state.mColFunctions, state.mGridStyle->mGridColumnGap, + state.mCols.Initialize(state.mColFunctions, state.mGridStyle->mColumnGap, grid.mGridColEnd, NS_UNCONSTRAINEDSIZE); auto constraint = aType == nsLayoutUtils::MIN_ISIZE ? SizingConstraint::eMinContent : SizingConstraint::eMaxContent; @@ -6593,7 +6598,7 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext, NS_UNCONSTRAINEDSIZE, &GridArea::mCols, constraint); state.mCols.mGridGap = - nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mGridColumnGap, + nsLayoutUtils::ResolveGapToLength(state.mGridStyle->mColumnGap, NS_UNCONSTRAINEDSIZE); nscoord length = 0; for (const TrackSize& sz : state.mCols.mSizes) { diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 4fb75edab..e6cc895d9 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1841,7 +1841,7 @@ fuzzy-if(skiaContent,1,24000) == 1025914-1.html 1025914-1-ref.html == 1050493-1.html 1050493-1-ref.html == 1050788-1.html about:blank == 1053035-1-flex.html 1053035-1-ref.html -test-pref(layout.css.grid.enabled,true) == 1053035-1-grid.html 1053035-1-ref.html +== 1053035-1-grid.html 1053035-1-ref.html == 1059167-1.html 1059167-1-ref.html == 1059498-1.html 1059498-1-ref.html == 1059498-2.html 1059498-1-ref.html 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 7ad85e1e5..1970d10e3 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; } </div> <div class="float"> -<div class="grid" style="width:60px; height:60px; grid-column-gap:12px"> +<div class="grid" style="width:60px; height:60px; gap:12px"> <span><x></x></span> <span><x></x></span> <span><x></x></span> @@ -74,7 +74,7 @@ br { clear: both; } </div> <div class="inline-grid"> -<div class="grid" style="width:60px; height:60px; grid-column-gap:12px; align-self:start; justify-self:start;"> +<div class="grid" style="width:60px; height:60px; gap:12px; align-self:start; justify-self:start;"> <span><x></x></span> <span><x></x></span> <span><x></x></span> @@ -142,7 +142,7 @@ br { clear: both; } </div> <div class="float" style="margin-top:-50px; width:62px"> -<div class="grid" style="padding-left:186px; height:60px; grid-column-gap:calc(186px * 0.2);"> +<div class="grid" style="padding-left:186px; height:60px; gap:12px calc(186px * 0.2);"> <span style="margin-left:-186px; width:30px"><x></x></span> <span style="margin-left:-186px; width:30px"><x></x></span> <span style="margin-left:-186px; width:30px"><x></x></span> 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 682e0ca38..8de84391e 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,15 +83,18 @@ fill,fit { .zero-progress { grid-row-gap: calc(10px - 1%); - grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; + grid-template-rows: [a] 10px repeat(3, [b] calc(4px / 10) [c]) [d]; + height:40px; } .w50.zero-progress { grid-row-gap: calc(10px - 1%); grid-template-rows: [a] 10px repeat(3, [b] 0 [c]) [d]; + height:50px; } .mw50.zero-progress { grid-row-gap: calc(10px - 1%); - grid-template-rows: [a] 10px repeat(4, [b] 0 [c]) [d]; + grid-template-rows: [a] 10px repeat(4, [b] calc(5px / 10) [c]) [d]; + height:50px; } </style> </head> diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index 35e3140a8..62a397b54 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -1,5 +1,3 @@ -default-preferences pref(layout.css.grid.enabled,true) - fails == grid-whitespace-handling-1a.xhtml grid-whitespace-handling-1-ref.xhtml fails == grid-whitespace-handling-1b.xhtml grid-whitespace-handling-1-ref.xhtml == grid-whitespace-handling-2.xhtml grid-whitespace-handling-2-ref.xhtml diff --git a/layout/reftests/list-item/reftest.list b/layout/reftests/list-item/reftest.list index c47473d0b..a795dfdf4 100644 --- a/layout/reftests/list-item/reftest.list +++ b/layout/reftests/list-item/reftest.list @@ -1,6 +1,6 @@ fuzzy-if(OSX>=1008,55,4) == numbering-1.html numbering-1-ref.html == numbering-2.html numbering-2-ref.html -pref(layout.css.grid.enabled,true) fuzzy-if(OSX>=1008,8,1) == numbering-3.html numbering-3-ref.html +fuzzy-if(OSX>=1008,8,1) == numbering-3.html numbering-3-ref.html fuzzy-if(OSX>=1008,72,2) == numbering-4.html numbering-4-ref.html == ol-reversed-1a.html ol-reversed-1-ref.html asserts(1) == ol-reversed-1b.html ol-reversed-1-ref.html # bug 478135 diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001-ref.html new file mode 100644 index 000000000..0606afe53 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001-ref.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<!-- + Reference for the correctness of gaps in horizontal and vertical multi-line + flex containers. +--> +<html> +<head> + <title>Reference: Testing row and column gaps in horizontal and vertical multi-line flex containers with the space-around property and auto margins</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <meta charset="utf-8"> + <style> + .outerBox { + width: 200px; + height: 220px; + border: 1px solid black; + float: left; + } + .flexContainer { + display: flex; + align-content: space-around; + justify-content: space-around; + } + .rowNoWrap { + flex-flow: row nowrap; + } + .columnNoWrap { + flex-flow: column nowrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + .autoLBMargins { + margin-left: auto; + margin-bottom: auto; + } + .autoBMargin { + margin-bottom: auto; + } + .right20 { + margin-right: 20px; + } + .bottom40 { + margin-bottom: 40px; + } + .tb30100 { + margin-top: 30px; + margin-bottom: 100px; + } + .lr3080 { + margin-left: 30px; + margin-right: 80px; + } + .w200 { + width: 200px; + } + .h220 { + height: 220px; + } + .fleft { + float: left; + } + </style> +</head> +<body> + <div class="outerBox"> + <div class="flexContainer w200 rowNoWrap tb30100"> + <div class="item right20"></div> + <div class="item right20"></div> + <div class="item right20"></div> + <div class="item"></div> + </div> + <div class="flexContainer w200 rowNoWrap"> + <div class="item autoLBMargins right20"></div> + <div class="item"></div> + </div> + </div> + <div class="outerBox"> + <div class="flexContainer fleft h220 columnNoWrap lr3080"> + <div class="item bottom40"></div> + <div class="item bottom40"></div> + <div class="item"></div> + </div> + <div class="flexContainer fleft h220 columnNoWrap"> + <div class="item bottom40"></div> + <div class="item bottom40"></div> + <div class="item autoBMargin"></div> + </div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001.html new file mode 100644 index 000000000..25b28e809 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-001.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<!-- + Testcase for the correctness of gaps in horizontal and vertical multi-line + flex containers. +--> +<html> +<head> + <title>CSS Test: Testing row and column gaps in horizontal and vertical multi-line flex containers with the space-around property and auto margins</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-align/#gap-flex"> + <link rel="match" href="flexbox-column-row-gap-001-ref.html"> + <meta charset="utf-8"> + <style> + .flexContainer { + display: flex; + width: 200px; + height: 220px; + border: 1px solid black; + column-gap: 10%; + row-gap: 40px; + align-content: space-around; + justify-content: space-around; + float: left; + } + .rowWrap { + flex-flow: row wrap; + } + .columnWrap { + flex-flow: column wrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + .autoLBMargins { + margin-left: auto; + margin-bottom: auto; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + <div class="item"></div> + </div> + <div class="flexContainer columnWrap"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002-ref.html new file mode 100644 index 000000000..e23ddfe26 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002-ref.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<!-- + Testcase for the correctness of gaps in vertical writing mode + multi-line flex containers. +--> +<html> +<head> + <title>Reference: Testing row and column gaps in vertical writing mode multi-line flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <meta charset="utf-8"> + <style> + .flexContainer { + display: flex; + width: 220px; + height: 200px; + border: 1px solid black; + align-content: flex-start; + justify-content: flex-end; + float: left; + writing-mode: vertical-lr; + } + .rowWrap { + flex-flow: row wrap; + } + .columnWrap { + flex-flow: column wrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + .b20 { + margin-bottom: 20px; + } + .t20 { + margin-top: 20px; + } + .l10 { + margin-left: 10px; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap"> + <div class="item b20"></div> + <div class="item b20"></div> + <div class="item b20"></div> + <div class="item"></div> + <div class="item l10 b20"></div> + <div class="item l10"></div> + </div> + <div class="flexContainer columnWrap"> + <div class="item"></div> + <div class="item l10"></div> + <div class="item l10"></div> + <div class="item l10"></div> + <div class="item l10"></div> + <div class="item l10 t20"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002.html new file mode 100644 index 000000000..fcd19cf8d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-002.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<!-- + Testcase for the correctness of gaps in vertical writing mode multi-line + flex containers. +--> +<html> +<head> + <title>CSS Test: Testing row and column gaps in vertical writing mode multi-line flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-align/#gap-flex"> + <link rel="match" href="flexbox-column-row-gap-002-ref.html"> + <meta charset="utf-8"> + <style> + .flexContainer { + display: flex; + width: 220px; + height: 200px; + border: 1px solid black; + column-gap: 10%; + row-gap: 10px; + align-content: flex-start; + justify-content: flex-end; + float: left; + writing-mode: vertical-lr; + } + .rowWrap { + flex-flow: row wrap; + } + .columnWrap { + flex-flow: column wrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer columnWrap"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003-ref.html new file mode 100644 index 000000000..6e7f220b4 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003-ref.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<html> +<head> + <title>Reference: Testing cross size computation with row and column gaps in horizontal multi-line flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <meta charset="utf-8"> +</html> + <style> + .flexContainer { + display: flex; + border: 1px solid black; + column-gap: 20px; + row-gap: 40px; + align-content: space-around; + justify-content: space-around; + } + .rowWrap { + flex-flow: row wrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + .autoLBMargins { + margin-left: auto; + margin-bottom: auto; + } + .w200 { + width: 200px; + } + .h100 { + height: 100px; + } + .h90 { + height: 90px; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap w200 h100"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + <div class="item"></div> + </div> + <div class="flexContainer rowWrap w200 h90"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + <div class="item"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003.html new file mode 100644 index 000000000..2dcd02717 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-003.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<html> +<head> + <title>CSS Test: Testing cross size computation with row and column gaps in horizontal multi-line flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-align/#gap-flex"> + <link rel="match" href="flexbox-column-row-gap-003-ref.html"> + <meta charset="utf-8"> + <style> + .flexContainer { + display: flex; + border: 1px solid black; + column-gap: 20px; + row-gap: 40px; + align-content: space-around; + justify-content: space-around; + } + .rowWrap { + flex-flow: row wrap; + } + .item { + border: 1px solid blue; + background: lightblue; + width: 28px; + height: 28px; + } + .autoLBMargins { + margin-left: auto; + margin-bottom: auto; + } + .w200 { + width: 200px; + } + .hclamp { + max-height: 90px; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap w200"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + <div class="item"></div> + </div> + <div class="flexContainer rowWrap w200 hclamp"> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item"></div> + <div class="item autoLBMargins"></div> + <div class="item"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004-ref.html new file mode 100644 index 000000000..0b40fb2d6 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004-ref.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<html> +<head> + <title>Reference: Testing percentage gap resolution in flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <meta charset="utf-8"> + <style> + .flexContainer { + display: flex; + border: 2px solid black; + column-gap: 10px; + align-content: start; + justify-content: start; + margin-top: 20px; + } + .item { + border: 1px solid blue; + background: yellow; + width: 48px; + height: 48px; + flex: none; + } + .vertLR { + writing-mode: vertical-lr; + } + .rowWrap { + flex-flow: row wrap; + } + .colWrap { + flex-flow: column wrap; + } + .w50 { + width: 50px; + } + .h100 { + height: 100px; + } + .w100 { + width: 100px; + } + .noWrap { + flex-wrap: nowrap; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap w50 h100"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer colWrap w50 h100 noWrap"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer vertLR rowWrap h100 w100"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer vertLR colWrap w100 noWrap"> + <div class="item"></div> + <div class="item"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004.html new file mode 100644 index 000000000..0d86b3818 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-column-row-gap-004.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0 +--> +<html> +<head> + <title>CSS Test: Testing percentage gap resolution in flex containers</title> + <link rel="author" title="Mihir Iyer" href="mailto:miyer@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-align/#column-row-gap"> + <link rel="match" href="flexbox-column-row-gap-004-ref.html"> + <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5081"> + <meta charset="utf-8"> + <meta name="assert" content="% row-gaps in a flexbox with indefinite block size are treated as 'normal'." /> + <style> + .flexContainer { + display: flex; + border: 2px solid black; + row-gap: 20%; + column-gap: 10%; + align-content: start; + justify-content: start; + margin-top: 20px; + } + .item { + border: 1px solid blue; + background: yellow; + width: 48px; + height: 48px; + flex: none; + } + .vertLR { + writing-mode: vertical-lr; + } + .rowWrap { + flex-flow: row wrap; + } + .colWrap { + flex-flow: column wrap; + } + .w50 { + width: 50px; + } + </style> +</head> +<body> + <div class="flexContainer rowWrap w50"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer colWrap w50"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer vertLR rowWrap"> + <div class="item"></div> + <div class="item"></div> + </div> + <div class="flexContainer vertLR colWrap"> + <div class="item"></div> + <div class="item"></div> + </div> +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute-ref.html new file mode 100644 index 000000000..7cea1fb1d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute-ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Flexible Box Layout Test Reference: Test flexbox intrinsic inline-size, gap, and absolute-positioned children</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + + <style> + div { + display: inline-flex; + background: fuchsia; + } + </style> + + <div> + <span>B</span> + <span style="width: 100px;"></span> + <span>C</span> + </div> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute.html new file mode 100644 index 000000000..850f1a42d --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-gap-position-absolute.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> + <meta charset="utf-8"> + <title>CSS Flexible Box Layout Test: Test flexbox intrinsic inline-size, gap, and absolute-positioned children</title> + <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com"> + <link rel="author" title="Mozilla" href="http://www.mozilla.org/"> + <link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#intrinsic-sizes"> + <link rel="help" href="https://drafts.csswg.org/css-align-3/#gaps"> + <link rel="match" href="flexbox-gap-position-absolute-ref.html"> + <meta name="assert" content="This test verifies the absolute-positioned children do not contribute the gap size to the flexbox's intrinsic inline-size."> + + <style> + div { + display: inline-flex; + gap: 100px; + background: fuchsia; + } + </style> + + <div> + <span style="position: absolute;"></span> + <span style="position: fixed;"></span> + <span>B</span> + <span>C</span> + </div> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/reftest.list b/layout/reftests/w3c-css/submitted/flexbox/reftest.list index 281ef4758..075aa660e 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list +++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list @@ -91,6 +91,13 @@ == flexbox-collapsed-item-horiz-002.html flexbox-collapsed-item-horiz-002-ref.html == flexbox-collapsed-item-horiz-003.html flexbox-collapsed-item-horiz-003-ref.html +# Tests for "row gap" and "column gap" +== flexbox-column-row-gap-001.html flexbox-column-row-gap-001-ref.html +== flexbox-column-row-gap-002.html flexbox-column-row-gap-002-ref.html +== flexbox-column-row-gap-003.html flexbox-column-row-gap-003-ref.html +== flexbox-column-row-gap-004.html flexbox-column-row-gap-004-ref.html +== flexbox-gap-position-absolute.html flexbox-gap-position-absolute-ref.html + # Tests for flex-flow shorthand property == flexbox-flex-flow-001.html flexbox-flex-flow-001-ref.html == flexbox-flex-flow-002.html flexbox-flex-flow-002-ref.html diff --git a/layout/style/Declaration.cpp b/layout/style/Declaration.cpp index 9d7ca312c..9e7a01aff 100644 --- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -1249,13 +1249,13 @@ Declaration::GetPropertyValueInternal( // #3 [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> case eCSSProperty_grid: { const nsCSSValue& columnGapValue = - *data->ValueFor(eCSSProperty_grid_column_gap); + *data->ValueFor(eCSSProperty_column_gap); if (columnGapValue.GetUnit() != eCSSUnit_Pixel || columnGapValue.GetFloatValue() != 0.0f) { return; // Not serializable, bail. } const nsCSSValue& rowGapValue = - *data->ValueFor(eCSSProperty_grid_row_gap); + *data->ValueFor(eCSSProperty_row_gap); if (rowGapValue.GetUnit() != eCSSUnit_Pixel || rowGapValue.GetFloatValue() != 0.0f) { return; // Not serializable, bail. @@ -1475,7 +1475,7 @@ Declaration::GetPropertyValueInternal( } MOZ_FALLTHROUGH; } - case eCSSProperty_grid_gap: { + case eCSSProperty_gap: { const nsCSSPropertyID* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); MOZ_ASSERT(subprops[2] == eCSSProperty_UNKNOWN, diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 8b9e25066..198703223 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -1011,7 +1011,7 @@ protected: bool ParseGridColumnRow(nsCSSPropertyID aStartPropID, nsCSSPropertyID aEndPropID); bool ParseGridArea(); - bool ParseGridGap(); + bool ParseGap(); bool ParseInitialLetter(); @@ -9714,8 +9714,8 @@ CSSParserImpl::ParseGrid() // "Also, the gutter properties are reset by this shorthand, // even though they can't be set by it." value.SetFloatValue(0.0f, eCSSUnit_Pixel); - AppendValue(eCSSProperty_grid_row_gap, value); - AppendValue(eCSSProperty_grid_column_gap, value); + AppendValue(eCSSProperty_row_gap, value); + AppendValue(eCSSProperty_column_gap, value); // [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> auto res = ParseGridShorthandAutoProps(NS_STYLE_GRID_AUTO_FLOW_ROW); @@ -10038,12 +10038,12 @@ CSSParserImpl::ParseGridArea() } bool -CSSParserImpl::ParseGridGap() +CSSParserImpl::ParseGap() { nsCSSValue first; if (ParseSingleTokenVariant(first, VARIANT_INHERIT, nullptr)) { - AppendValue(eCSSProperty_grid_row_gap, first); - AppendValue(eCSSProperty_grid_column_gap, first); + AppendValue(eCSSProperty_row_gap, first); + AppendValue(eCSSProperty_column_gap, first); return true; } if (ParseNonNegativeVariant(first, VARIANT_LPCALC, nullptr) != @@ -10055,8 +10055,8 @@ CSSParserImpl::ParseGridGap() if (result == CSSParseResult::Error) { return false; } - AppendValue(eCSSProperty_grid_row_gap, first); - AppendValue(eCSSProperty_grid_column_gap, + AppendValue(eCSSProperty_row_gap, first); + AppendValue(eCSSProperty_column_gap, result == CSSParseResult::NotFound ? first : second); return true; } @@ -11956,8 +11956,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSPropertyID aPropID) eCSSProperty_grid_row_end); case eCSSProperty_grid_area: return ParseGridArea(); - case eCSSProperty_grid_gap: - return ParseGridGap(); + case eCSSProperty_gap: + return ParseGap(); case eCSSProperty_image_region: return ParseRect(eCSSProperty_image_region); case eCSSProperty_align_content: diff --git a/layout/style/nsCSSPropAliasList.h b/layout/style/nsCSSPropAliasList.h index 4f2a6e6b6..7043d1931 100644 --- a/layout/style/nsCSSPropAliasList.h +++ b/layout/style/nsCSSPropAliasList.h @@ -34,6 +34,18 @@ ******/ +CSS_PROP_ALIAS(grid-gap, + gap, + GridGap, + "") +CSS_PROP_ALIAS(grid-column-gap, + column_gap, + GridColumnGap, + "") +CSS_PROP_ALIAS(grid-row-gap, + row_gap, + GridRowGap, + "") CSS_PROP_ALIAS(word-wrap, overflow_wrap, WordWrap, diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 45e919d4f..b51867f3c 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1516,7 +1516,7 @@ CSS_PROP_COLUMN( kColumnFillKTable, CSS_PROP_NO_OFFSET, eStyleAnimType_Discrete) -CSS_PROP_COLUMN( +CSS_PROP_POSITION( column-gap, column_gap, ColumnGap, @@ -1525,7 +1525,7 @@ CSS_PROP_COLUMN( "", VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC, nullptr, - offsetof(nsStyleColumn, mColumnGap), + offsetof(nsStylePosition, mColumnGap), eStyleAnimType_Coord) CSS_PROP_SHORTHAND( column-rule, @@ -2100,25 +2100,30 @@ CSS_PROP_UIRESET( CSS_PROP_NO_OFFSET, eStyleAnimType_Discrete) // bug 58646 CSS_PROP_SHORTHAND( + gap, + gap, + Gap, + CSS_PROPERTY_PARSE_FUNCTION, + "") +CSS_PROP_SHORTHAND( grid, grid, Grid, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") + "") CSS_PROP_SHORTHAND( grid-area, grid_area, GridArea, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") + "") CSS_PROP_POSITION( grid-auto-columns, grid_auto_columns, GridAutoColumns, CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_STORES_CALC, + "", 0, kGridTrackBreadthKTable, CSS_PROP_NO_OFFSET, @@ -2127,9 +2132,8 @@ CSS_PROP_POSITION( grid-auto-flow, grid_auto_flow, GridAutoFlow, - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_PARSE_FUNCTION, + "", 0, kGridAutoFlowKTable, CSS_PROP_NO_OFFSET, @@ -2139,9 +2143,8 @@ CSS_PROP_POSITION( grid_auto_rows, GridAutoRows, CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_STORES_CALC, + "", 0, kGridTrackBreadthKTable, CSS_PROP_NO_OFFSET, @@ -2151,79 +2154,49 @@ CSS_PROP_SHORTHAND( grid_column, GridColumn, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") + "") CSS_PROP_POSITION( grid-column-end, grid_column_end, GridColumnEnd, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled", + "", 0, nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_Discrete) CSS_PROP_POSITION( - grid-column-gap, - grid_column_gap, - GridColumnGap, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", - VARIANT_HLP | VARIANT_CALC, - nullptr, - offsetof(nsStylePosition, mGridColumnGap), - eStyleAnimType_Coord) -CSS_PROP_POSITION( grid-column-start, grid_column_start, GridColumnStart, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled", + "", 0, nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_Discrete) CSS_PROP_SHORTHAND( - grid-gap, - grid_gap, - GridGap, - CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") -CSS_PROP_SHORTHAND( grid-row, grid_row, GridRow, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") + "") CSS_PROP_POSITION( grid-row-end, grid_row_end, GridRowEnd, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled", + "", 0, nullptr, CSS_PROP_NO_OFFSET, eStyleAnimType_Discrete) CSS_PROP_POSITION( - grid-row-gap, - grid_row_gap, - GridRowGap, - CSS_PROPERTY_PARSE_VALUE | - CSS_PROPERTY_VALUE_NONNEGATIVE | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", - VARIANT_HLP | VARIANT_CALC, - nullptr, - offsetof(nsStylePosition, mGridRowGap), - eStyleAnimType_Coord) -CSS_PROP_POSITION( grid-row-start, grid_row_start, GridRowStart, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled", + "", 0, nullptr, CSS_PROP_NO_OFFSET, @@ -2233,14 +2206,13 @@ CSS_PROP_SHORTHAND( grid_template, GridTemplate, CSS_PROPERTY_PARSE_FUNCTION, - "layout.css.grid.enabled") + "") CSS_PROP_POSITION( grid-template-areas, grid_template_areas, GridTemplateAreas, - CSS_PROPERTY_PARSE_FUNCTION | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_PARSE_FUNCTION, + "", 0, nullptr, CSS_PROP_NO_OFFSET, @@ -2251,9 +2223,8 @@ CSS_PROP_POSITION( GridTemplateColumns, CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "", 0, kGridTrackBreadthKTable, CSS_PROP_NO_OFFSET, @@ -2264,9 +2235,8 @@ CSS_PROP_POSITION( GridTemplateRows, CSS_PROPERTY_PARSE_FUNCTION | CSS_PROPERTY_STORES_CALC | - CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH | - CSS_PROPERTY_ENABLED_IN_UA_SHEETS, - "layout.css.grid.enabled", + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH, + "", 0, kGridTrackBreadthKTable, CSS_PROP_NO_OFFSET, @@ -3560,6 +3530,17 @@ CSS_PROP_POSITION( nullptr, offsetof(nsStylePosition, mOffset), eStyleAnimType_Sides_Right) +CSS_PROP_POSITION( + row-gap, + row_gap, + RowGap, + CSS_PROPERTY_PARSE_VALUE | + CSS_PROPERTY_VALUE_NONNEGATIVE, + "", + VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC, + nullptr, + offsetof(nsStylePosition, mRowGap), + eStyleAnimType_Coord) CSS_PROP_TEXT( ruby-align, ruby_align, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 756e3eb25..7d4e008b4 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1332,7 +1332,6 @@ KTableEntry nsCSSProps::kDisplayKTable[] = { { eCSSKeyword_ruby_base_container, StyleDisplay::RubyBaseContainer }, { eCSSKeyword_ruby_text, StyleDisplay::RubyText }, { eCSSKeyword_ruby_text_container, StyleDisplay::RubyTextContainer }, - // The next two entries are controlled by the layout.css.grid.enabled pref. { eCSSKeyword_grid, StyleDisplay::Grid }, { eCSSKeyword_inline_grid, StyleDisplay::InlineGrid }, // The next 4 entries are controlled by the layout.css.prefixes.webkit pref. @@ -2953,8 +2952,6 @@ static const nsCSSPropertyID gGridSubpropTable[] = { eCSSProperty_grid_auto_flow, eCSSProperty_grid_auto_rows, eCSSProperty_grid_auto_columns, - eCSSProperty_grid_row_gap, // can only be reset, not get/set - eCSSProperty_grid_column_gap, // can only be reset, not get/set eCSSProperty_UNKNOWN }; @@ -2978,9 +2975,9 @@ static const nsCSSPropertyID gGridAreaSubpropTable[] = { eCSSProperty_UNKNOWN }; -static const nsCSSPropertyID gGridGapSubpropTable[] = { - eCSSProperty_grid_row_gap, - eCSSProperty_grid_column_gap, +static const nsCSSPropertyID gGapSubpropTable[] = { + eCSSProperty_row_gap, + eCSSProperty_column_gap, eCSSProperty_UNKNOWN }; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index efa485f61..eb56559d9 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -1093,21 +1093,6 @@ nsComputedDOMStyle::DoGetColumnWidth() } already_AddRefed<CSSValue> -nsComputedDOMStyle::DoGetColumnGap() -{ - RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - - const nsStyleColumn* column = StyleColumn(); - if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) { - val->SetAppUnits(StyleFont()->mFont.size); - } else { - SetValueToCoord(val, StyleColumn()->mColumnGap, true); - } - - return val.forget(); -} - -already_AddRefed<CSSValue> nsComputedDOMStyle::DoGetColumnFill() { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; @@ -3003,18 +2988,32 @@ nsComputedDOMStyle::DoGetGridRowEnd() } already_AddRefed<CSSValue> -nsComputedDOMStyle::DoGetGridColumnGap() +nsComputedDOMStyle::DoGetColumnGap() { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - SetValueToCoord(val, StylePosition()->mGridColumnGap, true); + + const nsStylePosition* positionData = StylePosition(); + if (positionData->mColumnGap.GetUnit() == eStyleUnit_Normal) { + val->SetIdent(eCSSKeyword_normal); + } else { + SetValueToCoord(val, positionData->mColumnGap, true); + } + return val.forget(); } already_AddRefed<CSSValue> -nsComputedDOMStyle::DoGetGridRowGap() +nsComputedDOMStyle::DoGetRowGap() { RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; - SetValueToCoord(val, StylePosition()->mGridRowGap, true); + + const nsStylePosition* positionData = StylePosition(); + if (positionData->mRowGap.GetUnit() == eStyleUnit_Normal) { + val->SetIdent(eCSSKeyword_normal); + } else { + SetValueToCoord(val, positionData->mRowGap, true); + } + return val.forget(); } diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 38a61e23c..363de2a8f 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -286,8 +286,6 @@ private: already_AddRefed<CSSValue> DoGetGridColumnEnd(); already_AddRefed<CSSValue> DoGetGridRowStart(); already_AddRefed<CSSValue> DoGetGridRowEnd(); - already_AddRefed<CSSValue> DoGetGridColumnGap(); - already_AddRefed<CSSValue> DoGetGridRowGap(); /* StyleImageLayer properties */ already_AddRefed<CSSValue> DoGetImageLayerImage(const nsStyleImageLayers& aLayers); @@ -503,7 +501,6 @@ private: already_AddRefed<CSSValue> DoGetColumnCount(); already_AddRefed<CSSValue> DoGetColumnFill(); already_AddRefed<CSSValue> DoGetColumnWidth(); - already_AddRefed<CSSValue> DoGetColumnGap(); already_AddRefed<CSSValue> DoGetColumnRuleWidth(); already_AddRefed<CSSValue> DoGetColumnRuleStyle(); already_AddRefed<CSSValue> DoGetColumnRuleColor(); @@ -541,6 +538,8 @@ private: already_AddRefed<CSSValue> DoGetJustifyContent(); already_AddRefed<CSSValue> DoGetJustifyItems(); already_AddRefed<CSSValue> DoGetJustifySelf(); + already_AddRefed<CSSValue> DoGetColumnGap(); + already_AddRefed<CSSValue> DoGetRowGap(); /* SVG properties */ already_AddRefed<CSSValue> DoGetFill(); diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h index ec223cda4..a17a6a822 100644 --- a/layout/style/nsComputedDOMStylePropertyList.h +++ b/layout/style/nsComputedDOMStylePropertyList.h @@ -151,10 +151,8 @@ COMPUTED_STYLE_PROP(grid_auto_columns, GridAutoColumns) COMPUTED_STYLE_PROP(grid_auto_flow, GridAutoFlow) COMPUTED_STYLE_PROP(grid_auto_rows, GridAutoRows) COMPUTED_STYLE_PROP(grid_column_end, GridColumnEnd) -COMPUTED_STYLE_PROP(grid_column_gap, GridColumnGap) COMPUTED_STYLE_PROP(grid_column_start, GridColumnStart) COMPUTED_STYLE_PROP(grid_row_end, GridRowEnd) -COMPUTED_STYLE_PROP(grid_row_gap, GridRowGap) COMPUTED_STYLE_PROP(grid_row_start, GridRowStart) COMPUTED_STYLE_PROP(grid_template_areas, GridTemplateAreas) COMPUTED_STYLE_PROP(grid_template_columns, GridTemplateColumns) @@ -217,6 +215,7 @@ COMPUTED_STYLE_PROP(position, Position) COMPUTED_STYLE_PROP(quotes, Quotes) COMPUTED_STYLE_PROP(resize, Resize) COMPUTED_STYLE_PROP(right, Right) +COMPUTED_STYLE_PROP(row_gap, RowGap) COMPUTED_STYLE_PROP(ruby_align, RubyAlign) COMPUTED_STYLE_PROP(ruby_position, RubyPosition) COMPUTED_STYLE_PROP(scroll_behavior, ScrollBehavior) diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index 1905d8c5c..7c09202e6 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -380,8 +380,6 @@ nsLayoutStylesheetCache::For(StyleBackendType aType) // Preferences::RegisterCallback(&DependentPrefChanged, // "layout.css.example-pref.enabled"); Preferences::RegisterCallback(&DependentPrefChanged, - "layout.css.grid.enabled"); - Preferences::RegisterCallback(&DependentPrefChanged, "dom.details_element.enabled"); } @@ -553,7 +551,7 @@ nsLayoutStylesheetCache::DependentPrefChanged(const char* aPref, void* aData) InvalidateSheet(gStyleCache_Gecko ? &gStyleCache_Gecko->sheet_ : nullptr, \ gStyleCache_Servo ? &gStyleCache_Servo->sheet_ : nullptr); - INVALIDATE(mUASheet); // for layout.css.grid.enabled + // INVALIDATE(mUASheet); // for layout.css.example-pref.enabled INVALIDATE(mHTMLSheet); // for dom.details_element.enabled #undef INVALIDATE diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index e59c10cd2..e824e7721 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -8873,25 +8873,27 @@ nsRuleNode::ComputePositionData(void* aStartStruct, parentPos->mGridRowEnd, conditions); - // grid-column-gap - if (SetCoord(*aRuleData->ValueForGridColumnGap(), - pos->mGridColumnGap, parentPos->mGridColumnGap, - SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | - SETCOORD_CALC_CLAMP_NONNEGATIVE | SETCOORD_UNSET_INITIAL, + // column-gap: normal, length, percent, calc, inherit, initial + if (SetCoord(*aRuleData->ValueForColumnGap(), + pos->mColumnGap, parentPos->mColumnGap, + SETCOORD_LPH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL | + SETCOORD_STORE_CALC | SETCOORD_CALC_CLAMP_NONNEGATIVE | + SETCOORD_UNSET_INITIAL, aContext, mPresContext, conditions)) { } else { - MOZ_ASSERT(aRuleData->ValueForGridColumnGap()->GetUnit() == eCSSUnit_Null, + MOZ_ASSERT(aRuleData->ValueForColumnGap()->GetUnit() == eCSSUnit_Null, "unexpected unit"); } - // grid-row-gap - if (SetCoord(*aRuleData->ValueForGridRowGap(), - pos->mGridRowGap, parentPos->mGridRowGap, - SETCOORD_LPH | SETCOORD_INITIAL_ZERO | SETCOORD_STORE_CALC | - SETCOORD_CALC_CLAMP_NONNEGATIVE | SETCOORD_UNSET_INITIAL, + // row-gap: normal, length, percent, calc, inherit, initial + if (SetCoord(*aRuleData->ValueForRowGap(), + pos->mRowGap, parentPos->mRowGap, + SETCOORD_LPH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL | + SETCOORD_STORE_CALC | SETCOORD_CALC_CLAMP_NONNEGATIVE | + SETCOORD_UNSET_INITIAL, aContext, mPresContext, conditions)) { } else { - MOZ_ASSERT(aRuleData->ValueForGridRowGap()->GetUnit() == eCSSUnit_Null, + MOZ_ASSERT(aRuleData->ValueForRowGap()->GetUnit() == eCSSUnit_Null, "unexpected unit"); } @@ -9298,18 +9300,6 @@ nsRuleNode::ComputeColumnData(void* aStartStruct, SETCOORD_UNSET_INITIAL, aContext, mPresContext, conditions); - // column-gap: length, inherit, normal - SetCoord(*aRuleData->ValueForColumnGap(), - column->mColumnGap, parent->mColumnGap, - SETCOORD_LH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL | - SETCOORD_CALC_LENGTH_ONLY | SETCOORD_UNSET_INITIAL, - aContext, mPresContext, conditions); - // clamp negative calc() to 0 - if (column->mColumnGap.GetUnit() == eStyleUnit_Coord) { - column->mColumnGap.SetCoordValue( - std::max(column->mColumnGap.GetCoordValue(), 0)); - } - // column-count: auto, integer, inherit const nsCSSValue* columnCountValue = aRuleData->ValueForColumnCount(); if (eCSSUnit_Auto == columnCountValue->GetUnit() || diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index acf287ea8..e83a6dcf9 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -825,7 +825,6 @@ nsStyleXUL::CalcDifference(const nsStyleXUL& aNewData) const nsStyleColumn::nsStyleColumn(StyleStructContext aContext) : mColumnCount(NS_STYLE_COLUMN_COUNT_AUTO) , mColumnWidth(eStyleUnit_Auto) - , mColumnGap(eStyleUnit_Normal) , mColumnRuleColor(StyleComplexColor::CurrentColor()) , mColumnRuleStyle(NS_STYLE_BORDER_STYLE_NONE) , mColumnFill(NS_STYLE_COLUMN_FILL_BALANCE) @@ -844,7 +843,6 @@ nsStyleColumn::~nsStyleColumn() nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource) : mColumnCount(aSource.mColumnCount) , mColumnWidth(aSource.mColumnWidth) - , mColumnGap(aSource.mColumnGap) , mColumnRuleColor(aSource.mColumnRuleColor) , mColumnRuleStyle(aSource.mColumnRuleStyle) , mColumnFill(aSource.mColumnFill) @@ -867,7 +865,6 @@ nsStyleColumn::CalcDifference(const nsStyleColumn& aNewData) const } if (mColumnWidth != aNewData.mColumnWidth || - mColumnGap != aNewData.mColumnGap || mColumnFill != aNewData.mColumnFill) { return NS_STYLE_HINT_REFLOW; } @@ -1423,8 +1420,8 @@ nsStylePosition::nsStylePosition(StyleStructContext aContext) , mFlexGrow(0.0f) , mFlexShrink(1.0f) , mZIndex(eStyleUnit_Auto) - , mGridColumnGap(nscoord(0), nsStyleCoord::CoordConstructor) - , mGridRowGap(nscoord(0), nsStyleCoord::CoordConstructor) + , mColumnGap(eStyleUnit_Normal) + , mRowGap(eStyleUnit_Normal) { MOZ_COUNT_CTOR(nsStylePosition); @@ -1489,8 +1486,8 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource) , mGridColumnEnd(aSource.mGridColumnEnd) , mGridRowStart(aSource.mGridRowStart) , mGridRowEnd(aSource.mGridRowEnd) - , mGridColumnGap(aSource.mGridColumnGap) - , mGridRowGap(aSource.mGridRowGap) + , mColumnGap(aSource.mColumnGap) + , mRowGap(aSource.mRowGap) { MOZ_COUNT_CTOR(nsStylePosition); } @@ -1590,8 +1587,8 @@ nsStylePosition::CalcDifference(const nsStylePosition& aNewData, mGridColumnEnd != aNewData.mGridColumnEnd || mGridRowStart != aNewData.mGridRowStart || mGridRowEnd != aNewData.mGridRowEnd || - mGridColumnGap != aNewData.mGridColumnGap || - mGridRowGap != aNewData.mGridRowGap) { + mColumnGap != aNewData.mColumnGap || + mRowGap != aNewData.mRowGap) { return hint | nsChangeHint_AllReflowHints; } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 35ff071a5..a01685cc4 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1848,8 +1848,8 @@ public: nsStyleGridLine mGridColumnEnd; nsStyleGridLine mGridRowStart; nsStyleGridLine mGridRowEnd; - nsStyleCoord mGridColumnGap; // [reset] coord, percent, calc - nsStyleCoord mGridRowGap; // [reset] coord, percent, calc + nsStyleCoord mColumnGap; // [reset] normal, coord, percent, calc + nsStyleCoord mRowGap; // [reset] normal, coord, percent, calc // FIXME: Logical-coordinate equivalents to these WidthDepends... and // HeightDepends... methods have been introduced (see below); we probably @@ -3502,7 +3502,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn uint32_t mColumnCount; // [reset] see nsStyleConsts.h nsStyleCoord mColumnWidth; // [reset] coord, auto - 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 1d5dc989f..e3e719771 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -1432,23 +1432,6 @@ var gCSSProperties = { alias_for: "column-fill", subproperties: [ "column-fill" ] }, - "column-gap": { - domProp: "columnGap", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "normal", "1em", "calc(-2em + 3em)" ], - other_values: [ "2px", "1em", "4em", "3%", "calc(3%)", "calc(1em - 3%)", - "calc(2px)", - "calc(-2px)", - "calc(0px)", - "calc(0pt)", - "calc(5em)", - "calc(3*25px)", - "calc(25px*3)", - "calc(3*25px + 5em)", - ], - invalid_values: [ "-3%", "-1px", "4" ] - }, "-moz-column-gap": { domProp: "MozColumnGap", inherited: false, @@ -6187,561 +6170,581 @@ if (IsCSSPropertyPrefEnabled("layout.css.filters.enabled")) { }; } -if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) { - var isGridTemplateSubgridValueEnabled = - IsCSSPropertyPrefEnabled("layout.css.grid-template-subgrid-value.enabled"); - - gCSSProperties["display"].other_values.push("grid", "inline-grid"); - gCSSProperties["grid-auto-flow"] = { - domProp: "gridAutoFlow", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "row" ], - other_values: [ - "column", - "column dense", - "row dense", - "dense column", - "dense row", - "dense", - ], - invalid_values: [ - "", - "auto", - "none", - "10px", - "column row", - "dense row dense", - ] - }; - - gCSSProperties["grid-auto-columns"] = { - domProp: "gridAutoColumns", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: [ - "40px", - "2em", - "2.5fr", - "12%", - "min-content", - "max-content", - "calc(2px - 99%)", - "minmax(20px, max-content)", - "minmax(min-content, auto)", - "minmax(auto, max-content)", - "m\\69nmax(20px, 4Fr)", - "MinMax(min-content, calc(20px + 10%))", - "fit-content(1px)", - "fit-content(calc(1px - 99%))", - "fit-content(10%)", - ], - invalid_values: [ - "", - "normal", - "40ms", - "-40px", - "-12%", - "-2em", - "-2.5fr", - "minmax()", - "minmax(20px)", - "mİnmax(20px, 100px)", - "minmax(20px, 100px, 200px)", - "maxmin(100px, 20px)", - "minmax(min-content, minmax(30px, max-content))", - "fit-content(-1px)", - "fit-content(auto)", - "fit-content(min-content)", - ] - }; - gCSSProperties["grid-auto-rows"] = { - domProp: "gridAutoRows", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: gCSSProperties["grid-auto-columns"].initial_values, - other_values: gCSSProperties["grid-auto-columns"].other_values, - invalid_values: gCSSProperties["grid-auto-columns"].invalid_values - }; - - gCSSProperties["grid-template-columns"] = { - domProp: "gridTemplateColumns", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "none" ], - other_values: [ - "auto", - "40px", - "2.5fr", - "[normal] 40px [] auto [ ] 12%", - "[foo] 40px min-content [ bar ] calc(2px - 99%) max-content", - "40px min-content calc(20px + 10%) max-content", - "minmax(min-content, auto)", - "minmax(auto, max-content)", - "m\\69nmax(20px, 4Fr)", - "40px MinMax(min-content, calc(20px + 10%)) max-content", - "40px 2em", - "[] 40px [-foo] 2em [bar baz This\ is\ one\ ident]", - // TODO bug 978478: "[a] repeat(3, [b] 20px [c] 40px [d]) [e]", - "repeat(1, 20px)", - "repeat(1, [a] 20px)", - "[a] Repeat(4, [a] 20px [] auto [b c]) [d]", - "[a] 2.5fr Repeat(4, [a] 20px [] auto [b c]) [d]", - "[a] 2.5fr [z] Repeat(4, [a] 20px [] auto [b c]) [d]", - "[a] 2.5fr [z] Repeat(4, [a] 20px [] auto) [d]", - "[a] 2.5fr [z] Repeat(4, 20px [b c] auto [b c]) [d]", - "[a] 2.5fr [z] Repeat(4, 20px auto) [d]", - "repeat(auto-fill, 0)", - "[a] repeat( Auto-fill,1%)", - "minmax(auto,0) [a] repeat(Auto-fit, 0) minmax(0,auto)", - "minmax(calc(1% + 1px),auto) repeat(Auto-fit,[] 1%) minmax(auto,1%)", - "[a] repeat( auto-fit,[a b] minmax(0,0) )", - "[a] 40px repeat(auto-fit,[a b] minmax(1px, 0) [])", - "[a] calc(1px - 99%) [b] repeat(auto-fit,[a b] minmax(1mm, 1%) [c]) [c]", - "repeat(auto-fill,minmax(1%,auto))", - "repeat(auto-fill,minmax(1em,min-content)) minmax(min-content,0)", - "repeat(auto-fill,minmax(max-content,1mm))", - "repeat(2, fit-content(1px))", - "fit-content(1px) 1fr", - "[a] fit-content(calc(1px - 99%)) [b]", - "[a] fit-content(10%) [b c] fit-content(1em)", - ], - invalid_values: [ - "", - "normal", - "40ms", - "-40px", - "-12%", - "-2fr", - "[foo]", - "[inherit] 40px", - "[initial] 40px", - "[unset] 40px", - "[default] 40px", - "[span] 40px", - "[6%] 40px", - "[5th] 40px", - "[foo[] bar] 40px", - "[foo]] 40px", - "(foo) 40px", - "[foo] [bar] 40px", - "40px [foo] [bar]", - "minmax()", - "minmax(20px)", - "mİnmax(20px, 100px)", - "minmax(20px, 100px, 200px)", - "maxmin(100px, 20px)", - "minmax(min-content, minmax(30px, max-content))", - "repeat(0, 20px)", - "repeat(-3, 20px)", - "rêpeat(1, 20px)", - "repeat(1)", - "repeat(1, )", - "repeat(3px, 20px)", - "repeat(2.0, 20px)", - "repeat(2.5, 20px)", - "repeat(2, (foo))", - "repeat(2, foo)", - "40px calc(0px + rubbish)", - "repeat(1, repeat(1, 20px))", - "repeat(auto-fill, auto)", - "repeat(auto-fit,auto)", - "repeat(auto-fill, fit-content(1px))", - "repeat(auto-fit, fit-content(1px))", - "repeat(auto-fit,[])", - "repeat(auto-fill, 0) repeat(auto-fit, 0) ", - "repeat(auto-fit, 0) repeat(auto-fill, 0) ", - "[a] repeat(auto-fit, 0) repeat(auto-fit, 0) ", - "[a] repeat(auto-fill, 0) [a] repeat(auto-fill, 0) ", - "repeat(auto-fill, 0 0)", - "repeat(auto-fill, 0 [] 0)", - "repeat(auto-fill, min-content)", - "repeat(auto-fit,max-content)", - "repeat(auto-fit,1fr)", - "repeat(auto-fit,minmax(auto,auto))", - "repeat(auto-fit,minmax(min-content,1fr))", - "repeat(auto-fit,minmax(1fr,auto))", - "repeat(auto-fill,minmax(1fr,1em))", - "repeat(auto-fill, 10px) auto", - "auto repeat(auto-fit, 10px)", - "minmax(min-content,max-content) repeat(auto-fit, 0)", - "10px [a] 10px [b a] 1fr [b] repeat(auto-fill, 0)", - "fit-content(-1px)", - "fit-content(auto)", - "fit-content(min-content)", - "fit-content(1px) repeat(auto-fit, 1px)", - "fit-content(1px) repeat(auto-fill, 1px)", - ], - unbalanced_values: [ - "(foo] 40px", - ] - }; - if (isGridTemplateSubgridValueEnabled) { - gCSSProperties["grid-template-columns"].other_values.push( - // See https://bugzilla.mozilla.org/show_bug.cgi?id=981300 - "[none auto subgrid min-content max-content foo] 40px", - - "subgrid", - "subgrid [] [foo bar]", - "subgrid repeat(1, [])", - "subgrid Repeat(4, [a] [b c] [] [d])", - "subgrid repeat(auto-fill, [])", - "subgrid [x] repeat( Auto-fill, [a b c]) []", - "subgrid [x] repeat(auto-fill, []) [y z]" - ); - gCSSProperties["grid-template-columns"].invalid_values.push( - "subgrid [inherit]", - "subgrid [initial]", - "subgrid [unset]", - "subgrid [default]", - "subgrid [span]", - "subgrid [foo] 40px", - "subgrid [foo 40px]", - "[foo] subgrid", - "subgrid rêpeat(1, [])", - "subgrid repeat(0, [])", - "subgrid repeat(-3, [])", - "subgrid repeat(2.0, [])", - "subgrid repeat(2.5, [])", - "subgrid repeat(3px, [])", - "subgrid repeat(1)", - "subgrid repeat(1, )", - "subgrid repeat(2, [40px])", - "subgrid repeat(2, foo)", - "subgrid repeat(1, repeat(1, []))", - "subgrid repeat(auto-fit,[])", - "subgrid [] repeat(auto-fit,[])", - "subgrid [a] repeat(auto-fit,[])", - "subgrid repeat(auto-fill, 1px)", - "subgrid repeat(auto-fill, 1px [])", - "subgrid repeat(Auto-fill, [a] [b c] [] [d])", - "subgrid repeat(auto-fill, []) repeat(auto-fill, [])" - ); - } - gCSSProperties["grid-template-rows"] = { - domProp: "gridTemplateRows", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: gCSSProperties["grid-template-columns"].initial_values, - other_values: gCSSProperties["grid-template-columns"].other_values, - invalid_values: gCSSProperties["grid-template-columns"].invalid_values - }; - gCSSProperties["grid-template-areas"] = { - domProp: "gridTemplateAreas", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "none" ], - other_values: [ - "''", - "'' ''", - "'1a-é_ .' \"b .\"", - "' Z\t\\aZ' 'Z Z'", - " '. . a b' '. .a b' ", - "'a.b' '. . .'", - "'.' '..'", - "'...' '.'", - "'...-blah' '. .'", - "'.. ..' '.. ...'", - ], - invalid_values: [ - "'a b' 'a/b'", - "'a . a'", - "'. a a' 'a a a'", - "'a a .' 'a a a'", - "'a a' 'a .'", - "'a a'\n'..'\n'a a'", - ] - }; - - gCSSProperties["grid-template"] = { - domProp: "gridTemplate", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "grid-template-areas", - "grid-template-rows", - "grid-template-columns", - ], - initial_values: [ - "none", - "none / none", - ], - other_values: [ - // <'grid-template-rows'> / <'grid-template-columns'> - "40px / 100px", - "[foo] 40px [bar] / [baz] repeat(auto-fill,100px) [fizz]", - " none/100px", - "40px/none", - // [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]? - "'fizz'", - "[bar] 'fizz'", - "'fizz' / [foo] 40px", - "[bar] 'fizz' / [foo] 40px", - "'fizz' 100px / [foo] 40px", - "[bar] 'fizz' 100px / [foo] 40px", - "[bar] 'fizz' 100px [buzz] / [foo] 40px", - "[bar] 'fizz' 100px [buzz] \n [a] '.' 200px [b] / [foo] 40px", - ], - invalid_values: [ - "'fizz' / repeat(1, 100px)", - "'fizz' repeat(1, 100px) / 0px", - "[foo] [bar] 40px / 100px", - "[fizz] [buzz] 100px / 40px", - "[fizz] [buzz] 'foo' / 40px", - "'foo' / none" - ] - }; - if (isGridTemplateSubgridValueEnabled) { - gCSSProperties["grid-template"].other_values.push( - "subgrid", - "subgrid/40px 20px", - "subgrid [foo] [] [bar baz] / 40px 20px", - "40px 20px/subgrid", - "40px 20px/subgrid [foo] [] repeat(3, [a] [b]) [bar baz]", - "subgrid/subgrid", - "subgrid [foo] [] [bar baz]/subgrid [foo] [] [bar baz]" - ); - gCSSProperties["grid-template"].invalid_values.push( - "subgrid []", - "subgrid [] / 'fizz'", - "subgrid / 'fizz'" - ); - } - - gCSSProperties["grid"] = { - domProp: "grid", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "grid-template-areas", - "grid-template-rows", - "grid-template-columns", - "grid-auto-flow", - "grid-auto-rows", - "grid-auto-columns", - "grid-column-gap", - "grid-row-gap", - ], - initial_values: [ - "none", - "none / none", - ], - other_values: [ - "auto-flow 40px / none", - "auto-flow / 40px", - "auto-flow dense auto / auto", - "dense auto-flow minmax(min-content, 2fr) / auto", - "dense auto-flow / 100px", - "none / auto-flow 40px", - "40px / auto-flow", - "none / dense auto-flow auto", - ].concat( - gCSSProperties["grid-template"].other_values - ), - invalid_values: [ - "auto-flow", - " / auto-flow", - "dense 0 / 0", - "dense dense 40px / 0", - "auto-flow / auto-flow", - "auto-flow / dense", - "auto-flow [a] 0 / 0", - "0 / auto-flow [a] 0", - "auto-flow -20px / 0", - "auto-flow 200ms / 0", - "auto-flow 40px 100px / 0", - ].concat( - gCSSProperties["grid-template"].invalid_values, - gCSSProperties["grid-auto-flow"].other_values, - gCSSProperties["grid-auto-flow"].invalid_values - .filter((v) => v != 'none') - ) - }; - - var gridLineOtherValues = [ - "foo", - "2", - "2 foo", - "foo 2", - "-3", - "-3 bar", - "bar -3", - "span 2", - "2 span", - "span foo", - "foo span", - "span 2 foo", - "span foo 2", - "2 foo span", - "foo 2 span", - ]; - var gridLineInvalidValues = [ +var isGridTemplateSubgridValueEnabled = + IsCSSPropertyPrefEnabled("layout.css.grid-template-subgrid-value.enabled"); + +gCSSProperties["display"].other_values.push("grid", "inline-grid"); +gCSSProperties["grid-auto-flow"] = { + domProp: "gridAutoFlow", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "row" ], + other_values: [ + "column", + "column dense", + "row dense", + "dense column", + "dense row", + "dense", + ], + invalid_values: [ "", - "4th", - "span", - "inherit 2", - "2 inherit", - "20px", - "2 3", - "2.5", - "2.0", - "0", - "0 foo", - "span 0", - "2 foo 3", - "foo 2 foo", - "2 span foo", - "foo span 2", - "span -3", - "span -3 bar", - "span 2 span", - "span foo span", - "span 2 foo span", - ]; - - gCSSProperties["grid-column-start"] = { - domProp: "gridColumnStart", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: gridLineOtherValues, - invalid_values: gridLineInvalidValues - }; - gCSSProperties["grid-column-end"] = { - domProp: "gridColumnEnd", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: gridLineOtherValues, - invalid_values: gridLineInvalidValues - }; - gCSSProperties["grid-row-start"] = { - domProp: "gridRowStart", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: gridLineOtherValues, - invalid_values: gridLineInvalidValues - }; - gCSSProperties["grid-row-end"] = { - domProp: "gridRowEnd", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "auto" ], - other_values: gridLineOtherValues, - invalid_values: gridLineInvalidValues - }; - - // The grid-column and grid-row shorthands take values of the form - // <grid-line> [ / <grid-line> ]? - var gridColumnRowOtherValues = [].concat(gridLineOtherValues); - gridLineOtherValues.concat([ "auto" ]).forEach(function(val) { - gridColumnRowOtherValues.push(" foo / " + val); - gridColumnRowOtherValues.push(val + "/2"); - }); - var gridColumnRowInvalidValues = [ - "foo, bar", - "foo / bar / baz", - ].concat(gridLineInvalidValues); - gridLineInvalidValues.forEach(function(val) { - gridColumnRowInvalidValues.push("span 3 / " + val); - gridColumnRowInvalidValues.push(val + " / foo"); - }); - gCSSProperties["grid-column"] = { - domProp: "gridColumn", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "grid-column-start", - "grid-column-end" - ], - initial_values: [ "auto", "auto / auto" ], - other_values: gridColumnRowOtherValues, - invalid_values: gridColumnRowInvalidValues - }; - gCSSProperties["grid-row"] = { - domProp: "gridRow", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "grid-row-start", - "grid-row-end" - ], - initial_values: [ "auto", "auto / auto" ], - other_values: gridColumnRowOtherValues, - invalid_values: gridColumnRowInvalidValues - }; + "auto", + "none", + "10px", + "column row", + "dense row dense", + ] +}; + +gCSSProperties["grid-auto-columns"] = { + domProp: "gridAutoColumns", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: [ + "40px", + "2em", + "2.5fr", + "12%", + "min-content", + "max-content", + "calc(2px - 99%)", + "minmax(20px, max-content)", + "minmax(min-content, auto)", + "minmax(auto, max-content)", + "m\\69nmax(20px, 4Fr)", + "MinMax(min-content, calc(20px + 10%))", + "fit-content(1px)", + "fit-content(calc(1px - 99%))", + "fit-content(10%)", + ], + invalid_values: [ + "", + "normal", + "40ms", + "-40px", + "-12%", + "-2em", + "-2.5fr", + "minmax()", + "minmax(20px)", + "mİnmax(20px, 100px)", + "minmax(20px, 100px, 200px)", + "maxmin(100px, 20px)", + "minmax(min-content, minmax(30px, max-content))", + "fit-content(-1px)", + "fit-content(auto)", + "fit-content(min-content)", + ] +}; +gCSSProperties["grid-auto-rows"] = { + domProp: "gridAutoRows", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: gCSSProperties["grid-auto-columns"].initial_values, + other_values: gCSSProperties["grid-auto-columns"].other_values, + invalid_values: gCSSProperties["grid-auto-columns"].invalid_values +}; + +gCSSProperties["grid-template-columns"] = { + domProp: "gridTemplateColumns", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "none" ], + other_values: [ + "auto", + "40px", + "2.5fr", + "[normal] 40px [] auto [ ] 12%", + "[foo] 40px min-content [ bar ] calc(2px - 99%) max-content", + "40px min-content calc(20px + 10%) max-content", + "minmax(min-content, auto)", + "minmax(auto, max-content)", + "m\\69nmax(20px, 4Fr)", + "40px MinMax(min-content, calc(20px + 10%)) max-content", + "40px 2em", + "[] 40px [-foo] 2em [bar baz This\ is\ one\ ident]", + // TODO bug 978478: "[a] repeat(3, [b] 20px [c] 40px [d]) [e]", + "repeat(1, 20px)", + "repeat(1, [a] 20px)", + "[a] Repeat(4, [a] 20px [] auto [b c]) [d]", + "[a] 2.5fr Repeat(4, [a] 20px [] auto [b c]) [d]", + "[a] 2.5fr [z] Repeat(4, [a] 20px [] auto [b c]) [d]", + "[a] 2.5fr [z] Repeat(4, [a] 20px [] auto) [d]", + "[a] 2.5fr [z] Repeat(4, 20px [b c] auto [b c]) [d]", + "[a] 2.5fr [z] Repeat(4, 20px auto) [d]", + "repeat(auto-fill, 0)", + "[a] repeat( Auto-fill,1%)", + "minmax(auto,0) [a] repeat(Auto-fit, 0) minmax(0,auto)", + "minmax(calc(1% + 1px),auto) repeat(Auto-fit,[] 1%) minmax(auto,1%)", + "[a] repeat( auto-fit,[a b] minmax(0,0) )", + "[a] 40px repeat(auto-fit,[a b] minmax(1px, 0) [])", + "[a] calc(1px - 99%) [b] repeat(auto-fit,[a b] minmax(1mm, 1%) [c]) [c]", + "repeat(auto-fill,minmax(1%,auto))", + "repeat(auto-fill,minmax(1em,min-content)) minmax(min-content,0)", + "repeat(auto-fill,minmax(max-content,1mm))", + "repeat(2, fit-content(1px))", + "fit-content(1px) 1fr", + "[a] fit-content(calc(1px - 99%)) [b]", + "[a] fit-content(10%) [b c] fit-content(1em)", + ], + invalid_values: [ + "", + "normal", + "40ms", + "-40px", + "-12%", + "-2fr", + "[foo]", + "[inherit] 40px", + "[initial] 40px", + "[unset] 40px", + "[default] 40px", + "[span] 40px", + "[6%] 40px", + "[5th] 40px", + "[foo[] bar] 40px", + "[foo]] 40px", + "(foo) 40px", + "[foo] [bar] 40px", + "40px [foo] [bar]", + "minmax()", + "minmax(20px)", + "mİnmax(20px, 100px)", + "minmax(20px, 100px, 200px)", + "maxmin(100px, 20px)", + "minmax(min-content, minmax(30px, max-content))", + "repeat(0, 20px)", + "repeat(-3, 20px)", + "rêpeat(1, 20px)", + "repeat(1)", + "repeat(1, )", + "repeat(3px, 20px)", + "repeat(2.0, 20px)", + "repeat(2.5, 20px)", + "repeat(2, (foo))", + "repeat(2, foo)", + "40px calc(0px + rubbish)", + "repeat(1, repeat(1, 20px))", + "repeat(auto-fill, auto)", + "repeat(auto-fit,auto)", + "repeat(auto-fill, fit-content(1px))", + "repeat(auto-fit, fit-content(1px))", + "repeat(auto-fit,[])", + "repeat(auto-fill, 0) repeat(auto-fit, 0) ", + "repeat(auto-fit, 0) repeat(auto-fill, 0) ", + "[a] repeat(auto-fit, 0) repeat(auto-fit, 0) ", + "[a] repeat(auto-fill, 0) [a] repeat(auto-fill, 0) ", + "repeat(auto-fill, 0 0)", + "repeat(auto-fill, 0 [] 0)", + "repeat(auto-fill, min-content)", + "repeat(auto-fit,max-content)", + "repeat(auto-fit,1fr)", + "repeat(auto-fit,minmax(auto,auto))", + "repeat(auto-fit,minmax(min-content,1fr))", + "repeat(auto-fit,minmax(1fr,auto))", + "repeat(auto-fill,minmax(1fr,1em))", + "repeat(auto-fill, 10px) auto", + "auto repeat(auto-fit, 10px)", + "minmax(min-content,max-content) repeat(auto-fit, 0)", + "10px [a] 10px [b a] 1fr [b] repeat(auto-fill, 0)", + "fit-content(-1px)", + "fit-content(auto)", + "fit-content(min-content)", + "fit-content(1px) repeat(auto-fit, 1px)", + "fit-content(1px) repeat(auto-fill, 1px)", + ], + unbalanced_values: [ + "(foo] 40px", + ] +}; +if (isGridTemplateSubgridValueEnabled) { + gCSSProperties["grid-template-columns"].other_values.push( + // See https://bugzilla.mozilla.org/show_bug.cgi?id=981300 + "[none auto subgrid min-content max-content foo] 40px", + + "subgrid", + "subgrid [] [foo bar]", + "subgrid repeat(1, [])", + "subgrid Repeat(4, [a] [b c] [] [d])", + "subgrid repeat(auto-fill, [])", + "subgrid [x] repeat( Auto-fill, [a b c]) []", + "subgrid [x] repeat(auto-fill, []) [y z]" + ); + gCSSProperties["grid-template-columns"].invalid_values.push( + "subgrid [inherit]", + "subgrid [initial]", + "subgrid [unset]", + "subgrid [default]", + "subgrid [span]", + "subgrid [foo] 40px", + "subgrid [foo 40px]", + "[foo] subgrid", + "subgrid rêpeat(1, [])", + "subgrid repeat(0, [])", + "subgrid repeat(-3, [])", + "subgrid repeat(2.0, [])", + "subgrid repeat(2.5, [])", + "subgrid repeat(3px, [])", + "subgrid repeat(1)", + "subgrid repeat(1, )", + "subgrid repeat(2, [40px])", + "subgrid repeat(2, foo)", + "subgrid repeat(1, repeat(1, []))", + "subgrid repeat(auto-fit,[])", + "subgrid [] repeat(auto-fit,[])", + "subgrid [a] repeat(auto-fit,[])", + "subgrid repeat(auto-fill, 1px)", + "subgrid repeat(auto-fill, 1px [])", + "subgrid repeat(Auto-fill, [a] [b c] [] [d])", + "subgrid repeat(auto-fill, []) repeat(auto-fill, [])" + ); +} +gCSSProperties["grid-template-rows"] = { + domProp: "gridTemplateRows", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: gCSSProperties["grid-template-columns"].initial_values, + other_values: gCSSProperties["grid-template-columns"].other_values, + invalid_values: gCSSProperties["grid-template-columns"].invalid_values +}; +gCSSProperties["grid-template-areas"] = { + domProp: "gridTemplateAreas", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "none" ], + other_values: [ + "''", + "'' ''", + "'1a-é_ .' \"b .\"", + "' Z\t\\aZ' 'Z Z'", + " '. . a b' '. .a b' ", + "'a.b' '. . .'", + "'.' '..'", + "'...' '.'", + "'...-blah' '. .'", + "'.. ..' '.. ...'", + ], + invalid_values: [ + "'a b' 'a/b'", + "'a . a'", + "'. a a' 'a a a'", + "'a a .' 'a a a'", + "'a a' 'a .'", + "'a a'\n'..'\n'a a'", + ] +}; + +gCSSProperties["grid-template"] = { + domProp: "gridTemplate", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "grid-template-areas", + "grid-template-rows", + "grid-template-columns", + ], + initial_values: [ + "none", + "none / none", + ], + other_values: [ + // <'grid-template-rows'> / <'grid-template-columns'> + "40px / 100px", + "[foo] 40px [bar] / [baz] repeat(auto-fill,100px) [fizz]", + " none/100px", + "40px/none", + // [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]? + "'fizz'", + "[bar] 'fizz'", + "'fizz' / [foo] 40px", + "[bar] 'fizz' / [foo] 40px", + "'fizz' 100px / [foo] 40px", + "[bar] 'fizz' 100px / [foo] 40px", + "[bar] 'fizz' 100px [buzz] / [foo] 40px", + "[bar] 'fizz' 100px [buzz] \n [a] '.' 200px [b] / [foo] 40px", + ], + invalid_values: [ + "'fizz' / repeat(1, 100px)", + "'fizz' repeat(1, 100px) / 0px", + "[foo] [bar] 40px / 100px", + "[fizz] [buzz] 100px / 40px", + "[fizz] [buzz] 'foo' / 40px", + "'foo' / none" + ] +}; +if (isGridTemplateSubgridValueEnabled) { + gCSSProperties["grid-template"].other_values.push( + "subgrid", + "subgrid/40px 20px", + "subgrid [foo] [] [bar baz] / 40px 20px", + "40px 20px/subgrid", + "40px 20px/subgrid [foo] [] repeat(3, [a] [b]) [bar baz]", + "subgrid/subgrid", + "subgrid [foo] [] [bar baz]/subgrid [foo] [] [bar baz]" + ); + gCSSProperties["grid-template"].invalid_values.push( + "subgrid []", + "subgrid [] / 'fizz'", + "subgrid / 'fizz'" + ); +} - var gridAreaOtherValues = gridLineOtherValues.slice(); - gridLineOtherValues.forEach(function(val) { - gridAreaOtherValues.push("foo / " + val); - gridAreaOtherValues.push(val + "/2/3"); - gridAreaOtherValues.push("foo / bar / " + val + " / baz"); - }); - var gridAreaInvalidValues = [ - "foo, bar", - "foo / bar / baz / fizz / buzz", - "default / foo / bar / baz", - "foo / initial / bar / baz", - "foo / bar / inherit / baz", - "foo / bar / baz / unset", - ].concat(gridLineInvalidValues); - gridLineInvalidValues.forEach(function(val) { - gridAreaInvalidValues.push("foo / " + val); - gridAreaInvalidValues.push("foo / bar / " + val); - gridAreaInvalidValues.push("foo / 4 / bar / " + val); - }); - - gCSSProperties["grid-area"] = { - domProp: "gridArea", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ - "grid-row-start", - "grid-column-start", - "grid-row-end", - "grid-column-end" - ], - initial_values: [ - "auto", - "auto / auto", - "auto / auto / auto", - "auto / auto / auto / auto" - ], - other_values: gridAreaOtherValues, - invalid_values: gridAreaInvalidValues - }; +gCSSProperties["grid"] = { + domProp: "grid", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "grid-template-areas", + "grid-template-rows", + "grid-template-columns", + "grid-auto-flow", + "grid-auto-rows", + "grid-auto-columns", + "grid-column-gap", + "grid-row-gap", + ], + initial_values: [ + "none", + "none / none", + ], + other_values: [ + "auto-flow 40px / none", + "auto-flow / 40px", + "auto-flow dense auto / auto", + "dense auto-flow minmax(min-content, 2fr) / auto", + "dense auto-flow / 100px", + "none / auto-flow 40px", + "40px / auto-flow", + "none / dense auto-flow auto", + ].concat( + gCSSProperties["grid-template"].other_values + ), + invalid_values: [ + "auto-flow", + " / auto-flow", + "dense 0 / 0", + "dense dense 40px / 0", + "auto-flow / auto-flow", + "auto-flow / dense", + "auto-flow [a] 0 / 0", + "0 / auto-flow [a] 0", + "auto-flow -20px / 0", + "auto-flow 200ms / 0", + "auto-flow 40px 100px / 0", + ].concat( + gCSSProperties["grid-template"].invalid_values, + gCSSProperties["grid-auto-flow"].other_values, + gCSSProperties["grid-auto-flow"].invalid_values + .filter((v) => v != 'none') + ) +}; + +var gridLineOtherValues = [ + "foo", + "2", + "2 foo", + "foo 2", + "-3", + "-3 bar", + "bar -3", + "span 2", + "2 span", + "span foo", + "foo span", + "span 2 foo", + "span foo 2", + "2 foo span", + "foo 2 span", +]; +var gridLineInvalidValues = [ + "", + "4th", + "span", + "inherit 2", + "2 inherit", + "20px", + "2 3", + "2.5", + "2.0", + "0", + "0 foo", + "span 0", + "2 foo 3", + "foo 2 foo", + "2 span foo", + "foo span 2", + "span -3", + "span -3 bar", + "span 2 span", + "span foo span", + "span 2 foo span", +]; - gCSSProperties["grid-column-gap"] = { - domProp: "gridColumnGap", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "0" ], - other_values: [ "2px", "2%", "1em", "calc(1px + 1em)", "calc(1%)", - "calc(1% + 1ch)" , "calc(1px - 99%)" ], - invalid_values: [ "-1px", "auto", "none", "1px 1px", "-1%", "fit-content(1px)" ], - }; - gCSSProperties["grid-row-gap"] = { - domProp: "gridRowGap", - inherited: false, - type: CSS_TYPE_LONGHAND, - initial_values: [ "0" ], - other_values: [ "2px", "2%", "1em", "calc(1px + 1em)", "calc(1%)", - "calc(1% + 1ch)" , "calc(1px - 99%)" ], - invalid_values: [ "-1px", "auto", "none", "1px 1px", "-1%", "min-content" ], - }; - gCSSProperties["grid-gap"] = { - domProp: "gridGap", - inherited: false, - type: CSS_TYPE_TRUE_SHORTHAND, - subproperties: [ "grid-column-gap", "grid-row-gap" ], - initial_values: [ "0", "0 0" ], - other_values: [ "1ch 0", "1px 1%", "1em 1px", "calc(1px) calc(1%)" ], - invalid_values: [ "-1px", "1px -1px", "1px 1px 1px", "inherit 1px", - "1px auto" ] - }; -} +gCSSProperties["grid-column-start"] = { + domProp: "gridColumnStart", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: gridLineOtherValues, + invalid_values: gridLineInvalidValues +}; +gCSSProperties["grid-column-end"] = { + domProp: "gridColumnEnd", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: gridLineOtherValues, + invalid_values: gridLineInvalidValues +}; +gCSSProperties["grid-row-start"] = { + domProp: "gridRowStart", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: gridLineOtherValues, + invalid_values: gridLineInvalidValues +}; +gCSSProperties["grid-row-end"] = { + domProp: "gridRowEnd", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "auto" ], + other_values: gridLineOtherValues, + invalid_values: gridLineInvalidValues +}; + +// The grid-column and grid-row shorthands take values of the form +// <grid-line> [ / <grid-line> ]? +var gridColumnRowOtherValues = [].concat(gridLineOtherValues); +gridLineOtherValues.concat([ "auto" ]).forEach(function(val) { + gridColumnRowOtherValues.push(" foo / " + val); + gridColumnRowOtherValues.push(val + "/2"); +}); +var gridColumnRowInvalidValues = [ + "foo, bar", + "foo / bar / baz", +].concat(gridLineInvalidValues); +gridLineInvalidValues.forEach(function(val) { + gridColumnRowInvalidValues.push("span 3 / " + val); + gridColumnRowInvalidValues.push(val + " / foo"); +}); +gCSSProperties["grid-column"] = { + domProp: "gridColumn", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "grid-column-start", + "grid-column-end" + ], + initial_values: [ "auto", "auto / auto" ], + other_values: gridColumnRowOtherValues, + invalid_values: gridColumnRowInvalidValues +}; +gCSSProperties["grid-row"] = { + domProp: "gridRow", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "grid-row-start", + "grid-row-end" + ], + initial_values: [ "auto", "auto / auto" ], + other_values: gridColumnRowOtherValues, + invalid_values: gridColumnRowInvalidValues +}; + +var gridAreaOtherValues = gridLineOtherValues.slice(); +gridLineOtherValues.forEach(function(val) { + gridAreaOtherValues.push("foo / " + val); + gridAreaOtherValues.push(val + "/2/3"); + gridAreaOtherValues.push("foo / bar / " + val + " / baz"); +}); +var gridAreaInvalidValues = [ + "foo, bar", + "foo / bar / baz / fizz / buzz", + "default / foo / bar / baz", + "foo / initial / bar / baz", + "foo / bar / inherit / baz", + "foo / bar / baz / unset", +].concat(gridLineInvalidValues); +gridLineInvalidValues.forEach(function(val) { + gridAreaInvalidValues.push("foo / " + val); + gridAreaInvalidValues.push("foo / bar / " + val); + gridAreaInvalidValues.push("foo / 4 / bar / " + val); +}); + +gCSSProperties["grid-area"] = { + domProp: "gridArea", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ + "grid-row-start", + "grid-column-start", + "grid-row-end", + "grid-column-end" + ], + initial_values: [ + "auto", + "auto / auto", + "auto / auto / auto", + "auto / auto / auto / auto" + ], + other_values: gridAreaOtherValues, + invalid_values: gridAreaInvalidValues +}; + +gCSSProperties["column-gap"] = { + domProp: "columnGap", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "2px", "2%", "1em", "calc(1px + 1em)", "calc(1%)", + "calc(1% + 1ch)" , "calc(1px - 99%)" ], + invalid_values: [ "-1px", "auto", "none", "1px 1px", "-1%", "fit-content(1px)" ], +}; +gCSSProperties["grid-column-gap"] = { + domProp: "gridColumnGap", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "column-gap", + subproperties: [ "column-gap" ] +}; +gCSSProperties["row-gap"] = { + domProp: "rowGap", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "normal" ], + other_values: [ "2px", "2%", "1em", "calc(1px + 1em)", "calc(1%)", + "calc(1% + 1ch)" , "calc(1px - 99%)" ], + invalid_values: [ "-1px", "auto", "none", "1px 1px", "-1%", "min-content" ], +}; +gCSSProperties["grid-row-gap"] = { + domProp: "gridRowGap", + inherited: false, + type: CSS_TYPE_SHORTHAND_AND_LONGHAND, + alias_for: "row-gap", + subproperties: [ "row-gap" ] +}; +gCSSProperties["gap"] = { + domProp: "gap", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + subproperties: [ "column-gap", "row-gap" ], + initial_values: [ "normal", "normal normal" ], + other_values: [ "1ch 0", "1px 1%", "1em 1px", "calc(1px) calc(1%)", + "normal 0", "1% normal" ], + invalid_values: [ "-1px", "1px -1px", "1px 1px 1px", "inherit 1px", + "1px auto" ] +}; +gCSSProperties["grid-gap"] = { + domProp: "gridGap", + inherited: false, + type: CSS_TYPE_TRUE_SHORTHAND, + alias_for: "gap", + subproperties: [ "column-gap", "row-gap" ], +}; if (IsCSSPropertyPrefEnabled("layout.css.display-contents.enabled")) { gCSSProperties["display"].other_values.push("contents"); diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index 83524b60d..2e300fbe8 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -69,8 +69,6 @@ var supported_properties = { "box-shadow": [ test_shadow_transition ], "column-count": [ test_pos_integer_or_auto_transition, test_integer_at_least_one_clamping ], - "column-gap": [ test_length_transition, - test_length_clamped ], "column-rule-color": [ test_color_transition, test_true_currentcolor_transition ], "column-rule-width": [ test_length_transition, @@ -161,8 +159,8 @@ var supported_properties = { /* test_float_zeroToOne_clamped */ ], "font-stretch": [ test_font_stretch ], "font-weight": [ test_font_weight ], - "grid-column-gap": [ test_grid_gap ], - "grid-row-gap": [ test_grid_gap ], + "column-gap": [ test_gap ], + "row-gap": [ test_gap ], "height": [ test_length_transition, test_percent_transition, test_length_percent_calc_transition, test_length_clamped, test_percent_clamped ], @@ -1922,10 +1920,7 @@ function test_font_weight(prop) { div.style.setProperty("transition-timing-function", "linear", ""); } -function test_grid_gap(prop) { - if (!SpecialPowers.getBoolPref("layout.css.grid.enabled")) { - return; - } +function test_gap(prop) { test_length_transition(prop); test_length_clamped(prop); test_percent_transition(prop); |