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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 template <unsigned N> | 67 template <unsigned N> |
| 68 static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N]) | 68 static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N]) |
| 69 { | 69 { |
| 70 unsigned length = N - 1; // Ignore the trailing null character | 70 unsigned length = N - 1; // Ignore the trailing null character |
| 71 if (a.length() != length) | 71 if (a.length() != length) |
| 72 return false; | 72 return false; |
| 73 | 73 |
| 74 return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF ::equalIgnoringCase(b, a.characters16(), length); | 74 return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF ::equalIgnoringCase(b, a.characters16(), length); |
| 75 } | 75 } |
| 76 | 76 |
| 77 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, | 77 CSSPropertyParser::CSSPropertyParser(CSSParserValueList* valueList, const CSSPar serTokenRange& range, |
| 78 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, | 78 const CSSParserContext& context, WillBeHeapVector<CSSProperty, 256>& parsedP roperties, |
| 79 StyleRule::Type ruleType) | 79 StyleRule::Type ruleType) |
| 80 : m_valueList(valueList) | 80 : m_valueList(valueList) |
| 81 , m_range(range) | |
| 81 , m_context(context) | 82 , m_context(context) |
| 82 , m_parsedProperties(parsedProperties) | 83 , m_parsedProperties(parsedProperties) |
| 83 , m_ruleType(ruleType) | 84 , m_ruleType(ruleType) |
| 84 , m_inParseShorthand(0) | 85 , m_inParseShorthand(0) |
| 85 , m_currentShorthand(CSSPropertyInvalid) | 86 , m_currentShorthand(CSSPropertyInvalid) |
| 86 , m_implicitShorthand(false) | 87 , m_implicitShorthand(false) |
| 87 { | 88 { |
| 88 } | 89 } |
| 89 | 90 |
| 90 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, | 91 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant, |
| 91 CSSParserValueList* valueList, const CSSParserContext& context, | 92 const CSSParserTokenRange& range, const CSSParserContext& context, |
| 92 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) | 93 WillBeHeapVector<CSSProperty, 256>& parsedProperties, StyleRule::Type ruleTy pe) |
| 93 { | 94 { |
| 94 int parsedPropertiesSize = parsedProperties.size(); | 95 int parsedPropertiesSize = parsedProperties.size(); |
| 95 | 96 |
| 96 CSSPropertyParser parser(valueList, context, parsedProperties, ruleType); | 97 CSSParserValueList valueList(range); |
|
Timothy Loh
2015/09/04 01:24:40
Probably OK for now but at some point this needs t
| |
| 98 if (!valueList.size()) | |
| 99 return false; // Parser error | |
| 100 CSSPropertyParser parser(&valueList, range, context, parsedProperties, ruleT ype); | |
| 97 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); | 101 CSSPropertyID resolvedProperty = resolveCSSPropertyID(unresolvedProperty); |
| 98 bool parseSuccess; | 102 bool parseSuccess; |
| 99 | 103 |
| 100 if (ruleType == StyleRule::Viewport) { | 104 if (ruleType == StyleRule::Viewport) { |
| 101 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) | 105 parseSuccess = (RuntimeEnabledFeatures::cssViewportEnabled() || isUAShee tBehavior(context.mode())) |
| 102 && parser.parseViewportProperty(resolvedProperty, important); | 106 && parser.parseViewportProperty(resolvedProperty, important); |
| 103 } else if (ruleType == StyleRule::FontFace) { | 107 } else if (ruleType == StyleRule::FontFace) { |
| 104 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); | 108 parseSuccess = parser.parseFontFaceDescriptor(resolvedProperty); |
| 105 } else { | 109 } else { |
| 106 parseSuccess = parser.parseValue(unresolvedProperty, important); | 110 parseSuccess = parser.parseValue(unresolvedProperty, important); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 | 332 |
| 329 static bool consumeComma(CSSParserValueList* valueList) | 333 static bool consumeComma(CSSParserValueList* valueList) |
| 330 { | 334 { |
| 331 CSSParserValue* value = valueList->current(); | 335 CSSParserValue* value = valueList->current(); |
| 332 if (!value || !isComma(value)) | 336 if (!value || !isComma(value)) |
| 333 return false; | 337 return false; |
| 334 valueList->next(); | 338 valueList->next(); |
| 335 return true; | 339 return true; |
| 336 } | 340 } |
| 337 | 341 |
| 342 static bool consumeCommaIncludingWhitespace(CSSParserTokenRange& valueList) | |
| 343 { | |
| 344 CSSParserToken value = valueList.peek(); | |
| 345 if (value.type() != CommaToken) | |
| 346 return false; | |
| 347 valueList.consumeIncludingWhitespace(); | |
| 348 return true; | |
| 349 } | |
| 350 | |
| 338 static inline bool isForwardSlashOperator(CSSParserValue* value) | 351 static inline bool isForwardSlashOperator(CSSParserValue* value) |
| 339 { | 352 { |
| 340 ASSERT(value); | 353 ASSERT(value); |
| 341 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; | 354 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; |
| 342 } | 355 } |
| 343 | 356 |
| 344 static bool isGeneratedImageValue(CSSParserValue* val) | 357 static bool isGeneratedImageValue(CSSParserValue* val) |
| 345 { | 358 { |
| 346 if (val->m_unit != CSSParserValue::Function) | 359 if (val->m_unit != CSSParserValue::Function) |
| 347 return false; | 360 return false; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 return; | 437 return; |
| 425 } | 438 } |
| 426 | 439 |
| 427 RefPtrWillBeRawPtr<CSSValue> value = prpValue; | 440 RefPtrWillBeRawPtr<CSSValue> value = prpValue; |
| 428 ShorthandScope scope(this, propId); | 441 ShorthandScope scope(this, propId); |
| 429 const CSSPropertyID* longhands = shorthand.properties(); | 442 const CSSPropertyID* longhands = shorthand.properties(); |
| 430 for (unsigned i = 0; i < shorthandLength; ++i) | 443 for (unsigned i = 0; i < shorthandLength; ++i) |
| 431 addProperty(longhands[i], value, important); | 444 addProperty(longhands[i], value, important); |
| 432 } | 445 } |
| 433 | 446 |
| 447 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID propId) | |
| 448 { | |
| 449 m_range.consumeWhitespace(); | |
| 450 switch (propId) { | |
| 451 case CSSPropertyWillChange: | |
| 452 return parseWillChange(); | |
| 453 default: | |
| 454 ASSERT_NOT_REACHED(); | |
| 455 } | |
| 456 return nullptr; | |
| 457 } | |
| 458 | |
| 434 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant) | 459 bool CSSPropertyParser::parseValue(CSSPropertyID unresolvedProperty, bool import ant) |
| 435 { | 460 { |
| 436 CSSPropertyID propId = resolveCSSPropertyID(unresolvedProperty); | 461 CSSPropertyID propId = resolveCSSPropertyID(unresolvedProperty); |
| 437 | 462 |
| 438 CSSParserValue* value = m_valueList->current(); | 463 CSSParserValue* value = m_valueList->current(); |
| 439 | 464 |
| 440 // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function. | 465 // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function. |
| 441 // FIXME: This is to avoid having to pass parsedCalc to all validUnit caller s. | 466 // FIXME: This is to avoid having to pass parsedCalc to all validUnit caller s. |
| 442 ASSERT(!m_parsedCalculation); | 467 ASSERT(!m_parsedCalculation); |
| 443 | 468 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 462 | 487 |
| 463 if (CSSParserFastPaths::isKeywordPropertyID(propId)) { | 488 if (CSSParserFastPaths::isKeywordPropertyID(propId)) { |
| 464 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) | 489 if (!CSSParserFastPaths::isValidKeywordPropertyAndValue(propId, id)) |
| 465 return false; | 490 return false; |
| 466 if (m_valueList->next() && !inShorthand()) | 491 if (m_valueList->next() && !inShorthand()) |
| 467 return false; | 492 return false; |
| 468 addProperty(propId, cssValuePool().createIdentifierValue(id), important) ; | 493 addProperty(propId, cssValuePool().createIdentifierValue(id), important) ; |
| 469 return true; | 494 return true; |
| 470 } | 495 } |
| 471 | 496 |
| 497 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
| 498 if (propId == CSSPropertyWillChange) { | |
| 499 parsedValue = parseSingleValue(propId); | |
| 500 if (!parsedValue || !m_range.atEnd()) | |
| 501 return false; | |
| 502 addProperty(propId, parsedValue.release(), important); | |
| 503 return true; | |
| 504 } | |
| 505 | |
| 472 bool validPrimitive = false; | 506 bool validPrimitive = false; |
| 473 Units unitless = FUnknown; | 507 Units unitless = FUnknown; |
| 474 RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr; | |
| 475 | 508 |
| 476 switch (propId) { | 509 switch (propId) { |
| 477 case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] | 510 case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ] |
| 478 parsedValue = parseSize(); | 511 parsedValue = parseSize(); |
| 479 break; | 512 break; |
| 480 case CSSPropertyQuotes: // [<string> <string>]+ | none | 513 case CSSPropertyQuotes: // [<string> <string>]+ | none |
| 481 if (id == CSSValueNone) | 514 if (id == CSSValueNone) |
| 482 validPrimitive = true; | 515 validPrimitive = true; |
| 483 else | 516 else |
| 484 parsedValue = parseQuotes(); | 517 parsedValue = parseQuotes(); |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1309 validPrimitive = true; | 1342 validPrimitive = true; |
| 1310 else | 1343 else |
| 1311 validPrimitive = validUnit(value, FLength | FNonNeg); | 1344 validPrimitive = validUnit(value, FLength | FNonNeg); |
| 1312 break; | 1345 break; |
| 1313 case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) | 1346 case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property) |
| 1314 validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit () == CSSPrimitiveValue::UnitType::Number && value->fValue == 1); | 1347 validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit () == CSSPrimitiveValue::UnitType::Number && value->fValue == 1); |
| 1315 break; | 1348 break; |
| 1316 case CSSPropertyWebkitColumnWidth: // auto | <length> | 1349 case CSSPropertyWebkitColumnWidth: // auto | <length> |
| 1317 parsedValue = parseColumnWidth(); | 1350 parsedValue = parseColumnWidth(); |
| 1318 break; | 1351 break; |
| 1319 case CSSPropertyWillChange: | |
| 1320 parsedValue = parseWillChange(); | |
| 1321 break; | |
| 1322 // End of CSS3 properties | 1352 // End of CSS3 properties |
| 1323 | 1353 |
| 1324 // Apple specific properties. These will never be standardized and are pure ly to | 1354 // Apple specific properties. These will never be standardized and are pure ly to |
| 1325 // support custom WebKit-based Apple applications. | 1355 // support custom WebKit-based Apple applications. |
| 1326 case CSSPropertyWebkitLineClamp: | 1356 case CSSPropertyWebkitLineClamp: |
| 1327 // When specifying number of lines, don't allow 0 as a valid value | 1357 // When specifying number of lines, don't allow 0 as a valid value |
| 1328 // When specifying either type of unit, require non-negative integers | 1358 // When specifying either type of unit, require non-negative integers |
| 1329 validPrimitive = (!id && !isCalculation(value) && validUnit(value, FInte ger | FPercent | FNonNeg) && (value->unit() == CSSPrimitiveValue::UnitType::Perc entage || value->fValue)); | 1359 validPrimitive = (!id && !isCalculation(value) && validUnit(value, FInte ger | FPercent | FNonNeg) && (value->unit() == CSSPrimitiveValue::UnitType::Perc entage || value->fValue)); |
| 1330 break; | 1360 break; |
| 1331 | 1361 |
| (...skipping 5472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6804 break; | 6834 break; |
| 6805 | 6835 |
| 6806 // If there are more arguments, they should be after a comma. | 6836 // If there are more arguments, they should be after a comma. |
| 6807 if (!consumeComma(functionArgs)) | 6837 if (!consumeComma(functionArgs)) |
| 6808 return nullptr; | 6838 return nullptr; |
| 6809 } | 6839 } |
| 6810 | 6840 |
| 6811 return imageSet.release(); | 6841 return imageSet.release(); |
| 6812 } | 6842 } |
| 6813 | 6843 |
| 6844 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRang e& range) | |
| 6845 { | |
| 6846 ASSERT(range.peek().type() == IdentToken); | |
| 6847 return cssValuePool().createIdentifierValue(range.consumeIncludingWhitespace ().id()); | |
| 6848 } | |
| 6849 | |
| 6814 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseWillChange() | 6850 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseWillChange() |
| 6815 { | 6851 { |
| 6816 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 6852 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
| 6817 if (m_valueList->current()->id == CSSValueAuto) { | 6853 if (m_range.peek().id() == CSSValueAuto) { |
| 6818 // FIXME: This will be read back as an empty string instead of auto | 6854 // FIXME: This will be read back as an empty string instead of auto |
| 6855 m_range.consumeIncludingWhitespace(); | |
| 6819 return values.release(); | 6856 return values.release(); |
| 6820 } | 6857 } |
| 6821 | 6858 |
| 6822 // Every comma-separated list of identifiers is a valid will-change value, | 6859 // Every comma-separated list of identifiers is a valid will-change value, |
| 6823 // unless the list includes an explicitly disallowed identifier. | 6860 // unless the list includes an explicitly disallowed identifier. |
| 6824 while (true) { | 6861 while (true) { |
| 6825 CSSParserValue* currentValue = m_valueList->current(); | 6862 if (m_range.peek().type() != IdentToken) |
| 6826 if (!currentValue || currentValue->m_unit != CSSParserValue::Identifier) | |
| 6827 return nullptr; | 6863 return nullptr; |
| 6828 | 6864 CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(m_range.peek( ).value()); |
| 6829 CSSPropertyID unresolvedProperty = unresolvedCSSPropertyID(currentValue- >string); | |
| 6830 if (unresolvedProperty) { | 6865 if (unresolvedProperty) { |
| 6831 ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); | 6866 ASSERT(CSSPropertyMetadata::isEnabledProperty(unresolvedProperty)); |
| 6832 // Now "all" is used by both CSSValue and CSSPropertyValue. | 6867 // Now "all" is used by both CSSValue and CSSPropertyValue. |
| 6833 // Need to return nullptr when currentValue is CSSPropertyAll. | 6868 // Need to return nullptr when currentValue is CSSPropertyAll. |
| 6834 if (unresolvedProperty == CSSPropertyWillChange || unresolvedPropert y == CSSPropertyAll) | 6869 if (unresolvedProperty == CSSPropertyWillChange || unresolvedPropert y == CSSPropertyAll) |
| 6835 return nullptr; | 6870 return nullptr; |
| 6836 values->append(cssValuePool().createIdentifierValue(unresolvedProper ty)); | 6871 values->append(cssValuePool().createIdentifierValue(unresolvedProper ty)); |
| 6872 m_range.consumeIncludingWhitespace(); | |
| 6837 } else { | 6873 } else { |
| 6838 switch (currentValue->id) { | 6874 switch (m_range.peek().id()) { |
| 6839 case CSSValueNone: | 6875 case CSSValueNone: |
| 6840 case CSSValueAll: | 6876 case CSSValueAll: |
| 6841 case CSSValueAuto: | 6877 case CSSValueAuto: |
| 6842 case CSSValueDefault: | 6878 case CSSValueDefault: |
| 6843 case CSSValueInitial: | 6879 case CSSValueInitial: |
| 6844 case CSSValueInherit: | 6880 case CSSValueInherit: |
| 6845 return nullptr; | 6881 return nullptr; |
| 6846 case CSSValueContents: | 6882 case CSSValueContents: |
| 6847 case CSSValueScrollPosition: | 6883 case CSSValueScrollPosition: |
| 6848 values->append(cssValuePool().createIdentifierValue(currentValue ->id)); | 6884 values->append(consumeIdent(m_range)); |
| 6849 break; | 6885 break; |
| 6850 default: | 6886 default: |
| 6887 m_range.consumeIncludingWhitespace(); | |
| 6851 break; | 6888 break; |
| 6852 } | 6889 } |
| 6853 } | 6890 } |
| 6854 | 6891 |
| 6855 if (!m_valueList->next()) | 6892 if (m_range.atEnd()) |
| 6856 break; | 6893 break; |
| 6857 if (!consumeComma(m_valueList)) | 6894 if (!consumeCommaIncludingWhitespace(m_range)) |
| 6858 return nullptr; | 6895 return nullptr; |
| 6859 } | 6896 } |
| 6860 | 6897 |
| 6861 return values.release(); | 6898 return values.release(); |
| 6862 } | 6899 } |
| 6863 | 6900 |
| 6864 PassRefPtrWillBeRawPtr<CSSFunctionValue> CSSPropertyParser::parseBuiltinFilterAr guments(CSSParserValueList* args, CSSValueID filterType) | 6901 PassRefPtrWillBeRawPtr<CSSFunctionValue> CSSPropertyParser::parseBuiltinFilterAr guments(CSSParserValueList* args, CSSValueID filterType) |
| 6865 { | 6902 { |
| 6866 RefPtrWillBeRawPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create( filterType); | 6903 RefPtrWillBeRawPtr<CSSFunctionValue> filterValue = CSSFunctionValue::create( filterType); |
| 6867 ASSERT(args); | 6904 ASSERT(args); |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8037 } | 8074 } |
| 8038 } | 8075 } |
| 8039 | 8076 |
| 8040 if (!list->length()) | 8077 if (!list->length()) |
| 8041 return nullptr; | 8078 return nullptr; |
| 8042 | 8079 |
| 8043 return list.release(); | 8080 return list.release(); |
| 8044 } | 8081 } |
| 8045 | 8082 |
| 8046 } // namespace blink | 8083 } // namespace blink |
| OLD | NEW |