Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. |
| 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
| 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
| 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) |
| 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
| 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
| 10 * | 10 * |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 if (a.length() != length) | 72 if (a.length() != length) |
| 73 return false; | 73 return false; |
| 74 | 74 |
| 75 return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF ::equalIgnoringCase(b, a.characters16(), length); | 75 return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF ::equalIgnoringCase(b, a.characters16(), length); |
| 76 } | 76 } |
| 77 | 77 |
| 78 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, | 78 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, |
| 79 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, | 79 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, |
| 80 StyleRule::Type ruleType) | 80 StyleRule::Type ruleType) |
| 81 : m_valueList(valueList) | 81 : m_valueList(valueList) |
| 82 , m_range(nullptr) | |
| 82 , m_context(context) | 83 , m_context(context) |
| 83 , m_parsedProperties(parsedProperties) | 84 , m_parsedProperties(parsedProperties) |
| 84 , m_ruleType(ruleType) | 85 , m_ruleType(ruleType) |
| 85 , m_inParseShorthand(0) | 86 , m_inParseShorthand(0) |
| 86 , m_currentShorthand(CSSPropertyInvalid) | 87 , m_currentShorthand(CSSPropertyInvalid) |
| 87 , m_implicitShorthand(false) | 88 , m_implicitShorthand(false) |
| 88 { | 89 { |
| 89 } | 90 } |
| 90 | 91 |
| 91 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, | 92 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, |
| 92 CSSParserValueList* valueList, const CSSParserContext& context, | 93 CSSParserValueList* valueList, CSSParserTokenRange* range, const CSSParserCo ntext& context, |
|
Timothy Loh
2015/09/03 02:05:53
Having the token range as a pointer is odd, I'd ju
rwlbuis
2015/09/03 22:27:54
Done.
| |
| 93 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) | 94 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) |
| 94 { | 95 { |
| 95 int parsedPropertiesSize = parsedProperties.size(); | 96 int parsedPropertiesSize = parsedProperties.size(); |
| 96 | 97 |
| 97 CSSPropertyParser parser(valueList, context, parsedProperties, ruleType); | 98 CSSPropertyParser parser(valueList, context, parsedProperties, ruleType); |
| 99 parser.m_range = range; | |
| 98 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); | 100 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); |
| 99 bool parseSuccess; | 101 bool parseSuccess; |
| 100 | 102 |
| 101 if (ruleType == StyleRule::Viewport) { | 103 if (ruleType == StyleRule::Viewport) { |
| 102 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) | 104 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) |
| 103 && parser.parseViewportProperty(resolvedProperty, important); | 105 && parser.parseViewportProperty(resolvedProperty, important); |
| 104 } else if (ruleType == StyleRule::FontFace) { | 106 } else if (ruleType == StyleRule::FontFace) { |
| 105 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); | 107 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); |
| 106 } else { | 108 } else { |
| 107 parseSuccess = parser.parseValue(unresolvedProperty, important); | 109 parseSuccess = parser.parseValue(unresolvedProperty, important); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 | 331 |
| 330 static bool consumeComma(CSSParserValueList* valueList) | 332 static bool consumeComma(CSSParserValueList* valueList) |
| 331 { | 333 { |
| 332 CSSParserValue* value = valueList->current(); | 334 CSSParserValue* value = valueList->current(); |
| 333 if (!value || !isComma(value)) | 335 if (!value || !isComma(value)) |
| 334 return false; | 336 return false; |
| 335 valueList->next(); | 337 valueList->next(); |
| 336 return true; | 338 return true; |
| 337 } | 339 } |
| 338 | 340 |
| 341 static bool consumeCommaIncludingWhitespace(CSSParserTokenRange& valueList) | |
| 342 { | |
| 343 CSSParserToken value = valueList.peek(); | |
| 344 if (value.type() != CommaToken) | |
| 345 return false; | |
| 346 valueList.consumeIncludingWhitespace(); | |
| 347 return true; | |
| 348 } | |
| 349 | |
| 339 static inline bool isForwardSlashOperator(CSSParserValue* value) | 350 static inline bool isForwardSlashOperator(CSSParserValue* value) |
| 340 { | 351 { |
| 341 ASSERT(value); | 352 ASSERT(value); |
| 342 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; | 353 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; |
| 343 } | 354 } |
| 344 | 355 |
| 345 static bool isGeneratedImageValue(CSSParserValue* val) | 356 static bool isGeneratedImageValue(CSSParserValue* val) |
| 346 { | 357 { |
| 347 if (val->m_unit != CSSParserValue::Function) | 358 if (val->m_unit != CSSParserValue::Function) |
| 348 return false; | 359 return false; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 return; | 436 return; |
| 426 } | 437 } |
| 427 | 438 |
| 428 RefPtrWillBeRawPtr<CSSValue> value = prpValue; | 439 RefPtrWillBeRawPtr<CSSValue> value = prpValue; |
| 429 ShorthandScope scope(this, propId); | 440 ShorthandScope scope(this, propId); |
| 430 const CSSPropertyID* longhands = shorthand.properties(); | 441 const CSSPropertyID* longhands = shorthand.properties(); |
| 431 for (unsigned i = 0; i < shorthandLength; ++i) | 442 for (unsigned i = 0; i < shorthandLength; ++i) |
| 432 addProperty(longhands[i], value, important); | 443 addProperty(longhands[i], value, important); |
| 433 } | 444 } |
| 434 | 445 |
| 446 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID propId) | |
| 447 { | |
| 448 m_range->consumeWhitespace(); | |
| 449 switch (propId) { | |
| 450 case CSSPropertyWillChange: | |
| 451 return parseWillChange(); | |
| 452 default: | |
| 453 ASSERT_NOT_REACHED(); | |
| 454 } | |
| 455 return nullptr; | |
| 456 } | |
| 457 | |
| 435 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant) | 458 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant) |
| 436 { | 459 { |
| 437 CSSPropertyID propId = resolveCSSPropertyID(unresolvedProperty); | 460 CSSPropertyID propId = resolveCSSPropertyID(unresolvedProperty); |
| 438 | 461 |
| 439 CSSParserValue* value = m_valueList->current(); | 462 CSSParserValue* value = m_valueList->current(); |
| 440 | 463 |
| 441 // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function. | 464 // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function. |
| 442 // FIXME: This is to avoid having to pass parsedCalc to all validUnit caller s. | 465 // FIXME: This is to avoid having to pass parsedCalc to all validUnit caller s. |
| 443 ASSERT(!m_parsedCalculation); | 466 ASSERT(!m_parsedCalculation); |
| 444 | 467 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 463 | 486 |
| 464 if (CSSParserFastPaths::isKeywordPropertyID(propId)) { | 487 if (CSSParserFastPaths::isKeywordPropertyID(propId)) { |
| 465 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) | 488 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) |
| 466 return false; | 489 return false; |
| 467 if (m_valueList->next() && !inShorthand()) | 490 if (m_valueList->next() && !inShorthand()) |
| 468 return false; | 491 return false; |
| 469 addProperty(propId, cssValuePool().createIdentifierValue(id), important) ; | 492 addProperty(propId, cssValuePool().createIdentifierValue(id), important) ; |
| 470 return true; | 493 return true; |
| 471 } | 494 } |
| 472 | 495 |
| 496 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
| 497 if (propId == CSSPropertyWillChange) { | |
| 498 parsedValue = parseSingleValue(propId); | |
| 499 if (!parsedValue || !m_range->atEnd()) | |
| 500 return false; | |
| 501 addProperty(propId, parsedValue.release(), important); | |
| 502 return true; | |
| 503 } | |
| 504 | |
| 473 bool validPrimitive = false; | 505 bool validPrimitive = false; |
| 474 Units unitless = FUnknown; | 506 Units unitless = FUnknown; |
| 475 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
| 476 | 507 |
| 477 switch (propId) { | 508 switch (propId) { |
| 478 case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] | 509 case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] |
| 479 parsedValue = parseSize(); | 510 parsedValue = parseSize(); |
| 480 break; | 511 break; |
| 481 case CSSPropertyQuotes: // [<string> <string>]+ | none | 512 case CSSPropertyQuotes: // [<string> <string>]+ | none |
| 482 if (id == CSSValueNone) | 513 if (id == CSSValueNone) |
| 483 validPrimitive = true; | 514 validPrimitive = true; |
| 484 else | 515 else |
| 485 parsedValue = parseQuotes(); | 516 parsedValue = parseQuotes(); |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 validPrimitive = true; | 1341 validPrimitive = true; |
| 1311 else | 1342 else |
| 1312 validPrimitive = validUnit(value, FLength | FNonNeg); | 1343 validPrimitive = validUnit(value, FLength | FNonNeg); |
| 1313 break; | 1344 break; |
| 1314 case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) | 1345 case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) |
| 1315 validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit () == CSSPrimitiveValue::UnitType::Number && value->fValue == 1); | 1346 validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit () == CSSPrimitiveValue::UnitType::Number && value->fValue == 1); |
| 1316 break; | 1347 break; |
| 1317 case CSSPropertyWebkitColumnWidth: // auto | <length> | 1348 case CSSPropertyWebkitColumnWidth: // auto | <length> |
| 1318 parsedValue = parseColumnWidth(); | 1349 parsedValue = parseColumnWidth(); |
| 1319 break; | 1350 break; |
| 1320 case CSSPropertyWillChange: | |
| 1321 parsedValue = parseWillChange(); | |
| 1322 break; | |
| 1323 // End of CSS3 properties | 1351 // End of CSS3 properties |
| 1324 | 1352 |
| 1325 // Apple specific properties. These will never be standardized and are pure ly to | 1353 // Apple specific properties. These will never be standardized and are pure ly to |
| 1326 // support custom WebKit-based Apple applications. | 1354 // support custom WebKit-based Apple applications. |
| 1327 case CSSPropertyWebkitLineClamp: | 1355 case CSSPropertyWebkitLineClamp: |
| 1328 // When specifying number of lines, don't allow 0 as a valid value | 1356 // When specifying number of lines, don't allow 0 as a valid value |
| 1329 // When specifying either type of unit, require non-negative integers | 1357 // When specifying either type of unit, require non-negative integers |
| 1330 validPrimitive = (!id && !isCalculation(value) && validUnit(value, FInte ger | FPercent | FNonNeg) && (value->unit() == CSSPrimitiveValue::UnitType::Perc entage || value->fValue)); | 1358 validPrimitive = (!id && !isCalculation(value) && validUnit(value, FInte ger | FPercent | FNonNeg) && (value->unit() == CSSPrimitiveValue::UnitType::Perc entage || value->fValue)); |
| 1331 break; | 1359 break; |
| 1332 | 1360 |
| (...skipping 5499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6832 if (!consumeComma(functionArgs)) | 6860 if (!consumeComma(functionArgs)) |
| 6833 return nullptr; | 6861 return nullptr; |
| 6834 } | 6862 } |
| 6835 | 6863 |
| 6836 return imageSet.release(); | 6864 return imageSet.release(); |
| 6837 } | 6865 } |
| 6838 | 6866 |
| 6839 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseWillChange() | 6867 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseWillChange() |
| 6840 { | 6868 { |
| 6841 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 6869 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
| 6842 if (m_valueList->current()->id == CSSValueAuto) { | 6870 CSSParserToken currentToken = m_range->consumeIncludingWhitespace(); |
| 6871 if (currentToken.id() == CSSValueAuto) { | |
| 6843 // FIXME: This will be read back as an empty string instead of auto | 6872 // FIXME: This will be read back as an empty string instead of auto |
| 6844 return values.release(); | 6873 return values.release(); |
| 6845 } | 6874 } |
| 6846 | 6875 |
| 6847 // Every comma-separated list of identifiers is a valid will-change value, | 6876 // Every comma-separated list of identifiers is a valid will-change value, |
|
Timothy Loh
2015/09/03 02:05:53
Heh, the function doesn't actually do this...
Timothy Loh
2015/09/03 02:06:58
That said, let's try and keep behaviour changes se
rwlbuis
2015/09/03 22:27:54
I agree. Sadly I don't think this is the only case
| |
| 6848 // unless the list includes an explicitly disallowed identifier. | 6877 // unless the list includes an explicitly disallowed identifier. |
| 6849 while (true) { | 6878 while (true) { |
| 6850 CSSParserValue* currentValue = m_valueList->current(); | 6879 if (currentToken.type() != IdentToken) |
| 6851 if (!currentValue || currentValue->m_unit != CSSParserValue::Identifier) | |
| 6852 return nullptr; | 6880 return nullptr; |
| 6853 | 6881 |
| 6854 CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(currentValue- >string); | 6882 CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(currentToken. value()); |
| 6855 if (unresolvedProperty) { | 6883 if (unresolvedProperty) { |
| 6856 ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); | 6884 ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); |
| 6857 // Now "all" is used by both CSSValue and CSSPropertyValue. | 6885 // Now "all" is used by both CSSValue and CSSPropertyValue. |
| 6858 // Need to return nullptr when currentValue is CSSPropertyAll. | 6886 // Need to return nullptr when currentValue is CSSPropertyAll. |
| 6859 if (unresolvedProperty == CSSPropertyWillChange || unresolvedPropert y == CSSPropertyAll) | 6887 if (unresolvedProperty == CSSPropertyWillChange || unresolvedPropert y == CSSPropertyAll) |
| 6860 return nullptr; | 6888 return nullptr; |
| 6861 values->append(cssValuePool().createIdentifierValue(unresolvedProper ty)); | 6889 values->append(cssValuePool().createIdentifierValue(unresolvedProper ty)); |
| 6862 } else { | 6890 } else { |
| 6863 switch (currentValue->id) { | 6891 switch (currentToken.id()) { |
| 6864 case CSSValueNone: | 6892 case CSSValueNone: |
| 6865 case CSSValueAll: | 6893 case CSSValueAll: |
| 6866 case CSSValueAuto: | 6894 case CSSValueAuto: |
| 6867 case CSSValueDefault: | 6895 case CSSValueDefault: |
| 6868 case CSSValueInitial: | 6896 case CSSValueInitial: |
| 6869 case CSSValueInherit: | 6897 case CSSValueInherit: |
| 6870 return nullptr; | 6898 return nullptr; |
| 6871 case CSSValueContents: | 6899 case CSSValueContents: |
| 6872 case CSSValueScrollPosition: | 6900 case CSSValueScrollPosition: |
| 6873 values->append(cssValuePool().createIdentifierValue(currentValue ->id)); | 6901 values->append(cssValuePool().createIdentifierValue(currentToken .id())); |
|
Timothy Loh
2015/09/03 02:05:53
Maybe we should have something like:
static consu
rwlbuis
2015/09/03 22:27:54
Sounds good, I did that. A bit sad that we need co
Timothy Loh
2015/09/04 01:24:40
Yeah, although I think it's more indicative that t
| |
| 6874 break; | 6902 break; |
| 6875 default: | 6903 default: |
| 6876 break; | 6904 break; |
| 6877 } | 6905 } |
| 6878 } | 6906 } |
| 6879 | 6907 |
| 6880 if (!m_valueList->next()) | 6908 if (m_range->atEnd()) |
| 6881 break; | 6909 break; |
| 6882 if (!consumeComma(m_valueList)) | 6910 if (!consumeCommaIncludingWhitespace(*m_range)) |
| 6883 return nullptr; | 6911 return nullptr; |
| 6912 currentToken = m_range->consumeIncludingWhitespace(); | |
| 6884 } | 6913 } |
| 6885 | 6914 |
| 6886 return values.release(); | 6915 return values.release(); |
| 6887 } | 6916 } |
| 6888 | 6917 |
| 6889 PassRefPtrWillBeRawPtr<CSSFunctionValue> CSSPropertyParser::parseBuiltinFilterAr guments(CSSParserValueList* args, CSSValueID filterType) | 6918 PassRefPtrWillBeRawPtr<CSSFunctionValue> CSSPropertyParser::parseBuiltinFilterAr guments(CSSParserValueList* args, CSSValueID filterType) |
| 6890 { | 6919 { |
| 6891 RefPtrWillBeRawPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create( filterType); | 6920 RefPtrWillBeRawPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create( filterType); |
| 6892 ASSERT(args); | 6921 ASSERT(args); |
| 6893 | 6922 |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8092 } | 8121 } |
| 8093 } | 8122 } |
| 8094 | 8123 |
| 8095 if (!list->length()) | 8124 if (!list->length()) |
| 8096 return nullptr; | 8125 return nullptr; |
| 8097 | 8126 |
| 8098 return list.release(); | 8127 return list.release(); |
| 8099 } | 8128 } |
| 8100 | 8129 |
| 8101 } // namespace blink | 8130 } // namespace blink |
| OLD | NEW |