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; |
} |