Bug 976787 part 3: Add the grid-auto-{columns,rows} properties to the style system. r=dholbert
authorSimon Sapin <simon.sapin@exyr.org>
Mon, 10 Mar 2014 15:54:15 -0700
changeset 183887 a9fb5a9c8ada58a4bff8c4da681c1dee5e41d2aa
parent 183886 a2cb9d6adebc91198718041e04dd7a87240f62c3
child 183888 8db3c07e2bad36a11cf1ec622fd0c155fa305126
push idunknown
push userunknown
push dateunknown
reviewersdholbert
bugs976787
milestone30.0a1
Bug 976787 part 3: Add the grid-auto-{columns,rows} properties to the style system. r=dholbert
layout/style/nsCSSParser.cpp
layout/style/nsCSSPropList.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsComputedDOMStylePropertyList.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -630,16 +630,17 @@ protected:
   bool ParseFlex();
   // For "flex-flow" shorthand property, defined in CSS Flexbox spec
   bool ParseFlexFlow();
 
   // CSS Grid
   bool ParseGridLineNames(nsCSSValue& aValue);
   bool ParseGridTrackBreadth(nsCSSValue& aValue);
   bool ParseGridTrackSize(nsCSSValue& aValue);
+  bool ParseGridAutoColumnsRows(nsCSSProperty aPropID);
   bool ParseGridTrackList(nsCSSProperty aPropID);
   bool ParseGridTemplateAreasLine(const nsAutoString& aInput,
                                   nsTArray<nsCSSGridNamedArea>& aNamedAreas,
                                   uint32_t aRow,
                                   uint32_t& aColumns);
   bool ParseGridTemplateAreas();
 
   // for 'clip' and '-moz-image-region'
@@ -6963,16 +6964,28 @@ CSSParserImpl::ParseGridTrackSize(nsCSSV
       ExpectSymbol(')', true)) {
     return true;
   }
   SkipUntil(')');
   return false;
 }
 
 bool
+CSSParserImpl::ParseGridAutoColumnsRows(nsCSSProperty aPropID)
+{
+  nsCSSValue value;
+  if (ParseVariant(value, VARIANT_INHERIT, nullptr) ||
+      ParseGridTrackSize(value)) {
+    AppendValue(aPropID, value);
+    return true;
+  }
+  return false;
+}
+
+bool
 CSSParserImpl::ParseGridTrackList(nsCSSProperty aPropID)
 {
   nsCSSValue value;
   if (ParseVariant(value, VARIANT_INHERIT | VARIANT_NONE, nullptr)) {
     AppendValue(aPropID, value);
     return true;
   }
   // FIXME: add subgrid
@@ -8123,16 +8136,19 @@ CSSParserImpl::ParsePropertyByFunction(n
   case eCSSProperty_filter:
     return ParseFilter();
   case eCSSProperty_flex:
     return ParseFlex();
   case eCSSProperty_flex_flow:
     return ParseFlexFlow();
   case eCSSProperty_font:
     return ParseFont();
+  case eCSSProperty_grid_auto_columns:
+  case eCSSProperty_grid_auto_rows:
+    return ParseGridAutoColumnsRows(aPropID);
   case eCSSProperty_grid_template_areas:
     return ParseGridTemplateAreas();
   case eCSSProperty_grid_template_columns:
   case eCSSProperty_grid_template_rows:
     return ParseGridTrackList(aPropID);
   case eCSSProperty_image_region:
     return ParseRect(eCSSProperty_image_region);
   case eCSSProperty_list_style:
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -2004,16 +2004,38 @@ CSS_PROP_UIRESET(
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_VALUE_NONNEGATIVE,
     "",
     VARIANT_HI,
     nullptr,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None) // bug 58646
 CSS_PROP_POSITION(
+    grid-auto-columns,
+    grid_auto_columns,
+    GridAutoColumns,
+    CSS_PROPERTY_PARSE_FUNCTION |
+        CSS_PROPERTY_STORES_CALC,
+    "layout.css.grid.enabled",
+    0,
+    kGridTrackBreadthKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_POSITION(
+    grid-auto-rows,
+    grid_auto_rows,
+    GridAutoRows,
+    CSS_PROPERTY_PARSE_FUNCTION |
+        CSS_PROPERTY_STORES_CALC,
+    "layout.css.grid.enabled",
+    0,
+    kGridTrackBreadthKTable,
+    CSS_PROP_NO_OFFSET,
+    eStyleAnimType_None)
+CSS_PROP_POSITION(
     grid-template-areas,
     grid_template_areas,
     GridTemplateAreas,
     CSS_PROPERTY_PARSE_FUNCTION,
     "layout.css.grid.enabled",
     0,
     nullptr,
     CSS_PROP_NO_OFFSET,
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2313,18 +2313,20 @@ nsComputedDOMStyle::GetGridLineNames(con
   val->SetString(lineNamesString);
   return val;
 }
 
 CSSValue*
 nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue,
                                      const nsStyleCoord& aMaxValue)
 {
-  // FIXME bug 978212: If we have frame, every <track-size> should
-  // be resolved into 'px' here, based on layout results.
+  // FIXME bug 978212: for grid-template-columns and grid-template-rows
+  // (not grid-auto-columns and grid-auto-rows), if we have frame,
+  // every <track-size> should be resolved into 'px' here,
+  // based on layout results.
   if (aMinValue == aMaxValue) {
     nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
     SetValueToCoord(val, aMinValue, true,
                     nullptr, nsCSSProps::kGridTrackBreadthKTable);
     return val;
   }
 
   nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
@@ -2377,16 +2379,30 @@ nsComputedDOMStyle::GetGridTrackList(con
     valueList->AppendCSSValue(GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i],
                                                aTrackList.mMaxTrackSizingFunctions[i]));
   }
 
   return valueList;
 }
 
 CSSValue*
+nsComputedDOMStyle::DoGetGridAutoColumns()
+{
+  return GetGridTrackSize(StylePosition()->mGridAutoColumnsMin,
+                          StylePosition()->mGridAutoColumnsMax);
+}
+
+CSSValue*
+nsComputedDOMStyle::DoGetGridAutoRows()
+{
+  return GetGridTrackSize(StylePosition()->mGridAutoRowsMin,
+                          StylePosition()->mGridAutoRowsMax);
+}
+
+CSSValue*
 nsComputedDOMStyle::DoGetGridTemplateColumns()
 {
   return GetGridTrackList(StylePosition()->mGridTemplateColumns);
 }
 
 CSSValue*
 nsComputedDOMStyle::DoGetGridTemplateRows()
 {
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -258,16 +258,18 @@ private:
   mozilla::dom::CSSValue* DoGetFontVariantCaps();
   mozilla::dom::CSSValue* DoGetFontVariantEastAsian();
   mozilla::dom::CSSValue* DoGetFontVariantLigatures();
   mozilla::dom::CSSValue* DoGetFontVariantNumeric();
   mozilla::dom::CSSValue* DoGetFontVariantPosition();
   mozilla::dom::CSSValue* DoGetFontWeight();
 
   /* Grid properties */
+  mozilla::dom::CSSValue* DoGetGridAutoColumns();
+  mozilla::dom::CSSValue* DoGetGridAutoRows();
   mozilla::dom::CSSValue* DoGetGridTemplateAreas();
   mozilla::dom::CSSValue* DoGetGridTemplateColumns();
   mozilla::dom::CSSValue* DoGetGridTemplateRows();
 
   /* Background properties */
   mozilla::dom::CSSValue* DoGetBackgroundAttachment();
   mozilla::dom::CSSValue* DoGetBackgroundColor();
   mozilla::dom::CSSValue* DoGetBackgroundImage();
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -125,16 +125,18 @@ COMPUTED_STYLE_PROP(font_synthesis,     
 COMPUTED_STYLE_PROP(font_variant,                  FontVariant)
 COMPUTED_STYLE_PROP(font_variant_alternates,       FontVariantAlternates)
 COMPUTED_STYLE_PROP(font_variant_caps,             FontVariantCaps)
 COMPUTED_STYLE_PROP(font_variant_east_asian,       FontVariantEastAsian)
 COMPUTED_STYLE_PROP(font_variant_ligatures,        FontVariantLigatures)
 COMPUTED_STYLE_PROP(font_variant_numeric,          FontVariantNumeric)
 COMPUTED_STYLE_PROP(font_variant_position,         FontVariantPosition)
 COMPUTED_STYLE_PROP(font_weight,                   FontWeight)
+COMPUTED_STYLE_PROP(grid_auto_columns,             GridAutoColumns)
+COMPUTED_STYLE_PROP(grid_auto_rows,                GridAutoRows)
 COMPUTED_STYLE_PROP(grid_template_areas,           GridTemplateAreas)
 COMPUTED_STYLE_PROP(grid_template_columns,         GridTemplateColumns)
 COMPUTED_STYLE_PROP(grid_template_rows,            GridTemplateRows)
 COMPUTED_STYLE_PROP(height,                        Height)
 COMPUTED_STYLE_PROP(image_orientation,             ImageOrientation)
 COMPUTED_STYLE_PROP(ime_mode,                      IMEMode)
 COMPUTED_STYLE_PROP(justify_content,               JustifyContent)
 COMPUTED_STYLE_PROP(left,                          Left)
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -7079,16 +7079,86 @@ SetGridTrackBreadth(const nsCSSValue& aV
     const nsStyleCoord dummyParentCoord;
     SetCoord(aValue, aResult, dummyParentCoord,
              SETCOORD_LPE | SETCOORD_STORE_CALC,
              aStyleContext, aPresContext, aCanStoreInRuleTree);
   }
 }
 
 static void
+SetGridTrackSize(const nsCSSValue& aValue,
+                 nsStyleCoord& aResultMin,
+                 nsStyleCoord& aResultMax,
+                 nsStyleContext* aStyleContext,
+                 nsPresContext* aPresContext,
+                 bool& aCanStoreInRuleTree)
+{
+  if (aValue.GetUnit() == eCSSUnit_Function) {
+    // A minmax() function.
+    nsCSSValue::Array* func = aValue.GetArrayValue();
+    NS_ASSERTION(func->Item(0).GetKeywordValue() == eCSSKeyword_minmax,
+                 "Expected minmax(), got another function name");
+    SetGridTrackBreadth(func->Item(1), aResultMin,
+                        aStyleContext, aPresContext, aCanStoreInRuleTree);
+    SetGridTrackBreadth(func->Item(2), aResultMax,
+                        aStyleContext, aPresContext, aCanStoreInRuleTree);
+  } else if (aValue.GetUnit() == eCSSUnit_Auto) {
+    // 'auto' computes to 'minmax(min-content, max-content)'
+    aResultMin.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT,
+                           eStyleUnit_Enumerated);
+    aResultMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
+                           eStyleUnit_Enumerated);
+  } else {
+    // A single <track-breadth>,
+    // specifies identical min and max sizing functions.
+    SetGridTrackBreadth(aValue, aResultMin,
+                        aStyleContext, aPresContext, aCanStoreInRuleTree);
+    aResultMax = aResultMin;
+  }
+}
+
+static void
+SetGridAutoColumnsRows(const nsCSSValue& aValue,
+                       nsStyleCoord& aResultMin,
+                       nsStyleCoord& aResultMax,
+                       const nsStyleCoord& aParentValueMin,
+                       const nsStyleCoord& aParentValueMax,
+                       nsStyleContext* aStyleContext,
+                       nsPresContext* aPresContext,
+                       bool& aCanStoreInRuleTree)
+
+{
+  switch (aValue.GetUnit()) {
+  case eCSSUnit_Null:
+    break;
+
+  case eCSSUnit_Inherit:
+    aCanStoreInRuleTree = false;
+    aResultMin = aParentValueMin;
+    aResultMax = aParentValueMax;
+    break;
+
+  case eCSSUnit_Initial:
+  case eCSSUnit_Unset:
+    // The initial value is 'auto',
+    // which computes to 'minmax(min-content, max-content)'.
+    // (Explicitly-specified 'auto' values are handled in SetGridTrackSize.)
+    aResultMin.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT,
+                           eStyleUnit_Enumerated);
+    aResultMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
+                           eStyleUnit_Enumerated);
+    break;
+
+  default:
+    SetGridTrackSize(aValue, aResultMin, aResultMax,
+                     aStyleContext, aPresContext, aCanStoreInRuleTree);
+  }
+}
+
+static void
 SetGridTrackList(const nsCSSValue& aValue,
                  nsStyleGridTrackList& aResult,
                  const nsStyleGridTrackList& aParentValue,
                  nsStyleContext* aStyleContext,
                  nsPresContext* aPresContext,
                  bool& aCanStoreInRuleTree)
 
 {
@@ -7132,44 +7202,21 @@ SetGridTrackList(const nsCSSValue& aValu
         } while (subItem);
       }
       item = item->mNext;
 
       if (!item) {
         break;
       }
 
-      // Compute a <track-size> value
-      nsStyleCoord minSizingFunction;
-      nsStyleCoord maxSizingFunction;
-      if (item->mValue.GetUnit() == eCSSUnit_Function) {
-        // A minmax() function.
-        nsCSSValue::Array* func = item->mValue.GetArrayValue();
-        NS_ASSERTION(func->Item(0).GetKeywordValue() == eCSSKeyword_minmax,
-                     "Expected minmax(), got another function name.");
-        SetGridTrackBreadth(func->Item(1), minSizingFunction,
-                            aStyleContext, aPresContext, aCanStoreInRuleTree);
-        SetGridTrackBreadth(func->Item(2), maxSizingFunction,
-                            aStyleContext, aPresContext, aCanStoreInRuleTree);
-      } else if (item->mValue.GetUnit() == eCSSUnit_Auto) {
-        // 'auto' computes to 'minmax(min-content, max-content)'
-        minSizingFunction.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT,
-                                      eStyleUnit_Enumerated);
-        maxSizingFunction.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
-                                      eStyleUnit_Enumerated);
-      } else {
-        // A single <track-breadth>,
-        // specifies identical min and max sizing functions.
-        SetGridTrackBreadth(item->mValue, minSizingFunction,
-                            aStyleContext, aPresContext, aCanStoreInRuleTree);
-        maxSizingFunction = minSizingFunction;
-      }
-
-      aResult.mMinTrackSizingFunctions.AppendElement(minSizingFunction);
-      aResult.mMaxTrackSizingFunctions.AppendElement(maxSizingFunction);
+      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(),
@@ -7375,16 +7422,32 @@ nsRuleNode::ComputePositionData(void* aS
 
   // justify-content: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForJustifyContent(),
               pos->mJustifyContent, canStoreInRuleTree,
               SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
               parentPos->mJustifyContent,
               NS_STYLE_JUSTIFY_CONTENT_FLEX_START, 0, 0, 0, 0);
 
+  // grid-auto-columns
+  SetGridAutoColumnsRows(*aRuleData->ValueForGridAutoColumns(),
+                         pos->mGridAutoColumnsMin,
+                         pos->mGridAutoColumnsMax,
+                         parentPos->mGridAutoColumnsMin,
+                         parentPos->mGridAutoColumnsMax,
+                         aContext, mPresContext, canStoreInRuleTree);
+
+  // grid-auto-rows
+  SetGridAutoColumnsRows(*aRuleData->ValueForGridAutoRows(),
+                         pos->mGridAutoRowsMin,
+                         pos->mGridAutoRowsMax,
+                         parentPos->mGridAutoRowsMin,
+                         parentPos->mGridAutoRowsMax,
+                         aContext, mPresContext, canStoreInRuleTree);
+
   // grid-template-columns
   SetGridTrackList(*aRuleData->ValueForGridTemplateColumns(),
                    pos->mGridTemplateColumns, parentPos->mGridTemplateColumns,
                    aContext, mPresContext, canStoreInRuleTree);
 
   // grid-template-rows
   SetGridTrackList(*aRuleData->ValueForGridTemplateRows(),
                    pos->mGridTemplateRows, parentPos->mGridTemplateRows,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1223,16 +1223,28 @@ nsStylePosition::nsStylePosition(void)
   mOffset.SetBottom(autoCoord);
   mWidth.SetAutoValue();
   mMinWidth.SetCoordValue(0);
   mMaxWidth.SetNoneValue();
   mHeight.SetAutoValue();
   mMinHeight.SetCoordValue(0);
   mMaxHeight.SetNoneValue();
   mFlexBasis.SetAutoValue();
+
+  // The initial value of grid-auto-columns and grid-auto-rows is 'auto',
+  // which computes to 'minmax(min-content, max-content)'.
+  mGridAutoColumnsMin.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT,
+                                  eStyleUnit_Enumerated);
+  mGridAutoColumnsMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
+                                  eStyleUnit_Enumerated);
+  mGridAutoRowsMin.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MIN_CONTENT,
+                               eStyleUnit_Enumerated);
+  mGridAutoRowsMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
+                               eStyleUnit_Enumerated);
+
   mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
   mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH;
   mAlignItems = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE;
   mAlignSelf = NS_STYLE_ALIGN_SELF_AUTO;
   mFlexDirection = NS_STYLE_FLEX_DIRECTION_ROW;
   mFlexWrap = NS_STYLE_FLEX_WRAP_NOWRAP;
   mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
   mOrder = NS_STYLE_ORDER_INITIAL;
@@ -1318,17 +1330,21 @@ nsChangeHint nsStylePosition::CalcDiffer
       mFlexWrap != aOther.mFlexWrap) {
     return NS_CombineHint(hint, nsChangeHint_AllReflowHints);
   }
 
 
   // Properties that apply to grid containers:
   if (mGridTemplateColumns != aOther.mGridTemplateColumns ||
       mGridTemplateRows != aOther.mGridTemplateRows ||
-      mGridTemplateAreas != aOther.mGridTemplateAreas) {
+      mGridTemplateAreas != aOther.mGridTemplateAreas ||
+      mGridAutoColumnsMin != aOther.mGridAutoColumnsMin ||
+      mGridAutoColumnsMax != aOther.mGridAutoColumnsMax ||
+      mGridAutoRowsMin != aOther.mGridAutoRowsMin ||
+      mGridAutoRowsMax != aOther.mGridAutoRowsMax) {
     return NS_CombineHint(hint, nsChangeHint_AllReflowHints);
   }
 
 
   // Changing justify-content on a flexbox might affect the positioning of its
   // children, but it won't affect any sizing.
   if (mJustifyContent != aOther.mJustifyContent) {
     NS_UpdateHint(hint, nsChangeHint_NeedReflow);
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1212,16 +1212,20 @@ struct nsStylePosition {
   nsStyleSides  mOffset;                // [reset] coord, percent, calc, auto
   nsStyleCoord  mWidth;                 // [reset] coord, percent, enum, calc, auto
   nsStyleCoord  mMinWidth;              // [reset] coord, percent, enum, calc
   nsStyleCoord  mMaxWidth;              // [reset] coord, percent, enum, calc, none
   nsStyleCoord  mHeight;                // [reset] coord, percent, calc, auto
   nsStyleCoord  mMinHeight;             // [reset] coord, percent, calc
   nsStyleCoord  mMaxHeight;             // [reset] coord, percent, calc, none
   nsStyleCoord  mFlexBasis;             // [reset] coord, percent, enum, calc, auto
+  nsStyleCoord  mGridAutoColumnsMin;    // [reset] coord, percent, enum, calc, flex
+  nsStyleCoord  mGridAutoColumnsMax;    // [reset] coord, percent, enum, calc, flex
+  nsStyleCoord  mGridAutoRowsMin;       // [reset] coord, percent, enum, calc, flex
+  nsStyleCoord  mGridAutoRowsMax;       // [reset] coord, percent, enum, calc, flex
   uint8_t       mBoxSizing;             // [reset] see nsStyleConsts.h
   uint8_t       mAlignContent;          // [reset] see nsStyleConsts.h
   uint8_t       mAlignItems;            // [reset] see nsStyleConsts.h
   uint8_t       mAlignSelf;             // [reset] see nsStyleConsts.h
   uint8_t       mFlexDirection;         // [reset] see nsStyleConsts.h
   uint8_t       mFlexWrap;              // [reset] see nsStyleConsts.h
   uint8_t       mJustifyContent;        // [reset] see nsStyleConsts.h
   int32_t       mOrder;                 // [reset] integer
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -4787,16 +4787,59 @@ if (SpecialPowers.getBoolPref("layout.cs
 			"sepia(10px)",
 			"sepia(-1)",
 		]
 	};
 }
 
 if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
 	gCSSProperties["display"].other_values.push("grid", "inline-grid");
+	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(20px + 10%)",
+			"minmax(20px, max-content)",
+			"m\\69nmax(20px, 4Fr)",
+			"MinMax(min-content, calc(20px + 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, auto)",
+			"minmax(min-content, minmax(30px, max-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",