Chromium Code Reviews| 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 |