Bug 1302949 - Skip invalid animation values; r=heycam
For animation values parsed using the Servo backend that are invalid,
we simply end up with an empty declaration block (and we fill in |mValue|
with the string so we can later serialize it).
MozReview-Commit-ID: 6ruwJGVzRla
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -312,18 +312,22 @@ public:
// ------------------------------------------------------------------
//
// Inlined helper methods
//
// ------------------------------------------------------------------
inline bool
-IsInvalidValuePair(const PropertyValuePair& aPair)
+IsInvalidValuePair(const PropertyValuePair& aPair, StyleBackendType aBackend)
{
+ if (aBackend == StyleBackendType::Servo) {
+ return !aPair.mServoDeclarationBlock;
+ }
+
// There are three types of values we store as token streams:
//
// * Shorthand values (where we manually extract the token stream's string
// value) and pass that along to various parsing methods
// * Longhand values with variable references
// * Invalid values
//
// We can distinguish between the last two cases because for invalid values
@@ -584,25 +588,32 @@ KeyframeUtils::ApplyDistributeSpacing(ns
/* static */ nsTArray<ComputedKeyframeValues>
KeyframeUtils::GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
MOZ_ASSERT(aElement);
+ StyleBackendType styleBackend = aElement->OwnerDoc()->GetStyleBackendType();
+
const size_t len = aKeyframes.Length();
nsTArray<ComputedKeyframeValues> result(len);
for (const Keyframe& frame : aKeyframes) {
nsCSSPropertyIDSet propertiesOnThisKeyframe;
ComputedKeyframeValues* computedValues = result.AppendElement();
for (const PropertyValuePair& pair :
PropertyPriorityIterator(frame.mPropertyValues)) {
- if (IsInvalidValuePair(pair)) {
+ MOZ_ASSERT(!pair.mServoDeclarationBlock ||
+ styleBackend == StyleBackendType::Servo,
+ "Animation values were parsed using Servo backend but target"
+ " element is not using Servo backend?");
+
+ if (IsInvalidValuePair(pair, styleBackend)) {
continue;
}
// Expand each value into the set of longhands and produce
// a KeyframeValueEntry for each value.
nsTArray<PropertyStyleAnimationValuePair> values;
// For shorthands, we store the string as a token stream so we need to
@@ -1339,42 +1350,52 @@ RequiresAdditiveAnimation(const nsTArray
properties.AddProperty(aProperty);
if (aOffset == 0.0) {
propertiesWithFromValue.AddProperty(aProperty);
} else if (aOffset == 1.0) {
propertiesWithToValue.AddProperty(aProperty);
}
};
+ StyleBackendType styleBackend = aDocument->GetStyleBackendType();
+
for (size_t i = 0, len = aKeyframes.Length(); i < len; i++) {
const Keyframe& frame = aKeyframes[i];
// We won't have called ApplySpacing when this is called so
// we can't use frame.mComputedOffset. Instead we do a rough version
// of that algorithm that substitutes null offsets with 0.0 for the first
// frame, 1.0 for the last frame, and 0.5 for everything else.
double computedOffset = i == len - 1
? 1.0
: i == 0 ? 0.0 : 0.5;
double offsetToUse = frame.mOffset
? frame.mOffset.value()
: computedOffset;
for (const PropertyValuePair& pair : frame.mPropertyValues) {
- if (IsInvalidValuePair(pair)) {
+ if (IsInvalidValuePair(pair, styleBackend)) {
continue;
}
if (nsCSSProps::IsShorthand(pair.mProperty)) {
- nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
- nsCSSParser parser(aDocument->CSSLoader());
- if (!parser.IsValueValidForProperty(pair.mProperty,
- tokenStream->mTokenStream)) {
- continue;
+ if (styleBackend == StyleBackendType::Gecko) {
+ nsCSSValueTokenStream* tokenStream =
+ pair.mValue.GetTokenStreamValue();
+ nsCSSParser parser(aDocument->CSSLoader());
+ if (!parser.IsValueValidForProperty(pair.mProperty,
+ tokenStream->mTokenStream)) {
+ continue;
+ }
}
+ // For the Servo backend, invalid shorthand values are represented by
+ // a null mServoDeclarationBlock member which we skip above in
+ // IsInvalidValuePair.
+ MOZ_ASSERT(styleBackend != StyleBackendType::Servo ||
+ pair.mServoDeclarationBlock);
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(
prop, pair.mProperty, CSSEnabledState::eForAllContent) {
addToPropertySets(*prop, offsetToUse);
}
} else {
addToPropertySets(pair.mProperty, offsetToUse);
}
}