Bug 1398482 part 2 - [css-grid][css-flexbox][css-multicol] Add 'row-gap' and 'gap' properties; make 'grid-[column|row]-gap' and 'grid-gap' alias the respective unprefixed properties (Gecko part). r=dholbert
authorMats Palmgren <mats@mozilla.com>
Tue, 24 Apr 2018 01:52:51 +0200
changeset 468724 8478901f3de66ebbd6c66cc0fd3dd112e0b1ce5e
parent 468723 ef9fa58539c0ab44cc1b85cb74902002417971b9
child 468725 ed064619187c82a277f867fb1d1987f3c81a1621
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1398482
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1398482 part 2 - [css-grid][css-flexbox][css-multicol] Add 'row-gap' and 'gap' properties; make 'grid-[column|row]-gap' and 'grid-gap' alias the respective unprefixed properties (Gecko part). r=dholbert
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsGridContainerFrame.cpp
layout/style/nsCSSPropAliasList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsComputedDOMStylePropertyList.h
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
layout/style/test/test_transitions_per_property.html
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -283,21 +283,20 @@ nsColumnSetFrame::GetAvailableContentBSi
   WritingMode wm = aReflowInput.GetWritingMode();
   LogicalMargin bp = aReflowInput.ComputedLogicalBorderPadding();
   bp.ApplySkipSides(GetLogicalSkipSides(&aReflowInput));
   bp.BEnd(wm) = aReflowInput.ComputedLogicalBorderPadding().BEnd(wm);
   return std::max(0, aReflowInput.AvailableBSize() - bp.BStartEnd(wm));
 }
 
 static nscoord
-GetColumnGap(nsColumnSetFrame*    aFrame,
-             const nsStyleColumn* aColStyle,
-             nscoord              aPercentageBasis)
+GetColumnGap(nsColumnSetFrame* aFrame,
+             nscoord           aPercentageBasis)
 {
-  const auto& columnGap = aColStyle->mColumnGap;
+  const auto& columnGap = aFrame->StylePosition()->mColumnGap;
   if (columnGap.GetUnit() == eStyleUnit_Normal) {
     return aFrame->StyleFont()->mFont.size;
   }
   return nsLayoutUtils::ResolveGapToLength(columnGap, aPercentageBasis);
 }
 
 nsColumnSetFrame::ReflowConfig
 nsColumnSetFrame::ChooseColumnStrategy(const ReflowInput& aReflowInput,
@@ -325,17 +324,17 @@ nsColumnSetFrame::ChooseColumnStrategy(c
   nscoord colBSize = GetAvailableContentBSize(aReflowInput);
 
   if (aReflowInput.ComputedBSize() != NS_INTRINSICSIZE) {
     colBSize = aReflowInput.ComputedBSize();
   } else if (aReflowInput.ComputedMaxBSize() != NS_INTRINSICSIZE) {
     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.
   const bool isBalancing = colStyle->mColumnFill == NS_STYLE_COLUMN_FILL_BALANCE
                            && !aForceAuto;
   if (isBalancing) {
     const uint32_t MAX_NESTED_COLUMN_BALANCING = 2;
     uint32_t cnt = 0;
@@ -509,17 +508,17 @@ nsColumnSetFrame::GetMinISize(gfxContext
   } else {
     NS_ASSERTION(colStyle->mColumnCount > 0,
                  "column-count and column-width can't both be auto");
     // As available width reduces to zero, we still have mColumnCount columns,
     // so multiply the child's min-width by the number of columns (n) and
     // 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.
     iSize = std::max(iSize, colISize);
   }
   // XXX count forced column breaks here? Maybe we should return the child's
   // min-width times the minimum number of columns.
   return iSize;
@@ -530,17 +529,17 @@ nsColumnSetFrame::GetPrefISize(gfxContex
 {
   // Our preferred width is our desired column width, if specified, otherwise
   // the child's preferred width, times the number of columns, plus the width
   // of any required column gaps
   // XXX what about forced column breaks here?
   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) {
     colISize = colStyle->mColumnWidth.GetCoordValue();
   } else if (mFrames.FirstChild()) {
     colISize = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
   } else {
     colISize = 0;
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -2370,19 +2370,19 @@ struct MOZ_STACK_CLASS nsGridContainerFr
 };
 
 void
 nsGridContainerFrame::GridReflowInput::CalculateTrackSizes(
   const Grid&        aGrid,
   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,
                        aContentBox.ISize(mWM), &GridArea::mCols,
                        aConstraint);
   mCols.AlignJustifyContent(mGridStyle, mWM, aContentBox);
   // Column positions and sizes are now final.
   mCols.mCanResolveLineRangeSize = true;
@@ -3126,26 +3126,26 @@ nsGridContainerFrame::Grid::PlaceGridIte
   // Initialize the end lines of the Explicit Grid (mExplicitGridCol[Row]End).
   // This is determined by the larger of the number of rows/columns defined
   // by 'grid-template-areas' and the 'grid-template-rows'/'-columns', plus one.
   // Also initialize the Implicit Grid (mGridCol[Row]End) to the same values.
   // Note that this is for a grid with a 1,1 origin.  We'll change that
   // 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));
   mGridColEnd = mExplicitGridColEnd =
     aState.mColFunctions.ComputeExplicitGridEnd(areas ? areas->mNColumns + 1 : 1);
   LineNameMap colLineNameMap(gridStyle->GridTemplateColumns(), numRepeatCols);
 
   uint32_t numRepeatRows = aState.mRowFunctions.InitRepeatTracks(
-                             gridStyle->mGridRowGap,
+                             gridStyle->mRowGap,
                              aComputedMinSize.BSize(aState.mWM),
                              aComputedSize.BSize(aState.mWM),
                              aComputedMaxSize.BSize(aState.mWM));
   mGridRowEnd = mExplicitGridRowEnd =
     aState.mRowFunctions.ComputeExplicitGridEnd(areas ? areas->NRows() + 1 : 1);
   LineNameMap rowLineNameMap(gridStyle->GridTemplateRows(), numRepeatRows);
 
   // http://dev.w3.org/csswg/css-grid/#line-placement
@@ -6365,25 +6365,25 @@ nsGridContainerFrame::IntrinsicISize(gfx
                      &max.BSize(state.mWM));
   }
 
   Grid grid;
   grid.PlaceGridItems(state, min, sz, max);  // XXX optimize
   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;
   state.mCols.CalculateSizes(state, state.mGridItems, state.mColFunctions,
                              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) {
     length += sz.mBase;
   }
   return length + state.mCols.SumOfGridGaps();
 }
 
--- a/layout/style/nsCSSPropAliasList.h
+++ b/layout/style/nsCSSPropAliasList.h
@@ -592,13 +592,28 @@ CSS_PROP_ALIAS(-webkit-transition-timing
                WEBKIT_PREFIX_PREF)
 CSS_PROP_ALIAS(-webkit-user-select,
                _webkit_user_select,
                _moz_user_select,
                WebkitUserSelect,
                WEBKIT_PREFIX_PREF)
 #undef WEBKIT_PREFIX_PREF
 
+CSS_PROP_ALIAS(grid-column-gap,
+               grid_column_gap,
+               column_gap,
+               GridColumnGap,
+               "")
+CSS_PROP_ALIAS(grid-gap,
+               grid_gap,
+               gap,
+               GridGap,
+               "")
+CSS_PROP_ALIAS(grid-row-gap,
+               grid_row_gap,
+               row_gap,
+               GridRowGap,
+               "")
 CSS_PROP_ALIAS(word-wrap,
                word_wrap,
                overflow_wrap,
                WordWrap,
                "")
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1359,16 +1359,22 @@ CSS_PROP_(
     -moz-force-broken-image-icon,
     _moz_force_broken_image_icon,
     CSS_PROP_DOMPROP_PREFIXED(ForceBrokenImageIcon),
     0,
     "",
     VARIANT_HI,
     nullptr) // bug 58646
 CSS_PROP_SHORTHAND(
+    gap,
+    gap,
+    Gap,
+    CSS_PROPERTY_PARSE_FUNCTION,
+    "")
+CSS_PROP_SHORTHAND(
     grid,
     grid,
     Grid,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")
 CSS_PROP_SHORTHAND(
     grid-area,
     grid_area,
@@ -1409,60 +1415,38 @@ CSS_PROP_(
     grid-column-end,
     grid_column_end,
     GridColumnEnd,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
     nullptr)
 CSS_PROP_(
-    grid-column-gap,
-    grid_column_gap,
-    GridColumnGap,
-    0,
-    "",
-    VARIANT_HLP | VARIANT_CALC,
-    nullptr)
-CSS_PROP_(
     grid-column-start,
     grid_column_start,
     GridColumnStart,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
     nullptr)
 CSS_PROP_SHORTHAND(
-    grid-gap,
-    grid_gap,
-    GridGap,
-    CSS_PROPERTY_PARSE_FUNCTION,
-    "")
-CSS_PROP_SHORTHAND(
     grid-row,
     grid_row,
     GridRow,
     CSS_PROPERTY_PARSE_FUNCTION,
     "")
 CSS_PROP_(
     grid-row-end,
     grid_row_end,
     GridRowEnd,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
     nullptr)
 CSS_PROP_(
-    grid-row-gap,
-    grid_row_gap,
-    GridRowGap,
-    0,
-    "",
-    VARIANT_HLP | VARIANT_CALC,
-    nullptr)
-CSS_PROP_(
     grid-row-start,
     grid_row_start,
     GridRowStart,
     CSS_PROPERTY_PARSE_FUNCTION,
     "",
     0,
     nullptr)
 CSS_PROP_SHORTHAND(
@@ -2379,16 +2363,24 @@ CSS_PROP_(
     rotate,
     rotate,
     Rotate,
     CSS_PROPERTY_PARSE_FUNCTION,
     "layout.css.individual-transform.enabled",
     0,
     nullptr)
 CSS_PROP_(
+    row-gap,
+    row_gap,
+    RowGap,
+    0,
+    "",
+    VARIANT_HLP | VARIANT_NORMAL | VARIANT_CALC,
+    nullptr)
+CSS_PROP_(
     ruby-align,
     ruby_align,
     RubyAlign,
     0,
     "",
     VARIANT_HK,
     kRubyAlignKTable)
 CSS_PROP_(
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -2667,19 +2667,19 @@ static const nsCSSPropertyID gGridRowSub
 static const nsCSSPropertyID gGridAreaSubpropTable[] = {
   eCSSProperty_grid_row_start,
   eCSSProperty_grid_column_start,
   eCSSProperty_grid_row_end,
   eCSSProperty_grid_column_end,
   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
 };
 
 static const nsCSSPropertyID gOverflowSubpropTable[] = {
   eCSSProperty_overflow_x,
   eCSSProperty_overflow_y,
   eCSSProperty_UNKNOWN
 };
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1247,31 +1247,16 @@ nsComputedDOMStyle::DoGetColumnWidth()
 
   // XXX fix the auto case. When we actually have a column frame, I think
   // we should return the computed column width.
   SetValueToCoord(val, StyleColumn()->mColumnWidth, true);
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
-nsComputedDOMStyle::DoGetColumnGap()
-{
-  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-
-  const nsStyleColumn* column = StyleColumn();
-  if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) {
-    val->SetIdent(eCSSKeyword_normal);
-  } else {
-    SetValueToCoord(val, StyleColumn()->mColumnGap, true);
-  }
-
-  return val.forget();
-}
-
-already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetColumnFill()
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
   val->SetIdent(
     nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnFill,
                                    nsCSSProps::kColumnFillKTable));
   return val.forget();
 }
@@ -3424,28 +3409,38 @@ nsComputedDOMStyle::DoGetGridRowStart()
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetGridRowEnd()
 {
   return GetGridLine(StylePosition()->mGridRowEnd);
 }
 
 already_AddRefed<CSSValue>
-nsComputedDOMStyle::DoGetGridColumnGap()
-{
-  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-  SetValueToCoord(val, StylePosition()->mGridColumnGap, true);
-  return val.forget();
-}
-
-already_AddRefed<CSSValue>
-nsComputedDOMStyle::DoGetGridRowGap()
-{
-  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
-  SetValueToCoord(val, StylePosition()->mGridRowGap, true);
+nsComputedDOMStyle::DoGetColumnGap()
+{
+  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+  const auto& columnGap = StylePosition()->mColumnGap;
+  if (columnGap.GetUnit() == eStyleUnit_Normal) {
+    val->SetIdent(eCSSKeyword_normal);
+  } else {
+    SetValueToCoord(val, columnGap, true);
+  }
+  return val.forget();
+}
+
+already_AddRefed<CSSValue>
+nsComputedDOMStyle::DoGetRowGap()
+{
+  RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+  const auto& rowGap = StylePosition()->mRowGap;
+  if (rowGap.GetUnit() == eStyleUnit_Normal) {
+    val->SetIdent(eCSSKeyword_normal);
+  } else {
+    SetValueToCoord(val, rowGap, true);
+  }
   return val.forget();
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetPaddingTop()
 {
   return GetPaddingWidthFor(eSideTop);
 }
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -311,18 +311,16 @@ private:
   already_AddRefed<CSSValue> DoGetGridAutoRows();
   already_AddRefed<CSSValue> DoGetGridTemplateAreas();
   already_AddRefed<CSSValue> DoGetGridTemplateColumns();
   already_AddRefed<CSSValue> DoGetGridTemplateRows();
   already_AddRefed<CSSValue> DoGetGridColumnStart();
   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);
   already_AddRefed<CSSValue> DoGetImageLayerPosition(const nsStyleImageLayers& aLayers);
   already_AddRefed<CSSValue> DoGetImageLayerPositionX(const nsStyleImageLayers& aLayers);
   already_AddRefed<CSSValue> DoGetImageLayerPositionY(const nsStyleImageLayers& aLayers);
   already_AddRefed<CSSValue> DoGetImageLayerRepeat(const nsStyleImageLayers& aLayers);
   already_AddRefed<CSSValue> DoGetImageLayerSize(const nsStyleImageLayers& aLayers);
@@ -534,17 +532,16 @@ private:
   already_AddRefed<CSSValue> DoGetWindowTransform();
   already_AddRefed<CSSValue> DoGetWindowTransformOrigin();
 
   /* Column properties */
   already_AddRefed<CSSValue> DoGetColumnCount();
   already_AddRefed<CSSValue> DoGetColumnFill();
   already_AddRefed<CSSValue> DoGetColumnSpan();
   already_AddRefed<CSSValue> DoGetColumnWidth();
-  already_AddRefed<CSSValue> DoGetColumnGap();
   already_AddRefed<CSSValue> DoGetColumnRuleWidth();
   already_AddRefed<CSSValue> DoGetColumnRuleStyle();
   already_AddRefed<CSSValue> DoGetColumnRuleColor();
 
   /* CSS Transitions */
   already_AddRefed<CSSValue> DoGetTransitionProperty();
   already_AddRefed<CSSValue> DoGetTransitionDuration();
   already_AddRefed<CSSValue> DoGetTransitionDelay();
@@ -572,16 +569,18 @@ private:
 
   /* CSS Box Alignment properties */
   already_AddRefed<CSSValue> DoGetAlignContent();
   already_AddRefed<CSSValue> DoGetAlignItems();
   already_AddRefed<CSSValue> DoGetAlignSelf();
   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();
   already_AddRefed<CSSValue> DoGetStroke();
   already_AddRefed<CSSValue> DoGetMarkerEnd();
   already_AddRefed<CSSValue> DoGetMarkerMid();
   already_AddRefed<CSSValue> DoGetMarkerStart();
   already_AddRefed<CSSValue> DoGetStrokeDasharray();
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -149,20 +149,18 @@ COMPUTED_STYLE_PROP(font_variant_ligatur
 COMPUTED_STYLE_PROP(font_variant_numeric,          FontVariantNumeric)
 COMPUTED_STYLE_PROP(font_variant_position,         FontVariantPosition)
 COMPUTED_STYLE_PROP(font_variation_settings,       FontVariationSettings)
 COMPUTED_STYLE_PROP(font_weight,                   FontWeight)
 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)
 COMPUTED_STYLE_PROP(grid_template_rows,            GridTemplateRows)
 COMPUTED_STYLE_PROP(height,                        Height)
 COMPUTED_STYLE_PROP(hyphens,                       Hyphens)
 COMPUTED_STYLE_PROP(image_orientation,             ImageOrientation)
 COMPUTED_STYLE_PROP(ime_mode,                      IMEMode)
@@ -219,16 +217,17 @@ COMPUTED_STYLE_PROP(page_break_inside,  
 COMPUTED_STYLE_PROP(perspective,                   Perspective)
 COMPUTED_STYLE_PROP(perspective_origin,            PerspectiveOrigin)
 COMPUTED_STYLE_PROP(pointer_events,                PointerEvents)
 COMPUTED_STYLE_PROP(position,                      Position)
 COMPUTED_STYLE_PROP(quotes,                        Quotes)
 COMPUTED_STYLE_PROP(resize,                        Resize)
 COMPUTED_STYLE_PROP(right,                         Right)
 COMPUTED_STYLE_PROP(rotate,                        Rotate)
+COMPUTED_STYLE_PROP(row_gap,                       RowGap)
 COMPUTED_STYLE_PROP(ruby_align,                    RubyAlign)
 COMPUTED_STYLE_PROP(ruby_position,                 RubyPosition)
 COMPUTED_STYLE_PROP(scale,                         Scale)
 COMPUTED_STYLE_PROP(scroll_behavior,               ScrollBehavior)
 COMPUTED_STYLE_PROP(scroll_snap_coordinate,        ScrollSnapCoordinate)
 COMPUTED_STYLE_PROP(scroll_snap_destination,       ScrollSnapDestination)
 COMPUTED_STYLE_PROP(scroll_snap_points_x,          ScrollSnapPointsX)
 COMPUTED_STYLE_PROP(scroll_snap_points_y,          ScrollSnapPointsY)
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -751,17 +751,16 @@ nsStyleXUL::CalcDifference(const nsStyle
 // --------------------
 // nsStyleColumn
 //
 /* static */ const uint32_t nsStyleColumn::kMaxColumnCount;
 
 nsStyleColumn::nsStyleColumn(const nsPresContext* 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)
   , mColumnSpan(NS_STYLE_COLUMN_SPAN_NONE)
   , mColumnRuleWidth((StaticPresData::Get()
                         ->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM])
   , mTwipsPerPixel(aContext->AppUnitsPerDevPixel())
 {
@@ -771,17 +770,16 @@ nsStyleColumn::nsStyleColumn(const nsPre
 nsStyleColumn::~nsStyleColumn()
 {
   MOZ_COUNT_DTOR(nsStyleColumn);
 }
 
 nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
   : mColumnCount(aSource.mColumnCount)
   , mColumnWidth(aSource.mColumnWidth)
-  , mColumnGap(aSource.mColumnGap)
   , mColumnRuleColor(aSource.mColumnRuleColor)
   , mColumnRuleStyle(aSource.mColumnRuleStyle)
   , mColumnFill(aSource.mColumnFill)
   , mColumnSpan(aSource.mColumnSpan)
   , mColumnRuleWidth(aSource.mColumnRuleWidth)
   , mTwipsPerPixel(aSource.mTwipsPerPixel)
 {
   MOZ_COUNT_CTOR(nsStyleColumn);
@@ -796,17 +794,16 @@ nsStyleColumn::CalcDifference(const nsSt
       mColumnSpan != aNewData.mColumnSpan) {
     // We force column count changes to do a reframe, because it's tricky to handle
     // some edge cases where the column count gets smaller and content overflows.
     // XXX not ideal
     return nsChangeHint_ReconstructFrame;
   }
 
   if (mColumnWidth != aNewData.mColumnWidth ||
-      mColumnGap != aNewData.mColumnGap ||
       mColumnFill != aNewData.mColumnFill) {
     return NS_STYLE_HINT_REFLOW;
   }
 
   if (GetComputedColumnRuleWidth() != aNewData.GetComputedColumnRuleWidth() ||
       mColumnRuleStyle != aNewData.mColumnRuleStyle ||
       mColumnRuleColor != aNewData.mColumnRuleColor) {
     return NS_STYLE_HINT_VISUAL;
@@ -1518,18 +1515,18 @@ nsStylePosition::nsStylePosition(const n
   , mJustifySelf(NS_STYLE_JUSTIFY_AUTO)
   , mFlexDirection(NS_STYLE_FLEX_DIRECTION_ROW)
   , mFlexWrap(NS_STYLE_FLEX_WRAP_NOWRAP)
   , mObjectFit(NS_STYLE_OBJECT_FIT_FILL)
   , mOrder(NS_STYLE_ORDER_INITIAL)
   , 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);
 
   // positioning values not inherited
 
   mObjectPosition.SetInitialPercentValues(0.5f);
 
   nsStyleCoord  autoCoord(eStyleUnit_Auto);
@@ -1582,18 +1579,18 @@ nsStylePosition::nsStylePosition(const n
   , mFlexGrow(aSource.mFlexGrow)
   , mFlexShrink(aSource.mFlexShrink)
   , mZIndex(aSource.mZIndex)
   , mGridTemplateAreas(aSource.mGridTemplateAreas)
   , mGridColumnStart(aSource.mGridColumnStart)
   , 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);
 
   if (aSource.mGridTemplateColumns) {
     mGridTemplateColumns =
       MakeUnique<nsStyleGridTemplate>(*aSource.mGridTemplateColumns);
   }
   if (aSource.mGridTemplateRows) {
@@ -1707,18 +1704,18 @@ nsStylePosition::CalcDifference(const ns
 
   // Properties that apply to grid items:
   // FIXME: only for grid items
   // (ie. parent frame is 'display: grid' or 'display: inline-grid')
   if (mGridColumnStart != aNewData.mGridColumnStart ||
       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;
   }
 
   // Changing 'justify-content/items/self' might affect the positioning,
   // but it won't affect any sizing.
   if (mJustifyContent != aNewData.mJustifyContent ||
       mJustifyItems != aNewData.mJustifyItems ||
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1502,18 +1502,18 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
 
   // nullptr for 'none'
   RefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
 
   nsStyleGridLine mGridColumnStart;
   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
   // want to work towards removing the physical methods, and using the logical
   // ones in all cases.
 
   bool WidthDependsOnContainer() const
     {
@@ -2926,17 +2926,16 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   /**
    * This is the maximum number of columns we can process. It's used in both
    * nsColumnSetFrame and nsRuleNode.
    */
   static const uint32_t kMaxColumnCount = 1000;
 
   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]
   uint8_t      mColumnFill;  // [reset] see nsStyleConsts.h
   uint8_t      mColumnSpan;  // [reset] see nsStyleConsts.h
 
   void SetColumnRuleWidth(nscoord aWidth) {
     mColumnRuleWidth = NS_ROUND_BORDER_TO_PIXELS(aWidth, mTwipsPerPixel);
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1700,34 +1700,16 @@ var gCSSProperties = {
   },
   "-moz-column-fill": {
     domProp: "MozColumnFill",
     inherited: false,
     type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     alias_for: "column-fill",
     subproperties: [ "column-fill" ]
   },
-  "column-gap": {
-    domProp: "columnGap",
-    inherited: false,
-    type: CSS_TYPE_LONGHAND,
-    initial_values: [ "normal" ],
-    other_values: [ "2px", "1em", "4em", "3%", "calc(3%)", "calc(1em - 3%)",
-      "calc(2px)",
-      "calc(-2px)",
-      "calc(0px)",
-      "calc(0pt)",
-      "calc(5em)",
-      "calc(-2em + 3em)",
-      "calc(3*25px)",
-      "calc(25px*3)",
-      "calc(3*25px + 5em)",
-    ],
-    invalid_values: [ "-3%", "-1px", "4" ]
-  },
   "-moz-column-gap": {
     domProp: "MozColumnGap",
     inherited: false,
     type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
     alias_for: "column-gap",
     subproperties: [ "column-gap" ]
   },
   "column-rule": {
@@ -7221,43 +7203,65 @@ gCSSProperties["grid-area"] = {
     "auto / auto",
     "auto / auto / auto",
     "auto / auto / auto / auto"
   ],
   other_values: gridAreaOtherValues,
   invalid_values: gridAreaInvalidValues
 };
 
-gCSSProperties["grid-column-gap"] = {
-  domProp: "gridColumnGap",
+gCSSProperties["column-gap"] = {
+  domProp: "columnGap",
   inherited: false,
   type: CSS_TYPE_LONGHAND,
-  initial_values: [ "0" ],
+  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_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" ],
+  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,
-  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" ]
+  alias_for: "gap",
+  subproperties: [ "column-gap", "row-gap" ],
 };
 
 if (IsCSSPropertyPrefEnabled("layout.css.contain.enabled")) {
   gCSSProperties["contain"] = {
     domProp: "contain",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "none" ],
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -68,18 +68,16 @@ var supported_properties = {
     "border-top-left-radius": [ test_radius_transition ],
     "border-top-right-radius": [ test_radius_transition ],
     "-moz-box-flex": [ test_float_zeroToOne_transition,
                        test_float_aboveOne_transition,
                        test_float_zeroToOne_clamped ],
     "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,
                            test_length_clamped ],
     "column-width": [ test_length_transition,
                       test_length_clamped ],
     "-moz-image-region": [ test_rect_transition ],
     "-moz-outline-radius-bottomleft": [ test_radius_transition ],
@@ -164,18 +162,18 @@ var supported_properties = {
                    test_length_percent_calc_transition,
                    test_length_clamped, test_percent_clamped ],
     "font-size-adjust": [ test_float_zeroToOne_transition,
                           test_float_aboveOne_transition,
                           /* FIXME: font-size-adjust treats zero specially */
                           /* test_float_zeroToOne_clamped */ ],
     "font-stretch": [ test_percent_transition, test_percent_clamped ],
     "font-weight": [ test_font_weight ],
-    "grid-column-gap": [ test_grid_gap ],
-    "grid-row-gap": [ test_grid_gap ],
+    "column-gap": [ test_grid_gap ],
+    "row-gap": [ test_grid_gap ],
     "height": [ test_length_transition, test_percent_transition,
                 test_length_percent_calc_transition,
                 test_length_clamped, test_percent_clamped ],
     "left": [ test_length_transition, test_percent_transition,
               test_length_percent_calc_transition,
               test_length_unclamped, test_percent_unclamped ],
     "letter-spacing": [ test_length_transition, test_length_unclamped ],
     "lighting-color": [ test_color_transition,