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

Unified Diff: third_party/WebKit/Source/core/css/parser/CSSParserImpl.cpp

Issue 2503683003: [WIP] Streaming CSS parser (Closed)
Patch Set: rebase Created 3 years, 11 months 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
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);
}
}

Powered by Google App Engine
This is Rietveld 408576698