Bug 1378368 - part1: do not always clamp negative calc values in SetCssTextToCoord. draft
authorJeremy Chen <jeremychen@mozilla.com>
Mon, 16 Oct 2017 13:29:46 +0800
changeset 680720 3089481921e9d615f535e644ed010781a6a8af70
parent 680630 2ba9ba4fa63b942d8d9401f6ff6e40f5730adcd1
child 680721 b1135eece4e243c6e81efcb7f4d78e0069758186
push id84597
push userbmo:jeremychen@mozilla.com
push dateMon, 16 Oct 2017 06:52:33 +0000
bugs1378368
milestone58.0a1
Bug 1378368 - part1: do not always clamp negative calc values in SetCssTextToCoord. nsComputedDOMStyle::SetCssTextToCoord() is a helper function for computing and serializing a nsStyleCoord. In the current implementation, SetCssTextToCoord implicitly clamp negative calc values, which is pretty non-trivial. In this patch, we expose an extra aClampNegativeCalc parameter for SetCssTextToCoord, so the callers can explicitly set the clamping mode as needed. MozReview-Commit-ID: IOIhssjUldC
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3611,17 +3611,17 @@ nsComputedDOMStyle::DoGetScrollSnapTypeY
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::GetScrollSnapPoints(const nsStyleCoord& aCoord)
 {
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
   if (aCoord.GetUnit() == eStyleUnit_None) {
     val->SetIdent(eCSSKeyword_none);
   } else {
     nsAutoString argumentString;
-    SetCssTextToCoord(argumentString, aCoord);
+    SetCssTextToCoord(argumentString, aCoord, true);
     nsAutoString tmp;
     tmp.AppendLiteral("repeat(");
     tmp.Append(argumentString);
     tmp.Append(')');
     val->SetString(tmp);
   }
   return val.forget();
 }
@@ -6305,20 +6305,20 @@ nsComputedDOMStyle::DoGetStopColor()
 }
 
 void
 nsComputedDOMStyle::BoxValuesToString(nsAString& aString,
                                       const nsTArray<nsStyleCoord>& aBoxValues)
 {
   MOZ_ASSERT(aBoxValues.Length() == 4, "wrong number of box values");
   nsAutoString value1, value2, value3, value4;
-  SetCssTextToCoord(value1, aBoxValues[0]);
-  SetCssTextToCoord(value2, aBoxValues[1]);
-  SetCssTextToCoord(value3, aBoxValues[2]);
-  SetCssTextToCoord(value4, aBoxValues[3]);
+  SetCssTextToCoord(value1, aBoxValues[0], true);
+  SetCssTextToCoord(value2, aBoxValues[1], true);
+  SetCssTextToCoord(value3, aBoxValues[2], true);
+  SetCssTextToCoord(value4, aBoxValues[3], true);
 
   // nsROCSSPrimitiveValue do not have binary comparison operators.
   // Compare string results instead.
   aString.Append(value1);
   if (value1 != value2 || value1 != value3 || value1 != value4) {
     aString.Append(' ');
     aString.Append(value2);
     if (value1 != value3 || value2 != value4) {
@@ -6376,21 +6376,23 @@ nsComputedDOMStyle::CreatePrimitiveValue
       }
       for (size_t i = 0;
            i < aStyleBasicShape->Coordinates().Length(); i += 2) {
         nsAutoString coordString;
         if (i > 0 || hasEvenOdd) {
           shapeFunctionString.AppendLiteral(", ");
         }
         SetCssTextToCoord(coordString,
-                          aStyleBasicShape->Coordinates()[i]);
+                          aStyleBasicShape->Coordinates()[i],
+                          true);
         shapeFunctionString.Append(coordString);
         shapeFunctionString.Append(' ');
         SetCssTextToCoord(coordString,
-                          aStyleBasicShape->Coordinates()[i + 1]);
+                          aStyleBasicShape->Coordinates()[i + 1],
+                          true);
         shapeFunctionString.Append(coordString);
       }
       break;
     }
     case StyleBasicShapeType::Circle:
     case StyleBasicShapeType::Ellipse: {
       const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
       MOZ_ASSERT(radii.Length() ==
@@ -6499,21 +6501,21 @@ already_AddRefed<CSSValue>
 nsComputedDOMStyle::DoGetShapeOutside()
 {
   return GetShapeSource(StyleDisplay()->mShapeOutside,
                         nsCSSProps::kShapeOutsideShapeBoxKTable);
 }
 
 void
 nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
-                                      const nsStyleCoord& aCoord)
+                                      const nsStyleCoord& aCoord,
+                                      bool aClampNegativeCalc)
 {
   RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
-  bool clampNegativeCalc = true;
-  SetValueToCoord(value, aCoord, clampNegativeCalc);
+  SetValueToCoord(value, aCoord, aClampNegativeCalc);
   value->GetCssText(aCssText);
 }
 
 already_AddRefed<CSSValue>
 nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter(
   const nsStyleFilter& aStyleFilter)
 {
   RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
@@ -6539,17 +6541,17 @@ nsComputedDOMStyle::CreatePrimitiveValue
     RefPtr<CSSValue> shadowValue =
       GetCSSShadowArray(aStyleFilter.GetDropShadow(),
                         StyleColor()->mColor,
                         false);
     ErrorResult dummy;
     shadowValue->GetCssText(argumentString, dummy);
   } else {
     // Filter function argument.
-    SetCssTextToCoord(argumentString, aStyleFilter.GetFilterParameter());
+    SetCssTextToCoord(argumentString, aStyleFilter.GetFilterParameter(), true);
   }
   filterFunctionString.Append(argumentString);
 
   // Filter function closing parenthesis.
   filterFunctionString.Append(')');
 
   value->SetString(filterFunctionString);
   return value.forget();
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -687,18 +687,19 @@ private:
   bool GetCBContentHeight(nscoord& aWidth);
   bool GetScrollFrameContentWidth(nscoord& aWidth);
   bool GetScrollFrameContentHeight(nscoord& aHeight);
   bool GetFrameBoundsWidthForTransform(nscoord &aWidth);
   bool GetFrameBoundsHeightForTransform(nscoord &aHeight);
   bool GetFrameBorderRectWidth(nscoord& aWidth);
   bool GetFrameBorderRectHeight(nscoord& aHeight);
 
-  /* Helper functions for computing the filter property style. */
-  void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord);
+  /* Helper functions for computing and serializing a nsStyleCoord. */
+  void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord,
+                         bool aClampNegativeCalc);
   already_AddRefed<CSSValue> CreatePrimitiveValueForStyleFilter(
     const nsStyleFilter& aStyleFilter);
 
   already_AddRefed<CSSValue>
   GetShapeSource(const mozilla::StyleShapeSource& aShapeSource,
                  const KTableEntry aBoxKeywordTable[]);
 
   template<typename ReferenceBox>