From 40a44c4767bfb250e2dea219540f045113bc9012 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 27 Mar 2014 11:54:40 -0400 Subject: [PATCH] Bug 983175 - Part 2: Add style system support for 'subgrid' in the grid-template* properties. r=dholbert http://dev.w3.org/csswg/css-grid/#subgrids --- layout/style/nsCSSKeywordList.h | 1 + layout/style/nsCSSParser.cpp | 129 +++++++++++++++--- layout/style/nsCSSValue.cpp | 17 ++- layout/style/nsComputedDOMStyle.cpp | 37 +++-- layout/style/nsComputedDOMStyle.h | 2 +- layout/style/nsRuleNode.cpp | 86 +++++++----- layout/style/nsStyleConsts.h | 4 + layout/style/nsStyleStruct.cpp | 2 +- layout/style/nsStyleStruct.h | 64 +++++---- layout/style/test/property_database.js | 17 ++- .../test/test_grid_container_shorthands.html | 20 +++ 11 files changed, 287 insertions(+), 92 deletions(-) diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index 68978e5e81ab..606023d9b5ae 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -522,6 +522,7 @@ CSS_KEY(style, style) CSS_KEY(styleset, styleset) CSS_KEY(stylistic, stylistic) CSS_KEY(sub, sub) +CSS_KEY(subgrid, subgrid) CSS_KEY(super, super) CSS_KEY(sw-resize, sw_resize) CSS_KEY(swash, swash) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index b2a99a8814de..e7522f8bdcdc 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -657,6 +657,7 @@ protected: // // If aValue is already a eCSSUnit_List, append to that list. CSSParseResult ParseGridLineNames(nsCSSValue& aValue); + bool ParseOptionalLineNameListAfterSubgrid(nsCSSValue& aValue); bool ParseGridTrackBreadth(nsCSSValue& aValue); CSSParseResult ParseGridTrackSize(nsCSSValue& aValue); bool ParseGridAutoColumnsRows(nsCSSProperty aPropID); @@ -7005,6 +7006,29 @@ CSSParserImpl::ParseGridLineNames(nsCSSValue& aValue) } } +// Assuming a 'subgrid' keyword was already consumed, parse ? +bool +CSSParserImpl::ParseOptionalLineNameListAfterSubgrid(nsCSSValue& aValue) +{ + nsCSSValueList* item = aValue.SetListValue(); + // This marker distinguishes the value from a . + item->mValue.SetIntValue(NS_STYLE_GRID_TEMPLATE_SUBGRID, + eCSSUnit_Enumerated); + for (;;) { + nsCSSValue lineNames; + CSSParseResult result = ParseGridLineNames(lineNames); + if (result == CSSParseResult::NotFound) { + return true; + } + if (result == CSSParseResult::Error) { + return false; + } + item->mNext = new nsCSSValueList; + item = item->mNext; + item->mValue = lineNames; + } +} + // Parse a bool CSSParserImpl::ParseGridTrackBreadth(nsCSSValue& aValue) @@ -7126,7 +7150,18 @@ CSSParserImpl::ParseGridTemplateColumnsRows(nsCSSProperty aPropID) AppendValue(aPropID, value); return true; } - // FIXME (bug 983175): add subgrid parsing + + nsSubstring* ident = NextIdent(); + if (ident) { + if (ident->LowerCaseEqualsLiteral("subgrid")) { + if (!ParseOptionalLineNameListAfterSubgrid(value)) { + return false; + } + AppendValue(aPropID, value); + return true; + } + UngetToken(); + } nsCSSValue firstLineNames; if (ParseGridLineNames(firstLineNames) == CSSParseResult::Error || @@ -7270,6 +7305,8 @@ CSSParserImpl::ParseGridTemplate() // TODO (bug 983175): add parsing for 'subgrid' by itself + // 'none' can appear either by itself, + // or as the beginning of <'grid-template-columns'> / <'grid-template-rows'> if (ParseVariant(value, VARIANT_NONE, nullptr)) { AppendValue(eCSSProperty_grid_template_columns, value); if (ExpectSymbol('/', true)) { @@ -7280,8 +7317,33 @@ CSSParserImpl::ParseGridTemplate() return true; } - // TODO (bug 983175): add parsing for subgrid - // as part of <'grid-template-columns'> + // 'subgrid' can appear either by itself, + // or as the beginning of <'grid-template-columns'> / <'grid-template-rows'> + nsSubstring* ident = NextIdent(); + if (ident) { + if (ident->LowerCaseEqualsLiteral("subgrid")) { + if (!ParseOptionalLineNameListAfterSubgrid(value)) { + return false; + } + AppendValue(eCSSProperty_grid_template_columns, value); + if (ExpectSymbol('/', true)) { + return ParseGridTemplateAfterSlash(/* aColumnsIsTrackList = */ false); + } + if (value.GetListValue()->mNext) { + // Non-empty after 'subgrid'. + // This is only valid as part of <'grid-template-columns'>, + // which must be followed by a slash. + return false; + } + // 'subgrid' by itself sets both grid-template-columns + // and grid-template-rows. + AppendValue(eCSSProperty_grid_template_rows, value); + value.SetNoneValue(); + AppendValue(eCSSProperty_grid_template_areas, value); + return true; + } + UngetToken(); + } // [ ? ] here is ambiguous: // it can be either the start of a , @@ -7309,34 +7371,61 @@ CSSParserImpl::ParseGridTemplate() } // Helper for parsing the 'grid-template' shorthand +// +// NOTE: This parses the portion after the slash, for *one* of the +// following types of expressions: +// - <'grid-template-columns'> / <'grid-template-rows'> +// - / [ ? ? ? ]+ +// +// We don't know which type of expression we've got until we've parsed the +// second half, since the pre-slash part is ambiguous. The various return +// clauses below are labeled with the type of expression they're completing. bool CSSParserImpl::ParseGridTemplateAfterSlash(bool aColumnsIsTrackList) { nsCSSValue rowsValue; - if (!ParseVariant(rowsValue, VARIANT_NONE, nullptr)) { - // TODO (bug 983175): add parsing for subgrid - // as part of <'grid-template-rows'> + if (ParseVariant(rowsValue, VARIANT_NONE, nullptr)) { + // <'grid-template-columns'> / <'grid-template-rows'> + AppendValue(eCSSProperty_grid_template_rows, rowsValue); + nsCSSValue areasValue(eCSSUnit_None); // implied + AppendValue(eCSSProperty_grid_template_areas, areasValue); + return true; + } - nsCSSValue firstLineNames; - if (ParseGridLineNames(firstLineNames) == CSSParseResult::Error || - !GetToken(true)) { - return false; - } - if (aColumnsIsTrackList && mToken.mType == eCSSToken_String) { - return ParseGridTemplateAfterString(firstLineNames); + nsSubstring* ident = NextIdent(); + if (ident) { + if (ident->LowerCaseEqualsLiteral("subgrid")) { + if (!ParseOptionalLineNameListAfterSubgrid(rowsValue)) { + return false; + } + // <'grid-template-columns'> / <'grid-template-rows'> + AppendValue(eCSSProperty_grid_template_rows, rowsValue); + nsCSSValue areasValue(eCSSUnit_None); // implied + AppendValue(eCSSProperty_grid_template_areas, areasValue); + return true; } UngetToken(); - - if (!ParseGridTrackListWithFirstLineNames(rowsValue, firstLineNames)) { - return false; - } } + + nsCSSValue firstLineNames; + if (ParseGridLineNames(firstLineNames) == CSSParseResult::Error || + !GetToken(true)) { + return false; + } + if (aColumnsIsTrackList && mToken.mType == eCSSToken_String) { + // [ / ]? [ ? ? ? ]+ + return ParseGridTemplateAfterString(firstLineNames); + } + UngetToken(); + + if (!ParseGridTrackListWithFirstLineNames(rowsValue, firstLineNames)) { + return false; + } + // <'grid-template-columns'> / <'grid-template-rows'> - // rowsValue is set by either ParseVariant - // or ParseGridTrackListWithFirstLineNames + AppendValue(eCSSProperty_grid_template_rows, rowsValue); nsCSSValue areasValue(eCSSUnit_None); // implied AppendValue(eCSSProperty_grid_template_areas, areasValue); - AppendValue(eCSSProperty_grid_template_rows, rowsValue); return true; } diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 712ec1c958e7..77279658abf4 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -1679,13 +1679,24 @@ AppendGridTemplateToString(const nsCSSValueList* val, nsCSSValue::Serialization aSerialization) { // This is called for the "list" that's the top-level value of the property. + bool isSubgrid = false; for (;;) { bool addSpaceSeparator = true; nsCSSUnit unit = val->mValue.GetUnit(); - if (unit == eCSSUnit_Null) { - // Empty or omitted . Serializes to nothing. - addSpaceSeparator = false; // Avoid a double space. + if (unit == eCSSUnit_Enumerated && + val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) { + isSubgrid = true; + aResult.AppendLiteral("subgrid"); + + } else if (unit == eCSSUnit_Null) { + // Empty or omitted . + if (isSubgrid) { + aResult.AppendLiteral("()"); + } else { + // Serializes to nothing. + addSpaceSeparator = false; // Avoid a double space. + } } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) { // Non-empty diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 2aca0edf1420..63aefb309cb3 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2302,14 +2302,15 @@ nsComputedDOMStyle::GetGridLineNames(const nsTArray& aLineNames) nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; nsAutoString lineNamesString; uint32_t i_end = aLineNames.Length(); - MOZ_ASSERT(i_end > 0, "GetGridLineNames called with an empty array"); lineNamesString.AssignLiteral("("); - for (uint32_t i = 0;;) { - nsStyleUtil::AppendEscapedCSSIdent(aLineNames[i], lineNamesString); - if (++i == i_end) { - break; + if (i_end > 0) { + for (uint32_t i = 0;;) { + nsStyleUtil::AppendEscapedCSSIdent(aLineNames[i], lineNamesString); + if (++i == i_end) { + break; + } + lineNamesString.AppendLiteral(" "); } - lineNamesString.AppendLiteral(" "); } lineNamesString.AppendLiteral(")"); val->SetString(lineNamesString); @@ -2353,8 +2354,24 @@ nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue, } CSSValue* -nsComputedDOMStyle::GetGridTrackList(const nsStyleGridTrackList& aTrackList) +nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList) { + if (aTrackList.mIsSubgrid) { + NS_ASSERTION(aTrackList.mMinTrackSizingFunctions.IsEmpty() && + aTrackList.mMaxTrackSizingFunctions.IsEmpty(), + "Unexpected sizing functions with subgrid"); + nsDOMCSSValueList* valueList = GetROCSSValueList(false); + + nsROCSSPrimitiveValue* subgridKeyword = new nsROCSSPrimitiveValue; + subgridKeyword->SetIdent(eCSSKeyword_subgrid); + valueList->AppendCSSValue(subgridKeyword); + + for (uint32_t i = 0; i < aTrackList.mLineNameLists.Length(); i++) { + valueList->AppendCSSValue(GetGridLineNames(aTrackList.mLineNameLists[i])); + } + return valueList; + } + uint32_t numSizes = aTrackList.mMinTrackSizingFunctions.Length(); MOZ_ASSERT(aTrackList.mMaxTrackSizingFunctions.Length() == numSizes, "Different number of min and max track sizing functions"); @@ -2373,7 +2390,7 @@ nsComputedDOMStyle::GetGridTrackList(const nsStyleGridTrackList& aTrackList) for (uint32_t i = 0;; i++) { const nsTArray& lineNames = aTrackList.mLineNameLists[i]; if (!lineNames.IsEmpty()) { - valueList->AppendCSSValue(GetGridLineNames(aTrackList.mLineNameLists[i])); + valueList->AppendCSSValue(GetGridLineNames(lineNames)); } if (i == numSizes) { break; @@ -2416,13 +2433,13 @@ nsComputedDOMStyle::DoGetGridAutoRows() CSSValue* nsComputedDOMStyle::DoGetGridTemplateColumns() { - return GetGridTrackList(StylePosition()->mGridTemplateColumns); + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns); } CSSValue* nsComputedDOMStyle::DoGetGridTemplateRows() { - return GetGridTrackList(StylePosition()->mGridTemplateRows); + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows); } CSSValue* diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index e88c7ff2bb7e..778c091a35fb 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -192,7 +192,7 @@ private: mozilla::dom::CSSValue* GetGridLineNames(const nsTArray& aLineNames); mozilla::dom::CSSValue* GetGridTrackSize(const nsStyleCoord& aMinSize, const nsStyleCoord& aMaxSize); - mozilla::dom::CSSValue* GetGridTrackList(const nsStyleGridTrackList& aTrackList); + mozilla::dom::CSSValue* GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList); mozilla::dom::CSSValue* GetGridLine(const nsStyleGridLine& aGridLine); bool GetLineHeightCoord(nscoord& aCoord); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 629c13d6b5c2..dd4b6f1cb92a 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7161,10 +7161,27 @@ SetGridAutoColumnsRows(const nsCSSValue& aValue, } } +static void +AppendGridLineNames(const nsCSSValue& aValue, + nsStyleGridTemplate& aResult) +{ + // Compute a value + nsTArray* nameList = aResult.mLineNameLists.AppendElement(); + // Null unit means empty list, nothing more to do. + if (aValue.GetUnit() != eCSSUnit_Null) { + const nsCSSValueList* item = aValue.GetListValue(); + do { + nsString* name = nameList->AppendElement(); + item->mValue.GetStringValue(*name); + item = item->mNext; + } while (item); + } +} + static void SetGridTrackList(const nsCSSValue& aValue, - nsStyleGridTrackList& aResult, - const nsStyleGridTrackList& aParentValue, + nsStyleGridTemplate& aResult, + const nsStyleGridTemplate& aParentValue, nsStyleContext* aStyleContext, nsPresContext* aPresContext, bool& aCanStoreInRuleTree) @@ -7176,6 +7193,7 @@ SetGridTrackList(const nsCSSValue& aValue, case eCSSUnit_Inherit: aCanStoreInRuleTree = false; + aResult.mIsSubgrid = aParentValue.mIsSubgrid; aResult.mLineNameLists = aParentValue.mLineNameLists; aResult.mMinTrackSizingFunctions = aParentValue.mMinTrackSizingFunctions; aResult.mMaxTrackSizingFunctions = aParentValue.mMaxTrackSizingFunctions; @@ -7184,6 +7202,7 @@ SetGridTrackList(const nsCSSValue& aValue, case eCSSUnit_Initial: case eCSSUnit_Unset: case eCSSUnit_None: + aResult.mIsSubgrid = false; aResult.mLineNameLists.Clear(); aResult.mMinTrackSizingFunctions.Clear(); aResult.mMaxTrackSizingFunctions.Clear(); @@ -7193,42 +7212,45 @@ SetGridTrackList(const nsCSSValue& aValue, aResult.mLineNameLists.Clear(); aResult.mMinTrackSizingFunctions.Clear(); aResult.mMaxTrackSizingFunctions.Clear(); - // This list is expected to have odd number of items, at least 3 - // starting with a (sub list of identifiers), - // and alternating between that and . const nsCSSValueList* item = aValue.GetListValue(); - for (;;) { - // Compute a value - nsTArray* nameList = aResult.mLineNameLists.AppendElement(); - // Null unit means empty list, nothing more to do. - if (item->mValue.GetUnit() != eCSSUnit_Null) { - const nsCSSValueList* subItem = item->mValue.GetListValue(); - do { - nsString* name = nameList->AppendElement(); - subItem->mValue.GetStringValue(*name); - subItem = subItem->mNext; - } while (subItem); - } + if (item->mValue.GetUnit() == eCSSUnit_Enumerated && + item->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) { + // subgrid ? + aResult.mIsSubgrid = true; item = item->mNext; - - if (!item) { - break; + while (item) { + AppendGridLineNames(item->mValue, aResult); + item = item->mNext; } + } else { + // + // The list is expected to have odd number of items, at least 3 + // starting with a (sub list of identifiers), + // and alternating between that and . + aResult.mIsSubgrid = false; + for (;;) { + AppendGridLineNames(item->mValue, aResult); + item = item->mNext; - nsStyleCoord& min = *aResult.mMinTrackSizingFunctions.AppendElement(); - nsStyleCoord& max = *aResult.mMaxTrackSizingFunctions.AppendElement(); - SetGridTrackSize(item->mValue, min, max, - aStyleContext, aPresContext, aCanStoreInRuleTree); + if (!item) { + break; + } - item = item->mNext; - MOZ_ASSERT(item, "Expected a eCSSUnit_List of odd length"); + nsStyleCoord& min = *aResult.mMinTrackSizingFunctions.AppendElement(); + nsStyleCoord& max = *aResult.mMaxTrackSizingFunctions.AppendElement(); + SetGridTrackSize(item->mValue, min, max, + aStyleContext, aPresContext, aCanStoreInRuleTree); + + item = item->mNext; + MOZ_ASSERT(item, "Expected a eCSSUnit_List of odd length"); + } + MOZ_ASSERT(!aResult.mMinTrackSizingFunctions.IsEmpty() && + aResult.mMinTrackSizingFunctions.Length() == + aResult.mMaxTrackSizingFunctions.Length() && + aResult.mMinTrackSizingFunctions.Length() + 1 == + aResult.mLineNameLists.Length(), + "Inconstistent array lengths for nsStyleGridTemplate"); } - MOZ_ASSERT(!aResult.mMinTrackSizingFunctions.IsEmpty() && - aResult.mMinTrackSizingFunctions.Length() == - aResult.mMaxTrackSizingFunctions.Length() && - aResult.mMinTrackSizingFunctions.Length() + 1 == - aResult.mLineNameLists.Length(), - "Inconstistent array lengths for nsStyleGridTrackList"); } } diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index fdf61cf70813..e4d23d6a9dcb 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -545,7 +545,11 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_GRID_AUTO_FLOW_ROW (1 << 2) #define NS_STYLE_GRID_AUTO_FLOW_DENSE (1 << 3) +// 'subgrid' keyword in grid-template-{columns,rows} +#define NS_STYLE_GRID_TEMPLATE_SUBGRID 0 + // CSS Grid keywords +// Should not overlap with NS_STYLE_GRID_TEMPLATE_SUBGRID #define NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT 1 #define NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT 2 diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 8bb041faa631..7d76aae0b412 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1257,7 +1257,7 @@ nsStylePosition::nsStylePosition(void) // Other members get their default constructors // which initialize them to representations of their respective initial value. // mGridTemplateAreas: nullptr for 'none' - // mGridTemplate{Rows,Columns}: empty arrays for 'none' + // mGridTemplate{Rows,Columns}: false and empty arrays for 'none' // mGrid{Column,Row}{Start,End}: false/0/empty values for 'auto' } diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 915693de2025..ca7ba2a27a12 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1157,32 +1157,48 @@ public: nsRect mImageRegion; // [inherited] the rect to use within an image }; -struct nsStyleGridTrackList { - // http://dev.w3.org/csswg/css-grid/#track-sizing - // This represents either: - // * 'none': all three arrays are empty - // * A : mMinTrackSizingFunctions and mMaxTrackSizingFunctions - // are of identical non-zero size, - // and mLineNameLists is one element longer than that. - // (Delimiting N columns requires N+1 lines: - // one before each track, plus one at the very end.) - // - // An omitted is still represented in mLineNameLists, - // as an empty sub-array. - // - // A specified as a single is represented - // as identical min and max sizing functions. - // - // The units for nsStyleCoord are: - // * eStyleUnit_Percent represents a - // * eStyleUnit_FlexFraction represents a flexible fraction - // * eStyleUnit_Coord represents a - // * eStyleUnit_Enumerated represents min-content or max-content +// Computed value of the grid-template-columns or grid-columns-rows property +// (but *not* grid-template-areas.) +// http://dev.w3.org/csswg/css-grid/#track-sizing +// +// This represents either: +// * none: +// mIsSubgrid is false, all three arrays are empty +// * : +// mIsSubgrid is false, +// mMinTrackSizingFunctions and mMaxTrackSizingFunctions +// are of identical non-zero size, +// and mLineNameLists is one element longer than that. +// (Delimiting N columns requires N+1 lines: +// one before each track, plus one at the very end.) +// +// An omitted is still represented in mLineNameLists, +// as an empty sub-array. +// +// A specified as a single is represented +// as identical min and max sizing functions. +// +// The units for nsStyleCoord are: +// * eStyleUnit_Percent represents a +// * eStyleUnit_FlexFraction represents a flexible fraction +// * eStyleUnit_Coord represents a +// * eStyleUnit_Enumerated represents min-content or max-content +// * subgrid ?: +// mIsSubgrid is true, +// mLineNameLists may or may not be empty, +// mMinTrackSizingFunctions and mMaxTrackSizingFunctions are empty. +struct nsStyleGridTemplate { + bool mIsSubgrid; nsTArray> mLineNameLists; nsTArray mMinTrackSizingFunctions; nsTArray mMaxTrackSizingFunctions; - inline bool operator!=(const nsStyleGridTrackList& aOther) const { + nsStyleGridTemplate() + : mIsSubgrid(false) + { + } + + inline bool operator!=(const nsStyleGridTemplate& aOther) const { return mLineNameLists != aOther.mLineNameLists || mMinTrackSizingFunctions != aOther.mMinTrackSizingFunctions || mMaxTrackSizingFunctions != aOther.mMaxTrackSizingFunctions; @@ -1298,8 +1314,8 @@ struct nsStylePosition { // need to have their copy constructor called when we're being copied. // See nsStylePosition::nsStylePosition(const nsStylePosition& aSource) // in nsStyleStruct.cpp - nsStyleGridTrackList mGridTemplateColumns; - nsStyleGridTrackList mGridTemplateRows; + nsStyleGridTemplate mGridTemplateColumns; + nsStyleGridTemplate mGridTemplateRows; // nullptr for 'none' nsRefPtr mGridTemplateAreas; diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index cf5e315ab6d3..402730d28a6a 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4880,6 +4880,9 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) { // See https://bugzilla.mozilla.org/show_bug.cgi?id=981300 "(none auto subgrid min-content max-content foo) 40px", + + "subgrid", + "subgrid () (foo bar)", ], invalid_values: [ "", @@ -4908,6 +4911,9 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) { "maxmin(100px, 20px)", "minmax(min-content, auto)", "minmax(min-content, minmax(30px, max-content))", + "subgrid (foo) 40px", + "subgrid (foo 40px)", + "(foo) subgrid", ] }; gCSSProperties["grid-template-rows"] = { @@ -4954,11 +4960,18 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) { "none / none", ], other_values: [ + "subgrid", // <'grid-template-columns'> / <'grid-template-rows'> "40px / 100px", "(foo) 40px (bar) / (baz) 100px (fizz)", " none/100px", "40px/none", + "subgrid/40px 20px", + "subgrid (foo) () (bar baz) / 40px 20px", + "40px 20px/subgrid", + "40px 20px/subgrid (foo) () (bar baz)", + "subgrid/subgrid", + "subgrid (foo) () (bar baz)/subgrid (foo) () (bar baz)", // [ / ]? [ ? ? ? ]+ "'fizz'", "(bar) 'fizz'", @@ -4970,7 +4983,9 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) { "(foo) 40px / (bar) 'fizz' 100px (buzz) \n (a) '.' 200px (b)", ], invalid_values: [ - "subgrid", // TODO + "subgrid ()", + "subgrid () / 'fizz'", + "subgrid / 'fizz'", "(foo) (bar) 40px / 100px", "40px / (fizz) (buzz) 100px", "40px / (fizz) (buzz) 'foo'", diff --git a/layout/style/test/test_grid_container_shorthands.html b/layout/style/test/test_grid_container_shorthands.html index 73d92ba0e26a..8acf2cd42ff5 100644 --- a/layout/style/test/test_grid_container_shorthands.html +++ b/layout/style/test/test_grid_container_shorthands.html @@ -82,6 +82,26 @@ var grid_template_test_cases = [ gridTemplateColumns: "(foo) 40px", gridTemplateRows: "(bar) 100px (buzz a) 200px (b)", }, + { + specified: "subgrid", + gridTemplateColumns: "subgrid", + gridTemplateRows: "subgrid", + }, + { + specified: "subgrid / subgrid", + gridTemplateColumns: "subgrid", + gridTemplateRows: "subgrid", + }, + { + specified: "subgrid / subgrid (foo)", + gridTemplateColumns: "subgrid", + gridTemplateRows: "subgrid (foo)", + }, + { + specified: "subgrid () (foo)/ subgrid (bar", + gridTemplateColumns: "subgrid () (foo)", + gridTemplateRows: "subgrid (bar)", + }, ]; grid_test_cases = grid_template_test_cases.concat([