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 b8661ea5d7ab6d062ef2ae17acbecf1a9999e8dd..ffbafd734ebe8a61a4fd1b0890215841bf37d51e 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
@@ -126,6 +126,125 @@ static CSSParserTokenRange consumeFunction(CSSParserTokenRange& range) |
return contents; |
} |
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeCalcExpression(const CSSParserTokenRange& range, CSSPropertyParser::Units unitflags) |
+{ |
+ bool mustBeNonNegative = unitflags & (CSSPropertyParser::FNonNeg | CSSPropertyParser::FPositiveInteger); |
+ RefPtrWillBeRawPtr<CSSCalcValue> calculation = CSSCalcValue::create(range, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll); |
+ if (!calculation) |
+ return nullptr; |
+ bool b = false; |
+ switch (calculation->category()) { |
+ case CalcLength: |
+ b = (unitflags & CSSPropertyParser::FLength); |
+ break; |
+ case CalcNumber: |
+ b = (unitflags & CSSPropertyParser::FNumber); |
+ if (!b && (unitflags & (CSSPropertyParser::FInteger | CSSPropertyParser::FPositiveInteger)) && calculation->isInt()) |
+ b = true; |
+ if (b && mustBeNonNegative && calculation->isNegative()) |
+ b = false; |
+ // Always resolve calc() to a UnitType::Number in the CSSParserValue if there are no non-numbers specified in the unitflags. |
+ if (b && !(unitflags & ~(CSSPropertyParser::FInteger | CSSPropertyParser::FNumber | CSSPropertyParser::FPositiveInteger | CSSPropertyParser::FNonNeg))) { |
+ double number = calculation->doubleValue(); |
+ if ((unitflags & CSSPropertyParser::FPositiveInteger) && number <= 0) |
+ return nullptr; |
+ return cssValuePool().createValue(number, calculation->isInt() ? CSSPrimitiveValue::UnitType::Integer : CSSPrimitiveValue::UnitType::Number); |
+ } |
+ break; |
+ case CalcPercent: |
+ b = (unitflags & CSSPropertyParser::FPercent); |
+ if (b && mustBeNonNegative && calculation->isNegative()) |
+ b = false; |
+ break; |
+ case CalcPercentLength: |
+ b = (unitflags & CSSPropertyParser::FPercent) && (unitflags & CSSPropertyParser::FLength); |
+ break; |
+ case CalcPercentNumber: |
+ b = (unitflags & CSSPropertyParser::FPercent) && (unitflags & CSSPropertyParser::FNumber); |
+ break; |
+ case CalcAngle: |
+ b = (unitflags & CSSPropertyParser::FAngle); |
+ break; |
+ case CalcTime: |
+ b = (unitflags & CSSPropertyParser::FTime); |
+ break; |
+ case CalcFrequency: |
+ b = (unitflags & CSSPropertyParser::FFrequency); |
+ break; |
+ case CalcOther: |
+ break; |
+ } |
+ if (!b) |
+ return nullptr; |
+ return CSSPrimitiveValue::create(calculation.release()); |
+} |
+ |
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeNumericValue(CSSParserTokenRange& range, CSSPropertyParser::Units unitflags, CSSParserMode cssParserMode) |
alancutter (OOO until 2018)
2015/09/25 04:13:06
After discussing with timloh we decided that split
|
+{ |
+ const CSSParserToken& token = range.peek(); |
+ if (token.functionId() == CSSValueCalc || token.functionId() == CSSValueWebkitCalc) { |
+ CSSParserTokenRange args = consumeFunction(range); |
Timothy Loh
2015/09/25 04:44:33
BTW this will advance the token stream for invalid
|
+ return consumeCalcExpression(args, unitflags); |
+ } |
+ bool validNumber = false; |
+ CSSPrimitiveValue::UnitType unitType = token.unitType(); |
+ if (token.type() == NumberToken) { |
+ if (unitflags & CSSPropertyParser::FNumber) { |
+ validNumber = true; |
+ } else if (shouldAcceptUnitLessValues(token.numericValue(), unitflags, cssParserMode)) { |
+ unitType = (unitflags & CSSPropertyParser::FLength) ? CSSPrimitiveValue::UnitType::Pixels : CSSPrimitiveValue::UnitType::Degrees; |
+ validNumber = true; |
+ } else if ((unitflags & CSSPropertyParser::FInteger) && token.numericValueType() == IntegerValueType) { |
+ validNumber = true; |
+ } else if ((unitflags & CSSPropertyParser::FPositiveInteger) && token.numericValueType() == IntegerValueType && token.numericValue() > 0) { |
+ validNumber = true; |
+ } |
+ } else if (token.type() == PercentageToken) { |
+ validNumber = unitflags & CSSPropertyParser::FPercent; |
+ } else { // DimensionToken |
+ switch (token.unitType()) { |
+ case CSSPrimitiveValue::UnitType::QuirkyEms: |
+ if (cssParserMode != UASheetMode) |
+ return nullptr; |
+ /* fallthrough intentional */ |
+ case CSSPrimitiveValue::UnitType::Ems: |
+ case CSSPrimitiveValue::UnitType::Rems: |
+ case CSSPrimitiveValue::UnitType::Chs: |
+ case CSSPrimitiveValue::UnitType::Exs: |
+ case CSSPrimitiveValue::UnitType::Pixels: |
+ case CSSPrimitiveValue::UnitType::Centimeters: |
+ case CSSPrimitiveValue::UnitType::Millimeters: |
+ case CSSPrimitiveValue::UnitType::Inches: |
+ case CSSPrimitiveValue::UnitType::Points: |
+ case CSSPrimitiveValue::UnitType::Picas: |
+ case CSSPrimitiveValue::UnitType::ViewportWidth: |
+ case CSSPrimitiveValue::UnitType::ViewportHeight: |
+ case CSSPrimitiveValue::UnitType::ViewportMin: |
+ case CSSPrimitiveValue::UnitType::ViewportMax: |
+ validNumber = unitflags & CSSPropertyParser::FLength; |
+ break; |
+ case CSSPrimitiveValue::UnitType::Milliseconds: |
+ case CSSPrimitiveValue::UnitType::Seconds: |
+ validNumber = unitflags & CSSPropertyParser::FTime; |
+ break; |
+ case CSSPrimitiveValue::UnitType::Degrees: |
+ case CSSPrimitiveValue::UnitType::Radians: |
+ case CSSPrimitiveValue::UnitType::Gradians: |
+ case CSSPrimitiveValue::UnitType::Turns: |
+ validNumber = unitflags & CSSPropertyParser::FAngle; |
+ break; |
+ default: |
+ break; |
+ } |
+ } |
+ if (validNumber) { |
+ if (unitflags & CSSPropertyParser::FNonNeg && token.numericValue() < 0) |
+ return nullptr; |
+ return cssValuePool().createValue(range.consumeIncludingWhitespace().numericValue(), unitType); |
+ } |
+ return nullptr; |
+} |
+ |
static inline bool isCSSWideKeyword(const CSSValueID& id) |
{ |
return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; |
@@ -396,6 +515,18 @@ static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFamily(CSSParserTokenRang |
return list.release(); |
} |
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeSpacing() |
+{ |
+ if (m_range.peek().id() == CSSValueNormal) |
+ return consumeIdent(m_range); |
+ return consumeNumericValue(m_range, FLength | FUnitlessQuirk, m_context.mode()); |
Timothy Loh
2015/09/25 04:44:33
// TODO(rwlbuis): Don't allow unitless values, and
|
+} |
+ |
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::consumeTabSize() |
+{ |
+ return consumeNumericValue(m_range, FInteger | FLength | FNonNeg, m_context.mode()); |
+} |
+ |
PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID propId) |
{ |
m_range.consumeWhitespace(); |
@@ -418,6 +549,11 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
return consumeFontFamily(m_range); |
case CSSPropertyFontWeight: |
return consumeFontWeight(m_range); |
+ case CSSPropertyLetterSpacing: |
+ case CSSPropertyWordSpacing: |
+ return consumeSpacing(); |
+ case CSSPropertyTabSize: |
+ return consumeTabSize(); |
default: |
return nullptr; |
} |