Index: Source/core/css/parser/CSSTokenizer.cpp |
diff --git a/Source/core/css/parser/CSSTokenizer.cpp b/Source/core/css/parser/CSSTokenizer.cpp |
index fd41459e1c71f589338ccb4a54028672f5fc6c63..460c81590f38149170dd27d4d91b387425087090 100644 |
--- a/Source/core/css/parser/CSSTokenizer.cpp |
+++ b/Source/core/css/parser/CSSTokenizer.cpp |
@@ -18,8 +18,9 @@ namespace blink { |
namespace blink { |
-CSSTokenizer::Scope::Scope(const String& string) |
-: m_string(string) |
+CSSTokenizerScope::CSSTokenizerScope(const String& string) |
+ : m_string(string) |
+ , m_hasVariableReference(false) |
{ |
// According to the spec, we should perform preprocessing here. |
// See: http://dev.w3.org/csswg/css-syntax/#input-preprocessing |
@@ -48,8 +49,9 @@ CSSTokenizer::Scope::Scope(const String& string) |
} |
} |
-CSSTokenizer::Scope::Scope(const String& string, CSSParserObserverWrapper& wrapper) |
-: m_string(string) |
+CSSTokenizerScope::CSSTokenizerScope(const String& string, CSSParserObserverWrapper& wrapper) |
+ : m_string(string) |
+ , m_hasVariableReference(false) |
{ |
if (string.isEmpty()) |
return; |
@@ -75,12 +77,12 @@ CSSTokenizer::Scope::Scope(const String& string, CSSParserObserverWrapper& wrapp |
wrapper.finalizeConstruction(m_tokens.begin()); |
} |
-CSSParserTokenRange CSSTokenizer::Scope::tokenRange() |
+CSSParserTokenRange CSSTokenizerScope::tokenRange() |
{ |
- return m_tokens; |
+ return CSSParserTokenRange(m_tokens, this); |
} |
-unsigned CSSTokenizer::Scope::tokenCount() |
+unsigned CSSTokenizerScope::tokenCount() |
{ |
return m_tokens.size(); |
} |
@@ -113,7 +115,7 @@ static bool twoCharsAreValidEscape(UChar first, UChar second) |
return first == '\\' && !isNewLine(second); |
} |
-CSSTokenizer::CSSTokenizer(CSSTokenizerInputStream& inputStream, Scope& scope) |
+CSSTokenizer::CSSTokenizer(CSSTokenizerInputStream& inputStream, CSSTokenizerScope& scope) |
: m_input(inputStream) |
, m_scope(scope) |
{ |
@@ -138,8 +140,9 @@ void CSSTokenizer::consume(unsigned offset) |
CSSParserToken CSSTokenizer::whiteSpace(UChar cc) |
{ |
- consumeUntilNonWhitespace(); |
- return CSSParserToken(WhitespaceToken); |
+ unsigned start = m_input.offset(); |
+ unsigned length = consumeUntilNonWhitespace(); |
+ return CSSParserToken(WhitespaceToken, m_input.rangeAsCSSParserString(start, length)); |
} |
static bool popIfBlockMatches(Vector<CSSParserTokenType>& blockStack, CSSParserTokenType type) |
@@ -262,12 +265,12 @@ CSSParserToken CSSTokenizer::solidus(UChar cc) |
CSSParserToken CSSTokenizer::colon(UChar cc) |
{ |
- return CSSParserToken(ColonToken); |
+ return CSSParserToken(ColonToken, lastConsumedCharacter()); |
} |
CSSParserToken CSSTokenizer::semiColon(UChar cc) |
{ |
- return CSSParserToken(SemicolonToken); |
+ return CSSParserToken(SemicolonToken, lastConsumedCharacter()); |
} |
CSSParserToken CSSTokenizer::hash(UChar cc) |
@@ -492,6 +495,8 @@ CSSParserToken CSSTokenizer::consumeIdentLikeToken() |
UChar next = m_input.nextInputChar(); |
if (next != '"' && next != '\'') |
return consumeUrlToken(); |
+ } else if (equalIgnoringCase(name, "var")) { |
+ m_scope.m_hasVariableReference = true; |
} |
return blockStart(LeftParenthesisToken, FunctionToken, name); |
} |
@@ -636,11 +641,15 @@ void CSSTokenizer::consumeBadUrlRemnants() |
} |
} |
-void CSSTokenizer::consumeUntilNonWhitespace() |
+unsigned CSSTokenizer::consumeUntilNonWhitespace() |
{ |
+ unsigned count = 0; |
// Using HTML space here rather than CSS space since we don't do preprocessing |
- while (isHTMLSpace<UChar>(m_input.nextInputChar())) |
+ while (isHTMLSpace<UChar>(m_input.nextInputChar())) { |
+ ++count; |
consume(); |
+ } |
+ return count; |
} |
void CSSTokenizer::consumeSingleWhitespaceIfNext() |
@@ -709,6 +718,11 @@ CSSParserString CSSTokenizer::consumeName() |
} |
} |
+CSSParserString CSSTokenizer::lastConsumedCharacter() |
+{ |
+ return m_input.rangeAsCSSParserString(m_input.offset() - 1, 1); |
+} |
+ |
// http://dev.w3.org/csswg/css-syntax/#consume-an-escaped-code-point |
UChar32 CSSTokenizer::consumeEscape() |
{ |