OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/CSSParserImpl.h" | 6 #include "core/css/parser/CSSParserImpl.h" |
7 | 7 |
8 #include "core/css/CSSKeyframesRule.h" | 8 #include "core/css/CSSKeyframesRule.h" |
9 #include "core/css/CSSStyleSheet.h" | 9 #include "core/css/CSSStyleSheet.h" |
10 #include "core/css/StylePropertySet.h" | 10 #include "core/css/StylePropertySet.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 : m_context(context) | 29 : m_context(context) |
30 , m_defaultNamespace(starAtom) | 30 , m_defaultNamespace(starAtom) |
31 , m_styleSheet(styleSheet) | 31 , m_styleSheet(styleSheet) |
32 { | 32 { |
33 CSSTokenizer::tokenize(string, m_tokens); | 33 CSSTokenizer::tokenize(string, m_tokens); |
34 } | 34 } |
35 | 35 |
36 bool CSSParserImpl::parseValue(MutableStylePropertySet* declaration, CSSProperty
ID propertyID, const String& string, bool important, const CSSParserContext& con
text) | 36 bool CSSParserImpl::parseValue(MutableStylePropertySet* declaration, CSSProperty
ID propertyID, const String& string, bool important, const CSSParserContext& con
text) |
37 { | 37 { |
38 CSSParserImpl parser(context, string); | 38 CSSParserImpl parser(context, string); |
39 CSSRuleSourceData::Type ruleType = CSSRuleSourceData::STYLE_RULE; | 39 StyleRule::Type ruleType = StyleRule::Style; |
40 if (declaration->cssParserMode() == CSSViewportRuleMode) | 40 if (declaration->cssParserMode() == CSSViewportRuleMode) |
41 ruleType = CSSRuleSourceData::VIEWPORT_RULE; | 41 ruleType = StyleRule::Viewport; |
42 parser.consumeDeclarationValue(CSSParserTokenRange(parser.m_tokens), propert
yID, important, ruleType); | 42 parser.consumeDeclarationValue(CSSParserTokenRange(parser.m_tokens), propert
yID, important, ruleType); |
43 if (parser.m_parsedProperties.isEmpty()) | 43 if (parser.m_parsedProperties.isEmpty()) |
44 return false; | 44 return false; |
45 declaration->addParsedProperties(parser.m_parsedProperties); | 45 declaration->addParsedProperties(parser.m_parsedProperties); |
46 return true; | 46 return true; |
47 } | 47 } |
48 | 48 |
49 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr
operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE
ntries, BitArray<numCSSProperties>& seenProperties) | 49 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr
operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE
ntries, BitArray<numCSSProperties>& seenProperties) |
50 { | 50 { |
51 // Add properties in reverse order so that highest priority definitions are
reached first. Duplicate definitions can then be ignored when found. | 51 // Add properties in reverse order so that highest priority definitions are
reached first. Duplicate definitions can then be ignored when found. |
(...skipping 21 matching lines...) Expand all Loading... |
73 return ImmutableStylePropertySet::create(results.data() + unusedEntries, res
ults.size() - unusedEntries, mode); | 73 return ImmutableStylePropertySet::create(results.data() + unusedEntries, res
ults.size() - unusedEntries, mode); |
74 } | 74 } |
75 | 75 |
76 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> CSSParserImpl::parseInlineStyl
eDeclaration(const String& string, Element* element) | 76 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> CSSParserImpl::parseInlineStyl
eDeclaration(const String& string, Element* element) |
77 { | 77 { |
78 Document& document = element->document(); | 78 Document& document = element->document(); |
79 CSSParserContext context = CSSParserContext(document.elementSheet().contents
()->parserContext(), UseCounter::getFrom(&document)); | 79 CSSParserContext context = CSSParserContext(document.elementSheet().contents
()->parserContext(), UseCounter::getFrom(&document)); |
80 CSSParserMode mode = element->isHTMLElement() && !document.inQuirksMode() ?
HTMLStandardMode : HTMLQuirksMode; | 80 CSSParserMode mode = element->isHTMLElement() && !document.inQuirksMode() ?
HTMLStandardMode : HTMLQuirksMode; |
81 context.setMode(mode); | 81 context.setMode(mode); |
82 CSSParserImpl parser(context, string); | 82 CSSParserImpl parser(context, string); |
83 parser.consumeDeclarationList(CSSParserTokenRange(parser.m_tokens), CSSRuleS
ourceData::STYLE_RULE); | 83 parser.consumeDeclarationList(CSSParserTokenRange(parser.m_tokens), StyleRul
e::Style); |
84 return createStylePropertySet(parser.m_parsedProperties, mode); | 84 return createStylePropertySet(parser.m_parsedProperties, mode); |
85 } | 85 } |
86 | 86 |
87 bool CSSParserImpl::parseDeclaration(MutableStylePropertySet* declaration, const
String& string, const CSSParserContext& context) | 87 bool CSSParserImpl::parseDeclaration(MutableStylePropertySet* declaration, const
String& string, const CSSParserContext& context) |
88 { | 88 { |
89 CSSParserImpl parser(context, string); | 89 CSSParserImpl parser(context, string); |
90 CSSRuleSourceData::Type ruleType = CSSRuleSourceData::STYLE_RULE; | 90 StyleRule::Type ruleType = StyleRule::Style; |
91 if (declaration->cssParserMode() == CSSViewportRuleMode) | 91 if (declaration->cssParserMode() == CSSViewportRuleMode) |
92 ruleType = CSSRuleSourceData::VIEWPORT_RULE; | 92 ruleType = StyleRule::Viewport; |
93 parser.consumeDeclarationList(CSSParserTokenRange(parser.m_tokens), ruleType
); | 93 parser.consumeDeclarationList(CSSParserTokenRange(parser.m_tokens), ruleType
); |
94 if (parser.m_parsedProperties.isEmpty()) | 94 if (parser.m_parsedProperties.isEmpty()) |
95 return false; | 95 return false; |
96 declaration->addParsedProperties(parser.m_parsedProperties); | 96 declaration->addParsedProperties(parser.m_parsedProperties); |
97 return true; | 97 return true; |
98 } | 98 } |
99 | 99 |
100 PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::parseRule(const String& str
ing, const CSSParserContext& context, AllowedRulesType allowedRules) | 100 PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::parseRule(const String& str
ing, const CSSParserContext& context, AllowedRulesType allowedRules) |
101 { | 101 { |
102 CSSParserImpl parser(context, string); | 102 CSSParserImpl parser(context, string); |
(...skipping 25 matching lines...) Expand all Loading... |
128 PassOwnPtr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& key
List) | 128 PassOwnPtr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& key
List) |
129 { | 129 { |
130 Vector<CSSParserToken> tokens; | 130 Vector<CSSParserToken> tokens; |
131 CSSTokenizer::tokenize(keyList, tokens); | 131 CSSTokenizer::tokenize(keyList, tokens); |
132 return consumeKeyframeKeyList(tokens); | 132 return consumeKeyframeKeyList(tokens); |
133 } | 133 } |
134 | 134 |
135 bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange& range) | 135 bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange& range) |
136 { | 136 { |
137 ASSERT(m_parsedProperties.isEmpty()); | 137 ASSERT(m_parsedProperties.isEmpty()); |
138 consumeDeclaration(range, CSSRuleSourceData::STYLE_RULE); | 138 consumeDeclaration(range, StyleRule::Style); |
139 bool result = !m_parsedProperties.isEmpty(); | 139 bool result = !m_parsedProperties.isEmpty(); |
140 m_parsedProperties.clear(); | 140 m_parsedProperties.clear(); |
141 return result; | 141 return result; |
142 } | 142 } |
143 | 143 |
144 static CSSParserImpl::AllowedRulesType computeNewAllowedRules(CSSParserImpl::All
owedRulesType allowedRules, StyleRuleBase* rule) | 144 static CSSParserImpl::AllowedRulesType computeNewAllowedRules(CSSParserImpl::All
owedRulesType allowedRules, StyleRuleBase* rule) |
145 { | 145 { |
146 if (!rule || allowedRules == CSSParserImpl::KeyframeRules) | 146 if (!rule || allowedRules == CSSParserImpl::KeyframeRules) |
147 return allowedRules; | 147 return allowedRules; |
148 ASSERT(allowedRules <= CSSParserImpl::RegularRules); | 148 ASSERT(allowedRules <= CSSParserImpl::RegularRules); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 | 338 |
339 PassRefPtrWillBeRawPtr<StyleRuleViewport> CSSParserImpl::consumeViewportRule(CSS
ParserTokenRange prelude, CSSParserTokenRange block) | 339 PassRefPtrWillBeRawPtr<StyleRuleViewport> CSSParserImpl::consumeViewportRule(CSS
ParserTokenRange prelude, CSSParserTokenRange block) |
340 { | 340 { |
341 // Allow @viewport rules from UA stylesheets even if the feature is disabled
. | 341 // Allow @viewport rules from UA stylesheets even if the feature is disabled
. |
342 if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_co
ntext.mode())) | 342 if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_co
ntext.mode())) |
343 return nullptr; | 343 return nullptr; |
344 | 344 |
345 prelude.consumeWhitespaceAndComments(); | 345 prelude.consumeWhitespaceAndComments(); |
346 if (!prelude.atEnd()) | 346 if (!prelude.atEnd()) |
347 return nullptr; // Parser error; @viewport prelude should be empty | 347 return nullptr; // Parser error; @viewport prelude should be empty |
348 consumeDeclarationList(block, CSSRuleSourceData::VIEWPORT_RULE); | 348 consumeDeclarationList(block, StyleRule::Viewport); |
349 RefPtrWillBeRawPtr<StyleRuleViewport> rule = StyleRuleViewport::create(); | 349 RefPtrWillBeRawPtr<StyleRuleViewport> rule = StyleRuleViewport::create(); |
350 rule->setProperties(createStylePropertySet(m_parsedProperties, CSSViewportRu
leMode)); | 350 rule->setProperties(createStylePropertySet(m_parsedProperties, CSSViewportRu
leMode)); |
351 m_parsedProperties.clear(); | 351 m_parsedProperties.clear(); |
352 return rule.release(); | 352 return rule.release(); |
353 } | 353 } |
354 | 354 |
355 PassRefPtrWillBeRawPtr<StyleRuleFontFace> CSSParserImpl::consumeFontFaceRule(CSS
ParserTokenRange prelude, CSSParserTokenRange block) | 355 PassRefPtrWillBeRawPtr<StyleRuleFontFace> CSSParserImpl::consumeFontFaceRule(CSS
ParserTokenRange prelude, CSSParserTokenRange block) |
356 { | 356 { |
357 prelude.consumeWhitespaceAndComments(); | 357 prelude.consumeWhitespaceAndComments(); |
358 if (!prelude.atEnd()) | 358 if (!prelude.atEnd()) |
359 return nullptr; // Parse error; @font-face prelude should be empty | 359 return nullptr; // Parse error; @font-face prelude should be empty |
360 consumeDeclarationList(block, CSSRuleSourceData::FONT_FACE_RULE); | 360 consumeDeclarationList(block, StyleRule::FontFace); |
361 | 361 |
362 // FIXME: This logic should be in CSSPropertyParser | 362 // FIXME: This logic should be in CSSPropertyParser |
363 // FIXME: Shouldn't we fail if font-family or src aren't specified? | 363 // FIXME: Shouldn't we fail if font-family or src aren't specified? |
364 for (unsigned i = 0; i < m_parsedProperties.size(); ++i) { | 364 for (unsigned i = 0; i < m_parsedProperties.size(); ++i) { |
365 CSSProperty& property = m_parsedProperties[i]; | 365 CSSProperty& property = m_parsedProperties[i]; |
366 if (property.id() == CSSPropertyFontVariant && property.value()->isPrimi
tiveValue()) { | 366 if (property.id() == CSSPropertyFontVariant && property.value()->isPrimi
tiveValue()) { |
367 property.wrapValueInCommaSeparatedList(); | 367 property.wrapValueInCommaSeparatedList(); |
368 } else if (property.id() == CSSPropertyFontFamily && (!property.value()-
>isValueList() || toCSSValueList(property.value())->length() != 1)) { | 368 } else if (property.id() == CSSPropertyFontFamily && (!property.value()-
>isValueList() || toCSSValueList(property.value())->length() != 1)) { |
369 m_parsedProperties.clear(); | 369 m_parsedProperties.clear(); |
370 return nullptr; | 370 return nullptr; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 selector->prependTagSelector(QualifiedName(nullAtom, typeSelector, m
_defaultNamespace)); | 441 selector->prependTagSelector(QualifiedName(nullAtom, typeSelector, m
_defaultNamespace)); |
442 } | 442 } |
443 | 443 |
444 selector->setForPage(); | 444 selector->setForPage(); |
445 | 445 |
446 RefPtrWillBeRawPtr<StyleRulePage> pageRule = StyleRulePage::create(); | 446 RefPtrWillBeRawPtr<StyleRulePage> pageRule = StyleRulePage::create(); |
447 Vector<OwnPtr<CSSParserSelector>> selectorVector; | 447 Vector<OwnPtr<CSSParserSelector>> selectorVector; |
448 selectorVector.append(selector.release()); | 448 selectorVector.append(selector.release()); |
449 pageRule->parserAdoptSelectorVector(selectorVector); | 449 pageRule->parserAdoptSelectorVector(selectorVector); |
450 | 450 |
451 consumeDeclarationList(block, CSSRuleSourceData::STYLE_RULE); | 451 consumeDeclarationList(block, StyleRule::Style); |
452 pageRule->setProperties(createStylePropertySet(m_parsedProperties, m_context
.mode())); | 452 pageRule->setProperties(createStylePropertySet(m_parsedProperties, m_context
.mode())); |
453 m_parsedProperties.clear(); | 453 m_parsedProperties.clear(); |
454 | 454 |
455 return pageRule.release(); | 455 return pageRule.release(); |
456 } | 456 } |
457 | 457 |
458 PassRefPtrWillBeRawPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRul
e(CSSParserTokenRange prelude, CSSParserTokenRange block) | 458 PassRefPtrWillBeRawPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRul
e(CSSParserTokenRange prelude, CSSParserTokenRange block) |
459 { | 459 { |
460 OwnPtr<Vector<double>> keyList = consumeKeyframeKeyList(prelude); | 460 OwnPtr<Vector<double>> keyList = consumeKeyframeKeyList(prelude); |
461 if (!keyList) | 461 if (!keyList) |
462 return nullptr; | 462 return nullptr; |
463 consumeDeclarationList(block, CSSRuleSourceData::KEYFRAMES_RULE); | 463 consumeDeclarationList(block, StyleRule::Keyframes); |
464 RefPtrWillBeRawPtr<StyleRuleKeyframe> rule = StyleRuleKeyframe::create(); | 464 RefPtrWillBeRawPtr<StyleRuleKeyframe> rule = StyleRuleKeyframe::create(); |
465 rule->setKeys(keyList.release()); | 465 rule->setKeys(keyList.release()); |
466 rule->setProperties(createStylePropertySet(m_parsedProperties, m_context.mod
e())); | 466 rule->setProperties(createStylePropertySet(m_parsedProperties, m_context.mod
e())); |
467 m_parsedProperties.clear(); | 467 m_parsedProperties.clear(); |
468 return rule.release(); | 468 return rule.release(); |
469 } | 469 } |
470 | 470 |
471 PassRefPtrWillBeRawPtr<StyleRule> CSSParserImpl::consumeStyleRule(CSSParserToken
Range prelude, CSSParserTokenRange block) | 471 PassRefPtrWillBeRawPtr<StyleRule> CSSParserImpl::consumeStyleRule(CSSParserToken
Range prelude, CSSParserTokenRange block) |
472 { | 472 { |
473 CSSSelectorList selectorList; | 473 CSSSelectorList selectorList; |
474 CSSSelectorParser::parseSelector(prelude, m_context, m_defaultNamespace, m_s
tyleSheet, selectorList); | 474 CSSSelectorParser::parseSelector(prelude, m_context, m_defaultNamespace, m_s
tyleSheet, selectorList); |
475 if (!selectorList.isValid()) | 475 if (!selectorList.isValid()) |
476 return nullptr; // Parse error, invalid selector list | 476 return nullptr; // Parse error, invalid selector list |
477 consumeDeclarationList(block, CSSRuleSourceData::STYLE_RULE); | 477 consumeDeclarationList(block, StyleRule::Style); |
478 | 478 |
479 RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create(); | 479 RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create(); |
480 rule->wrapperAdoptSelectorList(selectorList); | 480 rule->wrapperAdoptSelectorList(selectorList); |
481 rule->setProperties(createStylePropertySet(m_parsedProperties, m_context.mod
e())); | 481 rule->setProperties(createStylePropertySet(m_parsedProperties, m_context.mod
e())); |
482 m_parsedProperties.clear(); | 482 m_parsedProperties.clear(); |
483 return rule.release(); | 483 return rule.release(); |
484 } | 484 } |
485 | 485 |
486 void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, CSSRuleSou
rceData::Type ruleType) | 486 void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, StyleRule:
:Type ruleType) |
487 { | 487 { |
488 ASSERT(m_parsedProperties.isEmpty()); | 488 ASSERT(m_parsedProperties.isEmpty()); |
489 | 489 |
490 while (!range.atEnd()) { | 490 while (!range.atEnd()) { |
491 switch (range.peek().type()) { | 491 switch (range.peek().type()) { |
492 case CommentToken: | 492 case CommentToken: |
493 case WhitespaceToken: | 493 case WhitespaceToken: |
494 case SemicolonToken: | 494 case SemicolonToken: |
495 range.consume(); | 495 range.consume(); |
496 break; | 496 break; |
497 case IdentToken: { | 497 case IdentToken: { |
498 const CSSParserToken* declarationStart = &range.peek(); | 498 const CSSParserToken* declarationStart = &range.peek(); |
499 while (!range.atEnd() && range.peek().type() != SemicolonToken) | 499 while (!range.atEnd() && range.peek().type() != SemicolonToken) |
500 range.consumeComponentValue(); | 500 range.consumeComponentValue(); |
501 consumeDeclaration(range.makeSubRange(declarationStart, &range.peek(
)), ruleType); | 501 consumeDeclaration(range.makeSubRange(declarationStart, &range.peek(
)), ruleType); |
502 break; | 502 break; |
503 } | 503 } |
504 default: // Parser error | 504 default: // Parser error |
505 // FIXME: The spec allows at-rules in a declaration list | 505 // FIXME: The spec allows at-rules in a declaration list |
506 while (!range.atEnd() && range.peek().type() != SemicolonToken) | 506 while (!range.atEnd() && range.peek().type() != SemicolonToken) |
507 range.consumeComponentValue(); | 507 range.consumeComponentValue(); |
508 break; | 508 break; |
509 } | 509 } |
510 } | 510 } |
511 } | 511 } |
512 | 512 |
513 void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, CSSRuleSourceD
ata::Type ruleType) | 513 void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Typ
e ruleType) |
514 { | 514 { |
515 ASSERT(range.peek().type() == IdentToken); | 515 ASSERT(range.peek().type() == IdentToken); |
516 CSSPropertyID id = range.consumeIncludingWhitespaceAndComments().parseAsCSSP
ropertyID(); | 516 CSSPropertyID id = range.consumeIncludingWhitespaceAndComments().parseAsCSSP
ropertyID(); |
517 if (id == CSSPropertyInvalid) | 517 if (id == CSSPropertyInvalid) |
518 return; | 518 return; |
519 if (range.consume().type() != ColonToken) | 519 if (range.consume().type() != ColonToken) |
520 return; // Parse error | 520 return; // Parse error |
521 | 521 |
522 // FIXME: We shouldn't allow !important in @keyframes or @font-face | 522 // FIXME: We shouldn't allow !important in @keyframes or @font-face |
523 const CSSParserToken* last = range.end() - 1; | 523 const CSSParserToken* last = range.end() - 1; |
524 while (last->type() == WhitespaceToken || last->type() == CommentToken) | 524 while (last->type() == WhitespaceToken || last->type() == CommentToken) |
525 --last; | 525 --last; |
526 if (last->type() == IdentToken && equalIgnoringCase(last->value(), "importan
t")) { | 526 if (last->type() == IdentToken && equalIgnoringCase(last->value(), "importan
t")) { |
527 --last; | 527 --last; |
528 while (last->type() == WhitespaceToken || last->type() == CommentToken) | 528 while (last->type() == WhitespaceToken || last->type() == CommentToken) |
529 --last; | 529 --last; |
530 if (last->type() == DelimiterToken && last->delimiter() == '!') { | 530 if (last->type() == DelimiterToken && last->delimiter() == '!') { |
531 consumeDeclarationValue(range.makeSubRange(&range.peek(), last), id,
true, ruleType); | 531 consumeDeclarationValue(range.makeSubRange(&range.peek(), last), id,
true, ruleType); |
532 return; | 532 return; |
533 } | 533 } |
534 } | 534 } |
535 consumeDeclarationValue(range.makeSubRange(&range.peek(), range.end()), id,
false, ruleType); | 535 consumeDeclarationValue(range.makeSubRange(&range.peek(), range.end()), id,
false, ruleType); |
536 } | 536 } |
537 | 537 |
538 void CSSParserImpl::consumeDeclarationValue(CSSParserTokenRange range, CSSProper
tyID propertyID, bool important, CSSRuleSourceData::Type ruleType) | 538 void CSSParserImpl::consumeDeclarationValue(CSSParserTokenRange range, CSSProper
tyID propertyID, bool important, StyleRule::Type ruleType) |
539 { | 539 { |
540 CSSParserValueList valueList(range); | 540 CSSParserValueList valueList(range); |
541 if (!valueList.size()) | 541 if (!valueList.size()) |
542 return; // Parser error | 542 return; // Parser error |
543 bool inViewport = ruleType == CSSRuleSourceData::VIEWPORT_RULE; | 543 bool inViewport = ruleType == StyleRule::Viewport; |
544 CSSPropertyParser::parseValue(propertyID, important, &valueList, m_context,
inViewport, m_parsedProperties, ruleType); | 544 CSSPropertyParser::parseValue(propertyID, important, &valueList, m_context,
inViewport, m_parsedProperties, ruleType); |
545 } | 545 } |
546 | 546 |
547 PassOwnPtr<Vector<double>> CSSParserImpl::consumeKeyframeKeyList(CSSParserTokenR
ange range) | 547 PassOwnPtr<Vector<double>> CSSParserImpl::consumeKeyframeKeyList(CSSParserTokenR
ange range) |
548 { | 548 { |
549 OwnPtr<Vector<double>> result = adoptPtr(new Vector<double>); | 549 OwnPtr<Vector<double>> result = adoptPtr(new Vector<double>); |
550 while (true) { | 550 while (true) { |
551 range.consumeWhitespaceAndComments(); | 551 range.consumeWhitespaceAndComments(); |
552 const CSSParserToken& token = range.consumeIncludingWhitespaceAndComment
s(); | 552 const CSSParserToken& token = range.consumeIncludingWhitespaceAndComment
s(); |
553 if (token.type() == PercentageToken && token.numericValue() >= 0 && toke
n.numericValue() <= 100) | 553 if (token.type() == PercentageToken && token.numericValue() >= 0 && toke
n.numericValue() <= 100) |
554 result->append(token.numericValue() / 100); | 554 result->append(token.numericValue() / 100); |
555 else if (token.type() == IdentToken && equalIgnoringCase(token.value(),
"from")) | 555 else if (token.type() == IdentToken && equalIgnoringCase(token.value(),
"from")) |
556 result->append(0); | 556 result->append(0); |
557 else if (token.type() == IdentToken && equalIgnoringCase(token.value(),
"to")) | 557 else if (token.type() == IdentToken && equalIgnoringCase(token.value(),
"to")) |
558 result->append(1); | 558 result->append(1); |
559 else | 559 else |
560 return nullptr; // Parser error, invalid value in keyframe selector | 560 return nullptr; // Parser error, invalid value in keyframe selector |
561 if (range.atEnd()) | 561 if (range.atEnd()) |
562 return result.release(); | 562 return result.release(); |
563 if (range.consume().type() != CommaToken) | 563 if (range.consume().type() != CommaToken) |
564 return nullptr; // Parser error | 564 return nullptr; // Parser error |
565 } | 565 } |
566 } | 566 } |
567 | 567 |
568 } // namespace blink | 568 } // namespace blink |
OLD | NEW |