--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -1272,20 +1272,35 @@ DiluteColor(const nsCSSValue& aValue, do
double factor = 1.0 / Aresf;
aResult.SetColorValue(
NS_RGBA(ClampColor(R * aDilutionRatio * factor),
ClampColor(G * aDilutionRatio * factor),
ClampColor(B * aDilutionRatio * factor),
NSToIntRound(Aresf * 255.0)));
}
-static bool
-AddShadowItems(double aCoeff1, const nsCSSValue &aValue1,
- double aCoeff2, const nsCSSValue &aValue2,
- nsCSSValueList **&aResultTail)
+void
+AppendToCSSValueList(UniquePtr<nsCSSValueList>& aHead,
+ UniquePtr<nsCSSValueList>&& aValueToAppend,
+ nsCSSValueList** aTail)
+{
+ MOZ_ASSERT(!aHead == !*aTail,
+ "Can't have head w/o tail, & vice versa");
+
+ if (!aHead) {
+ aHead = Move(aValueToAppend);
+ *aTail = aHead.get();
+ } else {
+ (*aTail) = (*aTail)->mNext = aValueToAppend.release();
+ }
+}
+
+static UniquePtr<nsCSSValueList>
+AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1,
+ double aCoeff2, const nsCSSValue &aValue2)
{
// X, Y, Radius, Spread, Color, Inset
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Array,
"wrong unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Array,
"wrong unit");
nsCSSValue::Array *array1 = aValue1.GetArrayValue();
nsCSSValue::Array *array2 = aValue2.GetArrayValue();
@@ -1304,37 +1319,35 @@ AddShadowItems(double aCoeff1, const nsC
const nsCSSValue& inset2 = array2->Item(5);
if ((color1.GetUnit() != color2.GetUnit() &&
(!color1.IsNumericColorUnit() || !color2.IsNumericColorUnit())) ||
inset1.GetUnit() != inset2.GetUnit()) {
// We don't know how to animate between color and no-color, or
// between inset and not-inset.
// NOTE: In case when both colors' units are eCSSUnit_Null, that means
// neither color value was specified, so we can interpolate.
- return false;
+ return nullptr;
}
if (color1.GetUnit() != eCSSUnit_Null) {
if (aCoeff2 == 0.0 && aCoeff1 != 1.0) {
DiluteColor(color1, aCoeff1, resultArray->Item(4));
} else {
AddWeightedColors(aCoeff1, color1, aCoeff2, color2,
ColorAdditionType::Clamped,
resultArray->Item(4));
}
}
MOZ_ASSERT(inset1 == inset2, "should match");
resultArray->Item(5) = inset1;
- nsCSSValueList *resultItem = new nsCSSValueList;
+ auto resultItem = MakeUnique<nsCSSValueList>();
resultItem->mValue.SetArrayValue(resultArray, eCSSUnit_Array);
- *aResultTail = resultItem;
- aResultTail = &resultItem->mNext;
- return true;
+ return resultItem;
}
static void
AddTransformTranslate(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Percent ||
@@ -1853,28 +1866,26 @@ AddFilterFunctionImpl(double aCoeff1, co
initialVal);
break;
case eCSSKeyword_hue_rotate:
AddCSSValueAngle(aCoeff1, funcArg1,
aCoeff2, funcArg2,
resultArg);
break;
case eCSSKeyword_drop_shadow: {
- nsCSSValueList* resultShadow = resultArg.SetListValue();
- nsAutoPtr<nsCSSValueList> shadowValue;
- nsCSSValueList **shadowTail = getter_Transfers(shadowValue);
MOZ_ASSERT(!funcArg1.GetListValue()->mNext &&
!funcArg2.GetListValue()->mNext,
"drop-shadow filter func doesn't support lists");
- if (!AddShadowItems(aCoeff1, funcArg1.GetListValue()->mValue,
- aCoeff2, funcArg2.GetListValue()->mValue,
- shadowTail)) {
+ UniquePtr<nsCSSValueList> shadowValue =
+ AddWeightedShadowItems(aCoeff1, funcArg1.GetListValue()->mValue,
+ aCoeff2, funcArg2.GetListValue()->mValue);
+ if (!shadowValue) {
return false;
}
- *resultShadow = *shadowValue;
+ resultArg.AdoptListValue(Move(shadowValue));
break;
}
default:
MOZ_ASSERT(false, "unknown filter function");
return false;
}
*aResultTail = resultListEntry.forget();
@@ -2659,52 +2670,56 @@ StyleAnimationValue::AddWeighted(nsCSSPr
}
case eUnit_Shadow: {
// This is implemented according to:
// http://dev.w3.org/csswg/css3-transitions/#animation-of-property-types-
// and the third item in the summary of:
// http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html
const nsCSSValueList *shadow1 = aValue1.GetCSSValueListValue();
const nsCSSValueList *shadow2 = aValue2.GetCSSValueListValue();
- nsAutoPtr<nsCSSValueList> result;
- nsCSSValueList **resultTail = getter_Transfers(result);
+ UniquePtr<nsCSSValueList> result;
+ nsCSSValueList* tail = nullptr;
while (shadow1 && shadow2) {
- if (!AddShadowItems(aCoeff1, shadow1->mValue,
- aCoeff2, shadow2->mValue,
- resultTail)) {
+ UniquePtr<nsCSSValueList> shadowValue =
+ AddWeightedShadowItems(aCoeff1, shadow1->mValue,
+ aCoeff2, shadow2->mValue);
+ if (!shadowValue) {
return false;
}
shadow1 = shadow1->mNext;
shadow2 = shadow2->mNext;
+ AppendToCSSValueList(result, Move(shadowValue), &tail);
}
if (shadow1 || shadow2) {
const nsCSSValueList *longShadow;
double longCoeff;
if (shadow1) {
longShadow = shadow1;
longCoeff = aCoeff1;
} else {
longShadow = shadow2;
longCoeff = aCoeff2;
}
while (longShadow) {
// Passing coefficients that add to less than 1 produces the
// desired result of interpolating "0 0 0 transparent" with
// the current shadow.
- if (!AddShadowItems(longCoeff, longShadow->mValue,
- 0.0, longShadow->mValue,
- resultTail)) {
+ UniquePtr<nsCSSValueList> shadowValue =
+ AddWeightedShadowItems(longCoeff, longShadow->mValue,
+ 0.0, longShadow->mValue);
+ if (!shadowValue) {
return false;
}
longShadow = longShadow->mNext;
+ AppendToCSSValueList(result, Move(shadowValue), &tail);
}
}
- aResultValue.SetAndAdoptCSSValueListValue(result.forget(), eUnit_Shadow);
+ aResultValue.SetAndAdoptCSSValueListValue(result.release(), eUnit_Shadow);
return true;
}
case eUnit_Shape: {
RefPtr<nsCSSValue::Array> result =
AddShapeFunction(aProperty,
aCoeff1, aValue1.GetCSSValueArrayValue(),
aCoeff2, aValue2.GetCSSValueArrayValue());
if (!result) {