Chromium Code Reviews| 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..4f44c013b9a2c613544a273ce687e64027a00193 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) |
| +{ |
|
alancutter (OOO until 2018)
2014/11/07 19:36:12
ASSERT(end.type() == EOFToken) ?
Timothy Loh
2014/11/08 00:42:49
It basically never makes sense to deference an end
|
| + 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 + 1)->type() == StringToken) { |
| + if ((it + 2)->type() == RightParenthesisToken |
| + || ((it + 3)->type() == RightParenthesisToken && (it + 2)->type() == WhitespaceToken)) { |
|
alancutter (OOO until 2018)
2014/11/07 19:36:11
These iterator accesses need to be swapped around
Timothy Loh
2014/11/08 00:42:49
I tweaked the logic a bit here, ptal.
alancutter (OOO until 2018)
2014/11/08 00:59:08
This is better.
|
| + CSSParserString string; |
| + ++it; |
| + string.init(it->value()); |
| + value.id = CSSValueInvalid; |
| + value.isInt = false; |
| + value.unit = CSSPrimitiveValue::CSS_URI; |
| + value.string = string; |
| + ++it; |
| + if (it->type() == WhitespaceToken) |
| + ++it; |
| + break; |
| + } |
| + } |
| + |
| + 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) { |
|
alancutter (OOO until 2018)
2014/11/07 19:36:12
calcDepth == 0
Timothy Loh
2014/11/08 00:42:49
Done.
|
| + 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()) { |
|
alancutter (OOO until 2018)
2014/11/07 19:36:12
backetCounts.last() == 0
Timothy Loh
2014/11/08 00:42:49
Done.
|
| + 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; |
| + } |
|
alancutter (OOO until 2018)
2014/11/07 19:36:12
ASSERT(calcDepth > 0) for readability.
Timothy Loh
2014/11/08 00:42:49
Done.
|
| + 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(); |