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

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: ToT-ed again... Created 5 years, 5 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 unsigned bracketCount = 0;
25 while (!range.atEnd()) {
26 const CSSParserToken& token = range.consume();
27 switch (token.type()) {
28 case WhitespaceToken:
29 if (foundComma)
30 contentAfterComma = true;
31 break;
32 case IdentToken:
33 if (foundComma) {
34 contentAfterComma = true;
35 } else if (!foundVariableIdentToken) {
36 if (!isValidVariableName(token))
37 return false;
38 foundVariableIdentToken = true;
39 } else {
40 return false;
41 }
42 break;
43 case FunctionToken:
44 case LeftParenthesisToken:
45 if (!foundComma)
46 return false;
47 bracketCount++;
48 break;
49 case RightParenthesisToken:
50 if (!foundVariableIdentToken)
51 return false;
52 if (!bracketCount)
53 return foundVariableIdentToken && (!foundComma || contentAfterCo mma);
54 bracketCount--;
55 break;
56 case CommaToken:
57 if (!foundVariableIdentToken)
58 return false;
59 foundComma = true;
60 break;
61 case CommentToken:
62 case EOFToken:
63 ASSERT_NOT_REACHED();
64 case SemicolonToken:
65 return false;
66 case CDOToken:
67 case CDCToken:
68 case AtKeywordToken:
69 case IncludeMatchToken:
70 case DashMatchToken:
71 case PrefixMatchToken:
72 case SuffixMatchToken:
73 case SubstringMatchToken:
74 case ColumnToken:
75 case BadStringToken:
76 case BadUrlToken:
77 case ColonToken:
78 // TODO(leviw): Need to match CDO/CDC tokens
79 if (!foundComma)
80 return false;
81 break;
82 default:
83 if (!foundComma)
84 return false;
85 break;
86 }
87 }
88 return false;
89 }
90
91 static CSSVariableParser::DefinitionType classifyVariableRange(const CSSParserTo kenRange& originalRange, bool& important)
92 {
93 CSSParserTokenRange range = originalRange;
94 CSSVariableParser::DefinitionType type = CSSVariableParser::Variable;
95 bool lastTokenWasExclamation = false;
96
97 // TODO(leviw): this needs to be a stack.
98 bool foundImportant = false;
99
100 int bracketCount = 0;
101
Timothy Loh 2015/07/23 08:11:47 Probably something like: range.consumeWhitespace(
102 while (!range.atEnd()) {
103 const CSSParserToken& token = range.consume();
104 switch (token.type()) {
105 case FunctionToken:
106 if (token.valueEqualsIgnoringCase("var")) {
107 if (!isValidVariableReference(range))
108 return CSSVariableParser::Invalid; // Bail if any references are invalid
109 type = CSSVariableParser::VariableWithReferences;
110 } else {
111 bracketCount++;
112 }
113 lastTokenWasExclamation = false;
114 break;
115 case CommentToken:
116 case EOFToken:
117 ASSERT_NOT_REACHED();
118 case IdentToken:
119 // TODO(leviw): This isn't correct.
120 if (token.valueEqualsIgnoringCase("inherit")) {
121 type = CSSVariableParser::Inherit;
122 } else if (token.valueEqualsIgnoringCase("initial")) {
123 type = CSSVariableParser::Initial;
124 } else if (token.valueEqualsIgnoringCase("unset")) {
125 type = CSSVariableParser::Unset;
126 } else if (lastTokenWasExclamation && token.valueEqualsIgnoringCase( "important")) {
Timothy Loh 2015/07/23 08:11:47 Why does this need to handle !important when consu
127 if (foundImportant)
128 return CSSVariableParser::Invalid;
129 foundImportant = true;
130 important = true;
131 }
132 lastTokenWasExclamation = false;
133 break;
134 case DelimiterToken:
135 lastTokenWasExclamation = token.delimiter() == '!';
136 break;
137 case RightParenthesisToken:
138 if (!bracketCount)
139 return CSSVariableParser::Invalid;
140 bracketCount--;
141 break;
142 case LeftParenthesisToken:
143 bracketCount++;
144 break;
145 case SemicolonToken:
146 return CSSVariableParser::Invalid;
147 case CDOToken:
Timothy Loh 2015/07/23 08:11:47 The spec doesn't say these are invalid
148 case CDCToken:
149 case AtKeywordToken:
150 case IncludeMatchToken:
151 case DashMatchToken:
152 case PrefixMatchToken:
153 case SuffixMatchToken:
154 case SubstringMatchToken:
155 case ColumnToken:
156 case BadStringToken:
157 case BadUrlToken:
158 case ColonToken:
159 return CSSVariableParser::Invalid;
160 case WhitespaceToken:
161 break;
162 default:
163 lastTokenWasExclamation = false;
164 break;
165 }
166 }
167 if (bracketCount)
168 return CSSVariableParser::Invalid;
169 return type;
170 }
171
172 bool CSSVariableParser::containsValidVariableReferences(const CSSParserTokenRang e& originalRange)
173 {
174 bool important;
175 return VariableWithReferences == classifyVariableRange(originalRange, import ant);
176 }
177
178 CSSVariableParser::DefinitionType CSSVariableParser::parseVariableDefinition(con st CSSParserTokenRange& originalRange, bool& important)
179 {
180 important = false;
181 if (originalRange.atEnd())
182 return CSSVariableParser::Invalid;
183 return classifyVariableRange(originalRange, important);
184 }
185
186 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698