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

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

Issue 1192983003: CSS Custom Properties (Variables) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Post-merge Created 5 years, 2 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/css/parser/CSSVariableParser.h"
7
8 #include "core/css/CSSCustomPropertyDeclaration.h"
9 #include "core/css/parser/CSSParserTokenRange.h"
10 #include "core/css/parser/CSSParserValues.h"
11
12 namespace blink {
13
14 static bool isValidVariableName(const CSSParserToken& token)
15 {
16 if (token.type() != IdentToken)
17 return false;
18
19 CSSParserString value = token.value();
20 return value.length() >= 2 && value[0] == '-' && value[1] == '-';
21 }
22
23 static bool isValidVariableReference(CSSParserTokenRange range)
24 {
25 range.consumeWhitespace();
26 if (!isValidVariableName(range.consumeIncludingWhitespace()))
27 return false;
28 if (range.atEnd())
29 return true;
30
31 range.consumeWhitespace();
Timothy Loh 2015/09/30 02:09:28 This is a no-op because we used consumeIncludingWh
32 if (range.consume().type() != CommaToken)
33 return false;
34 if (range.atEnd())
35 return false;
36
37 int blockNestingLevel = 0;
Timothy Loh 2015/09/30 02:09:28 Can we just call classifyBlock recursively here?
38 while (!range.atEnd()) {
39 const CSSParserToken& token = range.consume();
40
41 if (token.blockType() == CSSParserToken::BlockStart) {
42 blockNestingLevel++;
43 } else if (token.blockType() == CSSParserToken::BlockEnd) {
44 blockNestingLevel--;
45 if (blockNestingLevel < 0)
46 return false;
47 }
48
49 switch (token.type()) {
50 case DelimiterToken:
51 if (token.delimiter() == '!' && !blockNestingLevel)
52 return false;
53 break;
54 case BadStringToken:
55 case BadUrlToken:
56 return false;
57 case CommentToken:
58 case EOFToken:
59 ASSERT_NOT_REACHED();
60 case SemicolonToken:
61 if (!blockNestingLevel)
62 return false;
63 break;
64 default:
65 break;
66 }
67 }
68 return true;
69 }
70
71 bool classifyBlock(CSSParserTokenRange range, bool& hasReferences, bool isTopLev elBlock = true)
72 {
73 int parenthesisCount = 0;
74 int braceCount = 0;
75 int bracketCount = 0;
76
77 // TODO(leviw): Use consumeBlock to keep track of nesting instead of doing i t directly here.
78 while (!range.atEnd()) {
79 if (range.peek().blockType() == CSSParserToken::BlockStart) {
80 const CSSParserToken& token = range.peek();
81 CSSParserTokenRange block = range.consumeBlock();
82 if (token.type() == FunctionToken && token.valueEqualsIgnoringCase(" var")) {
83 if (!isValidVariableReference(block))
84 return false; // Bail if any references are invalid
85 hasReferences = true;
86 continue;
87 }
88 if (!classifyBlock(block, hasReferences, false))
89 return false;
90 continue;
91 }
92
93 const CSSParserToken& token = range.consume();
94 switch (token.type()) {
95 case FunctionToken:
96 ASSERT_NOT_REACHED();
97 break;
98 case CommentToken:
Timothy Loh 2015/09/30 02:09:28 I would probably leave out the ASSERT_NOT_REACHED
99 case EOFToken:
100 ASSERT_NOT_REACHED();
101 case DelimiterToken: {
102 if (token.delimiter() == '!' && isTopLevelBlock)
103 return false;
104 break;
105 }
106 case RightParenthesisToken:
107 if (!parenthesisCount)
108 return false;
109 parenthesisCount--;
110 break;
111 case LeftParenthesisToken:
112 parenthesisCount++;
113 break;
114 case RightBraceToken:
115 if (!braceCount)
116 return false;
117 braceCount--;
118 break;
119 case LeftBraceToken:
120 braceCount++;
121 break;
122 case RightBracketToken:
123 if (!bracketCount)
124 return false;
125 bracketCount--;
126 break;
127 case LeftBracketToken:
128 bracketCount++;
129 break;
130 case BadStringToken:
131 case BadUrlToken:
132 return false;
133 case WhitespaceToken:
134 break;
135 case SemicolonToken:
136 if (isTopLevelBlock)
137 return false;
138 break;
139 default:
140 break;
141 }
142 }
143 return true;
144 }
145
146 static CSSValueID classifyVariableRange(CSSParserTokenRange range, bool& hasRefe rences)
147 {
148 hasReferences = false;
149
150 range.consumeWhitespace();
151 if (range.peek().type() == IdentToken) {
152 const CSSParserToken& ident = range.consumeIncludingWhitespace();
Timothy Loh 2015/09/30 02:09:28 We have a helper function now so we can write CSS
153 if (range.atEnd()) {
154 if (ident.valueEqualsIgnoringCase("inherit"))
155 return CSSValueInherit;
156 if (ident.valueEqualsIgnoringCase("initial"))
157 return CSSValueInitial;
158 if (ident.valueEqualsIgnoringCase("unset"))
159 return CSSValueUnset;
160 }
161 }
162
163 if (classifyBlock(range, hasReferences))
164 return CSSValueInternalVariableValue;
165 return CSSValueInvalid;
166 }
167
168 bool CSSVariableParser::containsValidVariableReferences(CSSParserTokenRange rang e)
169 {
170 bool hasReferences;
171 CSSValueID type = classifyVariableRange(range, hasReferences);
172 return type == CSSValueInternalVariableValue && hasReferences;
173 }
174
175 PassRefPtrWillBeRawPtr<CSSCustomPropertyDeclaration> CSSVariableParser::parseDec larationValue(const AtomicString& variableName, CSSParserTokenRange range)
176 {
177 if (range.atEnd())
178 return nullptr;
179
180 bool hasReferences;
181 CSSValueID type = classifyVariableRange(range, hasReferences);
182
183 if (type == CSSValueInvalid)
184 return nullptr;
185 if (type == CSSValueInternalVariableValue)
186 return CSSCustomPropertyDeclaration::create(variableName, CSSVariableDat a::create(range, hasReferences));
187 return CSSCustomPropertyDeclaration::create(variableName, type);
188 }
189
190 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698