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

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

Issue 647483009: CSS Parser: Implement parseValue (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase / update Created 6 years, 1 month 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
« no previous file with comments | « Source/core/css/parser/CSSParserValues.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/parser/CSSParserValues.cpp
diff --git a/Source/core/css/parser/CSSParserValues.cpp b/Source/core/css/parser/CSSParserValues.cpp
index 565112bf85c75f19340b3bf76dbb64f59e803d67..db68d66cc2d76ce028445013246ad52d577c879e 100644
--- a/Source/core/css/parser/CSSParserValues.cpp
+++ b/Source/core/css/parser/CSSParserValues.cpp
@@ -23,12 +23,179 @@
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSSelectorList.h"
+#include "core/css/parser/CSSPropertyParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
namespace blink {
using namespace WTF;
+CSSParserValueList::CSSParserValueList(CSSParserTokenIterator start, CSSParserTokenIterator end)
+: m_current(0)
+{
+ Vector<CSSParserValueList*> stack;
+ Vector<int> bracketCounts;
+ stack.append(this);
+ bracketCounts.append(0);
+ unsigned calcDepth = 0;
+ for (CSSParserTokenIterator it = start; it != end; ++it) {
+ ASSERT(stack.size() == bracketCounts.size());
+ ASSERT(!stack.isEmpty());
+ const CSSParserToken& token = *it;
+ CSSParserValue value;
+ switch (token.type()) {
+ case FunctionToken: {
+ if (token.value() == "url" && it + 2 < end && (it + 2)->type() == RightParenthesisToken) {
+ ++it;
+ if (it->type() == BadStringToken) {
+ destroyAndClear();
+ return;
+ }
+ ASSERT(it->type() == StringToken);
+ CSSParserString string;
+ string.init(it->value());
+ value.id = CSSValueInvalid;
+ value.isInt = false;
+ value.unit = CSSPrimitiveValue::CSS_URI;
+ value.string = string;
+ ++it;
+ }
+
+ CSSParserFunction* function = new CSSParserFunction;
+ CSSParserString name;
+ name.init(token.value());
+ function->id = cssValueKeywordID(name);
+ CSSParserValueList* list = new CSSParserValueList;
+ function->args = adoptPtr(list);
+
+ value.id = CSSValueInvalid;
+ value.isInt = false;
+ value.unit = CSSParserValue::Function;
+ value.function = function;
+
+ stack.last()->addValue(value);
+ stack.append(list);
+ bracketCounts.append(0);
+ calcDepth += (function->id == CSSValueCalc || function->id == CSSValueWebkitCalc);
+ continue;
+ }
+ case LeftParenthesisToken: {
+ if (calcDepth == 0) {
+ CSSParserValueList* list = new CSSParserValueList;
+ value.setFromValueList(adoptPtr(list));
+ stack.last()->addValue(value);
+ stack.append(list);
+ bracketCounts.append(0);
+ continue;
+ }
+ bracketCounts.last()++;
+ value.setFromOperator('(');
+ break;
+ }
+ case RightParenthesisToken: {
+ if (bracketCounts.last() == 0) {
+ stack.removeLast();
+ bracketCounts.removeLast();
+ if (bracketCounts.isEmpty()) {
+ destroyAndClear();
+ return;
+ }
+ CSSParserValueList* currentList = stack.last();
+ CSSParserValue* current = currentList->valueAt(currentList->size()-1);
+ if (current->unit == CSSParserValue::Function) {
+ CSSValueID id = current->function->id;
+ calcDepth -= (id == CSSValueCalc || id == CSSValueWebkitCalc);
+ }
+ continue;
+ }
+ ASSERT(calcDepth > 0);
+ bracketCounts.last()--;
+ value.setFromOperator(')');
+ break;
+ }
+ case IdentToken: {
+ CSSParserString string;
+ string.init(token.value());
+ value.id = cssValueKeywordID(string);
+ value.isInt = false;
+ value.unit = CSSPrimitiveValue::CSS_IDENT;
+ value.string = string;
+ break;
+ }
+ case DimensionToken:
+ case NumberToken:
+ case PercentageToken:
+ value.setFromNumber(token.numericValue(), token.unitType());
+ value.isInt = (token.numericValueType() == IntegerValueType);
+ break;
+ case HashToken:
+ case StringToken:
+ case UnicodeRangeToken:
+ case UrlToken: {
+ CSSParserString string;
+ string.init(token.value());
+ value.id = CSSValueInvalid;
+ value.isInt = false;
+ if (token.type() == HashToken)
+ value.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR;
+ else if (token.type() == StringToken)
+ value.unit = CSSPrimitiveValue::CSS_STRING;
+ else if (token.type() == UnicodeRangeToken)
+ value.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE;
+ else
+ value.unit = CSSPrimitiveValue::CSS_URI;
+ value.string = string;
+ break;
+ }
+ case DelimiterToken:
+ value.setFromOperator(token.delimiter());
+ if (calcDepth && token.delimiter() == '+' && (it - 1)->type() != WhitespaceToken) {
+ // calc(1px+ 2px) is invalid
+ destroyAndClear();
+ return;
+ }
+ break;
+ case CommaToken:
+ value.setFromOperator(',');
+ break;
+ case LeftBracketToken:
+ value.setFromOperator('[');
+ break;
+ case RightBracketToken:
+ value.setFromOperator(']');
+ break;
+ case LeftBraceToken:
+ value.setFromOperator('{');
+ break;
+ case RightBraceToken:
+ value.setFromOperator('}');
+ break;
+ case WhitespaceToken:
+ case CommentToken:
+ continue;
+ case BadStringToken:
+ case BadUrlToken:
+ case ColonToken:
+ case EOFToken:
+ case SemicolonToken:
+ destroyAndClear();
+ return;
+ }
+ stack.last()->addValue(value);
+ }
+
+ CSSParserValue rightParenthesis;
+ rightParenthesis.setFromOperator(')');
+ while (!stack.isEmpty()) {
+ while (bracketCounts.last() > 0) {
+ bracketCounts.last()--;
+ stack.last()->addValue(rightParenthesis);
+ }
+ stack.removeLast();
+ bracketCounts.removeLast();
+ }
+}
+
static void destroy(Vector<CSSParserValue, 4>& values)
{
size_t numValues = values.size();
« no previous file with comments | « Source/core/css/parser/CSSParserValues.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698