Bug 1210575 part 3: Refactor CSS gradient-parsing code to use a flags bitfield instead of multiple bool args for customizing behavior. r=heycam
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 07 Oct 2015 11:02:50 -0700
changeset 266570 d7c82707060bb75e595a85203e94cd7dba4e9e88
parent 266569 b2cc761bf9f7cdef670cc828eda559dbb8f987e7
child 266571 73d17d930b759852b5104e713ab21841d2b07d29
push id66234
push userdholbert@mozilla.com
push dateWed, 07 Oct 2015 18:04:06 +0000
treeherdermozilla-inbound@73d17d930b75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1210575
milestone44.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 1210575 part 3: Refactor CSS gradient-parsing code to use a flags bitfield instead of multiple bool args for customizing behavior. r=heycam
layout/style/nsCSSParser.cpp
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -1102,20 +1102,23 @@ protected:
   bool ParseSymbols(nsCSSValue& aValue);
   bool SetValueToURL(nsCSSValue& aValue, const nsString& aURL);
   bool TranslateDimension(nsCSSValue& aValue, int32_t aVariantMask,
                             float aNumber, const nsString& aUnit);
   bool ParseImageOrientation(nsCSSValue& aAngle);
   bool ParseImageRect(nsCSSValue& aImage);
   bool ParseElement(nsCSSValue& aValue);
   bool ParseColorStop(nsCSSValueGradient* aGradient);
-  bool ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating,
-                           bool aIsLegacy);
-  bool ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating,
-                           bool aIsLegacy);
+
+  enum GradientParsingFlags {
+    eGradient_Repeating    = 1 << 0, // repeating-{linear|radial}-gradient
+    eGradient_MozLegacy    = 1 << 1, // -moz-{linear|radial}-gradient
+  };
+  bool ParseLinearGradient(nsCSSValue& aValue, uint8_t aFlags);
+  bool ParseRadialGradient(nsCSSValue& aValue, uint8_t aFlags);
   bool IsLegacyGradientLine(const nsCSSTokenType& aType,
                             const nsString& aId);
   bool ParseGradientColorStops(nsCSSValueGradient* aGradient,
                                nsCSSValue& aValue);
 
   void SetParsingCompoundProperty(bool aBool) {
     mParsingCompoundProperty = aBool;
   }
@@ -6808,20 +6811,20 @@ CSSParserImpl::ParseWebkitPrefixedGradie
   // about to put into the CSS parser is a faithful representation of what it
   // would've seen if it were just parsing the original input stream):
   if (gotCloseParen) {
     unprefixedFuncBody.Append(char16_t(')'));
   }
 
   nsAutoScannerChanger scannerChanger(this, unprefixedFuncBody);
   if (unprefixedFuncName.EqualsLiteral("linear-gradient")) {
-    return ParseLinearGradient(aValue, false, false);
+    return ParseLinearGradient(aValue, 0);
   }
   if (unprefixedFuncName.EqualsLiteral("radial-gradient")) {
-    return ParseRadialGradient(aValue, false, false);
+    return ParseRadialGradient(aValue, 0);
   }
 
   NS_ERROR("CSSUnprefixingService returned an unrecognized type of "
            "gradient function");
 
   return false;
 }
 
@@ -7444,36 +7447,35 @@ CSSParserImpl::ParseVariant(nsCSSValue& 
       eCSSToken_URL == tk->mType) {
     SetValueToURL(aValue, tk->mIdent);
     return true;
   }
   if ((aVariantMask & VARIANT_GRADIENT) != 0 &&
       eCSSToken_Function == tk->mType) {
     // a generated gradient
     nsDependentString tmp(tk->mIdent, 0);
-    bool isLegacy = false;
+    uint8_t gradientFlags = 0;
     if (sMozGradientsEnabled &&
         StringBeginsWith(tmp, NS_LITERAL_STRING("-moz-"))) {
       tmp.Rebind(tmp, 5);
-      isLegacy = true;
-    }
-    bool isRepeating = false;
+      gradientFlags |= eGradient_MozLegacy;
+    }
     if (StringBeginsWith(tmp, NS_LITERAL_STRING("repeating-"))) {
       tmp.Rebind(tmp, 10);
-      isRepeating = true;
+      gradientFlags |= eGradient_Repeating;
     }
 
     if (tmp.LowerCaseEqualsLiteral("linear-gradient")) {
-      return ParseLinearGradient(aValue, isRepeating, isLegacy);
+      return ParseLinearGradient(aValue, gradientFlags);
     }
     if (tmp.LowerCaseEqualsLiteral("radial-gradient")) {
-      return ParseRadialGradient(aValue, isRepeating, isLegacy);
+      return ParseRadialGradient(aValue, gradientFlags);
     }
     if (ShouldUseUnprefixingService() &&
-        !isRepeating && !isLegacy &&
+        !gradientFlags &&
         StringBeginsWith(tmp, NS_LITERAL_STRING("-webkit-"))) {
       // Copy 'tmp' into a string on the stack, since as soon as we
       // start parsing, its backing store (in "tk") will be overwritten
       nsAutoString prefixedFuncName(tmp);
       return ParseWebkitPrefixedGradientWithService(prefixedFuncName, aValue);
     }
   }
   if ((aVariantMask & VARIANT_IMAGE_RECT) != 0 &&
@@ -9243,21 +9245,21 @@ CSSParserImpl::ParseColorStop(nsCSSValue
 // <legacy-gradient-line> : [ <position> || <angle>] ,
 //
 // <legacy-shape-size> : [ <shape> || <legacy-size> ] ,
 // <legacy-size> : closest-side | closest-corner | farthest-side
 //               | farthest-corner | contain | cover
 //
 // <color-stops> : <color-stop> , <color-stop> [, <color-stop>]*
 bool
-CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue, bool aIsRepeating,
-                                   bool aIsLegacy)
+CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue,
+                                   uint8_t aFlags)
 {
   nsRefPtr<nsCSSValueGradient> cssGradient
-    = new nsCSSValueGradient(false, aIsRepeating);
+    = new nsCSSValueGradient(false, aFlags & eGradient_Repeating);
 
   if (!GetToken(true)) {
     return false;
   }
 
   if (mToken.mType == eCSSToken_Ident &&
       mToken.mIdent.LowerCaseEqualsLiteral("to")) {
 
@@ -9285,17 +9287,17 @@ CSSParserImpl::ParseLinearGradient(nsCSS
     if (!ExpectSymbol(',', true)) {
       SkipUntil(')');
       return false;
     }
 
     return ParseGradientColorStops(cssGradient, aValue);
   }
 
-  if (!aIsLegacy) {
+  if (!(aFlags & eGradient_MozLegacy)) {
     UngetToken();
 
     // <angle> ,
     if (ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) &&
         !ExpectSymbol(',', true)) {
       SkipUntil(')');
       return false;
     }
@@ -9333,38 +9335,38 @@ CSSParserImpl::ParseLinearGradient(nsCSS
       }
     }
   }
 
   return ParseGradientColorStops(cssGradient, aValue);
 }
 
 bool
-CSSParserImpl::ParseRadialGradient(nsCSSValue& aValue, bool aIsRepeating,
-                                   bool aIsLegacy)
+CSSParserImpl::ParseRadialGradient(nsCSSValue& aValue,
+                                   uint8_t aFlags)
 {
   nsRefPtr<nsCSSValueGradient> cssGradient
-    = new nsCSSValueGradient(true, aIsRepeating);
+    = new nsCSSValueGradient(true, aFlags & eGradient_Repeating);
 
   // [ <shape> || <size> ]
   bool haveShape =
     ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
                  nsCSSProps::kRadialGradientShapeKTable);
 
   bool haveSize = ParseVariant(cssGradient->GetRadialSize(), VARIANT_KEYWORD,
-                               aIsLegacy ?
+                               (aFlags & eGradient_MozLegacy) ?
                                nsCSSProps::kRadialGradientLegacySizeKTable :
                                nsCSSProps::kRadialGradientSizeKTable);
   if (haveSize) {
     if (!haveShape) {
       // <size> <shape>
       haveShape = ParseVariant(cssGradient->GetRadialShape(), VARIANT_KEYWORD,
                                nsCSSProps::kRadialGradientShapeKTable);
     }
-  } else if (!aIsLegacy) {
+  } else if (!(aFlags & eGradient_MozLegacy)) {
     // Save RadialShape before parsing RadiusX because RadialShape and
     // RadiusX share the storage.
     int32_t shape =
       cssGradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated ?
       cssGradient->GetRadialShape().GetIntValue() : -1;
     // <length> | [<length> | <percentage>]{2}
     cssGradient->mIsExplicitSize = true;
     haveSize =
@@ -9405,17 +9407,17 @@ CSSParserImpl::ParseRadialGradient(nsCSS
     // [ <shape> || <size> ] ,
     return ParseGradientColorStops(cssGradient, aValue);
   }
 
   if (!GetToken(true)) {
     return false;
   }
 
-  if (!aIsLegacy) {
+  if (!(aFlags & eGradient_MozLegacy)) {
     if (mToken.mType == eCSSToken_Ident &&
         mToken.mIdent.LowerCaseEqualsLiteral("at")) {
       // [ <shape> || <size> ]? at <position> ,
       if (!ParseBoxPositionValues(cssGradient->mBgPos, false) ||
           !ExpectSymbol(',', true)) {
         SkipUntil(')');
         return false;
       }