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) | |
| 92 { | |
| 93 CSSParserTokenRange range = originalRange; | |
| 94 CSSVariableParser::DefinitionType type = CSSVariableParser::Variable; | |
| 95 bool lastTokenWasExclamation = false; | |
| 96 bool foundImportant = false; | |
| 97 | |
| 98 int bracketCount = 0; | |
| 99 | |
| 100 while (!range.atEnd()) { | |
| 101 const CSSParserToken& token = range.consume(); | |
| 102 switch (token.type()) { | |
| 103 case FunctionToken: | |
| 104 if (token.valueEqualsIgnoringCase("var")) { | |
| 105 if (!isValidVariableReference(range)) | |
| 106 return CSSVariableParser::Invalid; // Bail if any references are invalid | |
| 107 type = CSSVariableParser::VariableWithReferences; | |
| 108 } else { | |
| 109 bracketCount++; | |
| 110 } | |
| 111 lastTokenWasExclamation = false; | |
| 112 break; | |
| 113 case CommentToken: | |
| 114 case EOFToken: | |
| 115 ASSERT_NOT_REACHED(); | |
| 116 case IdentToken: | |
| 117 // TODO(leviw): This isn't correct. | |
| 118 if (token.valueEqualsIgnoringCase("inherit") || token.valueEqualsIgn oringCase("unset")) { | |
|
alancutter (OOO until 2018)
2015/07/14 06:12:57
We still want unset to serialise as unset, this lo
| |
| 119 type = CSSVariableParser::Inherit; | |
| 120 } else if (token.valueEqualsIgnoringCase("initial")) { | |
| 121 type = CSSVariableParser::Initial; | |
| 122 } else if (lastTokenWasExclamation && token.valueEqualsIgnoringCase( "important")) { | |
| 123 if (foundImportant) | |
| 124 return CSSVariableParser::Invalid; | |
| 125 foundImportant = true; | |
| 126 } | |
| 127 lastTokenWasExclamation = false; | |
| 128 break; | |
| 129 case DelimiterToken: | |
| 130 lastTokenWasExclamation = token.delimiter() == '!'; | |
| 131 break; | |
| 132 case RightParenthesisToken: | |
| 133 if (!bracketCount) | |
| 134 return CSSVariableParser::Invalid; | |
| 135 bracketCount--; | |
| 136 break; | |
| 137 case LeftParenthesisToken: | |
| 138 bracketCount++; | |
| 139 break; | |
| 140 case SemicolonToken: | |
| 141 return CSSVariableParser::Invalid; | |
| 142 case CDOToken: | |
| 143 case CDCToken: | |
| 144 case AtKeywordToken: | |
| 145 case IncludeMatchToken: | |
| 146 case DashMatchToken: | |
| 147 case PrefixMatchToken: | |
| 148 case SuffixMatchToken: | |
| 149 case SubstringMatchToken: | |
| 150 case ColumnToken: | |
| 151 case BadStringToken: | |
| 152 case BadUrlToken: | |
| 153 case ColonToken: | |
| 154 return CSSVariableParser::Invalid; | |
| 155 case WhitespaceToken: | |
| 156 break; | |
| 157 default: | |
| 158 lastTokenWasExclamation = false; | |
| 159 break; | |
| 160 } | |
| 161 } | |
| 162 if (bracketCount) | |
| 163 return CSSVariableParser::Invalid; | |
| 164 return type; | |
| 165 } | |
| 166 | |
| 167 bool CSSVariableParser::containsValidVariableReferences(const CSSParserTokenRang e& originalRange) | |
| 168 { | |
| 169 return VariableWithReferences == classifyVariableRange(originalRange); | |
| 170 } | |
| 171 | |
| 172 CSSVariableParser::DefinitionType CSSVariableParser::parseVariableDefinition(con st CSSParserTokenRange& originalRange) | |
| 173 { | |
| 174 if (originalRange.atEnd()) | |
| 175 return CSSVariableParser::Invalid; | |
| 176 return classifyVariableRange(originalRange); | |
| 177 } | |
| 178 | |
| 179 } // namespace blink | |
| OLD | NEW |