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 "core/css/parser/CSSParserImpl.h" | 5 #include "core/css/parser/CSSParserImpl.h" |
6 | 6 |
| 7 #include "core/css/CSSCustomIdentValue.h" |
7 #include "core/css/CSSCustomPropertyDeclaration.h" | 8 #include "core/css/CSSCustomPropertyDeclaration.h" |
8 #include "core/css/CSSKeyframesRule.h" | 9 #include "core/css/CSSKeyframesRule.h" |
9 #include "core/css/CSSStyleSheet.h" | 10 #include "core/css/CSSStyleSheet.h" |
10 #include "core/css/StylePropertySet.h" | 11 #include "core/css/StylePropertySet.h" |
11 #include "core/css/StyleRuleImport.h" | 12 #include "core/css/StyleRuleImport.h" |
12 #include "core/css/StyleRuleKeyframe.h" | 13 #include "core/css/StyleRuleKeyframe.h" |
13 #include "core/css/StyleRuleNamespace.h" | 14 #include "core/css/StyleRuleNamespace.h" |
14 #include "core/css/StyleSheetContents.h" | 15 #include "core/css/StyleSheetContents.h" |
15 #include "core/css/parser/CSSAtRuleID.h" | 16 #include "core/css/parser/CSSAtRuleID.h" |
16 #include "core/css/parser/CSSParserObserver.h" | 17 #include "core/css/parser/CSSParserObserver.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 const CSSProperty& property = input[i]; | 69 const CSSProperty& property = input[i]; |
69 if (property.isImportant() != important) | 70 if (property.isImportant() != important) |
70 continue; | 71 continue; |
71 const unsigned propertyIDIndex = property.id() - firstCSSProperty; | 72 const unsigned propertyIDIndex = property.id() - firstCSSProperty; |
72 | 73 |
73 if (property.id() == CSSPropertyVariable) { | 74 if (property.id() == CSSPropertyVariable) { |
74 const AtomicString& name = toCSSCustomPropertyDeclaration(property.v
alue())->name(); | 75 const AtomicString& name = toCSSCustomPropertyDeclaration(property.v
alue())->name(); |
75 if (seenCustomProperties.contains(name)) | 76 if (seenCustomProperties.contains(name)) |
76 continue; | 77 continue; |
77 seenCustomProperties.add(name); | 78 seenCustomProperties.add(name); |
| 79 } else if (property.id() == CSSPropertyApplyAtRule) { |
| 80 // TODO(timloh): Do we need to do anything here? |
78 } else { | 81 } else { |
79 if (seenProperties.get(propertyIDIndex)) | 82 if (seenProperties.get(propertyIDIndex)) |
80 continue; | 83 continue; |
81 seenProperties.set(propertyIDIndex); | 84 seenProperties.set(propertyIDIndex); |
82 } | 85 } |
83 output[--unusedEntries] = property; | 86 output[--unusedEntries] = property; |
84 } | 87 } |
85 } | 88 } |
86 | 89 |
87 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet(
WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode) | 90 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet(
WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode) |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 220 } |
218 } | 221 } |
219 | 222 |
220 selector->setForPage(); | 223 selector->setForPage(); |
221 Vector<OwnPtr<CSSParserSelector>> selectorVector; | 224 Vector<OwnPtr<CSSParserSelector>> selectorVector; |
222 selectorVector.append(selector.release()); | 225 selectorVector.append(selector.release()); |
223 CSSSelectorList selectorList = CSSSelectorList::adoptSelectorVector(selector
Vector); | 226 CSSSelectorList selectorList = CSSSelectorList::adoptSelectorVector(selector
Vector); |
224 return selectorList; | 227 return selectorList; |
225 } | 228 } |
226 | 229 |
| 230 PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> CSSParserImpl::parseCustomProp
ertySet(CSSParserTokenRange range) |
| 231 { |
| 232 range.consumeWhitespace(); |
| 233 if (range.peek().type() != LeftBraceToken) |
| 234 return nullptr; |
| 235 CSSParserTokenRange block = range.consumeBlock(); |
| 236 range.consumeWhitespace(); |
| 237 if (!range.atEnd()) |
| 238 return nullptr; |
| 239 CSSParserImpl parser(strictCSSParserContext()); |
| 240 parser.consumeDeclarationList(block, StyleRule::Style); |
| 241 |
| 242 // Drop nested @apply rules. Seems nicer to do this here instead of making |
| 243 // a different StyleRule type |
| 244 for (size_t i = parser.m_parsedProperties.size(); i--; ) { |
| 245 if (parser.m_parsedProperties[i].id() == CSSPropertyApplyAtRule) |
| 246 parser.m_parsedProperties.remove(i); |
| 247 } |
| 248 |
| 249 return createStylePropertySet(parser.m_parsedProperties, HTMLStandardMode); |
| 250 } |
| 251 |
227 PassOwnPtr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& key
List) | 252 PassOwnPtr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& key
List) |
228 { | 253 { |
229 return consumeKeyframeKeyList(CSSTokenizer::Scope(keyList).tokenRange()); | 254 return consumeKeyframeKeyList(CSSTokenizer::Scope(keyList).tokenRange()); |
230 } | 255 } |
231 | 256 |
232 bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange& range) | 257 bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange& range) |
233 { | 258 { |
234 ASSERT(m_parsedProperties.isEmpty()); | 259 ASSERT(m_parsedProperties.isEmpty()); |
235 consumeDeclaration(range, StyleRule::Style); | 260 consumeDeclaration(range, StyleRule::Style); |
236 bool result = !m_parsedProperties.isEmpty(); | 261 bool result = !m_parsedProperties.isEmpty(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 countAtRule(m_context.useCounter(), id); | 367 countAtRule(m_context.useCounter(), id); |
343 | 368 |
344 if (range.atEnd() || range.peek().type() == SemicolonToken) { | 369 if (range.atEnd() || range.peek().type() == SemicolonToken) { |
345 range.consume(); | 370 range.consume(); |
346 if (allowedRules == AllowCharsetRules && id == CSSAtRuleCharset) | 371 if (allowedRules == AllowCharsetRules && id == CSSAtRuleCharset) |
347 return consumeCharsetRule(prelude); | 372 return consumeCharsetRule(prelude); |
348 if (allowedRules <= AllowImportRules && id == CSSAtRuleImport) | 373 if (allowedRules <= AllowImportRules && id == CSSAtRuleImport) |
349 return consumeImportRule(prelude); | 374 return consumeImportRule(prelude); |
350 if (allowedRules <= AllowNamespaceRules && id == CSSAtRuleNamespace) | 375 if (allowedRules <= AllowNamespaceRules && id == CSSAtRuleNamespace) |
351 return consumeNamespaceRule(prelude); | 376 return consumeNamespaceRule(prelude); |
| 377 if (allowedRules == ApplyRules && id == CSSAtRuleApply) { |
| 378 consumeApplyRule(prelude); |
| 379 return nullptr; // consumeApplyRule just updates m_parsedProperties |
| 380 } |
352 return nullptr; // Parse error, unrecognised at-rule without block | 381 return nullptr; // Parse error, unrecognised at-rule without block |
353 } | 382 } |
354 | 383 |
355 CSSParserTokenRange block = range.consumeBlock(); | 384 CSSParserTokenRange block = range.consumeBlock(); |
356 if (allowedRules == KeyframeRules) | 385 if (allowedRules == KeyframeRules) |
357 return nullptr; // Parse error, no at-rules supported inside @keyframes | 386 return nullptr; // Parse error, no at-rules supported inside @keyframes |
358 if (allowedRules == NoRules) | 387 if (allowedRules == NoRules || allowedRules == ApplyRules) |
359 return nullptr; // Parse error, no at-rules supported inside declaration
lists | 388 return nullptr; // Parse error, no at-rules with blocks supported inside
declaration lists |
360 | 389 |
361 ASSERT(allowedRules <= RegularRules); | 390 ASSERT(allowedRules <= RegularRules); |
362 | 391 |
363 switch (id) { | 392 switch (id) { |
364 case CSSAtRuleMedia: | 393 case CSSAtRuleMedia: |
365 return consumeMediaRule(prelude, block); | 394 return consumeMediaRule(prelude, block); |
366 case CSSAtRuleSupports: | 395 case CSSAtRuleSupports: |
367 return consumeSupportsRule(prelude, block); | 396 return consumeSupportsRule(prelude, block); |
368 case CSSAtRuleViewport: | 397 case CSSAtRuleViewport: |
369 return consumeViewportRule(prelude, block); | 398 return consumeViewportRule(prelude, block); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 unsigned endOffset = m_observerWrapper->endOffset(prelude); | 624 unsigned endOffset = m_observerWrapper->endOffset(prelude); |
596 m_observerWrapper->observer().startRuleHeader(StyleRule::Page, m_observe
rWrapper->startOffset(prelude)); | 625 m_observerWrapper->observer().startRuleHeader(StyleRule::Page, m_observe
rWrapper->startOffset(prelude)); |
597 m_observerWrapper->observer().endRuleHeader(endOffset); | 626 m_observerWrapper->observer().endRuleHeader(endOffset); |
598 } | 627 } |
599 | 628 |
600 consumeDeclarationList(block, StyleRule::Style); | 629 consumeDeclarationList(block, StyleRule::Style); |
601 | 630 |
602 return StyleRulePage::create(std::move(selectorList), createStylePropertySet
(m_parsedProperties, m_context.mode())); | 631 return StyleRulePage::create(std::move(selectorList), createStylePropertySet
(m_parsedProperties, m_context.mode())); |
603 } | 632 } |
604 | 633 |
| 634 void CSSParserImpl::consumeApplyRule(CSSParserTokenRange prelude) |
| 635 { |
| 636 ASSERT(RuntimeEnabledFeatures::cssApplyAtRulesEnabled()); |
| 637 |
| 638 prelude.consumeWhitespace(); |
| 639 const CSSParserToken& ident = prelude.consumeIncludingWhitespace(); |
| 640 if (!prelude.atEnd() || !CSSVariableParser::isValidVariableName(ident)) |
| 641 return; // Parse error, expected a single custom property name |
| 642 m_parsedProperties.append(CSSProperty( |
| 643 CSSPropertyApplyAtRule, |
| 644 CSSCustomIdentValue::create(ident.value()))); |
| 645 } |
| 646 |
605 PassRefPtrWillBeRawPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRul
e(CSSParserTokenRange prelude, CSSParserTokenRange block) | 647 PassRefPtrWillBeRawPtr<StyleRuleKeyframe> CSSParserImpl::consumeKeyframeStyleRul
e(CSSParserTokenRange prelude, CSSParserTokenRange block) |
606 { | 648 { |
607 OwnPtr<Vector<double>> keyList = consumeKeyframeKeyList(prelude); | 649 OwnPtr<Vector<double>> keyList = consumeKeyframeKeyList(prelude); |
608 if (!keyList) | 650 if (!keyList) |
609 return nullptr; | 651 return nullptr; |
610 | 652 |
611 if (m_observerWrapper) { | 653 if (m_observerWrapper) { |
612 m_observerWrapper->observer().startRuleHeader(StyleRule::Keyframe, m_obs
erverWrapper->startOffset(prelude)); | 654 m_observerWrapper->observer().startRuleHeader(StyleRule::Keyframe, m_obs
erverWrapper->startOffset(prelude)); |
613 m_observerWrapper->observer().endRuleHeader(m_observerWrapper->endOffset
(prelude)); | 655 m_observerWrapper->observer().endRuleHeader(m_observerWrapper->endOffset
(prelude)); |
614 } | 656 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 while (!range.atEnd() && range.peek().type() != SemicolonToken) | 719 while (!range.atEnd() && range.peek().type() != SemicolonToken) |
678 range.consumeComponentValue(); | 720 range.consumeComponentValue(); |
679 | 721 |
680 consumeDeclaration(range.makeSubRange(declarationStart, &range.peek(
)), ruleType); | 722 consumeDeclaration(range.makeSubRange(declarationStart, &range.peek(
)), ruleType); |
681 | 723 |
682 if (useObserver) | 724 if (useObserver) |
683 m_observerWrapper->skipCommentsBefore(range, false); | 725 m_observerWrapper->skipCommentsBefore(range, false); |
684 break; | 726 break; |
685 } | 727 } |
686 case AtKeywordToken: { | 728 case AtKeywordToken: { |
687 RefPtrWillBeRawPtr<StyleRuleBase> rule = consumeAtRule(range, NoRule
s); | 729 AllowedRulesType allowedRules = ruleType == StyleRule::Style && Runt
imeEnabledFeatures::cssApplyAtRulesEnabled() ? ApplyRules : NoRules; |
| 730 RefPtrWillBeRawPtr<StyleRuleBase> rule = consumeAtRule(range, allowe
dRules); |
688 ASSERT_UNUSED(rule, !rule); | 731 ASSERT_UNUSED(rule, !rule); |
689 break; | 732 break; |
690 } | 733 } |
691 default: // Parse error, unexpected token in declaration list | 734 default: // Parse error, unexpected token in declaration list |
692 while (!range.atEnd() && range.peek().type() != SemicolonToken) | 735 while (!range.atEnd() && range.peek().type() != SemicolonToken) |
693 range.consumeComponentValue(); | 736 range.consumeComponentValue(); |
694 break; | 737 break; |
695 } | 738 } |
696 } | 739 } |
697 | 740 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 else | 818 else |
776 return nullptr; // Parser error, invalid value in keyframe selector | 819 return nullptr; // Parser error, invalid value in keyframe selector |
777 if (range.atEnd()) | 820 if (range.atEnd()) |
778 return result.release(); | 821 return result.release(); |
779 if (range.consume().type() != CommaToken) | 822 if (range.consume().type() != CommaToken) |
780 return nullptr; // Parser error | 823 return nullptr; // Parser error |
781 } | 824 } |
782 } | 825 } |
783 | 826 |
784 } // namespace blink | 827 } // namespace blink |
OLD | NEW |