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

Unified Diff: Source/core/css/parser/CSSVariableParser.cpp

Issue 1192983003: CSS Custom Properties (Variables) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Missing file :( Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/css/parser/CSSVariableParser.cpp
diff --git a/Source/core/css/parser/CSSVariableParser.cpp b/Source/core/css/parser/CSSVariableParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..676a27c20f5f0d2a5cf1b2ddbdf7b8214b4c9ecf
--- /dev/null
+++ b/Source/core/css/parser/CSSVariableParser.cpp
@@ -0,0 +1,200 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/CSSVariableParser.h"
+
+#include "core/css/parser/CSSParserTokenRange.h"
+#include "core/css/parser/CSSParserValues.h"
+
+namespace blink {
+
+static bool isValidVariableName(const CSSParserToken& token)
+{
+ CSSParserString value = token.value();
+ return value.length() >= 2 && value[0] == '-' && value[0] == value[1];
+}
+
+static bool isValidVariableReference(CSSParserTokenRange& range)
+{
+ bool foundVariableIdentToken = false;
+ bool foundComma = false;
+ bool contentAfterComma = false;
+ int parenthesisCount = 0;
+ int braceCount = 0;
+ int bracketCount = 0;
+ while (!range.atEnd()) {
+ const CSSParserToken& token = range.consume();
+
+ if (!foundVariableIdentToken) {
+ if (token.type() == IdentToken) {
+ if (!isValidVariableName(token))
+ return false;
+ foundVariableIdentToken = true;
+ } else if (token.type() != WhitespaceToken) {
+ return false;
+ }
+ continue;
+ }
+
+ if (!foundComma) {
+ if (token.type() == CommaToken)
+ foundComma = true;
+ else if (token.type() == RightParenthesisToken)
+ return true;
+ else if (token.type() != WhitespaceToken)
+ return false;
+ continue;
+ }
+
+ if (!contentAfterComma) {
+ if (token.type() == RightParenthesisToken)
+ return false;
+ contentAfterComma = true;
+ }
+
+ switch (token.type()) {
+ case DelimiterToken:
+ if (token.delimiter() == '!' && !parenthesisCount && !bracketCount && !braceCount)
+ return false;
+ break;
+ case FunctionToken:
+ case LeftParenthesisToken:
+ parenthesisCount++;
+ break;
+ case RightParenthesisToken:
+ if (!parenthesisCount)
+ return true;
+ parenthesisCount--;
+ break;
+ case RightBraceToken:
+ if (!braceCount)
+ return false;
+ braceCount--;
+ break;
+ case LeftBraceToken:
+ braceCount++;
+ break;
+ case RightBracketToken:
+ if (!bracketCount)
+ return false;
+ bracketCount--;
+ break;
+ case LeftBracketToken:
+ bracketCount++;
+ break;
+ case BadStringToken:
+ case BadUrlToken:
+ return false;
+ case CommentToken:
+ case EOFToken:
+ ASSERT_NOT_REACHED();
+ case SemicolonToken:
+ if (!parenthesisCount && !bracketCount && !braceCount)
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
+ return foundVariableIdentToken && (!foundComma || contentAfterComma);
+}
+
+static CSSVariableParser::DefinitionType classifyVariableRange(CSSParserTokenRange& originalRange)
+{
+ CSSParserTokenRange range = originalRange;
+ CSSVariableParser::DefinitionType type = CSSVariableParser::Variable;
+
+ int parenthesisCount = 0;
+ int braceCount = 0;
+ int bracketCount = 0;
alancutter (OOO until 2018) 2015/08/05 08:01:43 You can just search for closing brackets with the
+
+ range.consumeWhitespace();
+ if (range.peek().type() == IdentToken) {
+ const CSSParserToken& ident = range.consumeIncludingWhitespace();
+ if (range.atEnd()) {
+ if (ident.valueEqualsIgnoringCase("inherit"))
+ return CSSVariableParser::Inherit;
+ if (ident.valueEqualsIgnoringCase("initial"))
+ return CSSVariableParser::Initial;
+ if (ident.valueEqualsIgnoringCase("unset"))
+ return CSSVariableParser::Unset;
+ }
+ }
+
+ while (!range.atEnd()) {
+ const CSSParserToken& token = range.consume();
+ switch (token.type()) {
+ case FunctionToken:
+ if (token.valueEqualsIgnoringCase("var")) {
+ if (!isValidVariableReference(range))
+ return CSSVariableParser::Invalid; // Bail if any references are invalid
+ type = CSSVariableParser::VariableWithReferences;
+ } else {
+ parenthesisCount++;
+ }
+ break;
+ case CommentToken:
+ case EOFToken:
+ ASSERT_NOT_REACHED();
+ case DelimiterToken: {
+ if (token.delimiter() == '!' && !parenthesisCount && !bracketCount && !braceCount)
alancutter (OOO until 2018) 2015/08/05 08:01:43 You can use consumeComponentValue() and just check
+ return CSSVariableParser::Invalid;
+ break;
+ }
+ case RightParenthesisToken:
+ if (!parenthesisCount)
+ return CSSVariableParser::Invalid;
+ parenthesisCount--;
+ break;
+ case LeftParenthesisToken:
+ parenthesisCount++;
+ break;
+ case RightBraceToken:
+ if (!braceCount)
+ return CSSVariableParser::Invalid;
+ braceCount--;
+ break;
+ case LeftBraceToken:
+ braceCount++;
+ break;
+ case RightBracketToken:
+ if (!bracketCount)
+ return CSSVariableParser::Invalid;
+ bracketCount--;
+ break;
+ case LeftBracketToken:
+ bracketCount++;
+ break;
+ case BadStringToken:
+ case BadUrlToken:
+ return CSSVariableParser::Invalid;
+ case WhitespaceToken:
+ break;
+ case SemicolonToken:
+ if (!parenthesisCount && !bracketCount && !braceCount)
+ return CSSVariableParser::Invalid;
+ default:
+ break;
+ }
+ }
+ if (parenthesisCount)
+ return CSSVariableParser::Invalid;
+ return type;
+}
+
+bool CSSVariableParser::containsValidVariableReferences(const CSSParserTokenRange& originalRange)
+{
+ CSSParserTokenRange range = originalRange;
+ return classifyVariableRange(range) == VariableWithReferences;
+}
+
+CSSVariableParser::DefinitionType CSSVariableParser::parseVariableDefinition(CSSParserTokenRange& originalRange)
alancutter (OOO until 2018) 2015/08/05 08:01:43 I'd call this parseDeclarationValue() to align wit
+{
+ if (originalRange.atEnd())
+ return CSSVariableParser::Invalid;
+ return classifyVariableRange(originalRange);
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698