| 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);
|
| }
|
| }
|
|
|
|
|