Bug 1339690 - Part 7: Stop storing invalid property value. r=birtles

MozReview-Commit-ID: H3aRcJIk7CV

--HG--
extra : rebase_source : 774c1596364dd8e3eacf8a6bab093e9e1abf6e18
This commit is contained in:
Boris Chiou 2017-06-14 11:43:47 +08:00
Родитель 855f40d72b
Коммит ccd05b9231
7 изменённых файлов: 65 добавлений и 87 удалений

Просмотреть файл

@ -25,10 +25,19 @@ enum class CompositeOperation : uint8_t;
*/
struct PropertyValuePair
{
PropertyValuePair(nsCSSPropertyID aProperty, nsCSSValue&& aValue)
: mProperty(aProperty), mValue(Move(aValue)) { }
PropertyValuePair(nsCSSPropertyID aProperty,
RefPtr<RawServoDeclarationBlock>&& aValue)
: mProperty(aProperty), mServoDeclarationBlock(Move(aValue))
{
MOZ_ASSERT(mServoDeclarationBlock, "Should be valid property value");
}
nsCSSPropertyID mProperty;
// The specified value for the property. For shorthand properties or invalid
// property values, we store the specified property value as a token stream
// (string).
// The specified value for the property. For shorthand property values,
// we store the specified property value as a token stream (string).
// If this is uninitialized, we use the underlying value.
nsCSSValue mValue;
// The specified value when using the Servo backend.
@ -37,7 +46,7 @@ struct PropertyValuePair
#ifdef DEBUG
// Flag to indicate that when we call StyleAnimationValue::ComputeValues on
// this value we should behave as if that function had failed.
bool mSimulateComputeValuesFailure;
bool mSimulateComputeValuesFailure = false;
#endif
bool operator==(const PropertyValuePair&) const;

Просмотреть файл

@ -312,35 +312,6 @@ public:
}
};
// ------------------------------------------------------------------
//
// Inlined helper methods
//
// ------------------------------------------------------------------
inline bool
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
// we leave the token stream's mPropertyID as eCSSProperty_UNKNOWN.
return !nsCSSProps::IsShorthand(aPair.mProperty) &&
aPair.mValue.GetUnit() == eCSSUnit_TokenStream &&
aPair.mValue.GetTokenStreamValue()->mPropertyID
== eCSSProperty_UNKNOWN;
}
// ------------------------------------------------------------------
//
// Internal helper method declarations
@ -378,7 +349,7 @@ AppendValueAsString(JSContext* aCx,
nsTArray<nsString>& aValues,
JS::Handle<JS::Value> aValue);
static PropertyValuePair
static Maybe<PropertyValuePair>
MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
nsCSSParser& aParser, nsIDocument* aDocument);
@ -719,9 +690,14 @@ ConvertKeyframeSequence(JSContext* aCx,
for (PropertyValuesPair& pair : propertyValuePairs) {
MOZ_ASSERT(pair.mValues.Length() == 1);
keyframe->mPropertyValues.AppendElement(
Maybe<PropertyValuePair> valuePair =
MakePropertyValuePair(pair.mProperty, pair.mValues[0], parser,
aDocument));
aDocument);
if (!valuePair) {
continue;
}
keyframe->mPropertyValues.AppendElement(Move(valuePair.ref()));
#ifdef DEBUG
// When we go to convert keyframes into arrays of property values we
@ -877,27 +853,22 @@ AppendValueAsString(JSContext* aCx,
* @param aStringValue The property value to parse.
* @param aParser The CSS parser object to use.
* @param aDocument The document to use when parsing.
* @return The constructed PropertyValuePair object.
* @return The constructed PropertyValuePair, or Nothing() if |aStringValue| is
* an invalid property value.
*/
static PropertyValuePair
static Maybe<PropertyValuePair>
MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
nsCSSParser& aParser, nsIDocument* aDocument)
{
MOZ_ASSERT(aDocument);
PropertyValuePair result;
result.mProperty = aProperty;
#ifdef DEBUG
result.mSimulateComputeValuesFailure = false;
#endif
Maybe<PropertyValuePair> result;
if (aDocument->GetStyleBackendType() == StyleBackendType::Servo) {
RefPtr<RawServoDeclarationBlock> servoDeclarationBlock =
KeyframeUtils::ParseProperty(aProperty, aStringValue, aDocument);
if (servoDeclarationBlock) {
result.mServoDeclarationBlock = servoDeclarationBlock.forget();
result.emplace(aProperty, Move(servoDeclarationBlock));
}
return result;
}
@ -910,17 +881,20 @@ MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
aDocument->GetDocumentURI(),
aDocument->NodePrincipal(),
value);
if (value.GetUnit() == eCSSUnit_Null) {
// Invalid property value, so return Nothing.
return result;
}
}
if (value.GetUnit() == eCSSUnit_Null) {
// Either we have a shorthand, or we failed to parse a longhand.
// In either case, store the string value as a token stream.
// If we have a shorthand, store the string value as a token stream.
nsCSSValueTokenStream* tokenStream = new nsCSSValueTokenStream;
tokenStream->mTokenStream = aStringValue;
// We are about to convert a null value to a token stream value but
// by leaving the mPropertyID as unknown, we will be able to
// distinguish between invalid values and valid token stream values
// distinguish between shorthand values and valid token stream values
// (e.g. values with variable references).
MOZ_ASSERT(tokenStream->mPropertyID == eCSSProperty_UNKNOWN,
"The property of a token stream should be initialized"
@ -935,8 +909,7 @@ MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
value.SetTokenStreamValue(tokenStream);
}
result.mValue = value;
result.emplace(aProperty, Move(value));
return result;
}
@ -1034,10 +1007,6 @@ GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
"Animation values were parsed using Servo backend but target"
" element is not using Servo backend?");
if (IsInvalidValuePair(pair, StyleBackendType::Gecko)) {
continue;
}
// Expand each value into the set of longhands and produce
// a KeyframeValueEntry for each value.
nsTArray<PropertyStyleAnimationValuePair> values;
@ -1443,8 +1412,13 @@ GetKeyframeListFromPropertyIndexedKeyframe(JSContext* aCx,
keyframe->mComposite = composite;
keyframe->mComputedOffset = offset;
}
keyframe->mPropertyValues.AppendElement(
MakePropertyValuePair(pair.mProperty, stringValue, parser, aDocument));
Maybe<PropertyValuePair> valuePair =
MakePropertyValuePair(pair.mProperty, stringValue, parser, aDocument);
if (!valuePair) {
continue;
}
keyframe->mPropertyValues.AppendElement(Move(valuePair.ref()));
}
}
@ -1514,10 +1488,6 @@ RequiresAdditiveAnimation(const nsTArray<Keyframe>& aKeyframes,
: computedOffset;
for (const PropertyValuePair& pair : frame.mPropertyValues) {
if (IsInvalidValuePair(pair, styleBackend)) {
continue;
}
if (nsCSSProps::IsShorthand(pair.mProperty)) {
if (styleBackend == StyleBackendType::Gecko) {
nsCSSValueTokenStream* tokenStream =
@ -1528,9 +1498,7 @@ RequiresAdditiveAnimation(const nsTArray<Keyframe>& aKeyframes,
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(

Просмотреть файл

@ -856,23 +856,22 @@ GeckoCSSAnimationBuilder::GetKeyframePropertyValues(
continue;
}
PropertyValuePair pair;
pair.mProperty = prop;
StyleAnimationValue computedValue;
if (!StyleAnimationValue::ExtractComputedValue(prop, styleContext,
computedValue)) {
continue;
}
nsCSSValue propertyValue;
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(prop, Move(computedValue),
pair.mValue);
propertyValue);
MOZ_ASSERT(uncomputeResult,
"Unable to get specified value from computed value");
MOZ_ASSERT(pair.mValue.GetUnit() != eCSSUnit_Null,
MOZ_ASSERT(propertyValue.GetUnit() != eCSSUnit_Null,
"Not expecting to read invalid properties");
result.AppendElement(Move(pair));
result.AppendElement(Move(PropertyValuePair(prop, Move(propertyValue))));
aAnimatedProperties.AddProperty(prop);
}
@ -941,13 +940,13 @@ GeckoCSSAnimationBuilder::FillInMissingKeyframeValues(
}
if (startKeyframe && !aPropertiesSetAtStart.HasProperty(prop)) {
PropertyValuePair propertyValue;
propertyValue.mProperty = prop;
// An uninitialized nsCSSValue represents the underlying value.
PropertyValuePair propertyValue(prop, Move(nsCSSValue()));
startKeyframe->mPropertyValues.AppendElement(Move(propertyValue));
}
if (endKeyframe && !aPropertiesSetAtEnd.HasProperty(prop)) {
PropertyValuePair propertyValue;
propertyValue.mProperty = prop;
// An uninitialized nsCSSValue represents the underlying value.
PropertyValuePair propertyValue(prop, Move(nsCSSValue()));
endKeyframe->mPropertyValues.AppendElement(Move(propertyValue));
}
}

Просмотреть файл

@ -791,18 +791,21 @@ AppendKeyframe(double aOffset,
{
Keyframe& frame = *aKeyframes.AppendElement();
frame.mOffset.emplace(aOffset);
PropertyValuePair& pv = *frame.mPropertyValues.AppendElement();
pv.mProperty = aProperty;
if (aValue.mServo) {
pv.mServoDeclarationBlock =
RefPtr<RawServoDeclarationBlock> decl =
Servo_AnimationValue_Uncompute(aValue.mServo).Consume();
frame.mPropertyValues.AppendElement(
Move(PropertyValuePair(aProperty, Move(decl))));
} else {
nsCSSValue propertyValue;
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(aProperty, Move(aValue.mGecko),
pv.mValue);
propertyValue);
MOZ_ASSERT(uncomputeResult,
"Unable to get specified value from computed value");
frame.mPropertyValues.AppendElement(
Move(PropertyValuePair(aProperty, Move(propertyValue))));
}
return frame;
}

Просмотреть файл

@ -220155,7 +220155,7 @@
"testharness"
],
"web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument.html": [
"6f561694e38420194fd1817ee965436348221d06",
"9f828bd1b3785d240e9a99df8c3826dd489a224e",
"testharness"
],
"web-animations/interfaces/KeyframeEffect/setKeyframes.html": [
@ -220175,7 +220175,7 @@
"support"
],
"web-animations/resources/keyframe-utils.js": [
"ff5700466b5af6ffaad824437d6566003a22e25b",
"2903e56e508f7034e1918b5688c8a605db9bae51",
"support"
],
"web-animations/testcommon.js": [

Просмотреть файл

@ -258,9 +258,10 @@ test(() => {
{done: true},
]));
assert_frame_lists_equal(effect.getKeyframes(), [
{offset: null, computedOffset: 1, easing: 'linear', left: '100px,200px'}
{offset: null, computedOffset: 1, easing: 'linear'}
]);
}, 'Custom iterator with value list in keyframe should give bizarre string representation of list.');
}, 'Custom iterator with value list in keyframe should not contain invalid ' +
'property value pair of list.');
test(function(t) {
var keyframe = {};

Просмотреть файл

@ -128,7 +128,7 @@ var gPropertyIndexedKeyframesTests = [
{ offset: null, computedOffset: 0.25, easing: "linear",
left: "20px", top: "25px" },
{ offset: null, computedOffset: 0.50, easing: "linear",
left: "30px", top: "invalid" },
left: "30px" },
{ offset: null, computedOffset: 0.75, easing: "linear",
left: "40px", top: "45px" },
{ offset: null, computedOffset: 1.00, easing: "linear",
@ -166,8 +166,7 @@ var gPropertyIndexedKeyframesTests = [
{ desc: "a one property two value property-indexed keyframes specification"
+ " where the first value is invalid",
input: { left: ["invalid", "10px"] },
output: [{ offset: null, computedOffset: 0, easing: "linear",
left: "invalid" },
output: [{ offset: null, computedOffset: 0, easing: "linear" },
{ offset: null, computedOffset: 1, easing: "linear",
left: "10px" }] },
{ desc: "a one property two value property-indexed keyframes specification"
@ -175,8 +174,7 @@ var gPropertyIndexedKeyframesTests = [
input: { left: ["10px", "invalid"] },
output: [{ offset: null, computedOffset: 0, easing: "linear",
left: "10px" },
{ offset: null, computedOffset: 1, easing: "linear",
left: "invalid" }] },
{ offset: null, computedOffset: 1, easing: "linear" }] },
];
var gKeyframeSequenceTests = [