Index: Source/core/css/parser/CSSParserImpl.cpp |
diff --git a/Source/core/css/parser/CSSParserImpl.cpp b/Source/core/css/parser/CSSParserImpl.cpp |
index f0037def229fdd6d8d3fbce9032894378816c13a..444d3435e7398f05674b08f58fc3e20b3c159360 100644 |
--- a/Source/core/css/parser/CSSParserImpl.cpp |
+++ b/Source/core/css/parser/CSSParserImpl.cpp |
@@ -124,9 +124,10 @@ void CSSParserImpl::parseStyleSheet(const String& string, const CSSParserContext |
{ |
CSSParserImpl parser(context, styleSheet); |
CSSTokenizer::Scope scope(string); |
- parser.consumeRuleList(scope.tokenRange(), TopLevelRuleList, [&styleSheet](PassRefPtrWillBeRawPtr<StyleRuleBase> rule) { |
+ bool firstRuleValid = parser.consumeRuleList(scope.tokenRange(), TopLevelRuleList, [&styleSheet](PassRefPtrWillBeRawPtr<StyleRuleBase> rule) { |
styleSheet->parserAppendRule(rule); |
}); |
+ styleSheet->setHasSyntacticallyValidCSSHeader(firstRuleValid); |
} |
PassOwnPtr<Vector<double>> CSSParserImpl::parseKeyframeKeyList(const String& keyList) |
@@ -156,7 +157,7 @@ static CSSParserImpl::AllowedRulesType computeNewAllowedRules(CSSParserImpl::All |
} |
template<typename T> |
-void CSSParserImpl::consumeRuleList(CSSParserTokenRange range, RuleListType ruleListType, const T callback) |
+bool CSSParserImpl::consumeRuleList(CSSParserTokenRange range, RuleListType ruleListType, const T callback) |
{ |
AllowedRulesType allowedRules = RegularRules; |
switch (ruleListType) { |
@@ -173,32 +174,39 @@ void CSSParserImpl::consumeRuleList(CSSParserTokenRange range, RuleListType rule |
ASSERT_NOT_REACHED(); |
} |
+ bool seenRule = false; |
+ bool firstRuleValid = false; |
while (!range.atEnd()) { |
+ RefPtrWillBeRawPtr<StyleRuleBase> rule; |
switch (range.peek().type()) { |
case WhitespaceToken: |
range.consumeWhitespace(); |
- break; |
+ continue; |
case AtKeywordToken: |
- if (PassRefPtrWillBeRawPtr<StyleRuleBase> rule = consumeAtRule(range, allowedRules)) { |
- allowedRules = computeNewAllowedRules(allowedRules, rule.get()); |
- callback(rule); |
- } |
+ rule = consumeAtRule(range, allowedRules); |
break; |
case CDOToken: |
case CDCToken: |
if (ruleListType == TopLevelRuleList) { |
range.consume(); |
- break; |
+ continue; |
} |
// fallthrough |
default: |
- if (PassRefPtrWillBeRawPtr<StyleRuleBase> rule = consumeQualifiedRule(range, allowedRules)) { |
- allowedRules = computeNewAllowedRules(allowedRules, rule.get()); |
- callback(rule); |
- } |
+ rule = consumeQualifiedRule(range, allowedRules); |
break; |
} |
+ if (!seenRule) { |
+ seenRule = true; |
+ firstRuleValid = rule; |
+ } |
+ if (rule) { |
+ allowedRules = computeNewAllowedRules(allowedRules, rule.get()); |
+ callback(rule.release()); |
+ } |
} |
+ |
+ return firstRuleValid; |
} |
PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::consumeAtRule(CSSParserTokenRange& range, AllowedRulesType allowedRules) |
@@ -213,12 +221,8 @@ PassRefPtrWillBeRawPtr<StyleRuleBase> CSSParserImpl::consumeAtRule(CSSParserToke |
if (range.atEnd() || range.peek().type() == SemicolonToken) { |
range.consume(); |
- if (allowedRules == AllowCharsetRules && name.equalIgnoringCase("charset")) { |
- // @charset is actually parsed before we get into the CSS parser. |
- // In theory we should validate the prelude is a string, but we don't |
- // have error logging yet so it doesn't matter. |
- return nullptr; |
- } |
+ if (allowedRules == AllowCharsetRules && name.equalIgnoringCase("charset")) |
+ return consumeCharsetRule(prelude); |
if (allowedRules <= AllowImportRules && name.equalIgnoringCase("import")) |
return consumeImportRule(prelude); |
if (allowedRules <= AllowNamespaceRules && name.equalIgnoringCase("namespace")) |
@@ -289,6 +293,15 @@ static AtomicString consumeStringOrURI(CSSParserTokenRange& range) |
return uri.value(); |
} |
+PassRefPtrWillBeRawPtr<StyleRuleCharset> CSSParserImpl::consumeCharsetRule(CSSParserTokenRange prelude) |
+{ |
+ prelude.consumeWhitespace(); |
+ const CSSParserToken& string = prelude.consumeIncludingWhitespace(); |
+ if (string.type() != StringToken || !prelude.atEnd()) |
+ return nullptr; // Parse error, expected a single string |
+ return StyleRuleCharset::create(); |
+} |
+ |
PassRefPtrWillBeRawPtr<StyleRuleImport> CSSParserImpl::consumeImportRule(CSSParserTokenRange prelude) |
{ |
prelude.consumeWhitespace(); |