Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Side by Side Diff: third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp

Issue 1192983003: CSS Custom Properties (Variables) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Post-merge Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/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/CSSParserObserver.h" 16 #include "core/css/parser/CSSParserObserver.h"
16 #include "core/css/parser/CSSParserObserverWrapper.h" 17 #include "core/css/parser/CSSParserObserverWrapper.h"
17 #include "core/css/parser/CSSParserSelector.h" 18 #include "core/css/parser/CSSParserSelector.h"
18 #include "core/css/parser/CSSPropertyParser.h" 19 #include "core/css/parser/CSSPropertyParser.h"
19 #include "core/css/parser/CSSSelectorParser.h" 20 #include "core/css/parser/CSSSelectorParser.h"
20 #include "core/css/parser/CSSSupportsParser.h" 21 #include "core/css/parser/CSSSupportsParser.h"
21 #include "core/css/parser/CSSTokenizer.h" 22 #include "core/css/parser/CSSVariableParser.h"
22 #include "core/css/parser/MediaQueryParser.h" 23 #include "core/css/parser/MediaQueryParser.h"
23 #include "core/dom/Document.h" 24 #include "core/dom/Document.h"
24 #include "core/dom/Element.h" 25 #include "core/dom/Element.h"
25 #include "core/frame/UseCounter.h" 26 #include "core/frame/UseCounter.h"
26 #include "platform/TraceEvent.h" 27 #include "platform/TraceEvent.h"
27 #include "wtf/BitArray.h" 28 #include "wtf/BitArray.h"
28 29
29 namespace blink { 30 namespace blink {
30 31
31 CSSParserImpl::CSSParserImpl(const CSSParserContext& context, StyleSheetContents * styleSheet) 32 CSSParserImpl::CSSParserImpl(const CSSParserContext& context, StyleSheetContents * styleSheet)
(...skipping 16 matching lines...) Expand all
48 return declaration->addParsedProperties(parser.m_parsedProperties); 49 return declaration->addParsedProperties(parser.m_parsedProperties);
49 } 50 }
50 51
51 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE ntries, BitArray<numCSSProperties>& seenProperties) 52 static inline void filterProperties(bool important, const WillBeHeapVector<CSSPr operty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedE ntries, BitArray<numCSSProperties>& seenProperties)
52 { 53 {
53 // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found. 54 // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
54 for (size_t i = input.size(); i--; ) { 55 for (size_t i = input.size(); i--; ) {
55 const CSSProperty& property = input[i]; 56 const CSSProperty& property = input[i];
56 if (property.isImportant() != important) 57 if (property.isImportant() != important)
57 continue; 58 continue;
58 const unsigned propertyIDIndex = property.id() - firstCSSProperty; 59 // CSSPropertyVariable is asserted to be one number before the firstCSSP roperty. We need to include it here.
59 if (seenProperties.get(propertyIDIndex)) 60 const unsigned propertyIDIndex = property.id() - CSSPropertyVariable;
Timothy Loh 2015/09/30 02:09:27 This looks wrong, won't the last property access o
61 if (seenProperties.get(propertyIDIndex) && property.id() != CSSPropertyV ariable)
60 continue; 62 continue;
61 seenProperties.set(propertyIDIndex); 63 seenProperties.set(propertyIDIndex);
62 output[--unusedEntries] = property; 64 output[--unusedEntries] = property;
63 } 65 }
64 } 66 }
65 67
66 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet( WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode) 68 static PassRefPtrWillBeRawPtr<ImmutableStylePropertySet> createStylePropertySet( WillBeHeapVector<CSSProperty, 256>& parsedProperties, CSSParserMode mode)
67 { 69 {
68 BitArray<numCSSProperties> seenProperties; 70 BitArray<numCSSProperties> seenProperties;
69 size_t unusedEntries = parsedProperties.size(); 71 size_t unusedEntries = parsedProperties.size();
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 } 655 }
654 } 656 }
655 657
656 // Yield remaining comments 658 // Yield remaining comments
657 if (useObserver) { 659 if (useObserver) {
658 m_observerWrapper->yieldCommentsBefore(range); 660 m_observerWrapper->yieldCommentsBefore(range);
659 m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(r ange)); 661 m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(r ange));
660 } 662 }
661 } 663 }
662 664
665 template <typename CharacterType>
666 static bool isCustomProperty(const CharacterType* propertyName, unsigned length)
667 {
668 return (length >= 2 && propertyName[0] == '-' && propertyName[1] == '-');
669 }
670
671 inline bool isCustomProperty(CSSParserToken token)
Timothy Loh 2015/09/30 02:09:27 This is duplicated between here and CSSVariablePar
672 {
673 CSSParserString string = token.value();
674 return string.is8Bit() ? isCustomProperty(string.characters8(), string.lengt h()) : isCustomProperty(string.characters16(), string.length());
675 }
676
663 void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Typ e ruleType) 677 void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, StyleRule::Typ e ruleType)
664 { 678 {
665 CSSParserTokenRange rangeCopy = range; // For inspector callbacks 679 CSSParserTokenRange rangeCopy = range; // For inspector callbacks
666 680
667 ASSERT(range.peek().type() == IdentToken); 681 ASSERT(range.peek().type() == IdentToken);
668 CSSPropertyID unresolvedProperty = range.consumeIncludingWhitespace().parseA sUnresolvedCSSPropertyID(); 682 const CSSParserToken& token = range.consumeIncludingWhitespace();
683 CSSPropertyID unresolvedProperty = token.parseAsUnresolvedCSSPropertyID();
669 if (range.consume().type() != ColonToken) 684 if (range.consume().type() != ColonToken)
670 return; // Parse error 685 return; // Parse error
671 686
672 bool important = false; 687 bool important = false;
673 const CSSParserToken* declarationValueEnd = range.end(); 688 const CSSParserToken* declarationValueEnd = range.end();
674 const CSSParserToken* last = range.end() - 1; 689 const CSSParserToken* last = range.end() - 1;
675 while (last->type() == WhitespaceToken) 690 while (last->type() == WhitespaceToken)
676 --last; 691 --last;
677 if (last->type() == IdentToken && last->valueEqualsIgnoringCase("important") ) { 692 if (last->type() == IdentToken && last->valueEqualsIgnoringCase("important") ) {
678 --last; 693 --last;
679 while (last->type() == WhitespaceToken) 694 while (last->type() == WhitespaceToken)
680 --last; 695 --last;
681 if (last->type() == DelimiterToken && last->delimiter() == '!') { 696 if (last->type() == DelimiterToken && last->delimiter() == '!') {
682 important = true; 697 important = true;
683 declarationValueEnd = last; 698 declarationValueEnd = last;
684 } 699 }
685 } 700 }
701 if (RuntimeEnabledFeatures::cssVariablesEnabled() && unresolvedProperty == C SSPropertyInvalid && isCustomProperty(token)) {
702 AtomicString variableName = token.value();
703 consumeVariableDeclarationValue(range.makeSubRange(&range.peek(), declar ationValueEnd), variableName, important);
704 return;
705 }
686 706
687 if (important && (ruleType == StyleRule::FontFace || ruleType == StyleRule:: Keyframes)) 707 if (important && (ruleType == StyleRule::FontFace || ruleType == StyleRule:: Keyframes))
688 return; 708 return;
689 709
690 if (m_observerWrapper && ruleType == StyleRule::Style) { 710 if (m_observerWrapper && ruleType == StyleRule::Style) {
691 size_t propertiesCount = m_parsedProperties.size(); 711 size_t propertiesCount = m_parsedProperties.size();
692 if (unresolvedProperty != CSSPropertyInvalid) 712 if (unresolvedProperty != CSSPropertyInvalid)
693 consumeDeclarationValue(range.makeSubRange(&range.peek(), declaratio nValueEnd), unresolvedProperty, important, ruleType); 713 consumeDeclarationValue(range.makeSubRange(&range.peek(), declaratio nValueEnd), unresolvedProperty, important, ruleType);
694 m_observerWrapper->observer().observeProperty( 714 m_observerWrapper->observer().observeProperty(
695 m_observerWrapper->startOffset(rangeCopy), m_observerWrapper->endOff set(rangeCopy), 715 m_observerWrapper->startOffset(rangeCopy), m_observerWrapper->endOff set(rangeCopy),
696 important, m_parsedProperties.size() != propertiesCount); 716 important, m_parsedProperties.size() != propertiesCount);
697 return; 717 return;
698 } 718 }
699 719
700 if (unresolvedProperty == CSSPropertyInvalid) 720 if (unresolvedProperty == CSSPropertyInvalid)
701 return; 721 return;
702 722
703 consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEn d), unresolvedProperty, important, ruleType); 723 consumeDeclarationValue(range.makeSubRange(&range.peek(), declarationValueEn d), unresolvedProperty, important, ruleType);
704 } 724 }
705 725
726 void CSSParserImpl::consumeVariableDeclarationValue(CSSParserTokenRange range, c onst AtomicString& variableName, bool important)
727 {
728 if (PassRefPtrWillBeRawPtr<CSSCustomPropertyDeclaration> value = CSSVariable Parser::parseDeclarationValue(variableName, range))
Timothy Loh 2015/09/30 02:09:28 I think this is supposed to be: if (RefPtr..<> va
729 m_parsedProperties.append(CSSProperty(CSSPropertyVariable, value, import ant));
730 }
731
706 void CSSParserImpl::consumeDeclarationValue(CSSParserTokenRange range, CSSProper tyID unresolvedProperty, bool important, StyleRule::Type ruleType) 732 void CSSParserImpl::consumeDeclarationValue(CSSParserTokenRange range, CSSProper tyID unresolvedProperty, bool important, StyleRule::Type ruleType)
707 { 733 {
708 CSSPropertyParser::parseValue(unresolvedProperty, important, range, m_contex t, m_parsedProperties, ruleType); 734 CSSPropertyParser::parseValue(unresolvedProperty, important, range, m_contex t, m_parsedProperties, ruleType);
709 } 735 }
710 736
711 PassOwnPtr<Vector<double>> CSSParserImpl::consumeKeyframeKeyList(CSSParserTokenR ange range) 737 PassOwnPtr<Vector<double>> CSSParserImpl::consumeKeyframeKeyList(CSSParserTokenR ange range)
712 { 738 {
713 OwnPtr<Vector<double>> result = adoptPtr(new Vector<double>); 739 OwnPtr<Vector<double>> result = adoptPtr(new Vector<double>);
714 while (true) { 740 while (true) {
715 range.consumeWhitespace(); 741 range.consumeWhitespace();
716 const CSSParserToken& token = range.consumeIncludingWhitespace(); 742 const CSSParserToken& token = range.consumeIncludingWhitespace();
717 if (token.type() == PercentageToken && token.numericValue() >= 0 && toke n.numericValue() <= 100) 743 if (token.type() == PercentageToken && token.numericValue() >= 0 && toke n.numericValue() <= 100)
718 result->append(token.numericValue() / 100); 744 result->append(token.numericValue() / 100);
719 else if (token.type() == IdentToken && token.valueEqualsIgnoringCase("fr om")) 745 else if (token.type() == IdentToken && token.valueEqualsIgnoringCase("fr om"))
720 result->append(0); 746 result->append(0);
721 else if (token.type() == IdentToken && token.valueEqualsIgnoringCase("to ")) 747 else if (token.type() == IdentToken && token.valueEqualsIgnoringCase("to "))
722 result->append(1); 748 result->append(1);
723 else 749 else
724 return nullptr; // Parser error, invalid value in keyframe selector 750 return nullptr; // Parser error, invalid value in keyframe selector
725 if (range.atEnd()) 751 if (range.atEnd())
726 return result.release(); 752 return result.release();
727 if (range.consume().type() != CommaToken) 753 if (range.consume().type() != CommaToken)
728 return nullptr; // Parser error 754 return nullptr; // Parser error
729 } 755 }
730 } 756 }
731 757
732 } // namespace blink 758 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698