Chromium Code Reviews| 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 565127705adba3e30bfe5e08269ffabb5055a199..136b670fdeee02bb79ae93dea5dc391caa1c0e7f 100644 |
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| @@ -545,6 +545,85 @@ static CSSPrimitiveValue* consumeFontVariantCaps(CSSParserTokenRange& range) |
| CSSValueUnicase, CSSValueTitlingCaps>(range); |
| } |
| +class VariantNumericValidator { |
|
Timothy Loh
2016/05/10 05:26:25
Why is this different to the ligatures parser? Sho
drott
2016/05/10 10:59:06
It should, changed this to contain and build the v
|
| + STACK_ALLOCATED(); |
| + |
| +public: |
| + VariantNumericValidator() : m_sawNumericFigureValue(false) |
| + , m_sawNumericSpacingValue(false) |
| + , m_sawNumericFractionValue(false) |
| + , m_sawOrdinalValue(false) |
| + , m_sawSlashedZeroValue(false) { } |
| + |
| + enum class ValidationResult { |
| + ValidNumeric, |
| + InvalidNumeric, |
| + SeenUnknownID |
| + }; |
| + |
| + ValidationResult validAfterSeenID(CSSValueID valueID) |
| + { |
| + switch (valueID) { |
| + case CSSValueLiningNums: |
| + case CSSValueOldstyleNums: |
| + if (m_sawNumericFigureValue) |
| + return ValidationResult::InvalidNumeric; |
| + m_sawNumericFigureValue = true; |
| + break; |
| + case CSSValueProportionalNums: |
| + case CSSValueTabularNums: |
| + if (m_sawNumericSpacingValue) |
| + return ValidationResult::InvalidNumeric; |
| + m_sawNumericSpacingValue = true; |
| + break; |
| + case CSSValueDiagonalFractions: |
| + case CSSValueStackedFractions: |
| + if (m_sawNumericFractionValue) |
| + return ValidationResult::InvalidNumeric; |
| + m_sawNumericFractionValue = true; |
| + break; |
| + case CSSValueOrdinal: |
| + if (m_sawOrdinalValue) |
| + return ValidationResult::InvalidNumeric; |
| + m_sawOrdinalValue = true; |
| + break; |
| + case CSSValueSlashedZero: |
| + if (m_sawSlashedZeroValue) |
| + return ValidationResult::InvalidNumeric; |
| + m_sawSlashedZeroValue = true; |
| + break; |
| + default: |
| + return ValidationResult::SeenUnknownID; |
| + } |
| + return ValidationResult::ValidNumeric; |
| + } |
| + |
| +private: |
| + bool m_sawNumericFigureValue; |
| + bool m_sawNumericSpacingValue; |
| + bool m_sawNumericFractionValue; |
| + bool m_sawOrdinalValue; |
| + bool m_sawSlashedZeroValue; |
| +}; |
| + |
| +static CSSValue* consumeFontVariantNumeric(CSSParserTokenRange& range) |
| +{ |
| + if (range.peek().id() == CSSValueNormal) |
| + return consumeIdent(range); |
| + |
| + CSSValueList* variantNumericValues = CSSValueList::createSpaceSeparated(); |
| + VariantNumericValidator numericValidator; |
| + do { |
| + CSSValueID id = range.peek().id(); |
| + if (numericValidator.validAfterSeenID(id) != |
| + VariantNumericValidator::ValidationResult::ValidNumeric) |
| + return nullptr; |
| + variantNumericValues->append(consumeIdent(range)); |
| + } while (!range.atEnd()); |
| + |
| + return variantNumericValues; |
| +} |
| + |
| static CSSPrimitiveValue* consumeFontVariantCSS21(CSSParserTokenRange& range) |
| { |
| return consumeIdent<CSSValueNormal, CSSValueSmallCaps>(range); |
| @@ -3476,6 +3555,8 @@ CSSValue* CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty, |
| return consumeFontVariantCaps(m_range); |
| case CSSPropertyFontVariantLigatures: |
| return consumeFontVariantLigatures(m_range); |
| + case CSSPropertyFontVariantNumeric: |
| + return consumeFontVariantNumeric(m_range); |
| case CSSPropertyFontFeatureSettings: |
| return consumeFontFeatureSettings(m_range); |
| case CSSPropertyFontFamily: |
| @@ -4033,6 +4114,7 @@ bool CSSPropertyParser::consumeFont(bool important) |
| addProperty(CSSPropertyFontStyle, CSSPropertyFont, fontStyle ? fontStyle : cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| addProperty(CSSPropertyFontVariantCaps, CSSPropertyFont, fontVariantCaps ? fontVariantCaps : cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| addProperty(CSSPropertyFontVariantLigatures, CSSPropertyFont, cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| + addProperty(CSSPropertyFontVariantNumeric, CSSPropertyFont, cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| addProperty(CSSPropertyFontWeight, CSSPropertyFont, fontWeight ? fontWeight : cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| addProperty(CSSPropertyFontStretch, CSSPropertyFont, fontStretch ? fontStretch : cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| @@ -4076,14 +4158,24 @@ bool CSSPropertyParser::consumeFontVariantShorthand(bool important) |
| CSSPrimitiveValue* capsValue = nullptr; |
| FontVariantLigaturesParser ligaturesParser; |
| + VariantNumericValidator numericValidator; |
| + CSSValueList* numericValues = CSSValueList::createSpaceSeparated(); |
| do { |
| + CSSValueID id = m_range.peek().id(); |
| FontVariantLigaturesParser::ParseResult parseResult = ligaturesParser.consumeLigature(m_range); |
| if (parseResult == FontVariantLigaturesParser::ParseResult::ConsumedValue) |
| continue; |
| - if (parseResult == FontVariantLigaturesParser::ParseResult::DisallowedValue) |
| + |
| + VariantNumericValidator::ValidationResult numericValidationResult = numericValidator.validAfterSeenID(id); |
| + if (numericValidationResult == VariantNumericValidator::ValidationResult::ValidNumeric) { |
| + numericValues->append(consumeIdent(m_range)); |
| + continue; |
| + } |
| + |
| + if (parseResult == FontVariantLigaturesParser::ParseResult::DisallowedValue |
| + || numericValidationResult == VariantNumericValidator::ValidationResult::InvalidNumeric) |
| return false; |
| - CSSValueID id = m_range.peek().id(); |
| switch (id) { |
| case CSSValueSmallCaps: |
| case CSSValueAllSmallCaps: |
| @@ -4102,6 +4194,11 @@ bool CSSPropertyParser::consumeFontVariantShorthand(bool important) |
| } while (!m_range.atEnd()); |
| addProperty(CSSPropertyFontVariantLigatures, CSSPropertyFontVariant, ligaturesParser.finalizeValue(), important); |
| + if (numericValues->length()) { |
| + addProperty(CSSPropertyFontVariantNumeric, CSSPropertyFontVariant, numericValues, important); |
| + } else { |
| + addProperty(CSSPropertyFontVariantNumeric, CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| + } |
| addProperty(CSSPropertyFontVariantCaps, CSSPropertyFontVariant, capsValue ? capsValue : cssValuePool().createIdentifierValue(CSSValueNormal), important); |
| return true; |
| } |