Bug 1063162 part 1 - Add auto value support to StyleComplexColor. r?birtles
MozReview-Commit-ID: E6EFICyY3dh
--- 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);