OLD | NEW |
---|---|
(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 | |
OLD | NEW |