Index: third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp |
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp |
index 56c252edc71bf0f05bcb6bc5fd9340c87efd9e6d..2f88a8e394e650d025037c6bb4d4e6ef59b1d706 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp |
@@ -17,7 +17,6 @@ |
#include "core/css/parser/CSSLazyParsingState.h" |
#include "core/css/parser/CSSLazyPropertyParserImpl.h" |
#include "core/css/parser/CSSParserObserver.h" |
-#include "core/css/parser/CSSParserObserverWrapper.h" |
#include "core/css/parser/CSSParserSelector.h" |
#include "core/css/parser/CSSPropertyParser.h" |
#include "core/css/parser/CSSSelectorParser.h" |
@@ -38,9 +37,7 @@ namespace blink { |
CSSParserImpl::CSSParserImpl(const CSSParserContext& context, |
StyleSheetContents* styleSheet) |
- : m_context(context), |
- m_styleSheet(styleSheet), |
- m_observerWrapper(nullptr) {} |
+ : m_context(context), m_styleSheet(styleSheet) {} |
MutableStylePropertySet::SetResult CSSParserImpl::parseValue( |
MutableStylePropertySet* declaration, |
@@ -160,9 +157,10 @@ ImmutableStylePropertySet* CSSParserImpl::parseInlineStyleDeclaration( |
? HTMLStandardMode |
: HTMLQuirksMode; |
context.setMode(mode); |
- CSSParserImpl parser(context, document.elementSheet().contents()); |
CSSTokenizer tokenizer(string); |
- parser.consumeDeclarationList(tokenizer.tokenRange(), StyleRule::Style); |
+ CSSParserTokenStream stream(tokenizer); |
+ CSSParserImpl parser(context, document.elementSheet().contents()); |
+ parser.consumeDeclarationList(stream, StyleRule::Style); |
return createStylePropertySet(parser.m_parsedProperties, mode); |
} |
@@ -174,7 +172,8 @@ bool CSSParserImpl::parseDeclarationList(MutableStylePropertySet* declaration, |
if (declaration->cssParserMode() == CSSViewportRuleMode) |
ruleType = StyleRule::Viewport; |
CSSTokenizer tokenizer(string); |
- parser.consumeDeclarationList(tokenizer.tokenRange(), ruleType); |
+ CSSParserTokenStream stream(tokenizer); |
+ parser.consumeDeclarationList(stream, ruleType); |
if (parser.m_parsedProperties.isEmpty()) |
return false; |
@@ -197,19 +196,19 @@ StyleRuleBase* CSSParserImpl::parseRule(const String& string, |
AllowedRulesType allowedRules) { |
CSSParserImpl parser(context, styleSheet); |
CSSTokenizer tokenizer(string); |
- CSSParserTokenRange range = tokenizer.tokenRange(); |
- range.consumeWhitespace(); |
- if (range.atEnd()) |
+ CSSParserTokenStream stream(tokenizer); |
+ stream.skipWhitespaceAndComments(); |
+ if (stream.atEnd()) |
return nullptr; // Parse error, empty rule |
StyleRuleBase* rule; |
- if (range.peek().type() == AtKeywordToken) |
- rule = parser.consumeAtRule(range, allowedRules); |
+ if (stream.peek().type() == AtKeywordToken) |
+ rule = parser.consumeAtRule(stream, allowedRules); |
else |
- rule = parser.consumeQualifiedRule(range, allowedRules); |
+ rule = parser.consumeQualifiedRule(stream, allowedRules); |
if (!rule) |
return nullptr; // Parse error, failed to consume rule |
- range.consumeWhitespace(); |
- if (!rule || !range.atEnd()) |
+ stream.skipWhitespaceAndComments(); |
+ if (!rule || !stream.atEnd()) |
return nullptr; // Parse error, trailing garbage |
return rule; |
} |
@@ -221,33 +220,22 @@ void CSSParserImpl::parseStyleSheet(const String& string, |
TRACE_EVENT_BEGIN2("blink,blink_style", "CSSParserImpl::parseStyleSheet", |
"baseUrl", context.baseURL().getString().utf8(), "mode", |
context.mode()); |
- |
- TRACE_EVENT_BEGIN0("blink,blink_style", |
- "CSSParserImpl::parseStyleSheet.tokenize"); |
CSSTokenizer tokenizer(string); |
- TRACE_EVENT_END0("blink,blink_style", |
- "CSSParserImpl::parseStyleSheet.tokenize"); |
- |
- TRACE_EVENT_BEGIN0("blink,blink_style", |
- "CSSParserImpl::parseStyleSheet.parse"); |
+ CSSParserTokenStream stream(tokenizer); |
CSSParserImpl parser(context, styleSheet); |
if (deferPropertyParsing) { |
- parser.m_lazyState = new CSSLazyParsingState( |
- context, tokenizer.takeEscapedStrings(), string, parser.m_styleSheet); |
+ parser.m_lazyState = |
+ new CSSLazyParsingState(context, string, parser.m_styleSheet); |
} |
- bool firstRuleValid = |
- parser.consumeRuleList(tokenizer.tokenRange(), TopLevelRuleList, |
- [&styleSheet](StyleRuleBase* rule) { |
- if (rule->isCharsetRule()) |
- return; |
- styleSheet->parserAppendRule(rule); |
- }); |
+ bool firstRuleValid = parser.consumeRuleList( |
+ stream, TopLevelRuleList, [&styleSheet](StyleRuleBase* rule) { |
+ if (rule->isCharsetRule()) |
+ return; |
+ styleSheet->parserAppendRule(rule); |
+ }); |
styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid); |
- TRACE_EVENT_END0("blink,blink_style", "CSSParserImpl::parseStyleSheet.parse"); |
- |
- TRACE_EVENT_END2("blink,blink_style", "CSSParserImpl::parseStyleSheet", |
- "tokenCount", tokenizer.tokenCount(), "length", |
- string.length()); |
+ TRACE_EVENT_END1("blink,blink_style", "CSSParserImpl::parseStyleSheet", |
+ "length", string.length()); |
} |
CSSSelectorList CSSParserImpl::parsePageSelector( |
@@ -307,15 +295,7 @@ ImmutableStylePropertySet* CSSParserImpl::parseCustomPropertySet( |
if (!range.atEnd()) |
return nullptr; |
CSSParserImpl parser(strictCSSParserContext()); |
- parser.consumeDeclarationList(block, StyleRule::Style); |
- |
- // Drop nested @apply rules. Seems nicer to do this here instead of making |
- // a different StyleRule type |
- for (size_t i = parser.m_parsedProperties.size(); i--;) { |
- if (parser.m_parsedProperties[i].id() == CSSPropertyApplyAtRule) |
- parser.m_parsedProperties.remove(i); |
- } |
- |
+ parser.consumeDeclarationListForAtApply(block); |
return createStylePropertySet(parser.m_parsedProperties, HTMLStandardMode); |
} |
@@ -326,7 +306,7 @@ std::unique_ptr<Vector<double>> CSSParserImpl::parseKeyframeKeyList( |
bool CSSParserImpl::supportsDeclaration(CSSParserTokenRange& range) { |
ASSERT(m_parsedProperties.isEmpty()); |
- consumeDeclaration(range, StyleRule::Style); |
+ consumeDeclaration(range, StyleRule::Style, 0, 0); |
bool result = !m_parsedProperties.isEmpty(); |
m_parsedProperties.clear(); |
return result; |
@@ -336,38 +316,45 @@ void CSSParserImpl::parseDeclarationListForInspector( |
const String& declaration, |
const CSSParserContext& context, |
CSSParserObserver& observer) { |
- CSSParserImpl parser(context); |
- CSSParserObserverWrapper wrapper(observer); |
- parser.m_observerWrapper = &wrapper; |
- CSSTokenizer tokenizer(declaration, wrapper); |
observer.startRuleHeader(StyleRule::Style, 0); |
observer.endRuleHeader(1); |
- parser.consumeDeclarationList(tokenizer.tokenRange(), StyleRule::Style); |
+ |
+ CSSParserImpl parser(context); |
+ parser.m_observer = &observer; |
+ CSSTokenizer tokenizer(declaration); |
+ CSSParserTokenStream stream(tokenizer); |
+ parser.consumeDeclarationList(stream, StyleRule::Style); |
} |
void CSSParserImpl::parseStyleSheetForInspector(const String& string, |
const CSSParserContext& context, |
StyleSheetContents* styleSheet, |
CSSParserObserver& observer) { |
+ CSSTokenizer tokenizer(string); |
+ CSSParserTokenStream stream(tokenizer); |
CSSParserImpl parser(context, styleSheet); |
- CSSParserObserverWrapper wrapper(observer); |
- parser.m_observerWrapper = &wrapper; |
- CSSTokenizer tokenizer(string, wrapper); |
- bool firstRuleValid = |
- parser.consumeRuleList(tokenizer.tokenRange(), TopLevelRuleList, |
- [&styleSheet](StyleRuleBase* rule) { |
- if (rule->isCharsetRule()) |
- return; |
- styleSheet->parserAppendRule(rule); |
- }); |
+ parser.m_observer = &observer; |
+ bool firstRuleValid = parser.consumeRuleList( |
+ stream, TopLevelRuleList, [&styleSheet](StyleRuleBase* rule) { |
+ if (rule->isCharsetRule()) |
+ return; |
+ styleSheet->parserAppendRule(rule); |
+ }); |
styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid); |
} |
StylePropertySet* CSSParserImpl::parseDeclarationListForLazyStyle( |
- CSSParserTokenRange block, |
+ const String& string, |
+ size_t startOffset, |
const CSSParserContext& context) { |
+ CSSTokenizer tokenizer(string, startOffset); |
+ CSSParserTokenStream stream(tokenizer); |
+ stream.peek(); |
+ // We can't start the stream inside the block as the } wouldn't end the |
+ // stream. |
+ CSSParserTokenStream block(stream, CSSParserTokenStream::MakeSubStream); |
CSSParserImpl parser(context); |
- parser.consumeDeclarationList(std::move(block), StyleRule::Style); |
+ parser.consumeDeclarationList(block, StyleRule::Style); |
return createStylePropertySet(parser.m_parsedProperties, context.mode()); |
} |
@@ -386,7 +373,7 @@ static CSSParserImpl::AllowedRulesType computeNewAllowedRules( |
} |
template <typename T> |
-bool CSSParserImpl::consumeRuleList(CSSParserTokenRange range, |
+bool CSSParserImpl::consumeRuleList(CSSParserTokenStream& stream, |
RuleListType ruleListType, |
const T callback) { |
AllowedRulesType allowedRules = RegularRules; |
@@ -406,24 +393,30 @@ bool CSSParserImpl::consumeRuleList(CSSParserTokenRange range, |
bool seenRule = false; |
bool firstRuleValid = false; |
- while (!range.atEnd()) { |
+ while (true) { |
StyleRuleBase* rule; |
- switch (range.peek().type()) { |
+ size_t qualifiedRuleStartOffset = stream.offsetAfterComments(); |
+ if (stream.atEnd()) |
+ break; |
+ switch (stream.peek().type()) { |
case WhitespaceToken: |
- range.consumeWhitespace(); |
+ stream.consume(); |
continue; |
case AtKeywordToken: |
- rule = consumeAtRule(range, allowedRules); |
+ rule = consumeAtRule(stream, allowedRules); |
+ stream.clean(); |
break; |
case CDOToken: |
case CDCToken: |
if (ruleListType == TopLevelRuleList) { |
- range.consume(); |
+ stream.consume(); |
continue; |
} |
// fallthrough |
default: |
- rule = consumeQualifiedRule(range, allowedRules); |
+ rule = consumeQualifiedRule(stream, allowedRules, |
+ qualifiedRuleStartOffset); |
+ stream.clean(); |
break; |
} |
if (!seenRule) { |
@@ -439,26 +432,29 @@ bool CSSParserImpl::consumeRuleList(CSSParserTokenRange range, |
return firstRuleValid; |
} |
-StyleRuleBase* CSSParserImpl::consumeAtRule(CSSParserTokenRange& range, |
+StyleRuleBase* CSSParserImpl::consumeAtRule(CSSParserTokenStream& stream, |
AllowedRulesType allowedRules) { |
- ASSERT(range.peek().type() == AtKeywordToken); |
- const StringView name = range.consumeIncludingWhitespace().value(); |
- const CSSParserToken* preludeStart = &range.peek(); |
- while (!range.atEnd() && range.peek().type() != LeftBraceToken && |
- range.peek().type() != SemicolonToken) |
- range.consumeComponentValue(); |
- |
- CSSParserTokenRange prelude = range.makeSubRange(preludeStart, &range.peek()); |
+ DCHECK_EQ(stream.peek().type(), AtKeywordToken); |
+ const StringView name = stream.peek().value(); |
+ stream.consume(); |
+ stream.skipWhitespaceAndComments(); |
+ size_t preludeStartOffset = stream.offset(); |
+ size_t preludeStart = stream.index(); |
+ stream.consumeUntilAtEndOrPeekedTypeIs<LeftBraceToken, SemicolonToken>(); |
+ |
+ CSSParserTokenRange prelude = stream.makeSubRangeFrom(preludeStart); |
CSSAtRuleID id = cssAtRuleID(name); |
if (id != CSSAtRuleInvalid && m_context.useCounter()) |
countAtRule(m_context.useCounter(), id); |
- if (range.atEnd() || range.peek().type() == SemicolonToken) { |
- range.consume(); |
+ if (stream.atEnd() || stream.peek().type() == SemicolonToken) { |
+ size_t preludeEndOffset = stream.previousOffset(); |
+ if (!stream.atEnd()) |
+ stream.consume(); |
if (allowedRules == AllowCharsetRules && id == CSSAtRuleCharset) |
return consumeCharsetRule(prelude); |
if (allowedRules <= AllowImportRules && id == CSSAtRuleImport) |
- return consumeImportRule(prelude); |
+ return consumeImportRule(prelude, preludeStartOffset, preludeEndOffset); |
if (allowedRules <= AllowNamespaceRules && id == CSSAtRuleNamespace) |
return consumeNamespaceRule(prelude); |
if (allowedRules == ApplyRules && id == CSSAtRuleApply) { |
@@ -468,7 +464,7 @@ StyleRuleBase* CSSParserImpl::consumeAtRule(CSSParserTokenRange& range, |
return nullptr; // Parse error, unrecognised at-rule without block |
} |
- CSSParserTokenRange block = range.consumeBlock(); |
+ CSSParserTokenStream block(stream, CSSParserTokenStream::MakeSubStream); |
if (allowedRules == KeyframeRules) |
return nullptr; // Parse error, no at-rules supported inside @keyframes |
if (allowedRules == NoRules || allowedRules == ApplyRules) |
@@ -479,44 +475,41 @@ StyleRuleBase* CSSParserImpl::consumeAtRule(CSSParserTokenRange& range, |
switch (id) { |
case CSSAtRuleMedia: |
- return consumeMediaRule(prelude, block); |
+ return consumeMediaRule(prelude, block, preludeStartOffset); |
case CSSAtRuleSupports: |
- return consumeSupportsRule(prelude, block); |
+ return consumeSupportsRule(prelude, block, preludeStartOffset); |
case CSSAtRuleViewport: |
- return consumeViewportRule(prelude, block); |
+ return consumeViewportRule(prelude, block, preludeStartOffset); |
case CSSAtRuleFontFace: |
- return consumeFontFaceRule(prelude, block); |
+ return consumeFontFaceRule(prelude, block, preludeStartOffset); |
case CSSAtRuleWebkitKeyframes: |
- return consumeKeyframesRule(true, prelude, block); |
+ return consumeKeyframesRule(true, prelude, block, preludeStartOffset); |
case CSSAtRuleKeyframes: |
- return consumeKeyframesRule(false, prelude, block); |
+ return consumeKeyframesRule(false, prelude, block, preludeStartOffset); |
case CSSAtRulePage: |
- return consumePageRule(prelude, block); |
+ return consumePageRule(prelude, block, preludeStartOffset); |
default: |
return nullptr; // Parse error, unrecognised at-rule with block |
} |
} |
StyleRuleBase* CSSParserImpl::consumeQualifiedRule( |
- CSSParserTokenRange& range, |
- AllowedRulesType allowedRules) { |
- const CSSParserToken* preludeStart = &range.peek(); |
- while (!range.atEnd() && range.peek().type() != LeftBraceToken) |
- range.consumeComponentValue(); |
+ CSSParserTokenStream& stream, |
+ AllowedRulesType allowedRules, |
+ size_t startOffset) { |
+ if (allowedRules <= RegularRules) |
+ return consumeStyleRule(stream, startOffset); |
- if (range.atEnd()) |
- return nullptr; // Parse error, EOF instead of qualified rule block |
+ size_t preludeStart = stream.index(); |
+ stream.consumeUntilAtEndOrPeekedTypeIs<LeftBraceToken>(); |
- CSSParserTokenRange prelude = range.makeSubRange(preludeStart, &range.peek()); |
- CSSParserTokenRange block = range.consumeBlock(); |
- |
- if (allowedRules <= RegularRules) |
- return consumeStyleRule(prelude, block); |
- if (allowedRules == KeyframeRules) |
- return consumeKeyframeStyleRule(prelude, block); |
+ if (stream.atEnd()) |
+ return nullptr; // Parse error, EOF instead of qualified rule block |
- ASSERT_NOT_REACHED(); |
- return nullptr; |
+ CSSParserTokenRange prelude = stream.makeSubRangeFrom(preludeStart); |
+ CSSParserTokenStream block(stream, CSSParserTokenStream::MakeSubStream); |
+ DCHECK(allowedRules == KeyframeRules); |
+ return consumeKeyframeStyleRule(prelude, block, startOffset); |
} |
// This may still consume tokens if it fails |
@@ -546,18 +539,18 @@ StyleRuleCharset* CSSParserImpl::consumeCharsetRule( |
return StyleRuleCharset::create(); |
} |
-StyleRuleImport* CSSParserImpl::consumeImportRule(CSSParserTokenRange prelude) { |
+StyleRuleImport* CSSParserImpl::consumeImportRule(CSSParserTokenRange prelude, |
+ size_t startOffset, |
+ size_t endOffset) { |
AtomicString uri(consumeStringOrURI(prelude)); |
if (uri.isNull()) |
return nullptr; // Parse error, expected string or URI |
- if (m_observerWrapper) { |
- unsigned endOffset = m_observerWrapper->endOffset(prelude); |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Import, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader(endOffset); |
- m_observerWrapper->observer().startRuleBody(endOffset); |
- m_observerWrapper->observer().endRuleBody(endOffset); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Import, startOffset); |
+ m_observer->endRuleHeader(endOffset); |
+ m_observer->startRuleBody(endOffset); |
+ m_observer->endRuleBody(endOffset); |
} |
return StyleRuleImport::create(uri, |
@@ -579,16 +572,14 @@ StyleRuleNamespace* CSSParserImpl::consumeNamespaceRule( |
} |
StyleRuleMedia* CSSParserImpl::consumeMediaRule(CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
HeapVector<Member<StyleRuleBase>> rules; |
- if (m_observerWrapper) { |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Media, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader( |
- m_observerWrapper->endOffset(prelude)); |
- m_observerWrapper->observer().startRuleBody( |
- m_observerWrapper->previousTokenStartOffset(block)); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Media, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
+ m_observer->startRuleBody(block.offset() - 1); |
} |
if (m_styleSheet) |
@@ -597,9 +588,8 @@ StyleRuleMedia* CSSParserImpl::consumeMediaRule(CSSParserTokenRange prelude, |
consumeRuleList(block, RegularRuleList, |
[&rules](StyleRuleBase* rule) { rules.push_back(rule); }); |
- if (m_observerWrapper) |
- m_observerWrapper->observer().endRuleBody( |
- m_observerWrapper->endOffset(block)); |
+ if (m_observer) |
+ m_observer->endRuleBody(block.offset()); |
return StyleRuleMedia::create(MediaQueryParser::parseMediaQuerySet(prelude), |
rules); |
@@ -607,28 +597,25 @@ StyleRuleMedia* CSSParserImpl::consumeMediaRule(CSSParserTokenRange prelude, |
StyleRuleSupports* CSSParserImpl::consumeSupportsRule( |
CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
CSSSupportsParser::SupportsResult supported = |
CSSSupportsParser::supportsCondition(prelude, *this); |
if (supported == CSSSupportsParser::Invalid) |
return nullptr; // Parse error, invalid @supports condition |
- if (m_observerWrapper) { |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Supports, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader( |
- m_observerWrapper->endOffset(prelude)); |
- m_observerWrapper->observer().startRuleBody( |
- m_observerWrapper->previousTokenStartOffset(block)); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Supports, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
+ m_observer->startRuleBody(block.offset() - 1); |
} |
HeapVector<Member<StyleRuleBase>> rules; |
consumeRuleList(block, RegularRuleList, |
[&rules](StyleRuleBase* rule) { rules.push_back(rule); }); |
- if (m_observerWrapper) |
- m_observerWrapper->observer().endRuleBody( |
- m_observerWrapper->endOffset(block)); |
+ if (m_observer) |
+ m_observer->endRuleBody(block.offset()); |
return StyleRuleSupports::create(prelude.serialize().stripWhiteSpace(), |
supported, rules); |
@@ -636,7 +623,8 @@ StyleRuleSupports* CSSParserImpl::consumeSupportsRule( |
StyleRuleViewport* CSSParserImpl::consumeViewportRule( |
CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
// Allow @viewport rules from UA stylesheets even if the feature is disabled. |
if (!RuntimeEnabledFeatures::cssViewportEnabled() && |
!isUASheetBehavior(m_context.mode())) |
@@ -645,13 +633,11 @@ StyleRuleViewport* CSSParserImpl::consumeViewportRule( |
if (!prelude.atEnd()) |
return nullptr; // Parser error; @viewport prelude should be empty |
- if (m_observerWrapper) { |
- unsigned endOffset = m_observerWrapper->endOffset(prelude); |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Viewport, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader(endOffset); |
- m_observerWrapper->observer().startRuleBody(endOffset); |
- m_observerWrapper->observer().endRuleBody(endOffset); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Viewport, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
+ m_observer->startRuleBody(block.offset() - 1); |
+ m_observer->endRuleBody(block.offset() - 1); |
} |
if (m_styleSheet) |
@@ -664,17 +650,16 @@ StyleRuleViewport* CSSParserImpl::consumeViewportRule( |
StyleRuleFontFace* CSSParserImpl::consumeFontFaceRule( |
CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
if (!prelude.atEnd()) |
return nullptr; // Parse error; @font-face prelude should be empty |
- if (m_observerWrapper) { |
- unsigned endOffset = m_observerWrapper->endOffset(prelude); |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::FontFace, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader(endOffset); |
- m_observerWrapper->observer().startRuleBody(endOffset); |
- m_observerWrapper->observer().endRuleBody(endOffset); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::FontFace, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
+ m_observer->startRuleBody(block.offset() - 1); |
+ m_observer->endRuleBody(block.offset() - 1); |
} |
if (m_styleSheet) |
@@ -688,8 +673,8 @@ StyleRuleFontFace* CSSParserImpl::consumeFontFaceRule( |
StyleRuleKeyframes* CSSParserImpl::consumeKeyframesRule( |
bool webkitPrefixed, |
CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
- CSSParserTokenRange rangeCopy = prelude; // For inspector callbacks |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
const CSSParserToken& nameToken = prelude.consumeIncludingWhitespace(); |
if (!prelude.atEnd()) |
return nullptr; // Parse error; expected single non-whitespace token in |
@@ -706,15 +691,10 @@ StyleRuleKeyframes* CSSParserImpl::consumeKeyframesRule( |
return nullptr; // Parse error; expected ident token in @keyframes header |
} |
- if (m_observerWrapper) { |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Keyframes, m_observerWrapper->startOffset(rangeCopy)); |
- m_observerWrapper->observer().endRuleHeader( |
- m_observerWrapper->endOffset(prelude)); |
- m_observerWrapper->observer().startRuleBody( |
- m_observerWrapper->previousTokenStartOffset(block)); |
- m_observerWrapper->observer().endRuleBody( |
- m_observerWrapper->endOffset(block)); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Keyframes, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
+ m_observer->startRuleBody(block.offset() - 1); |
} |
StyleRuleKeyframes* keyframeRule = StyleRuleKeyframes::create(); |
@@ -724,20 +704,23 @@ StyleRuleKeyframes* CSSParserImpl::consumeKeyframesRule( |
}); |
keyframeRule->setName(name); |
keyframeRule->setVendorPrefixed(webkitPrefixed); |
+ |
+ if (m_observer) |
+ m_observer->endRuleBody(block.offset()); |
+ |
return keyframeRule; |
} |
StyleRulePage* CSSParserImpl::consumePageRule(CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
CSSSelectorList selectorList = parsePageSelector(prelude, m_styleSheet); |
if (!selectorList.isValid()) |
return nullptr; // Parse error, invalid @page selector |
- if (m_observerWrapper) { |
- unsigned endOffset = m_observerWrapper->endOffset(prelude); |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Page, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader(endOffset); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Page, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
} |
consumeDeclarationList(block, StyleRule::Style); |
@@ -760,16 +743,15 @@ void CSSParserImpl::consumeApplyRule(CSSParserTokenRange prelude) { |
StyleRuleKeyframe* CSSParserImpl::consumeKeyframeStyleRule( |
CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
+ CSSParserTokenStream& block, |
+ size_t preludeStartOffset) { |
std::unique_ptr<Vector<double>> keyList = consumeKeyframeKeyList(prelude); |
if (!keyList) |
return nullptr; |
- if (m_observerWrapper) { |
- m_observerWrapper->observer().startRuleHeader( |
- StyleRule::Keyframe, m_observerWrapper->startOffset(prelude)); |
- m_observerWrapper->observer().endRuleHeader( |
- m_observerWrapper->endOffset(prelude)); |
+ if (m_observer) { |
+ m_observer->startRuleHeader(StyleRule::Keyframe, preludeStartOffset); |
+ m_observer->endRuleHeader(block.offset() - 1); |
} |
consumeDeclarationList(block, StyleRule::Keyframe); |
@@ -778,45 +760,36 @@ StyleRuleKeyframe* CSSParserImpl::consumeKeyframeStyleRule( |
createStylePropertySet(m_parsedProperties, m_context.mode())); |
} |
-static void observeSelectors(CSSParserObserverWrapper& wrapper, |
- CSSParserTokenRange selectors) { |
- // This is easier than hooking into the CSSSelectorParser |
- selectors.consumeWhitespace(); |
- CSSParserTokenRange originalRange = selectors; |
- wrapper.observer().startRuleHeader(StyleRule::Style, |
- wrapper.startOffset(originalRange)); |
- |
- while (!selectors.atEnd()) { |
- const CSSParserToken* selectorStart = &selectors.peek(); |
- while (!selectors.atEnd() && selectors.peek().type() != CommaToken) |
- selectors.consumeComponentValue(); |
- CSSParserTokenRange selector = |
- selectors.makeSubRange(selectorStart, &selectors.peek()); |
- selectors.consumeIncludingWhitespace(); |
- |
- wrapper.observer().observeSelector(wrapper.startOffset(selector), |
- wrapper.endOffset(selector)); |
- } |
- |
- wrapper.observer().endRuleHeader(wrapper.endOffset(originalRange)); |
-} |
+StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenStream& stream, |
+ size_t startOffset) { |
+ if (m_observer) |
+ m_observer->startRuleHeader(StyleRule::Style, startOffset); |
+ CSSSelectorList selectorList = CSSSelectorParser::consumeSelector( |
+ stream, m_context, m_styleSheet, startOffset, m_observer); |
-StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, |
- CSSParserTokenRange block) { |
- CSSSelectorList selectorList = |
- CSSSelectorParser::parseSelector(prelude, m_context, m_styleSheet); |
if (!selectorList.isValid()) |
+ stream.consumeUntilAtEndOrPeekedTypeIs<LeftBraceToken>(); |
+ |
+ DCHECK(stream.atEnd() || stream.peek().type() == LeftBraceToken); |
+ |
+ if (m_observer) |
+ m_observer->endRuleHeader(stream.previousOffset()); |
+ |
+ if (!selectorList.isValid()) { |
+ if (!stream.atEnd()) |
+ stream.skipBlock(); |
return nullptr; // Parse error, invalid selector list |
+ } |
- // TODO(csharrison): How should we lazily parse css that needs the observer? |
- if (m_observerWrapper) { |
- observeSelectors(*m_observerWrapper, prelude); |
- } else if (m_lazyState && |
- m_lazyState->shouldLazilyParseProperties(selectorList, block)) { |
+ if (m_lazyState && m_lazyState->shouldLazilyParseProperties(selectorList)) { |
DCHECK(m_styleSheet); |
+ size_t blockOffset = stream.previousOffset(); |
+ stream.skipBlock(); |
return StyleRule::createLazy(std::move(selectorList), |
- m_lazyState->createLazyParser(block)); |
+ m_lazyState->createLazyParser(blockOffset)); |
} |
+ |
+ CSSParserTokenStream block(stream, CSSParserTokenStream::MakeSubStream); |
consumeDeclarationList(block, StyleRule::Style); |
return StyleRule::create( |
@@ -824,18 +797,11 @@ StyleRule* CSSParserImpl::consumeStyleRule(CSSParserTokenRange prelude, |
createStylePropertySet(m_parsedProperties, m_context.mode())); |
} |
-void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, |
- StyleRule::RuleType ruleType) { |
- ASSERT(m_parsedProperties.isEmpty()); |
- |
- bool useObserver = m_observerWrapper && (ruleType == StyleRule::Style || |
- ruleType == StyleRule::Keyframe); |
- if (useObserver) { |
- m_observerWrapper->observer().startRuleBody( |
- m_observerWrapper->previousTokenStartOffset(range)); |
- m_observerWrapper->skipCommentsBefore(range, true); |
- } |
- |
+void CSSParserImpl::consumeDeclarationListForAtApply( |
+ CSSParserTokenRange range) { |
+ DCHECK(m_parsedProperties.isEmpty()); |
+ DCHECK(RuntimeEnabledFeatures::cssApplyAtRulesEnabled()); |
+ DCHECK(!m_observer); |
while (!range.atEnd()) { |
switch (range.peek().type()) { |
case WhitespaceToken: |
@@ -844,18 +810,51 @@ void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, |
break; |
case IdentToken: { |
const CSSParserToken* declarationStart = &range.peek(); |
- |
- if (useObserver) |
- m_observerWrapper->yieldCommentsBefore(range); |
- |
while (!range.atEnd() && range.peek().type() != SemicolonToken) |
range.consumeComponentValue(); |
- |
consumeDeclaration(range.makeSubRange(declarationStart, &range.peek()), |
- ruleType); |
+ StyleRule::Style, 0, 0); |
+ break; |
+ } |
+ case AtKeywordToken: |
+ range.consume(); |
+ while (!range.atEnd() && range.peek().type() != LeftBraceToken && |
+ range.peek().type() != SemicolonToken) |
+ range.consumeComponentValue(); |
+ range.consumeComponentValue(); |
+ break; |
+ default: // Parse error, unexpected token in declaration list |
+ while (!range.atEnd() && range.peek().type() != SemicolonToken) |
+ range.consumeComponentValue(); |
+ break; |
+ } |
+ } |
+} |
- if (useObserver) |
- m_observerWrapper->skipCommentsBefore(range, false); |
+void CSSParserImpl::consumeDeclarationList(CSSParserTokenStream& stream, |
+ StyleRule::RuleType ruleType) { |
+ DCHECK(m_parsedProperties.isEmpty()); |
+ |
+ bool useObserver = m_observer && (ruleType == StyleRule::Style || |
+ ruleType == StyleRule::Keyframe); |
+ if (useObserver) |
+ m_observer->startRuleBody(stream.offset() ? stream.offset() - 1 : 0); |
+ |
+ while (true) { |
+ if (useObserver) |
+ stream.yieldComments(*m_observer); |
+ size_t declarationStartOffset = stream.offset(); |
+ if (stream.atEnd()) |
+ break; |
+ switch (stream.peek().type()) { |
+ case WhitespaceToken: |
+ case SemicolonToken: |
+ stream.consume(); |
+ break; |
+ case IdentToken: { |
+ consumeDeclaration(stream, ruleType, declarationStartOffset); |
+ if (!stream.atEnd()) |
+ stream.consume(); |
break; |
} |
case AtKeywordToken: { |
@@ -864,29 +863,38 @@ void CSSParserImpl::consumeDeclarationList(CSSParserTokenRange range, |
RuntimeEnabledFeatures::cssApplyAtRulesEnabled() |
? ApplyRules |
: NoRules; |
- StyleRuleBase* rule = consumeAtRule(range, allowedRules); |
+ StyleRuleBase* rule = consumeAtRule(stream, allowedRules); |
DCHECK(!rule); |
break; |
} |
default: // Parse error, unexpected token in declaration list |
- while (!range.atEnd() && range.peek().type() != SemicolonToken) |
- range.consumeComponentValue(); |
+ stream.consumeUntilAtEndOrPeekedTypeIs<SemicolonToken>(); |
+ if (!stream.atEnd()) |
+ stream.consume(); |
break; |
} |
} |
- // Yield remaining comments |
- if (useObserver) { |
- m_observerWrapper->yieldCommentsBefore(range); |
- m_observerWrapper->observer().endRuleBody( |
- m_observerWrapper->endOffset(range)); |
- } |
+ if (useObserver) |
+ m_observer->endRuleBody(stream.offset()); |
} |
-void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, |
- StyleRule::RuleType ruleType) { |
- CSSParserTokenRange rangeCopy = range; // For inspector callbacks |
+void CSSParserImpl::consumeDeclaration(CSSParserTokenStream& stream, |
+ StyleRule::RuleType ruleType, |
+ size_t declarationStartOffset) { |
+ DCHECK_EQ(stream.peek().type(), IdentToken); |
+ size_t startIndex = stream.index(); |
+ stream.consume(); |
+ stream.consumeUntilAtEndOrPeekedTypeIs<SemicolonToken>(); |
+ consumeDeclaration(stream.makeSubRangeFrom(startIndex), ruleType, |
+ declarationStartOffset, stream.previousOffset()); |
+ stream.clean(); |
+} |
+void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, |
+ StyleRule::RuleType ruleType, |
+ size_t declarationStartOffset, |
+ size_t declarationEndOffset) { |
ASSERT(range.peek().type() == IdentToken); |
const CSSParserToken& token = range.consumeIncludingWhitespace(); |
CSSPropertyID unresolvedProperty = token.parseAsUnresolvedCSSPropertyID(); |
@@ -931,12 +939,11 @@ void CSSParserImpl::consumeDeclaration(CSSParserTokenRange range, |
unresolvedProperty, important, ruleType); |
} |
- if (m_observerWrapper && |
+ if (m_observer && |
(ruleType == StyleRule::Style || ruleType == StyleRule::Keyframe)) { |
- m_observerWrapper->observer().observeProperty( |
- m_observerWrapper->startOffset(rangeCopy), |
- m_observerWrapper->endOffset(rangeCopy), important, |
- m_parsedProperties.size() != propertiesCount); |
+ m_observer->observeProperty(declarationStartOffset, declarationEndOffset, |
+ important, |
+ m_parsedProperties.size() != propertiesCount); |
} |
} |