diff --git a/crates/swc_atoms/words.txt b/crates/swc_atoms/words.txt index 239850e42a2d..1c63a715da51 100644 --- a/crates/swc_atoms/words.txt +++ b/crates/swc_atoms/words.txt @@ -2213,6 +2213,7 @@ src srcdoc srcset start +starting-style startOffset startoffset static diff --git a/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/input.css b/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/input.css new file mode 100644 index 000000000000..b8a62d750868 --- /dev/null +++ b/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/input.css @@ -0,0 +1,10 @@ +@starting-style { + h1 { + background-color: transparent; + } + @layer foo { + div { + height: 100px; + } + } +} \ No newline at end of file diff --git a/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/output.min.css b/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/output.min.css new file mode 100644 index 000000000000..038208565688 --- /dev/null +++ b/crates/swc_css_minifier/tests/fixture/compress-at-rule/starting-style/output.min.css @@ -0,0 +1 @@ +@starting-style{h1{background-color:transparent}@layer foo{div{height:100px}}} diff --git a/crates/swc_css_parser/src/parser/at_rules/mod.rs b/crates/swc_css_parser/src/parser/at_rules/mod.rs index 6e23126dd2e2..46f25c7a8e47 100644 --- a/crates/swc_css_parser/src/parser/at_rules/mod.rs +++ b/crates/swc_css_parser/src/parser/at_rules/mod.rs @@ -413,6 +413,17 @@ where None } + js_word!("starting-style") => { + self.input.skip_ws(); + + if !is!(self, EOF) { + let span = self.input.cur_span(); + + return Err(Error::new(span, ErrorKind::Expected("'{' token"))); + } + + None + } _ => { return Err(Error::new(Default::default(), ErrorKind::Ignore)); } @@ -738,6 +749,13 @@ where declaration_list } + js_word!("starting-style") => { + let rule_list = self.parse_as::>()?; + let rule_list: Vec = + rule_list.into_iter().map(ComponentValue::from).collect(); + + rule_list + } _ => { return Err(Error::new(Default::default(), ErrorKind::Ignore)); } diff --git a/crates/swc_css_parser/tests/fixture/at-rule/starting-style/input.css b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/input.css new file mode 100644 index 000000000000..b8a62d750868 --- /dev/null +++ b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/input.css @@ -0,0 +1,10 @@ +@starting-style { + h1 { + background-color: transparent; + } + @layer foo { + div { + height: 100px; + } + } +} \ No newline at end of file diff --git a/crates/swc_css_parser/tests/fixture/at-rule/starting-style/output.json b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/output.json new file mode 100644 index 000000000000..aeaf0c9f902e --- /dev/null +++ b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/output.json @@ -0,0 +1,353 @@ +{ + "type": "Stylesheet", + "span": { + "start": 1, + "end": 148, + "ctxt": 0 + }, + "rules": [ + { + "type": "AtRule", + "span": { + "start": 1, + "end": 148, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 2, + "end": 16, + "ctxt": 0 + }, + "value": "starting-style", + "raw": "starting-style" + }, + "prelude": null, + "block": { + "type": "SimpleBlock", + "span": { + "start": 17, + "end": 148, + "ctxt": 0 + }, + "name": { + "type": "PreservedToken", + "span": { + "start": 17, + "end": 18, + "ctxt": 0 + }, + "token": "LBrace" + }, + "value": [ + { + "type": "QualifiedRule", + "span": { + "start": 23, + "end": 72, + "ctxt": 0 + }, + "prelude": { + "type": "SelectorList", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "children": [ + { + "type": "ComplexSelector", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "children": [ + { + "type": "CompoundSelector", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "nestingSelector": null, + "typeSelector": { + "type": "TagNameSelector", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "name": { + "type": "WqName", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "prefix": null, + "value": { + "type": "Ident", + "span": { + "start": 23, + "end": 25, + "ctxt": 0 + }, + "value": "h1", + "raw": "h1" + } + } + }, + "subclassSelectors": [] + } + ] + } + ] + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 26, + "end": 72, + "ctxt": 0 + }, + "name": { + "type": "PreservedToken", + "span": { + "start": 26, + "end": 27, + "ctxt": 0 + }, + "token": "LBrace" + }, + "value": [ + { + "type": "Declaration", + "span": { + "start": 36, + "end": 65, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 36, + "end": 52, + "ctxt": 0 + }, + "value": "background-color", + "raw": "background-color" + }, + "value": [ + { + "type": "Ident", + "span": { + "start": 54, + "end": 65, + "ctxt": 0 + }, + "value": "transparent", + "raw": "transparent" + } + ], + "important": null + } + ] + } + }, + { + "type": "AtRule", + "span": { + "start": 77, + "end": 146, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 78, + "end": 83, + "ctxt": 0 + }, + "value": "layer", + "raw": "layer" + }, + "prelude": { + "type": "LayerName", + "span": { + "start": 84, + "end": 87, + "ctxt": 0 + }, + "name": [ + { + "type": "Ident", + "span": { + "start": 84, + "end": 87, + "ctxt": 0 + }, + "value": "foo", + "raw": "foo" + } + ] + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 88, + "end": 146, + "ctxt": 0 + }, + "name": { + "type": "PreservedToken", + "span": { + "start": 88, + "end": 89, + "ctxt": 0 + }, + "token": "LBrace" + }, + "value": [ + { + "type": "QualifiedRule", + "span": { + "start": 98, + "end": 140, + "ctxt": 0 + }, + "prelude": { + "type": "SelectorList", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "children": [ + { + "type": "ComplexSelector", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "children": [ + { + "type": "CompoundSelector", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "nestingSelector": null, + "typeSelector": { + "type": "TagNameSelector", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "name": { + "type": "WqName", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "prefix": null, + "value": { + "type": "Ident", + "span": { + "start": 98, + "end": 101, + "ctxt": 0 + }, + "value": "div", + "raw": "div" + } + } + }, + "subclassSelectors": [] + } + ] + } + ] + }, + "block": { + "type": "SimpleBlock", + "span": { + "start": 102, + "end": 140, + "ctxt": 0 + }, + "name": { + "type": "PreservedToken", + "span": { + "start": 102, + "end": 103, + "ctxt": 0 + }, + "token": "LBrace" + }, + "value": [ + { + "type": "Declaration", + "span": { + "start": 116, + "end": 129, + "ctxt": 0 + }, + "name": { + "type": "Ident", + "span": { + "start": 116, + "end": 122, + "ctxt": 0 + }, + "value": "height", + "raw": "height" + }, + "value": [ + { + "type": "Length", + "span": { + "start": 124, + "end": 129, + "ctxt": 0 + }, + "value": { + "type": "Number", + "span": { + "start": 124, + "end": 127, + "ctxt": 0 + }, + "value": 100.0, + "raw": "100" + }, + "unit": { + "type": "Ident", + "span": { + "start": 127, + "end": 129, + "ctxt": 0 + }, + "value": "px", + "raw": "px" + } + } + ], + "important": null + } + ] + } + } + ] + } + } + ] + } + } + ] +} diff --git a/crates/swc_css_parser/tests/fixture/at-rule/starting-style/span.swc-stderr b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/span.swc-stderr new file mode 100644 index 000000000000..bdc4baab8baa --- /dev/null +++ b/crates/swc_css_parser/tests/fixture/at-rule/starting-style/span.swc-stderr @@ -0,0 +1,460 @@ + + x Stylesheet + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | ,-> @starting-style { + 2 | | h1 { + 3 | | background-color: transparent; + 4 | | } + 5 | | @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | | } + 10 | `-> } + `---- + + x Rule + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | ,-> @starting-style { + 2 | | h1 { + 3 | | background-color: transparent; + 4 | | } + 5 | | @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | | } + 10 | `-> } + `---- + + x AtRule + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | ,-> @starting-style { + 2 | | h1 { + 3 | | background-color: transparent; + 4 | | } + 5 | | @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | | } + 10 | `-> } + `---- + + x AtRuleName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + : ^^^^^^^^^^^^^^ + 2 | h1 { + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + : ^^^^^^^^^^^^^^ + 2 | h1 { + `---- + + x SimpleBlock + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | ,-> @starting-style { + 2 | | h1 { + 3 | | background-color: transparent; + 4 | | } + 5 | | @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | | } + 10 | `-> } + `---- + + x LBrace + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + : ^ + 2 | h1 { + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | ,-> h1 { + 3 | | background-color: transparent; + 4 | `-> } + 5 | @layer foo { + `---- + + x QualifiedRule + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | ,-> h1 { + 3 | | background-color: transparent; + 4 | `-> } + 5 | @layer foo { + `---- + + x SelectorList + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x ComplexSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x CompoundSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x TypeSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x TagNameSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x WqName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^^ + 3 | background-color: transparent; + `---- + + x SimpleBlock + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | ,-> h1 { + 3 | | background-color: transparent; + 4 | `-> } + 5 | @layer foo { + `---- + + x LBrace + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:1:1] + 1 | @starting-style { + 2 | h1 { + : ^ + 3 | background-color: transparent; + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 4 | } + `---- + + x Declaration + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 4 | } + `---- + + x DeclarationName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^^^^^^ + 4 | } + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^^^^^^ + 4 | } + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^ + 4 | } + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:2:1] + 2 | h1 { + 3 | background-color: transparent; + : ^^^^^^^^^^^ + 4 | } + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | ,-> @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | `-> } + 10 | } + `---- + + x AtRule + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | ,-> @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | `-> } + 10 | } + `---- + + x AtRuleName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^^^^^ + 6 | div { + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^^^^^ + 6 | div { + `---- + + x LayerPrelude + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^^^ + 6 | div { + `---- + + x LayerName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^^^ + 6 | div { + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^^^ + 6 | div { + `---- + + x SimpleBlock + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | ,-> @layer foo { + 6 | | div { + 7 | | height: 100px; + 8 | | } + 9 | `-> } + 10 | } + `---- + + x LBrace + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:4:1] + 4 | } + 5 | @layer foo { + : ^ + 6 | div { + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | ,-> div { + 7 | | height: 100px; + 8 | `-> } + 9 | } + `---- + + x QualifiedRule + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | ,-> div { + 7 | | height: 100px; + 8 | `-> } + 9 | } + `---- + + x SelectorList + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x ComplexSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x CompoundSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x TypeSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x TagNameSelector + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x WqName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^^^ + 7 | height: 100px; + `---- + + x SimpleBlock + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | ,-> div { + 7 | | height: 100px; + 8 | `-> } + 9 | } + `---- + + x LBrace + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:5:1] + 5 | @layer foo { + 6 | div { + : ^ + 7 | height: 100px; + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^^^^^^^^^ + 8 | } + `---- + + x Declaration + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^^^^^^^^^ + 8 | } + `---- + + x DeclarationName + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^^ + 8 | } + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^^ + 8 | } + `---- + + x ComponentValue + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^ + 8 | } + `---- + + x Dimension + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^ + 8 | } + `---- + + x Length + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^^^ + 8 | } + `---- + + x Number + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^^ + 8 | } + `---- + + x Ident + ,-[$DIR/tests/fixture/at-rule/starting-style/input.css:6:1] + 6 | div { + 7 | height: 100px; + : ^^ + 8 | } + `----