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

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

Issue 1192983003: CSS Custom Properties (Variables) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: ToTed Created 5 years, 4 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/CSSCustomVariableValue.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 {
Timothy Loh 2015/08/25 09:21:10 Probably a good idea to check the token type is an
16 CSSParserString value = token.value();
17 return value.length() >= 2 && value[0] == '-' && value[0] == value[1];
Timothy Loh 2015/08/25 09:21:11 err.. value[1] == '-'?
18 }
19
20 static bool isValidVariableReference(CSSParserTokenRange& range)
Timothy Loh 2015/08/25 09:21:10 Use consumeBlock in the calling function and make
21 {
22 bool foundVariableIdentToken = false;
23 bool foundComma = false;
24 bool contentAfterComma = false;
25
26 // TODO(leviw): Use CSSParserToken::BlockType signals instead of checking fo r these directly.
27 int parenthesisCount = 0;
28 int braceCount = 0;
29 int bracketCount = 0;
30 while (!range.atEnd()) {
31 const CSSParserToken& token = range.consume();
32
33 if (!foundVariableIdentToken) {
Timothy Loh 2015/08/25 09:21:10 This would be easier without the state machine loo
34 if (token.type() == IdentToken) {
35 if (!isValidVariableName(token))
36 return false;
37 foundVariableIdentToken = true;
38 } else if (token.type() != WhitespaceToken) {
39 return false;
40 }
41 continue;
42 }
43
44 if (!foundComma) {
45 if (token.type() == CommaToken)
46 foundComma = true;
47 else if (token.type() == RightParenthesisToken)
48 return true;
49 else if (token.type() != WhitespaceToken)
50 return false;
51 continue;
52 }
53
54 if (!contentAfterComma) {
55 if (token.type() == RightParenthesisToken)
56 return false;
57 contentAfterComma = true;
58 }
59
60 switch (token.type()) {
61 case DelimiterToken:
62 if (token.delimiter() == '!' && !parenthesisCount && !bracketCount & & !braceCount)
63 return false;
64 break;
65 case FunctionToken:
66 case LeftParenthesisToken:
67 parenthesisCount++;
68 break;
69 case RightParenthesisToken:
70 if (!parenthesisCount)
71 return true;
72 parenthesisCount--;
73 break;
74 case RightBraceToken:
75 if (!braceCount)
76 return false;
77 braceCount--;
78 break;
79 case LeftBraceToken:
80 braceCount++;
81 break;
82 case RightBracketToken:
83 if (!bracketCount)
84 return false;
85 bracketCount--;
86 break;
87 case LeftBracketToken:
88 bracketCount++;
89 break;
90 case BadStringToken:
91 case BadUrlToken:
92 return false;
93 case CommentToken:
94 case EOFToken:
95 ASSERT_NOT_REACHED();
96 case SemicolonToken:
97 if (!parenthesisCount && !bracketCount && !braceCount)
98 return false;
99 break;
100 default:
101 break;
102 }
103 }
104 return foundVariableIdentToken && (!foundComma || contentAfterComma);
105 }
106
107 static CSSValueID classifyVariableRange(CSSParserTokenRange& originalRange, bool & hasReferences)
Timothy Loh 2015/08/25 09:21:11 CSSParserTokenRange& originalRange -> CSSParserTok
108 {
109 hasReferences = false;
110 CSSParserTokenRange range = originalRange;
111
112 int parenthesisCount = 0;
113 int braceCount = 0;
114 int bracketCount = 0;
115
116 range.consumeWhitespace();
117 if (range.peek().type() == IdentToken) {
118 const CSSParserToken& ident = range.consumeIncludingWhitespace();
119 if (range.atEnd()) {
120 if (ident.valueEqualsIgnoringCase("inherit"))
121 return CSSValueInherit;
122 if (ident.valueEqualsIgnoringCase("initial"))
123 return CSSValueInitial;
124 if (ident.valueEqualsIgnoringCase("unset"))
125 return CSSValueUnset;
126 }
127 }
128
129 // TODO(leviw): Use consumeBlock to keep track of nesting instead of doing i t directly here.
130 while (!range.atEnd()) {
131 const CSSParserToken& token = range.consume();
132 switch (token.type()) {
133 case FunctionToken:
134 if (token.valueEqualsIgnoringCase("var")) {
135 if (!isValidVariableReference(range))
136 return CSSValueInvalid; // Bail if any references are invali d
137 hasReferences = true;
138 } else {
139 parenthesisCount++;
140 }
141 break;
142 case CommentToken:
143 case EOFToken:
144 ASSERT_NOT_REACHED();
145 case DelimiterToken: {
146 if (token.delimiter() == '!' && !parenthesisCount && !bracketCount & & !braceCount)
147 return CSSValueInvalid;
148 break;
149 }
150 case RightParenthesisToken:
151 if (!parenthesisCount)
152 return CSSValueInvalid;
153 parenthesisCount--;
154 break;
155 case LeftParenthesisToken:
156 parenthesisCount++;
157 break;
158 case RightBraceToken:
159 if (!braceCount)
160 return CSSValueInvalid;
161 braceCount--;
162 break;
163 case LeftBraceToken:
164 braceCount++;
165 break;
166 case RightBracketToken:
167 if (!bracketCount)
168 return CSSValueInvalid;
169 bracketCount--;
170 break;
171 case LeftBracketToken:
172 bracketCount++;
173 break;
174 case BadStringToken:
175 case BadUrlToken:
176 return CSSValueInvalid;
177 case WhitespaceToken:
178 break;
179 case SemicolonToken:
180 if (!parenthesisCount && !bracketCount && !braceCount)
181 return CSSValueInvalid;
182 default:
183 break;
184 }
185 }
186 if (parenthesisCount)
187 return CSSValueInvalid;
188 return CSSValueInternalVariableValue;
189 }
190
191 bool CSSVariableParser::containsValidVariableReferences(const CSSParserTokenRang e& originalRange)
Timothy Loh 2015/08/25 09:21:10 CSSParserTokenRange& originalRange -> CSSParserTok
192 {
193 CSSParserTokenRange range = originalRange;
194 bool hasReferences;
195 CSSValueID type = classifyVariableRange(range, hasReferences);
196 return type == CSSValueInternalVariableValue && hasReferences;
197 }
198
199 PassRefPtrWillBeRawPtr<CSSCustomVariableValue> CSSVariableParser::parseDeclarati onValue(const AtomicString& variableName, CSSParserTokenRange& originalRange)
Timothy Loh 2015/08/25 09:21:11 CSSParserTokenRange& originalRange -> CSSParserTok
200 {
201 if (originalRange.atEnd())
202 return nullptr;
203
204 bool hasReferences;
205 CSSValueID type = classifyVariableRange(originalRange, hasReferences);
206
207 if (type == CSSValueInvalid)
208 return nullptr;
209 if (type == CSSValueInternalVariableValue)
210 return CSSCustomVariableValue::create(variableName, CSSVariableData::cre ate(originalRange, hasReferences));
211 return CSSCustomVariableValue::create(variableName, type);
212 }
213
214 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698