Skip to content

Commit a34f359

Browse files
authoredAug 24, 2023
feat(css/ast): Support @scope at-rule (#7837)
> ### Describe the feature > [Chrome 118 is shipping soon](https://chromium-review.googlesource.com/c/chromium/src/+/4790561), which is expected to be one of the more popular CSS features, giving new hope for style isolation of components. > > * Explainer https://css.oddbird.net/scope/explainer > * Specification https://drafts.csswg.org/css-cascade-6/#scope-atrule > Closed: #7836
1 parent da5bc10 commit a34f359

File tree

19 files changed

+9159
-2
lines changed

19 files changed

+9159
-2
lines changed
 

‎crates/swc_atoms/words.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,7 @@ scaleZ
21172117
scalex
21182118
scaley
21192119
scalez
2120+
scope
21202121
script
21212122
scroll
21222123
scroll-behavior

‎crates/swc_css_ast/src/at_rule.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use swc_atoms::{Atom, JsWord};
44
use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
55

66
use crate::{
7-
CustomIdent, CustomPropertyName, DashedIdent, Declaration, Dimension, FamilyName, Function,
8-
Ident, ListOfComponentValues, Number, Percentage, Ratio, SelectorList, SimpleBlock, Str, Url,
7+
CustomIdent, CustomPropertyName, DashedIdent, Declaration, Dimension, FamilyName,
8+
ForgivingSelectorList, Function, Ident, ListOfComponentValues, Number, Percentage, Ratio,
9+
SelectorList, SimpleBlock, Str, Url,
910
};
1011

1112
#[ast_node("AtRule")]
@@ -84,6 +85,18 @@ pub enum AtRulePrelude {
8485
ContainerPrelude(ContainerCondition),
8586
#[tag("CustomMedia")]
8687
CustomMediaPrelude(CustomMediaQuery),
88+
#[tag("ScopeRange")]
89+
ScopePrelude(ScopeRange),
90+
}
91+
92+
#[ast_node("ScopeRange")]
93+
#[derive(Eq, Hash, EqIgnoreSpan)]
94+
pub struct ScopeRange {
95+
pub span: Span,
96+
/// https://drafts.csswg.org/css-cascade-6/#typedef-scope-start
97+
pub scope_start: Option<ForgivingSelectorList>,
98+
/// https://drafts.csswg.org/css-cascade-6/#typedef-scope-end
99+
pub scope_end: Option<ForgivingSelectorList>,
87100
}
88101

89102
#[ast_node]

‎crates/swc_css_codegen/src/lib.rs

+20
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ where
324324
n
325325
)
326326
}
327+
AtRulePrelude::ScopePrelude(n) => {
328+
emit!(self, n);
329+
}
327330
}
328331
}
329332

@@ -2459,6 +2462,23 @@ where
24592462
}
24602463
}
24612464

2465+
#[emitter]
2466+
fn emit_scope_range(&mut self, n: &ScopeRange) -> Result {
2467+
if let Some(start) = &n.scope_start {
2468+
formatting_space!(self);
2469+
write_raw!(self, "(");
2470+
emit!(self, start);
2471+
write_raw!(self, ")");
2472+
}
2473+
if let Some(end) = &n.scope_end {
2474+
write_raw!(self, " to");
2475+
space!(self);
2476+
write_raw!(self, "(");
2477+
emit!(self, end);
2478+
write_raw!(self, ")");
2479+
}
2480+
}
2481+
24622482
fn emit_list_pseudo_element_selector_children(
24632483
&mut self,
24642484
nodes: &[PseudoElementSelectorChildren],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@scope {
2+
3+
/* Only match links inside a light-scheme */
4+
a {
5+
color: darkmagenta;
6+
}
7+
}
8+
9+
@scope (.light-scheme) {
10+
11+
/* Only match links inside a light-scheme */
12+
a {
13+
color: darkmagenta;
14+
}
15+
}
16+
17+
@scope to (.content > *) {
18+
img {
19+
border-radius: 50%;
20+
}
21+
22+
.content {
23+
padding: 1em;
24+
}
25+
}
26+
27+
@scope (.media-object) to (.content > *) {
28+
img {
29+
border-radius: 50%;
30+
}
31+
32+
.content {
33+
padding: 1em;
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@scope {
2+
a {
3+
color: darkmagenta;
4+
}
5+
}
6+
@scope (.light-scheme) {
7+
a {
8+
color: darkmagenta;
9+
}
10+
}
11+
@scope to (.content > *) {
12+
img {
13+
border-radius: 50%;
14+
}
15+
.content {
16+
padding: 1em;
17+
}
18+
}
19+
@scope (.media-object) to (.content > *) {
20+
img {
21+
border-radius: 50%;
22+
}
23+
.content {
24+
padding: 1em;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@scope{a{color:darkmagenta}}@scope(.light-scheme){a{color:darkmagenta}}@scope to (.content>*){img{border-radius:50%}.content{padding:1em}}@scope(.media-object) to (.content>*){img{border-radius:50%}.content{padding:1em}}

‎crates/swc_css_parser/src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ impl Error {
7171
ErrorKind::InvalidKeyframesName(s) => {
7272
format!("{} is not valid name for keyframes", s).into()
7373
}
74+
ErrorKind::InvalidScopeAtRule => "Invalid @scope at-rule".into(),
7475
}
7576
}
7677

@@ -115,6 +116,7 @@ pub enum ErrorKind {
115116
InvalidAnPlusBMicrosyntax,
116117
InvalidCustomIdent(JsWord),
117118
InvalidKeyframesName(&'static str),
119+
InvalidScopeAtRule,
118120

119121
UnknownAtRuleNotTerminated,
120122
}

‎crates/swc_css_parser/src/macros.rs

+4
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,8 @@ macro_rules! tok {
146146
(">") => {
147147
swc_css_ast::Token::Delim { value: '>' }
148148
};
149+
150+
("to") => {
151+
swc_css_ast::Token::Ident { value: js_word!("to"), .. }
152+
};
149153
}

‎crates/swc_css_parser/src/parser/at_rules/mod.rs

+80
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,15 @@ where
424424

425425
None
426426
}
427+
js_word!("scope") => {
428+
self.input.skip_ws();
429+
430+
let prelude = AtRulePrelude::ScopePrelude(self.parse()?);
431+
432+
self.input.skip_ws();
433+
434+
Some(prelude)
435+
}
427436
_ => {
428437
return Err(Error::new(Default::default(), ErrorKind::Ignore));
429438
}
@@ -756,6 +765,13 @@ where
756765

757766
rule_list
758767
}
768+
js_word!("scope") => {
769+
let rule_list = self.parse_as::<Vec<Rule>>()?;
770+
let rule_list: Vec<ComponentValue> =
771+
rule_list.into_iter().map(ComponentValue::from).collect();
772+
773+
rule_list
774+
}
759775
_ => {
760776
return Err(Error::new(Default::default(), ErrorKind::Ignore));
761777
}
@@ -2625,3 +2641,67 @@ where
26252641
})
26262642
}
26272643
}
2644+
2645+
impl<I> Parse<ScopeRange> for Parser<I>
2646+
where
2647+
I: ParserInput,
2648+
{
2649+
fn parse(&mut self) -> PResult<ScopeRange> {
2650+
let span = self.input.cur_span();
2651+
2652+
if is!(self, EOF) {
2653+
return Ok(ScopeRange {
2654+
span: span!(self, span.lo),
2655+
scope_start: None,
2656+
scope_end: None,
2657+
});
2658+
}
2659+
2660+
match cur!(self) {
2661+
tok!("(") => {
2662+
bump!(self);
2663+
let start = self.parse()?;
2664+
expect!(self, ")");
2665+
self.input.skip_ws();
2666+
2667+
let end = if is!(self, EOF) {
2668+
None
2669+
} else if is_case_insensitive_ident!(self, "to") {
2670+
bump!(self);
2671+
self.input.skip_ws();
2672+
expect!(self, "(");
2673+
let result = self.parse()?;
2674+
expect!(self, ")");
2675+
Some(result)
2676+
} else {
2677+
None
2678+
};
2679+
2680+
Ok(ScopeRange {
2681+
span: span!(self, span.lo),
2682+
scope_start: Some(start),
2683+
scope_end: end,
2684+
})
2685+
}
2686+
_ => {
2687+
if is_case_insensitive_ident!(self, "to") {
2688+
bump!(self);
2689+
2690+
self.input.skip_ws();
2691+
2692+
expect!(self, "(");
2693+
let end = self.parse()?;
2694+
expect!(self, ")");
2695+
2696+
return Ok(ScopeRange {
2697+
span: span!(self, span.lo),
2698+
scope_start: None,
2699+
scope_end: Some(end),
2700+
});
2701+
}
2702+
2703+
return Err(Error::new(span, ErrorKind::InvalidScopeAtRule));
2704+
}
2705+
}
2706+
}
2707+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@scope {
2+
3+
/* Only match links inside a light-scheme */
4+
a {
5+
color: darkmagenta;
6+
}
7+
}
8+
9+
@scope (.light-scheme) {
10+
11+
/* Only match links inside a light-scheme */
12+
a {
13+
color: darkmagenta;
14+
}
15+
}
16+
17+
@scope to (.content > *) {
18+
img {
19+
border-radius: 50%;
20+
}
21+
22+
.content {
23+
padding: 1em;
24+
}
25+
}
26+
27+
@scope (.media-object) to (.content > *) {
28+
img {
29+
border-radius: 50%;
30+
}
31+
32+
.content {
33+
padding: 1em;
34+
}
35+
}
36+
37+
@scope TO (.content > *) {
38+
img {
39+
border-radius: 50%;
40+
}
41+
42+
.content {
43+
padding: 1em;
44+
}
45+
}

‎crates/swc_css_parser/tests/fixture/at-rule/scope/basic/output.json

+1,551
Large diffs are not rendered by default.

‎crates/swc_css_parser/tests/fixture/at-rule/scope/basic/span.swc-stderr

+1,860
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* https: //chromium-review.googlesource.com/c/chromium/src/+/4629290 */
2+
@scope (.a) {
3+
@container (width > 0px) {
4+
:scope {
5+
z-index: 1;
6+
}
7+
8+
.b {
9+
background-color: green;
10+
}
11+
}
12+
}
13+
14+
@scope (.a) {
15+
/* The theme layer wins over the base layer. Note that @layer statements
16+
are allowed here, but aren't affected by the enclosing @scope. */
17+
@layer base,
18+
theme;
19+
20+
@layer theme {
21+
:scope {
22+
z-index: 1;
23+
}
24+
25+
.b {
26+
background-color: green;
27+
}
28+
}
29+
}
30+
31+
@scope (.a) {
32+
@media (width > 0px) {
33+
:scope {
34+
z-index: 1;
35+
}
36+
37+
.b {
38+
background-color: green;
39+
}
40+
}
41+
}
42+
43+
@scope (.a) {
44+
@starting-style {
45+
:scope {
46+
width: 100px;
47+
}
48+
49+
.b {
50+
width: 100px;
51+
}
52+
}
53+
}
54+
55+
@scope (.a) {
56+
@supports (width:0px) {
57+
:scope {
58+
z-index: 1;
59+
}
60+
61+
.b {
62+
background-color: green;
63+
}
64+
}
65+
}

‎crates/swc_css_parser/tests/fixture/at-rule/scope/chromium/output.json

+2,089
Large diffs are not rendered by default.

‎crates/swc_css_parser/tests/fixture/at-rule/scope/chromium/span.swc-stderr

+2,718
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@scope (#inner) {
2+
@keyframes --my-anim {
3+
to {
4+
background-color: rgb(0, 0, 255);
5+
}
6+
}
7+
}
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
{
2+
"type": "Stylesheet",
3+
"span": {
4+
"start": 1,
5+
"end": 124,
6+
"ctxt": 0
7+
},
8+
"rules": [
9+
{
10+
"type": "AtRule",
11+
"span": {
12+
"start": 1,
13+
"end": 122,
14+
"ctxt": 0
15+
},
16+
"name": {
17+
"type": "Ident",
18+
"span": {
19+
"start": 2,
20+
"end": 7,
21+
"ctxt": 0
22+
},
23+
"value": "scope",
24+
"raw": "scope"
25+
},
26+
"prelude": {
27+
"type": "ScopeRange",
28+
"span": {
29+
"start": 8,
30+
"end": 17,
31+
"ctxt": 0
32+
},
33+
"scopeStart": {
34+
"type": "SelectorList",
35+
"span": {
36+
"start": 9,
37+
"end": 15,
38+
"ctxt": 0
39+
},
40+
"children": [
41+
{
42+
"type": "ComplexSelector",
43+
"span": {
44+
"start": 9,
45+
"end": 15,
46+
"ctxt": 0
47+
},
48+
"children": [
49+
{
50+
"type": "CompoundSelector",
51+
"span": {
52+
"start": 9,
53+
"end": 15,
54+
"ctxt": 0
55+
},
56+
"nestingSelector": null,
57+
"typeSelector": null,
58+
"subclassSelectors": [
59+
{
60+
"type": "IdSelector",
61+
"span": {
62+
"start": 9,
63+
"end": 15,
64+
"ctxt": 0
65+
},
66+
"text": {
67+
"type": "Ident",
68+
"span": {
69+
"start": 9,
70+
"end": 15,
71+
"ctxt": 0
72+
},
73+
"value": "inner",
74+
"raw": "inner"
75+
}
76+
}
77+
]
78+
}
79+
]
80+
}
81+
]
82+
},
83+
"scopeEnd": null
84+
},
85+
"block": {
86+
"type": "SimpleBlock",
87+
"span": {
88+
"start": 17,
89+
"end": 122,
90+
"ctxt": 0
91+
},
92+
"name": {
93+
"type": "PreservedToken",
94+
"span": {
95+
"start": 17,
96+
"end": 18,
97+
"ctxt": 0
98+
},
99+
"token": "LBrace"
100+
},
101+
"value": [
102+
{
103+
"type": "AtRule",
104+
"span": {
105+
"start": 23,
106+
"end": 120,
107+
"ctxt": 0
108+
},
109+
"name": {
110+
"type": "Ident",
111+
"span": {
112+
"start": 24,
113+
"end": 33,
114+
"ctxt": 0
115+
},
116+
"value": "keyframes",
117+
"raw": "keyframes"
118+
},
119+
"prelude": {
120+
"type": "CustomIdent",
121+
"span": {
122+
"start": 34,
123+
"end": 43,
124+
"ctxt": 0
125+
},
126+
"value": "--my-anim",
127+
"raw": "--my-anim"
128+
},
129+
"block": {
130+
"type": "SimpleBlock",
131+
"span": {
132+
"start": 44,
133+
"end": 120,
134+
"ctxt": 0
135+
},
136+
"name": {
137+
"type": "PreservedToken",
138+
"span": {
139+
"start": 44,
140+
"end": 45,
141+
"ctxt": 0
142+
},
143+
"token": "LBrace"
144+
},
145+
"value": [
146+
{
147+
"type": "KeyframeBlock",
148+
"span": {
149+
"start": 54,
150+
"end": 114,
151+
"ctxt": 0
152+
},
153+
"prelude": [
154+
{
155+
"type": "Ident",
156+
"span": {
157+
"start": 54,
158+
"end": 56,
159+
"ctxt": 0
160+
},
161+
"value": "to",
162+
"raw": "to"
163+
}
164+
],
165+
"block": {
166+
"type": "SimpleBlock",
167+
"span": {
168+
"start": 57,
169+
"end": 114,
170+
"ctxt": 0
171+
},
172+
"name": {
173+
"type": "PreservedToken",
174+
"span": {
175+
"start": 57,
176+
"end": 58,
177+
"ctxt": 0
178+
},
179+
"token": "LBrace"
180+
},
181+
"value": [
182+
{
183+
"type": "Declaration",
184+
"span": {
185+
"start": 71,
186+
"end": 103,
187+
"ctxt": 0
188+
},
189+
"name": {
190+
"type": "Ident",
191+
"span": {
192+
"start": 71,
193+
"end": 87,
194+
"ctxt": 0
195+
},
196+
"value": "background-color",
197+
"raw": "background-color"
198+
},
199+
"value": [
200+
{
201+
"type": "Function",
202+
"span": {
203+
"start": 89,
204+
"end": 103,
205+
"ctxt": 0
206+
},
207+
"name": {
208+
"type": "Ident",
209+
"span": {
210+
"start": 89,
211+
"end": 92,
212+
"ctxt": 0
213+
},
214+
"value": "rgb",
215+
"raw": "rgb"
216+
},
217+
"value": [
218+
{
219+
"type": "Number",
220+
"span": {
221+
"start": 93,
222+
"end": 94,
223+
"ctxt": 0
224+
},
225+
"value": 0.0,
226+
"raw": "0"
227+
},
228+
{
229+
"type": "Delimiter",
230+
"span": {
231+
"start": 94,
232+
"end": 95,
233+
"ctxt": 0
234+
},
235+
"value": ","
236+
},
237+
{
238+
"type": "Number",
239+
"span": {
240+
"start": 96,
241+
"end": 97,
242+
"ctxt": 0
243+
},
244+
"value": 0.0,
245+
"raw": "0"
246+
},
247+
{
248+
"type": "Delimiter",
249+
"span": {
250+
"start": 97,
251+
"end": 98,
252+
"ctxt": 0
253+
},
254+
"value": ","
255+
},
256+
{
257+
"type": "Number",
258+
"span": {
259+
"start": 99,
260+
"end": 102,
261+
"ctxt": 0
262+
},
263+
"value": 255.0,
264+
"raw": "255"
265+
}
266+
]
267+
}
268+
],
269+
"important": null
270+
}
271+
]
272+
}
273+
}
274+
]
275+
}
276+
}
277+
]
278+
}
279+
}
280+
]
281+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
2+
x Stylesheet
3+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
4+
1 | ,-> @scope (#inner) {
5+
2 | | @keyframes --my-anim {
6+
3 | | to {
7+
4 | | background-color: rgb(0, 0, 255);
8+
5 | | }
9+
6 | | }
10+
7 | | }
11+
8 | `->
12+
`----
13+
14+
x Rule
15+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
16+
1 | ,-> @scope (#inner) {
17+
2 | | @keyframes --my-anim {
18+
3 | | to {
19+
4 | | background-color: rgb(0, 0, 255);
20+
5 | | }
21+
6 | | }
22+
7 | `-> }
23+
`----
24+
25+
x AtRule
26+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
27+
1 | ,-> @scope (#inner) {
28+
2 | | @keyframes --my-anim {
29+
3 | | to {
30+
4 | | background-color: rgb(0, 0, 255);
31+
5 | | }
32+
6 | | }
33+
7 | `-> }
34+
`----
35+
36+
x AtRuleName
37+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
38+
1 | @scope (#inner) {
39+
: ^^^^^
40+
2 | @keyframes --my-anim {
41+
`----
42+
43+
x Ident
44+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
45+
1 | @scope (#inner) {
46+
: ^^^^^
47+
2 | @keyframes --my-anim {
48+
`----
49+
50+
x ForgivingSelectorList
51+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
52+
1 | @scope (#inner) {
53+
: ^^^^^^
54+
2 | @keyframes --my-anim {
55+
`----
56+
57+
x ComplexSelector
58+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
59+
1 | @scope (#inner) {
60+
: ^^^^^^
61+
2 | @keyframes --my-anim {
62+
`----
63+
64+
x CompoundSelector
65+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
66+
1 | @scope (#inner) {
67+
: ^^^^^^
68+
2 | @keyframes --my-anim {
69+
`----
70+
71+
x SubclassSelector
72+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
73+
1 | @scope (#inner) {
74+
: ^^^^^^
75+
2 | @keyframes --my-anim {
76+
`----
77+
78+
x IdSelector
79+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
80+
1 | @scope (#inner) {
81+
: ^^^^^^
82+
2 | @keyframes --my-anim {
83+
`----
84+
85+
x Ident
86+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
87+
1 | @scope (#inner) {
88+
: ^^^^^^
89+
2 | @keyframes --my-anim {
90+
`----
91+
92+
x SimpleBlock
93+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
94+
1 | ,-> @scope (#inner) {
95+
2 | | @keyframes --my-anim {
96+
3 | | to {
97+
4 | | background-color: rgb(0, 0, 255);
98+
5 | | }
99+
6 | | }
100+
7 | `-> }
101+
`----
102+
103+
x LBrace
104+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
105+
1 | @scope (#inner) {
106+
: ^
107+
2 | @keyframes --my-anim {
108+
`----
109+
110+
x ComponentValue
111+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
112+
1 | @scope (#inner) {
113+
2 | ,-> @keyframes --my-anim {
114+
3 | | to {
115+
4 | | background-color: rgb(0, 0, 255);
116+
5 | | }
117+
6 | `-> }
118+
7 | }
119+
`----
120+
121+
x AtRule
122+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
123+
1 | @scope (#inner) {
124+
2 | ,-> @keyframes --my-anim {
125+
3 | | to {
126+
4 | | background-color: rgb(0, 0, 255);
127+
5 | | }
128+
6 | `-> }
129+
7 | }
130+
`----
131+
132+
x AtRuleName
133+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
134+
1 | @scope (#inner) {
135+
2 | @keyframes --my-anim {
136+
: ^^^^^^^^^
137+
3 | to {
138+
`----
139+
140+
x Ident
141+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
142+
1 | @scope (#inner) {
143+
2 | @keyframes --my-anim {
144+
: ^^^^^^^^^
145+
3 | to {
146+
`----
147+
148+
x CustomIdent
149+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
150+
1 | @scope (#inner) {
151+
2 | @keyframes --my-anim {
152+
: ^^^^^^^^^
153+
3 | to {
154+
`----
155+
156+
x SimpleBlock
157+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
158+
1 | @scope (#inner) {
159+
2 | ,-> @keyframes --my-anim {
160+
3 | | to {
161+
4 | | background-color: rgb(0, 0, 255);
162+
5 | | }
163+
6 | `-> }
164+
7 | }
165+
`----
166+
167+
x LBrace
168+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:1:1]
169+
1 | @scope (#inner) {
170+
2 | @keyframes --my-anim {
171+
: ^
172+
3 | to {
173+
`----
174+
175+
x ComponentValue
176+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:2:1]
177+
2 | @keyframes --my-anim {
178+
3 | ,-> to {
179+
4 | | background-color: rgb(0, 0, 255);
180+
5 | `-> }
181+
6 | }
182+
`----
183+
184+
x Ident
185+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:2:1]
186+
2 | @keyframes --my-anim {
187+
3 | to {
188+
: ^^
189+
4 | background-color: rgb(0, 0, 255);
190+
`----
191+
192+
x SimpleBlock
193+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:2:1]
194+
2 | @keyframes --my-anim {
195+
3 | ,-> to {
196+
4 | | background-color: rgb(0, 0, 255);
197+
5 | `-> }
198+
6 | }
199+
`----
200+
201+
x LBrace
202+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:2:1]
203+
2 | @keyframes --my-anim {
204+
3 | to {
205+
: ^
206+
4 | background-color: rgb(0, 0, 255);
207+
`----
208+
209+
x ComponentValue
210+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
211+
3 | to {
212+
4 | background-color: rgb(0, 0, 255);
213+
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
214+
5 | }
215+
`----
216+
217+
x Declaration
218+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
219+
3 | to {
220+
4 | background-color: rgb(0, 0, 255);
221+
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
222+
5 | }
223+
`----
224+
225+
x DeclarationName
226+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
227+
3 | to {
228+
4 | background-color: rgb(0, 0, 255);
229+
: ^^^^^^^^^^^^^^^^
230+
5 | }
231+
`----
232+
233+
x Ident
234+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
235+
3 | to {
236+
4 | background-color: rgb(0, 0, 255);
237+
: ^^^^^^^^^^^^^^^^
238+
5 | }
239+
`----
240+
241+
x ComponentValue
242+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
243+
3 | to {
244+
4 | background-color: rgb(0, 0, 255);
245+
: ^^^^^^^^^^^^^^
246+
5 | }
247+
`----
248+
249+
x Color
250+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
251+
3 | to {
252+
4 | background-color: rgb(0, 0, 255);
253+
: ^^^^^^^^^^^^^^
254+
5 | }
255+
`----
256+
257+
x Function
258+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
259+
3 | to {
260+
4 | background-color: rgb(0, 0, 255);
261+
: ^^^^^^^^^^^^^^
262+
5 | }
263+
`----
264+
265+
x Ident
266+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
267+
3 | to {
268+
4 | background-color: rgb(0, 0, 255);
269+
: ^^^
270+
5 | }
271+
`----
272+
273+
x ComponentValue
274+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
275+
3 | to {
276+
4 | background-color: rgb(0, 0, 255);
277+
: ^
278+
5 | }
279+
`----
280+
281+
x Number
282+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
283+
3 | to {
284+
4 | background-color: rgb(0, 0, 255);
285+
: ^
286+
5 | }
287+
`----
288+
289+
x ComponentValue
290+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
291+
3 | to {
292+
4 | background-color: rgb(0, 0, 255);
293+
: ^
294+
5 | }
295+
`----
296+
297+
x Delimiter
298+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
299+
3 | to {
300+
4 | background-color: rgb(0, 0, 255);
301+
: ^
302+
5 | }
303+
`----
304+
305+
x ComponentValue
306+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
307+
3 | to {
308+
4 | background-color: rgb(0, 0, 255);
309+
: ^
310+
5 | }
311+
`----
312+
313+
x Number
314+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
315+
3 | to {
316+
4 | background-color: rgb(0, 0, 255);
317+
: ^
318+
5 | }
319+
`----
320+
321+
x ComponentValue
322+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
323+
3 | to {
324+
4 | background-color: rgb(0, 0, 255);
325+
: ^
326+
5 | }
327+
`----
328+
329+
x Delimiter
330+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
331+
3 | to {
332+
4 | background-color: rgb(0, 0, 255);
333+
: ^
334+
5 | }
335+
`----
336+
337+
x ComponentValue
338+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
339+
3 | to {
340+
4 | background-color: rgb(0, 0, 255);
341+
: ^^^
342+
5 | }
343+
`----
344+
345+
x Number
346+
,-[$DIR/tests/fixture/at-rule/scope/wpt/input.css:3:1]
347+
3 | to {
348+
4 | background-color: rgb(0, 0, 255);
349+
: ^^^
350+
5 | }
351+
`----

‎crates/swc_css_visit/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,13 @@ define!({
641641
LayerPrelude(LayerPrelude),
642642
ContainerPrelude(ContainerCondition),
643643
CustomMediaPrelude(CustomMediaQuery),
644+
ScopePrelude(ScopeRange),
645+
}
646+
647+
pub struct ScopeRange {
648+
pub span: Span,
649+
pub scope_start: Option<ForgivingSelectorList>,
650+
pub scope_end: Option<ForgivingSelectorList>,
644651
}
645652

646653
pub struct ListOfComponentValues {

1 commit comments

Comments
 (1)

github-actions[bot] commented on Aug 24, 2023

@github-actions[bot]

Benchmark

Benchmark suite Current: a34f359 Previous: 65db1ba Ratio
es/full/bugs-1 290305 ns/iter (± 11202) 289435 ns/iter (± 7811) 1.00
es/full/minify/libraries/antd 1368513636 ns/iter (± 7108874) 1278765837 ns/iter (± 24101170) 1.07
es/full/minify/libraries/d3 288419539 ns/iter (± 4883346) 270711542 ns/iter (± 4279117) 1.07
es/full/minify/libraries/echarts 1092609136 ns/iter (± 4095173) 1037074718 ns/iter (± 5864876) 1.05
es/full/minify/libraries/jquery 84432628 ns/iter (± 600899) 83034020 ns/iter (± 291020) 1.02
es/full/minify/libraries/lodash 98175010 ns/iter (± 1017714) 96141915 ns/iter (± 171217) 1.02
es/full/minify/libraries/moment 49834529 ns/iter (± 330190) 49106151 ns/iter (± 178097) 1.01
es/full/minify/libraries/react 18016753 ns/iter (± 136967) 17829757 ns/iter (± 23920) 1.01
es/full/minify/libraries/terser 224903620 ns/iter (± 2388830) 213871082 ns/iter (± 569362) 1.05
es/full/minify/libraries/three 408366918 ns/iter (± 8078142) 377205159 ns/iter (± 1786471) 1.08
es/full/minify/libraries/typescript 2703039681 ns/iter (± 25661620) 2586539772 ns/iter (± 8387760) 1.05
es/full/minify/libraries/victory 591206521 ns/iter (± 8231464) 551230352 ns/iter (± 2170019) 1.07
es/full/minify/libraries/vue 121047392 ns/iter (± 2619769) 117830253 ns/iter (± 402684) 1.03
es/full/codegen/es3 34292 ns/iter (± 73) 33951 ns/iter (± 104) 1.01
es/full/codegen/es5 34268 ns/iter (± 254) 33917 ns/iter (± 41) 1.01
es/full/codegen/es2015 34384 ns/iter (± 62) 33984 ns/iter (± 63) 1.01
es/full/codegen/es2016 34384 ns/iter (± 138) 33964 ns/iter (± 65) 1.01
es/full/codegen/es2017 34349 ns/iter (± 50) 33989 ns/iter (± 66) 1.01
es/full/codegen/es2018 34337 ns/iter (± 68) 33989 ns/iter (± 106) 1.01
es/full/codegen/es2019 34328 ns/iter (± 52) 33975 ns/iter (± 88) 1.01
es/full/codegen/es2020 34225 ns/iter (± 87) 33912 ns/iter (± 98) 1.01
es/full/all/es3 168162650 ns/iter (± 993704) 167725308 ns/iter (± 1095275) 1.00
es/full/all/es5 160950274 ns/iter (± 1114552) 159242647 ns/iter (± 724924) 1.01
es/full/all/es2015 120347990 ns/iter (± 554776) 120372523 ns/iter (± 755277) 1.00
es/full/all/es2016 120141917 ns/iter (± 940380) 118329232 ns/iter (± 1203138) 1.02
es/full/all/es2017 118900330 ns/iter (± 1373891) 117751736 ns/iter (± 797056) 1.01
es/full/all/es2018 116729431 ns/iter (± 1097422) 115894626 ns/iter (± 726013) 1.01
es/full/all/es2019 115736617 ns/iter (± 1019772) 114946518 ns/iter (± 719595) 1.01
es/full/all/es2020 112096006 ns/iter (± 1075434) 111017690 ns/iter (± 704506) 1.01
es/full/parser 490481 ns/iter (± 7816) 490628 ns/iter (± 4821) 1.00
es/full/base/fixer 20027 ns/iter (± 169) 17273 ns/iter (± 70) 1.16
es/full/base/resolver_and_hygiene 80909 ns/iter (± 289) 78135 ns/iter (± 317) 1.04
serialization of serde 297 ns/iter (± 2) 297 ns/iter (± 0) 1
css/minify/libraries/bootstrap 28247475 ns/iter (± 94291) 29056801 ns/iter (± 28719) 0.97
css/visitor/compare/clone 1647660 ns/iter (± 2857) 1630646 ns/iter (± 4543) 1.01
css/visitor/compare/visit_mut_span 1774445 ns/iter (± 3220) 1759457 ns/iter (± 7886) 1.01
css/visitor/compare/visit_mut_span_panic 1846632 ns/iter (± 3559) 1817234 ns/iter (± 6863) 1.02
css/visitor/compare/fold_span 2580456 ns/iter (± 10278) 2574550 ns/iter (± 7858) 1.00
css/visitor/compare/fold_span_panic 2769726 ns/iter (± 20215) 2756894 ns/iter (± 11780) 1.00
css/lexer/bootstrap_5_1_3 4529510 ns/iter (± 21913) 4459458 ns/iter (± 5814) 1.02
css/lexer/foundation_6_7_4 3790061 ns/iter (± 5332) 3756447 ns/iter (± 4815) 1.01
css/lexer/tailwind_3_1_1 724156 ns/iter (± 2295) 715144 ns/iter (± 1163) 1.01
css/parser/bootstrap_5_1_3 19539408 ns/iter (± 120531) 19990106 ns/iter (± 23464) 0.98
css/parser/foundation_6_7_4 15233692 ns/iter (± 53513) 15673900 ns/iter (± 19417) 0.97
css/parser/tailwind_3_1_1 3013927 ns/iter (± 7560) 3024234 ns/iter (± 2830) 1.00
es/codegen/colors 730595 ns/iter (± 398749) 726751 ns/iter (± 396012) 1.01
es/codegen/large 2921585 ns/iter (± 1535739) 2912570 ns/iter (± 1531875) 1.00
es/codegen/with-parser/colors 45841 ns/iter (± 247) 45661 ns/iter (± 504) 1.00
es/codegen/with-parser/large 489581 ns/iter (± 1235) 489022 ns/iter (± 1111) 1.00
es/minify/libraries/antd 1215299752 ns/iter (± 16101705) 1134016238 ns/iter (± 12302201) 1.07
es/minify/libraries/d3 247988974 ns/iter (± 2586652) 240305489 ns/iter (± 665671) 1.03
es/minify/libraries/echarts 967126350 ns/iter (± 8797090) 907796569 ns/iter (± 5058757) 1.07
es/minify/libraries/jquery 74557075 ns/iter (± 708785) 73493658 ns/iter (± 169452) 1.01
es/minify/libraries/lodash 87721832 ns/iter (± 1022407) 87061678 ns/iter (± 185716) 1.01
es/minify/libraries/moment 43907185 ns/iter (± 536621) 43614234 ns/iter (± 73626) 1.01
es/minify/libraries/react 16104816 ns/iter (± 163460) 16061667 ns/iter (± 64617) 1.00
es/minify/libraries/terser 199399970 ns/iter (± 7568027) 186340214 ns/iter (± 428727) 1.07
es/minify/libraries/three 342478544 ns/iter (± 9190935) 321885709 ns/iter (± 851854) 1.06
es/minify/libraries/typescript 2350882006 ns/iter (± 29448434) 2245243251 ns/iter (± 9046659) 1.05
es/minify/libraries/victory 513011922 ns/iter (± 10099992) 473867510 ns/iter (± 1417946) 1.08
es/minify/libraries/vue 107687412 ns/iter (± 1071216) 106167174 ns/iter (± 2589623) 1.01
es/visitor/compare/clone 1960530 ns/iter (± 5545) 1944574 ns/iter (± 5747) 1.01
es/visitor/compare/visit_mut_span 2276188 ns/iter (± 5274) 2263280 ns/iter (± 4799) 1.01
es/visitor/compare/visit_mut_span_panic 2343398 ns/iter (± 5013) 2339833 ns/iter (± 5161) 1.00
es/visitor/compare/fold_span 3393473 ns/iter (± 9930) 3388615 ns/iter (± 8692) 1.00
es/visitor/compare/fold_span_panic 3478588 ns/iter (± 6366) 3488194 ns/iter (± 5188) 1.00
es/lexer/colors 13112 ns/iter (± 87) 13123 ns/iter (± 172) 1.00
es/lexer/angular 6028722 ns/iter (± 5704) 6048477 ns/iter (± 4605) 1.00
es/lexer/backbone 779541 ns/iter (± 253) 779247 ns/iter (± 411) 1.00
es/lexer/jquery 4459106 ns/iter (± 29346) 4470053 ns/iter (± 4420) 1.00
es/lexer/jquery mobile 6741439 ns/iter (± 6109) 6851027 ns/iter (± 6340) 0.98
es/lexer/mootools 3523563 ns/iter (± 1770) 3553860 ns/iter (± 6084) 0.99
es/lexer/underscore 651332 ns/iter (± 434) 659311 ns/iter (± 693) 0.99
es/lexer/three 21095507 ns/iter (± 26693) 21300233 ns/iter (± 9227) 0.99
es/lexer/yui 3787994 ns/iter (± 2451) 3763154 ns/iter (± 1998) 1.01
es/parser/colors 27979 ns/iter (± 42) 28228 ns/iter (± 166) 0.99
es/parser/angular 13752924 ns/iter (± 154861) 13618747 ns/iter (± 43260) 1.01
es/parser/backbone 2038968 ns/iter (± 9564) 2023932 ns/iter (± 10740) 1.01
es/parser/jquery 11114495 ns/iter (± 78808) 10984343 ns/iter (± 39989) 1.01
es/parser/jquery mobile 17146582 ns/iter (± 222873) 16805804 ns/iter (± 49039) 1.02
es/parser/mootools 8496962 ns/iter (± 20776) 8477549 ns/iter (± 21489) 1.00
es/parser/underscore 1753233 ns/iter (± 11034) 1753137 ns/iter (± 9533) 1.00
es/parser/three 49388817 ns/iter (± 568681) 47264121 ns/iter (± 780747) 1.04
es/parser/yui 8451262 ns/iter (± 57848) 8378374 ns/iter (± 31635) 1.01
es/preset-env/usage/builtin_type 138812 ns/iter (± 32867) 137715 ns/iter (± 33072) 1.01
es/preset-env/usage/property 16548 ns/iter (± 112) 16806 ns/iter (± 194) 0.98
es/resolver/typescript 89792400 ns/iter (± 1171744) 90329347 ns/iter (± 1015045) 0.99
es/fixer/typescript 64538358 ns/iter (± 824428) 65221202 ns/iter (± 397205) 0.99
es/hygiene/typescript 132207326 ns/iter (± 1564435) 130547369 ns/iter (± 614975) 1.01
es/resolver_with_hygiene/typescript 245374895 ns/iter (± 3011469) 239648289 ns/iter (± 860354) 1.02
es/visitor/base-perf/module_clone 60324 ns/iter (± 399) 60459 ns/iter (± 140) 1.00
es/visitor/base-perf/fold_empty 64326 ns/iter (± 236) 64546 ns/iter (± 290) 1.00
es/visitor/base-perf/fold_noop_impl_all 64692 ns/iter (± 343) 64269 ns/iter (± 215) 1.01
es/visitor/base-perf/fold_noop_impl_vec 65449 ns/iter (± 373) 64638 ns/iter (± 257) 1.01
es/visitor/base-perf/boxing_boxed_clone 57 ns/iter (± 0) 57 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed_clone 39 ns/iter (± 0) 38 ns/iter (± 0) 1.03
es/visitor/base-perf/boxing_boxed 105 ns/iter (± 0) 109 ns/iter (± 0) 0.96
es/visitor/base-perf/boxing_unboxed 74 ns/iter (± 0) 77 ns/iter (± 0) 0.96
es/visitor/base-perf/visit_empty 0 ns/iter (± 0) 0 ns/iter (± 0) NaN
es/visitor/base-perf/visit_contains_this 2651 ns/iter (± 11) 2593 ns/iter (± 4) 1.02
es/base/parallel/resolver/typescript 3831258785 ns/iter (± 204382904) 3692325519 ns/iter (± 223084402) 1.04
es/base/parallel/hygiene/typescript 1453635239 ns/iter (± 13785203) 1438909365 ns/iter (± 15007686) 1.01
misc/visitors/time-complexity/time 5 134 ns/iter (± 1) 134 ns/iter (± 1) 1
misc/visitors/time-complexity/time 10 397 ns/iter (± 8) 387 ns/iter (± 12) 1.03
misc/visitors/time-complexity/time 15 684 ns/iter (± 11) 591 ns/iter (± 41) 1.16
misc/visitors/time-complexity/time 20 1073 ns/iter (± 6) 1059 ns/iter (± 10) 1.01
misc/visitors/time-complexity/time 40 3610 ns/iter (± 317) 4130 ns/iter (± 6) 0.87
misc/visitors/time-complexity/time 60 7268 ns/iter (± 6) 8805 ns/iter (± 465) 0.83
es/full-target/es2016 233935 ns/iter (± 739) 233166 ns/iter (± 1052) 1.00
es/full-target/es2017 222378 ns/iter (± 982) 222675 ns/iter (± 1041) 1.00
es/full-target/es2018 208854 ns/iter (± 691) 212304 ns/iter (± 1060) 0.98
es2020_nullish_coalescing 70438 ns/iter (± 322) 71935 ns/iter (± 245) 0.98
es2020_optional_chaining 81871 ns/iter (± 191) 81157 ns/iter (± 135) 1.01
es2022_class_properties 114680 ns/iter (± 397) 114798 ns/iter (± 424) 1.00
es2018_object_rest_spread 75805 ns/iter (± 300) 74674 ns/iter (± 225) 1.02
es2019_optional_catch_binding 65557 ns/iter (± 224) 64783 ns/iter (± 570) 1.01
es2017_async_to_generator 63490 ns/iter (± 258) 63385 ns/iter (± 151) 1.00
es2016_exponentiation 68736 ns/iter (± 218) 69065 ns/iter (± 223) 1.00
es2015_arrow 71553 ns/iter (± 223) 72419 ns/iter (± 298) 0.99
es2015_block_scoped_fn 69008 ns/iter (± 334) 68141 ns/iter (± 161) 1.01
es2015_block_scoping 122495 ns/iter (± 356) 123282 ns/iter (± 414) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.