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

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: Missing file :( 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/parser/CSSParserTokenRange.h"
9 #include "core/css/parser/CSSParserValues.h"
10
11 namespace blink {
12
13 static bool isValidVariableName(const CSSParserToken& token)
14 {
15 CSSParserString value = token.value();
16 return value.length() >= 2 && value[0] == '-' && value[0] == value[1];
17 }
18
19 static bool isValidVariableReference(CSSParserTokenRange& range)
20 {
21 bool foundVariableIdentToken = false;
22 bool foundComma = false;
23 bool contentAfterComma = false;
24 int parenthesisCount = 0;
25 int braceCount = 0;
26 int bracketCount = 0;
27 while (!range.atEnd()) {
28 const CSSParserToken& token = range.consume();
29
30 if (!foundVariableIdentToken) {
31 if (token.type() == IdentToken) {
32 if (!isValidVariableName(token))
33 return false;
34 foundVariableIdentToken = true;
35 } else if (token.type() != WhitespaceToken) {
36 return false;
37 }
38 continue;
39 }
40
41 if (!foundComma) {
42 if (token.type() == CommaToken)
43 foundComma = true;
44 else if (token.type() == RightParenthesisToken)
45 return true;
46 else if (token.type() != WhitespaceToken)
47 return false;
48 continue;
49 }
50
51 if (!contentAfterComma) {
52 if (token.type() == RightParenthesisToken)
53 return false;
54 contentAfterComma = true;
55 }
56
57 switch (token.type()) {
58 case DelimiterToken:
59 if (token.delimiter() == '!' && !parenthesisCount && !bracketCount & & !braceCount)
60 return false;
61 break;
62 case FunctionToken:
63 case LeftParenthesisToken:
64 parenthesisCount++;
65 break;
66 case RightParenthesisToken:
67 if (!parenthesisCount)
68 return true;
69 parenthesisCount--;
70 break;
71 case RightBraceToken:
72 if (!braceCount)
73 return false;
74 braceCount--;
75 break;
76 case LeftBraceToken:
77 braceCount++;
78 break;
79 case RightBracketToken:
80 if (!bracketCount)
81 return false;
82 bracketCount--;
83 break;
84 case LeftBracketToken:
85 bracketCount++;
86 break;
87 case BadStringToken:
88 case BadUrlToken:
89 return false;
90 case CommentToken:
91 case EOFToken:
92 ASSERT_NOT_REACHED();
93 case SemicolonToken:
94 if (!parenthesisCount && !bracketCount && !braceCount)
95 return false;
96 break;
97 default:
98 break;
99 }
100 }
101 return foundVariableIdentToken && (!foundComma || contentAfterComma);
102 }
103
104 static CSSVariableParser::DefinitionType classifyVariableRange(CSSParserTokenRan ge& originalRange)
105 {
106 CSSParserTokenRange range = originalRange;
107 CSSVariableParser::DefinitionType type = CSSVariableParser::Variable;
108
109 int parenthesisCount = 0;
110 int braceCount = 0;
111 int bracketCount = 0;
alancutter (OOO until 2018) 2015/08/05 08:01:43 You can just search for closing brackets with the
112
113 range.consumeWhitespace();
114 if (range.peek().type() == IdentToken) {
115 const CSSParserToken& ident = range.consumeIncludingWhitespace();
116 if (range.atEnd()) {
117 if (ident.valueEqualsIgnoringCase("inherit"))
118 return CSSVariableParser::Inherit;
119 if (ident.valueEqualsIgnoringCase("initial"))
120 return CSSVariableParser::Initial;
121 if (ident.valueEqualsIgnoringCase("unset"))
122 return CSSVariableParser::Unset;
123 }
124 }
125
126 while (!range.atEnd()) {
127 const CSSParserToken& token = range.consume();
128 switch (token.type()) {
129 case FunctionToken:
130 if (token.valueEqualsIgnoringCase("var")) {
131 if (!isValidVariableReference(range))
132 return CSSVariableParser::Invalid; // Bail if any references are invalid
133 type = CSSVariableParser::VariableWithReferences;
134 } else {
135 parenthesisCount++;
136 }
137 break;
138 case CommentToken:
139 case EOFToken:
140 ASSERT_NOT_REACHED();
141 case DelimiterToken: {
142 if (token.delimiter() == '!' && !parenthesisCount && !bracketCount & & !braceCount)
alancutter (OOO until 2018) 2015/08/05 08:01:43 You can use consumeComponentValue() and just check
143 return CSSVariableParser::Invalid;
144 break;
145 }
146 case RightParenthesisToken:
147 if (!parenthesisCount)
148 return CSSVariableParser::Invalid;
149 parenthesisCount--;
150 break;
151 case LeftParenthesisToken:
152 parenthesisCount++;
153 break;
154 case RightBraceToken:
155 if (!braceCount)
156 return CSSVariableParser::Invalid;
157 braceCount--;
158 break;
159 case LeftBraceToken:
160 braceCount++;
161 break;
162 case RightBracketToken:
163 if (!bracketCount)
164 return CSSVariableParser::Invalid;
165 bracketCount--;
166 break;
167 case LeftBracketToken:
168 bracketCount++;
169 break;
170 case BadStringToken:
171 case BadUrlToken:
172 return CSSVariableParser::Invalid;
173 case WhitespaceToken:
174 break;
175 case SemicolonToken:
176 if (!parenthesisCount && !bracketCount && !braceCount)
177 return CSSVariableParser::Invalid;
178 default:
179 break;
180 }
181 }
182 if (parenthesisCount)
183 return CSSVariableParser::Invalid;
184 return type;
185 }
186
187 bool CSSVariableParser::containsValidVariableReferences(const CSSParserTokenRang e& originalRange)
188 {
189 CSSParserTokenRange range = originalRange;
190 return classifyVariableRange(range) == VariableWithReferences;
191 }
192
193 CSSVariableParser::DefinitionType CSSVariableParser::parseVariableDefinition(CSS ParserTokenRange& originalRange)
alancutter (OOO until 2018) 2015/08/05 08:01:43 I'd call this parseDeclarationValue() to align wit
194 {
195 if (originalRange.atEnd())
196 return CSSVariableParser::Invalid;
197 return classifyVariableRange(originalRange);
198 }
199
200 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698