OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/css/parser/CSSPropertyParser.h" | 6 #include "core/css/parser/CSSPropertyParser.h" |
7 | 7 |
8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
9 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
10 #include "core/css/CSSFontFaceSrcValue.h" | 10 #include "core/css/CSSFontFaceSrcValue.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 119 |
120 static CSSParserTokenRange consumeFunction(CSSParserTokenRange& range) | 120 static CSSParserTokenRange consumeFunction(CSSParserTokenRange& range) |
121 { | 121 { |
122 ASSERT(range.peek().type() == FunctionToken); | 122 ASSERT(range.peek().type() == FunctionToken); |
123 CSSParserTokenRange contents = range.consumeBlock(); | 123 CSSParserTokenRange contents = range.consumeBlock(); |
124 range.consumeWhitespace(); | 124 range.consumeWhitespace(); |
125 contents.consumeWhitespace(); | 125 contents.consumeWhitespace(); |
126 return contents; | 126 return contents; |
127 } | 127 } |
128 | 128 |
| 129 class CalcParseScope { |
| 130 public: |
| 131 CalcParseScope(CSSParserTokenRange& range, ValueRange valueRange = ValueRang
eAll) |
| 132 : m_sourceRange(range) |
| 133 , m_range(range) |
| 134 { |
| 135 const CSSParserToken& token = range.peek(); |
| 136 if (token.functionId() == CSSValueCalc || token.functionId() == CSSValue
WebkitCalc) |
| 137 m_calcValue = CSSCalcValue::create(consumeFunction(m_range), valueRa
nge); |
| 138 } |
| 139 |
| 140 const CSSCalcValue* value() const { return m_calcValue.get(); } |
| 141 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> releaseValue() |
| 142 { |
| 143 m_sourceRange = m_range; |
| 144 return CSSPrimitiveValue::create(m_calcValue.release()); |
| 145 } |
| 146 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> releaseNumber() |
| 147 { |
| 148 m_sourceRange = m_range; |
| 149 CSSPrimitiveValue::UnitType unitType = m_calcValue->isInt() ? CSSPrimiti
veValue::UnitType::Integer : CSSPrimitiveValue::UnitType::Number; |
| 150 return cssValuePool().createValue(m_calcValue->doubleValue(), unitType); |
| 151 } |
| 152 |
| 153 private: |
| 154 CSSParserTokenRange& m_sourceRange; |
| 155 CSSParserTokenRange m_range; |
| 156 RefPtrWillBeRawPtr<CSSCalcValue> m_calcValue; |
| 157 }; |
| 158 |
| 159 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRa
nge& range, CSSParserMode cssParserMode, double minimumValue = std::numeric_limi
ts<int>::min()) |
| 160 { |
| 161 const CSSParserToken& token = range.peek(); |
| 162 if (token.type() == NumberToken) { |
| 163 if (token.numericValueType() == NumberValueType || token.numericValue()
< minimumValue) |
| 164 return nullptr; |
| 165 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), token.unitType()); |
| 166 } |
| 167 CalcParseScope calcScope(range); |
| 168 if (const CSSCalcValue* calculation = calcScope.value()) { |
| 169 if (calculation->category() != CalcNumber || !calculation->isInt()) |
| 170 return nullptr; |
| 171 double value = calculation->doubleValue(); |
| 172 if (value < minimumValue) |
| 173 return nullptr; |
| 174 return calcScope.releaseNumber(); |
| 175 } |
| 176 return nullptr; |
| 177 } |
| 178 |
| 179 inline bool shouldAcceptUnitlessValues(double fValue, CSSParserMode cssParserMod
e, UnitlessQuirk unitless) |
| 180 { |
| 181 // Quirks mode for certain properties and presentation attributes accept uni
t-less values for certain units. |
| 182 return !fValue // 0 can always be unitless. |
| 183 || isUnitLessLengthParsingEnabledForMode(cssParserMode) // HTML and SVG
attribute values can always be unitless. |
| 184 || (cssParserMode == HTMLQuirksMode && (unitless == UnitlessQuirk::Allow
)); |
| 185 } |
| 186 |
| 187 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRan
ge& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk uni
tless = UnitlessQuirk::Forbid) |
| 188 { |
| 189 const CSSParserToken& token = range.peek(); |
| 190 if (token.type() == DimensionToken) { |
| 191 switch (token.unitType()) { |
| 192 case CSSPrimitiveValue::UnitType::QuirkyEms: |
| 193 if (cssParserMode != UASheetMode) |
| 194 return nullptr; |
| 195 /* fallthrough intentional */ |
| 196 case CSSPrimitiveValue::UnitType::Ems: |
| 197 case CSSPrimitiveValue::UnitType::Rems: |
| 198 case CSSPrimitiveValue::UnitType::Chs: |
| 199 case CSSPrimitiveValue::UnitType::Exs: |
| 200 case CSSPrimitiveValue::UnitType::Pixels: |
| 201 case CSSPrimitiveValue::UnitType::Centimeters: |
| 202 case CSSPrimitiveValue::UnitType::Millimeters: |
| 203 case CSSPrimitiveValue::UnitType::Inches: |
| 204 case CSSPrimitiveValue::UnitType::Points: |
| 205 case CSSPrimitiveValue::UnitType::Picas: |
| 206 case CSSPrimitiveValue::UnitType::ViewportWidth: |
| 207 case CSSPrimitiveValue::UnitType::ViewportHeight: |
| 208 case CSSPrimitiveValue::UnitType::ViewportMin: |
| 209 case CSSPrimitiveValue::UnitType::ViewportMax: |
| 210 break; |
| 211 default: |
| 212 return nullptr; |
| 213 } |
| 214 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) |
| 215 return nullptr; |
| 216 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), token.unitType()); |
| 217 } |
| 218 if (token.type() == NumberToken) { |
| 219 if (!shouldAcceptUnitlessValues(token.numericValue(), cssParserMode, uni
tless) |
| 220 || (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
) |
| 221 return nullptr; |
| 222 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), CSSPrimitiveValue::UnitType::Pixels); |
| 223 } |
| 224 CalcParseScope calcScope(range, valueRange); |
| 225 if (const CSSCalcValue* calculation = calcScope.value()) { |
| 226 if (calculation->category() != CalcLength) |
| 227 return nullptr; |
| 228 return calcScope.releaseValue(); |
| 229 } |
| 230 return nullptr; |
| 231 } |
| 232 |
129 static inline bool isCSSWideKeyword(const CSSValueID& id) | 233 static inline bool isCSSWideKeyword(const CSSValueID& id) |
130 { | 234 { |
131 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset
|| id == CSSValueDefault; | 235 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset
|| id == CSSValueDefault; |
132 } | 236 } |
133 | 237 |
134 // Methods for consuming non-shorthand properties starts here. | 238 // Methods for consuming non-shorthand properties starts here. |
135 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r
ange) | 239 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r
ange) |
136 { | 240 { |
137 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); | 241 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); |
138 if (range.peek().id() == CSSValueAuto) { | 242 if (range.peek().id() == CSSValueAuto) { |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 list->append(parsedValue); | 493 list->append(parsedValue); |
390 } else if ((parsedValue = consumeFamilyName(range))) { | 494 } else if ((parsedValue = consumeFamilyName(range))) { |
391 list->append(parsedValue); | 495 list->append(parsedValue); |
392 } else { | 496 } else { |
393 return nullptr; | 497 return nullptr; |
394 } | 498 } |
395 } while (consumeCommaIncludingWhitespace(range)); | 499 } while (consumeCommaIncludingWhitespace(range)); |
396 return list.release(); | 500 return list.release(); |
397 } | 501 } |
398 | 502 |
| 503 static PassRefPtrWillBeRawPtr<CSSValue> consumeSpacing(CSSParserTokenRange& rang
e, CSSParserMode cssParserMode) |
| 504 { |
| 505 if (range.peek().id() == CSSValueNormal) |
| 506 return consumeIdent(range); |
| 507 // TODO(timloh): Don't allow unitless values, and allow <percentage>s in wor
d-spacing. |
| 508 return consumeLength(range, cssParserMode, ValueRangeAll, UnitlessQuirk::All
ow); |
| 509 } |
| 510 |
| 511 static PassRefPtrWillBeRawPtr<CSSValue> consumeTabSize(CSSParserTokenRange& rang
e, CSSParserMode cssParserMode) |
| 512 { |
| 513 RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = consumeInteger(range, cs
sParserMode, 0); |
| 514 if (parsedValue) |
| 515 return parsedValue; |
| 516 return consumeLength(range, cssParserMode, ValueRangeNonNegative); |
| 517 } |
| 518 |
399 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID propId) | 519 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
ID propId) |
400 { | 520 { |
401 m_range.consumeWhitespace(); | 521 m_range.consumeWhitespace(); |
402 switch (propId) { | 522 switch (propId) { |
403 case CSSPropertyWillChange: | 523 case CSSPropertyWillChange: |
404 return consumeWillChange(m_range); | 524 return consumeWillChange(m_range); |
405 case CSSPropertyPage: | 525 case CSSPropertyPage: |
406 return consumePage(m_range); | 526 return consumePage(m_range); |
407 case CSSPropertyQuotes: | 527 case CSSPropertyQuotes: |
408 return consumeQuotes(m_range); | 528 return consumeQuotes(m_range); |
409 case CSSPropertyWebkitHighlight: | 529 case CSSPropertyWebkitHighlight: |
410 return consumeWebkitHighlight(m_range); | 530 return consumeWebkitHighlight(m_range); |
411 case CSSPropertyFontVariantLigatures: | 531 case CSSPropertyFontVariantLigatures: |
412 return consumeFontVariantLigatures(m_range); | 532 return consumeFontVariantLigatures(m_range); |
413 case CSSPropertyWebkitFontFeatureSettings: | 533 case CSSPropertyWebkitFontFeatureSettings: |
414 return consumeFontFeatureSettings(m_range); | 534 return consumeFontFeatureSettings(m_range); |
415 case CSSPropertyFontVariant: | 535 case CSSPropertyFontVariant: |
416 return consumeFontVariant(); | 536 return consumeFontVariant(); |
417 case CSSPropertyFontFamily: | 537 case CSSPropertyFontFamily: |
418 return consumeFontFamily(m_range); | 538 return consumeFontFamily(m_range); |
419 case CSSPropertyFontWeight: | 539 case CSSPropertyFontWeight: |
420 return consumeFontWeight(m_range); | 540 return consumeFontWeight(m_range); |
| 541 case CSSPropertyLetterSpacing: |
| 542 case CSSPropertyWordSpacing: |
| 543 return consumeSpacing(m_range, m_context.mode()); |
| 544 case CSSPropertyTabSize: |
| 545 return consumeTabSize(m_range, m_context.mode()); |
421 default: | 546 default: |
422 return nullptr; | 547 return nullptr; |
423 } | 548 } |
424 } | 549 } |
425 | 550 |
426 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse
rTokenRange& range) | 551 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse
rTokenRange& range) |
427 { | 552 { |
428 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); | 553 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated
(); |
429 | 554 |
430 do { | 555 do { |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); | 708 addProperty(CSSPropertyOverflowX, overflowXValue.release(), important); |
584 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); | 709 addProperty(CSSPropertyOverflowY, overflowYValue.release(), important); |
585 return true; | 710 return true; |
586 } | 711 } |
587 default: | 712 default: |
588 return false; | 713 return false; |
589 } | 714 } |
590 } | 715 } |
591 | 716 |
592 } // namespace blink | 717 } // namespace blink |
OLD | NEW |