Skip to content

Commit

Permalink
[CSS] @scope can have orphan declarations with an implicit enclosing …
Browse files Browse the repository at this point in the history
…style rule

https://bugs.webkit.org/show_bug.cgi?id=266710
rdar://119937025

Reviewed by Antti Koivisto.

* LayoutTests/fast/css/scope-at-rule-expected.html:
* LayoutTests/fast/css/scope-at-rule.html:
* LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/scope-nesting-expected.txt:
* Source/WebCore/css/parser/CSSParserImpl.cpp:
(WebCore::CSSParserImpl::consumeNestedGroupRules):

Rename the method to use a name closer to the spec

(WebCore::CSSParserImpl::consumeMediaRule):
(WebCore::CSSParserImpl::consumeSupportsRule):
(WebCore::CSSParserImpl::consumeScopeRule):

Allow declarations inside @scope, not just rules

(WebCore::CSSParserImpl::consumeLayerRule):
(WebCore::CSSParserImpl::consumeContainerRule):
(WebCore::CSSParserImpl::consumeRegularRuleList): Deleted.
* Source/WebCore/css/parser/CSSParserImpl.h:

Canonical link: https://commits.webkit.org/272407@main
  • Loading branch information
mdubet committed Dec 21, 2023
1 parent 10d5db7 commit e80242b
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 13 deletions.
12 changes: 12 additions & 0 deletions LayoutTests/fast/css/scope-at-rule-expected.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,15 @@
<div>
<span>should not be green</span>
</div>
<div>
<span class="green">should be green</span>
</div>
<div>
<span>should not be green</span>
</div>
<div>
<span class="green">should be green</span>
</div>
<div>
<span>should not be green</span>
</div>
28 changes: 28 additions & 0 deletions LayoutTests/fast/css/scope-at-rule.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@
}
}

#green-15 {
@scope (#b) {
& {
color: green;
}
}
}

#green-16 {
@scope (#b) {
color: green;
}
}

</style>

<div class="a">
Expand Down Expand Up @@ -160,3 +174,17 @@
</div>
<span class="green-14">should not be green</div>
</div>

<div id="green-15">
<div id="b">
should be green
</div>
should not be green
</div>

<div id="green-16">
<div id="b">
should be green
</div>
should not be green
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ PASS @scope nested within style rule
PASS Parent pseudo class within scope-start
PASS Parent pseudo class within scope-end
PASS Parent pseudo class within body of nested @scope
FAIL Implicit rule within nested @scope assert_equals: expected "1" but got "auto"
FAIL Implicit rule within nested @scope (proximity) assert_equals: expected "1" but got "2"
PASS Implicit rule within nested @scope
PASS Implicit rule within nested @scope (proximity)

15 changes: 6 additions & 9 deletions Source/WebCore/css/parser/CSSParserImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ Ref<StyleRuleBase> CSSParserImpl::createNestingParentRule()
return StyleRuleWithNesting::create(WTFMove(properties), m_context.hasDocumentSecurityOrigin, CSSSelectorList { WTFMove(selectorList) }, { });
}

Vector<Ref<StyleRuleBase>> CSSParserImpl::consumeRegularRuleList(CSSParserTokenRange block)
Vector<Ref<StyleRuleBase>> CSSParserImpl::consumeNestedGroupRules(CSSParserTokenRange block)
{
NestingLevelIncrementer incrementer { m_ruleListNestingLevel };

Expand Down Expand Up @@ -668,7 +668,7 @@ RefPtr<StyleRuleMedia> CSSParserImpl::consumeMediaRule(CSSParserTokenRange prelu
m_observerWrapper->observer().startRuleBody(m_observerWrapper->previousTokenStartOffset(block));
}

auto rules = consumeRegularRuleList(block);
auto rules = consumeNestedGroupRules(block);

if (m_observerWrapper)
m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block));
Expand All @@ -688,7 +688,7 @@ RefPtr<StyleRuleSupports> CSSParserImpl::consumeSupportsRule(CSSParserTokenRange
m_observerWrapper->observer().startRuleBody(m_observerWrapper->previousTokenStartOffset(block));
}

auto rules = consumeRegularRuleList(block);
auto rules = consumeNestedGroupRules(block);

if (m_observerWrapper)
m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block));
Expand Down Expand Up @@ -1062,10 +1062,7 @@ RefPtr<StyleRuleScope> CSSParserImpl::consumeScopeRule(CSSParserTokenRange prelu

NestingLevelIncrementer incrementer { m_scopeRuleNestingLevel };
m_ancestorRuleTypeStack.append(AncestorRuleType::Scope);
Vector<Ref<StyleRuleBase>> rules;
consumeRuleList(block, RegularRuleList, [&rules](Ref<StyleRuleBase> rule) {
rules.append(rule);
});
auto rules = consumeNestedGroupRules(block);
m_ancestorRuleTypeStack.removeLast();
auto rule = StyleRuleScope::create(WTFMove(scopeStart), WTFMove(scopeEnd), WTFMove(rules));
if (m_styleSheet)
Expand Down Expand Up @@ -1122,7 +1119,7 @@ RefPtr<StyleRuleLayer> CSSParserImpl::consumeLayerRule(CSSParserTokenRange prelu
m_observerWrapper->observer().startRuleBody(m_observerWrapper->previousTokenStartOffset(*block));
}

auto rules = consumeRegularRuleList(*block);
auto rules = consumeNestedGroupRules(*block);

if (m_observerWrapper)
m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(*block));
Expand Down Expand Up @@ -1154,7 +1151,7 @@ RefPtr<StyleRuleContainer> CSSParserImpl::consumeContainerRule(CSSParserTokenRan
m_observerWrapper->observer().startRuleBody(m_observerWrapper->previousTokenStartOffset(block));
}

auto rules = consumeRegularRuleList(block);
auto rules = consumeNestedGroupRules(block);

if (m_observerWrapper)
m_observerWrapper->observer().endRuleBody(m_observerWrapper->endOffset(block));
Expand Down
6 changes: 4 additions & 2 deletions Source/WebCore/css/parser/CSSParserImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ class CSSParserImpl {
// This function updates the range it's given.
RefPtr<StyleRuleBase> consumeQualifiedRule(CSSParserTokenRange&, AllowedRulesType);

// This function is used for all the nested group rules (@media, @supports,..etc)
Vector<Ref<StyleRuleBase>> consumeRegularRuleList(CSSParserTokenRange block);
// This function is used for all the nested group rules (@media, @layer, @supports, @scope, @container,..etc)
// It handles potentially orphaned declarations (in the context of style nesting)
// https://drafts.csswg.org/css-nesting/#conditionals
Vector<Ref<StyleRuleBase>> consumeNestedGroupRules(CSSParserTokenRange block);

static RefPtr<StyleRuleCharset> consumeCharsetRule(CSSParserTokenRange prelude);
RefPtr<StyleRuleImport> consumeImportRule(CSSParserTokenRange prelude);
Expand Down

0 comments on commit e80242b

Please sign in to comment.