| Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| index a2a4cceb257b2c1f646abb85a4ae1d4f96a7fe17..29162c36e7cfb03dbc1d97c63b91a95c0f196c5b 100644
|
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
|
| @@ -999,6 +999,37 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeZoom(CSSParserTokenRange& range,
|
| return zoom.release();
|
| }
|
|
|
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationDirection(CSSParserTokenRange& range)
|
| +{
|
| + CSSValueID id = range.peek().id();
|
| + if (id == CSSValueNormal || id == CSSValueAlternate || id == CSSValueReverse || id == CSSValueAlternateReverse)
|
| + return consumeIdent(range);
|
| + return nullptr;
|
| +}
|
| +
|
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationFillMode(CSSParserTokenRange& range)
|
| +{
|
| + CSSValueID id = range.peek().id();
|
| + if (id == CSSValueNone || id == CSSValueForwards || id == CSSValueBackwards || id == CSSValueBoth)
|
| + return consumeIdent(range);
|
| + return nullptr;
|
| +}
|
| +
|
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationIterationCount(CSSParserTokenRange& range)
|
| +{
|
| + if (range.peek().id() == CSSValueInfinite)
|
| + return consumeIdent(range);
|
| + return consumeNumber(range, ValueRangeNonNegative);
|
| +}
|
| +
|
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationPlayState(CSSParserTokenRange& range)
|
| +{
|
| + CSSValueID id = range.peek().id();
|
| + if (id == CSSValueRunning || id == CSSValuePaused)
|
| + return consumeIdent(range);
|
| + return nullptr;
|
| +}
|
| +
|
| static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationName(CSSParserTokenRange& range, const CSSParserContext& context, bool allowQuotedName)
|
| {
|
| if (range.peek().id() == CSSValueNone)
|
| @@ -1018,6 +1049,25 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationName(CSSParserTokenRange
|
| return consumeCustomIdent(range);
|
| }
|
|
|
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeTransitionProperty(CSSParserTokenRange& range)
|
| +{
|
| + const CSSParserToken& token = range.peek();
|
| + if (token.type() != IdentToken)
|
| + return nullptr;
|
| + // TODO(timloh): This should check isCSSWideKeyword
|
| + if (token.id() == CSSValueInitial || token.id() == CSSValueInherit)
|
| + return nullptr;
|
| + if (token.id() == CSSValueNone)
|
| + return consumeIdent(range);
|
| +
|
| + if (CSSPropertyID property = token.parseAsUnresolvedCSSPropertyID()) {
|
| + ASSERT(CSSPropertyMetadata::isEnabledProperty(property));
|
| + range.consumeIncludingWhitespace();
|
| + return cssValuePool().createIdentifierValue(property);
|
| + }
|
| + return consumeCustomIdent(range);
|
| +}
|
| +
|
| static PassRefPtrWillBeRawPtr<CSSValue> consumeSteps(CSSParserTokenRange& range)
|
| {
|
| ASSERT(range.peek().functionId() == CSSValueSteps);
|
| @@ -1101,11 +1151,21 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationValue(CSSPropertyID prop
|
| case CSSPropertyAnimationDelay:
|
| case CSSPropertyTransitionDelay:
|
| return consumeTime(range, ValueRangeAll);
|
| + case CSSPropertyAnimationDirection:
|
| + return consumeAnimationDirection(range);
|
| case CSSPropertyAnimationDuration:
|
| case CSSPropertyTransitionDuration:
|
| return consumeTime(range, ValueRangeNonNegative);
|
| + case CSSPropertyAnimationFillMode:
|
| + return consumeAnimationFillMode(range);
|
| + case CSSPropertyAnimationIterationCount:
|
| + return consumeAnimationIterationCount(range);
|
| case CSSPropertyAnimationName:
|
| return consumeAnimationName(range, context, useLegacyParsing);
|
| + case CSSPropertyAnimationPlayState:
|
| + return consumeAnimationPlayState(range);
|
| + case CSSPropertyTransitionProperty:
|
| + return consumeTransitionProperty(range);
|
| case CSSPropertyAnimationTimingFunction:
|
| case CSSPropertyTransitionTimingFunction:
|
| return consumeAnimationTimingFunction(range);
|
| @@ -1115,6 +1175,18 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeAnimationValue(CSSPropertyID prop
|
| }
|
| }
|
|
|
| +static bool isValidAnimationPropertyList(CSSPropertyID property, const CSSValueList& valueList)
|
| +{
|
| + if (property != CSSPropertyTransitionProperty || valueList.length() < 2)
|
| + return true;
|
| + for (auto& value : valueList) {
|
| + if (value->isPrimitiveValue() && toCSSPrimitiveValue(*value).isValueID()
|
| + && toCSSPrimitiveValue(*value).getValueID() == CSSValueNone)
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| static PassRefPtrWillBeRawPtr<CSSValueList> consumeAnimationPropertyList(CSSPropertyID property, CSSParserTokenRange& range, const CSSParserContext& context, bool useLegacyParsing)
|
| {
|
| RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
|
| @@ -1124,6 +1196,8 @@ static PassRefPtrWillBeRawPtr<CSSValueList> consumeAnimationPropertyList(CSSProp
|
| return nullptr;
|
| list->append(value.release());
|
| } while (consumeCommaIncludingWhitespace(range));
|
| + if (!isValidAnimationPropertyList(property, *list))
|
| + return nullptr;
|
| ASSERT(list->length());
|
| return list.release();
|
| }
|
| @@ -1211,9 +1285,14 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
|
| return consumeZoom(m_range, m_context);
|
| case CSSPropertyAnimationDelay:
|
| case CSSPropertyTransitionDelay:
|
| + case CSSPropertyAnimationDirection:
|
| case CSSPropertyAnimationDuration:
|
| case CSSPropertyTransitionDuration:
|
| + case CSSPropertyAnimationFillMode:
|
| + case CSSPropertyAnimationIterationCount:
|
| case CSSPropertyAnimationName:
|
| + case CSSPropertyAnimationPlayState:
|
| + case CSSPropertyTransitionProperty:
|
| case CSSPropertyAnimationTimingFunction:
|
| case CSSPropertyTransitionTimingFunction:
|
| return consumeAnimationPropertyList(property, m_range, m_context, unresolvedProperty == CSSPropertyAliasWebkitAnimationName);
|
|
|