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 |