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