Bug 1063162 part 1 - Add auto value support to StyleComplexColor. r?birtles draft
authorXidorn Quan <me@upsuper.org>
Thu, 22 Dec 2016 11:03:37 +1100
changeset 452830 dfd8876b734c4656f2990b448d153500105dfeb2
parent 447449 bd9e81439725f3d4135652cc3d65f2bfba527b7b
child 452831 28ef6f162b98740b61953b06996f2f06ad9919b2
child 453832 83f322618ba47c366eb29afb1159f0505a172a50
push id39516
push usermozilla@upsuper.org
push dateThu, 22 Dec 2016 10:59:24 +0000
reviewersbirtles
bugs1063162
milestone53.0a1
Bug 1063162 part 1 - Add auto value support to StyleComplexColor. r?birtles MozReview-Commit-ID: E6EFICyY3dh
layout/style/StyleAnimationValue.cpp
layout/style/StyleComplexColor.h
layout/style/nsRuleNode.cpp
layout/style/test/test_transitions_per_property.html
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -4630,18 +4630,22 @@ StyleAnimationValue::ExtractComputedValu
         aComputedValue.SetNoneValue();
       }
       return true;
     case eStyleAnimType_Color:
       aComputedValue.SetColorValue(
         StyleDataAtOffset<nscolor>(styleStruct, ssOffset));
       return true;
     case eStyleAnimType_ComplexColor: {
-      aComputedValue.SetComplexColorValue(
-        StyleDataAtOffset<StyleComplexColor>(styleStruct, ssOffset));
+      auto& color = StyleDataAtOffset<StyleComplexColor>(styleStruct, ssOffset);
+      if (color.mIsAuto) {
+        aComputedValue.SetAutoValue();
+      } else {
+        aComputedValue.SetComplexColorValue(color);
+      }
       return true;
     }
     case eStyleAnimType_PaintServer: {
       const nsStyleSVGPaint& paint =
         StyleDataAtOffset<nsStyleSVGPaint>(styleStruct, ssOffset);
       switch (paint.Type()) {
         case eStyleSVGPaintType_Color:
           aComputedValue.SetColorValue(paint.GetColor());
@@ -4948,17 +4952,19 @@ StyleAnimationValue::SetCurrentColorValu
 {
   FreeValue();
   mUnit = eUnit_CurrentColor;
 }
 
 void
 StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aColor)
 {
-  if (aColor.IsCurrentColor()) {
+  if (aColor.mIsAuto) {
+    SetAutoValue();
+  } else if (aColor.IsCurrentColor()) {
     SetCurrentColorValue();
   } else if (aColor.IsNumericColor()) {
     SetColorValue(aColor.mColor);
   } else {
     SetComplexColorValue(do_AddRef(new ComplexColorValue(aColor)));
   }
 }
 
--- a/layout/style/StyleComplexColor.h
+++ b/layout/style/StyleComplexColor.h
@@ -19,26 +19,39 @@ namespace mozilla {
  * Conceptually, the formula is "color * (1 - p) + currentcolor * p"
  * where p is mForegroundRatio. See mozilla::LinearBlendColors for
  * the actual algorithm.
  */
 struct StyleComplexColor
 {
   nscolor mColor;
   uint8_t mForegroundRatio;
+  // Whether the complex color represents a computed-value time auto
+  // value. This is only a flag indicating that this value should not
+  // be interpolatable with other colors, while other fields still
+  // represents the actual used color of this value.
+  bool mIsAuto;
 
-  static StyleComplexColor FromColor(nscolor aColor) { return {aColor, 0}; }
-  static StyleComplexColor CurrentColor() { return {NS_RGBA(0, 0, 0, 0), 255}; }
+  static StyleComplexColor FromColor(nscolor aColor) {
+    return {aColor, 0, false};
+  }
+  static StyleComplexColor CurrentColor() {
+    return {NS_RGBA(0, 0, 0, 0), 255, false};
+  }
+  static StyleComplexColor Auto() {
+    return {NS_RGBA(0, 0, 0, 0), 255, true};
+  }
 
   bool IsNumericColor() const { return mForegroundRatio == 0; }
   bool IsCurrentColor() const { return mForegroundRatio == 255; }
 
   bool operator==(const StyleComplexColor& aOther) const {
     return mForegroundRatio == aOther.mForegroundRatio &&
-           (IsCurrentColor() || mColor == aOther.mColor);
+           (IsCurrentColor() || mColor == aOther.mColor) &&
+           mIsAuto == aOther.mIsAuto;
   }
   bool operator!=(const StyleComplexColor& aOther) const {
     return !(*this == aOther);
   }
 };
 
 }
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1132,22 +1132,23 @@ SetComplexColor(const nsCSSValue& aValue
     aConditions.SetUncacheable();
     aResult = aParentColor;
   } else if (unit == eCSSUnit_EnumColor &&
              aValue.GetIntValue() == NS_COLOR_CURRENTCOLOR) {
     aResult = StyleComplexColor::CurrentColor();
   } else if (unit == eCSSUnit_ComplexColor) {
     aResult = aValue.GetStyleComplexColorValue();
   } else {
+    nscolor resultColor;
     if (!SetColor(aValue, aParentColor.mColor, aPresContext,
-                  nullptr, aResult.mColor, aConditions)) {
+                  nullptr, resultColor, aConditions)) {
       MOZ_ASSERT_UNREACHABLE("Unknown color value");
       return;
     }
-    aResult.mForegroundRatio = 0;
+    aResult = StyleComplexColor::FromColor(resultColor);
   }
 }
 
 template<UnsetAction UnsetTo>
 static Maybe<nscoord>
 ComputeLineWidthValue(const nsCSSValue& aValue,
                       const nscoord aParentCoord,
                       const nscoord aInitialCoord,
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -1372,16 +1372,31 @@ function test_true_currentcolor_transiti
      msg_prefix + "interpolation of rgba color and currentcolor");
 
   // It is not possible to check distance, because there is a hidden
   // dimension for ratio of currentcolor.
 
   div.style.removeProperty("color");
 }
 
+function test_auto_color_transition(prop, get_color=(x => x), is_shorthand=false) {
+  const msg_prefix = `color-valued property ${prop}: `;
+  const test_color = "rgb(51, 102, 153)";
+  div.style.setProperty("transition-property", "none", "");
+  div.style.setProperty(prop, "auto", "");
+  let used_value_of_auto = get_color(cs.getPropertyValue(prop));
+  isnot(used_value_of_auto, test_color,
+        msg_prefix + "ensure used auto value is different than our test color");
+
+  div.style.setProperty("transition-property", prop, "");
+  div.style.setProperty(prop, test_color, "");
+  is(get_color(cs.getPropertyValue(prop)), test_color,
+     msg_prefix + "not interpolatable between auto and rgb color");
+}
+
 function get_color_from_shorthand_value(value) {
   var m = value.match(/rgba?\([^, ]*, [^, ]*, [^, ]*(?:, [^, ]*)?\)/);
   isnot(m, null, "shorthand property value should contain color");
   return m[0];
 }
 
 function test_color_shorthand_transition(prop) {
   test_color_transition(prop, get_color_from_shorthand_value, true);