Bug 1251999 - [css-grid] Update <fixed-size> parsing to the latest spec. r=dholbert
authorMats Palmgren <mats@mozilla.com>
Wed, 02 Mar 2016 23:39:34 +0100
changeset 324777 bd98615e4b4b712b634c1cbdb7e71143e9015004
parent 324776 a46c9fc47597b83718b340d6430b4c927cd05d37
child 324778 9060d17ed51093ffe5ae5fe1b842e8a72a7c59a2
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1251999
milestone47.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 1251999 - [css-grid] Update <fixed-size> parsing to the latest spec. r=dholbert
layout/generic/nsGridContainerFrame.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.h
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -420,19 +420,18 @@ struct MOZ_STACK_CLASS nsGridContainerFr
     if (maxFill == NS_UNCONSTRAINEDSIZE && aMinSize == NS_UNCONSTRAINEDSIZE) {
       // "Otherwise, the specified track list repeats only once."
       return 1;
     }
     nscoord repeatTrackSize = 0;
     // Note that the repeat() track size is included in |sum| in this loop.
     nscoord sum = 0;
     for (uint32_t i = 0; i < numTracks; ++i) {
-      // "The <auto-repeat> variant ... requires definite minimum track sizes"
-      // "... treating each track as its max track sizing function if that is
-      //  definite or as its minimum track sizing function otherwise"
+      // "treating each track as its max track sizing function if that is
+      // definite or as its minimum track sizing function otherwise"
       // https://drafts.csswg.org/css-grid/#valdef-repeat-auto-fill
       const auto& maxCoord = mMaxSizingFunctions[i];
       const auto* coord = &maxCoord;
       if (!coord->IsCoordPercentCalcUnit()) {
         coord = &mMinSizingFunctions[i];
         if (!coord->IsCoordPercentCalcUnit()) {
           return 1;
         }
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -941,19 +941,17 @@ protected:
   // is considered the same as an empty list),
   // treat CSSParseResult::NotFound the same as CSSParseResult::Ok.
   //
   // If aValue is already a eCSSUnit_List, append to that list.
   CSSParseResult ParseGridLineNames(nsCSSValue& aValue);
   bool ParseGridLineNameListRepeat(nsCSSValueList** aTailPtr);
   bool ParseOptionalLineNameListAfterSubgrid(nsCSSValue& aValue);
 
-  // eFixedTrackSize in aFlags makes it parse a <fixed-breadth>.
-  CSSParseResult ParseGridTrackBreadth(nsCSSValue& aValue,
-    GridTrackSizeFlags aFlags = GridTrackSizeFlags::eDefaultTrackSize);
+  CSSParseResult ParseGridTrackBreadth(nsCSSValue& aValue);
   // eFixedTrackSize in aFlags makes it parse a <fixed-size>.
   CSSParseResult ParseGridTrackSize(nsCSSValue& aValue,
     GridTrackSizeFlags aFlags = GridTrackSizeFlags::eDefaultTrackSize);
 
   bool ParseGridAutoColumnsRows(nsCSSProperty aPropID);
   bool ParseGridTrackListRepeat(nsCSSValueList** aTailPtr);
   bool ParseGridTrackRepeatIntro(bool            aForSubgrid,
                                  int32_t*        aRepetitions,
@@ -8570,30 +8568,25 @@ CSSParserImpl::ParseOptionalLineNameList
       }
       item->mNext = new nsCSSValueList;
       item = item->mNext;
       item->mValue = lineNames;
     }
   }
 }
 
-// Parse a <track-breadth>, or <fixed-breadth> when aFlags has eFixedTrackSize.
 CSSParseResult
-CSSParserImpl::ParseGridTrackBreadth(nsCSSValue& aValue,
-                                     GridTrackSizeFlags aFlags)
-{
-  CSSParseResult result = (aFlags & GridTrackSizeFlags::eFixedTrackSize) ?
-      ParseNonNegativeVariant(aValue, VARIANT_LPCALC, nullptr) :
-      ParseNonNegativeVariant(aValue,
-                              VARIANT_AUTO | VARIANT_LPCALC | VARIANT_KEYWORD,
-                              nsCSSProps::kGridTrackBreadthKTable);
+CSSParserImpl::ParseGridTrackBreadth(nsCSSValue& aValue)
+{
+  CSSParseResult result = ParseNonNegativeVariant(aValue,
+                            VARIANT_AUTO | VARIANT_LPCALC | VARIANT_KEYWORD,
+                            nsCSSProps::kGridTrackBreadthKTable);
 
   if (result == CSSParseResult::Ok ||
-      result == CSSParseResult::Error ||
-      (aFlags & GridTrackSizeFlags::eFixedTrackSize)) {
+      result == CSSParseResult::Error) {
     return result;
   }
 
   // Attempt to parse <flex> (a dimension with the "fr" unit).
   if (!GetToken(true)) {
     return CSSParseResult::NotFound;
   }
   if (!(eCSSToken_Dimension == mToken.mType &&
@@ -8606,37 +8599,48 @@ CSSParserImpl::ParseGridTrackBreadth(nsC
   return CSSParseResult::Ok;
 }
 
 // Parse a <track-size>, or <fixed-size> when aFlags has eFixedTrackSize.
 CSSParseResult
 CSSParserImpl::ParseGridTrackSize(nsCSSValue& aValue,
                                   GridTrackSizeFlags aFlags)
 {
+  const bool requireFixedSize =
+    !!(aFlags & GridTrackSizeFlags::eFixedTrackSize);
   // Attempt to parse a single <track-breadth>.
-  CSSParseResult result = ParseGridTrackBreadth(aValue, aFlags);
+  CSSParseResult result = ParseGridTrackBreadth(aValue);
+  if (requireFixedSize && result == CSSParseResult::Ok &&
+      !aValue.IsLengthPercentCalcUnit()) {
+    result = CSSParseResult::Error;
+  }
   if (result == CSSParseResult::Ok ||
       result == CSSParseResult::Error) {
     return result;
   }
 
   // Attempt to parse a minmax() function.
   if (!GetToken(true)) {
     return CSSParseResult::NotFound;
   }
   if (!(eCSSToken_Function == mToken.mType &&
         mToken.mIdent.LowerCaseEqualsLiteral("minmax"))) {
     UngetToken();
     return CSSParseResult::NotFound;
   }
   nsCSSValue::Array* func = aValue.InitFunction(eCSSKeyword_minmax, 2);
-  if (ParseGridTrackBreadth(func->Item(1), aFlags) == CSSParseResult::Ok &&
+  if (ParseGridTrackBreadth(func->Item(1)) == CSSParseResult::Ok &&
       ExpectSymbol(',', true) &&
-      ParseGridTrackBreadth(func->Item(2), aFlags) == CSSParseResult::Ok &&
+      ParseGridTrackBreadth(func->Item(2)) == CSSParseResult::Ok &&
       ExpectSymbol(')', true)) {
+    if (requireFixedSize &&
+        !func->Item(1).IsLengthPercentCalcUnit() &&
+        !func->Item(2).IsLengthPercentCalcUnit()) {
+      return CSSParseResult::Error;
+    }
     return CSSParseResult::Ok;
   }
   SkipUntil(')');
   return CSSParseResult::Error;
 }
 
 bool
 CSSParserImpl::ParseGridAutoColumnsRows(nsCSSProperty aPropID)
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -441,16 +441,18 @@ public:
    * it to |aResult|.
    */
   void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
                       Serialization aValueSerialization) const;
 
   nsCSSUnit GetUnit() const { return mUnit; }
   bool      IsLengthUnit() const
     { return eCSSUnit_PhysicalMillimeter <= mUnit && mUnit <= eCSSUnit_Pixel; }
+  bool      IsLengthPercentCalcUnit() const
+    { return IsLengthUnit() || mUnit == eCSSUnit_Percent || IsCalcUnit(); }
   /**
    * A "fixed" length unit is one that means a specific physical length
    * which we try to match based on the physical characteristics of an
    * output device.
    */
   bool      IsFixedLengthUnit() const  
     { return mUnit == eCSSUnit_PhysicalMillimeter; }
   /**