From 75a14f98b7370226115ee24eec6eb8c802bd4837 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Sun, 30 Jan 2022 16:49:09 +0300 Subject: [PATCH] fix(css): Allow empty `@media` at-rule (#3404) --- crates/swc_css_ast/src/at_rule/media.rs | 2 +- crates/swc_css_codegen/src/lib.rs | 11 +++-- .../tests/fixture/at-rules/media/3/input.css | 5 +++ .../tests/fixture/at-rules/media/3/output.css | 1 + .../fixture/at-rules/media/3/output.min.css | 1 + crates/swc_css_parser/src/parser/at_rule.rs | 9 +++- .../tests/fixture/at-rule/media/input.css | 3 ++ .../tests/fixture/at-rule/media/output.json | 22 +++++++++- .../fixture/at-rule/media/span.rust-debug | 42 +++++++++++++++++-- crates/swc_css_visit/src/lib.rs | 2 +- 10 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 crates/swc_css_codegen/tests/fixture/at-rules/media/3/input.css create mode 100644 crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.css create mode 100644 crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.min.css diff --git a/crates/swc_css_ast/src/at_rule/media.rs b/crates/swc_css_ast/src/at_rule/media.rs index 925ee0098733..58d51b1683bc 100644 --- a/crates/swc_css_ast/src/at_rule/media.rs +++ b/crates/swc_css_ast/src/at_rule/media.rs @@ -5,7 +5,7 @@ use swc_common::{ast_node, EqIgnoreSpan, Span}; #[ast_node("MediaRule")] pub struct MediaRule { pub span: Span, - pub media: MediaQueryList, + pub media: Option, pub rules: Vec, } diff --git a/crates/swc_css_codegen/src/lib.rs b/crates/swc_css_codegen/src/lib.rs index e469cc8ab1f9..e75fcc7b2ce0 100644 --- a/crates/swc_css_codegen/src/lib.rs +++ b/crates/swc_css_codegen/src/lib.rs @@ -288,11 +288,14 @@ where fn emit_media_rule(&mut self, n: &MediaRule) -> Result { punct!(self, "@"); keyword!(self, "media"); - space!(self); - - emit!(self, n.media); - formatting_space!(self); + if n.media.is_some() { + space!(self); + emit!(self, n.media); + formatting_space!(self); + } else { + formatting_space!(self); + } punct!(self, "{"); self.emit_list(&n.rules, ListFormat::NotDelimited | ListFormat::MultiLine)?; diff --git a/crates/swc_css_codegen/tests/fixture/at-rules/media/3/input.css b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/input.css new file mode 100644 index 000000000000..7a08aaffbe29 --- /dev/null +++ b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/input.css @@ -0,0 +1,5 @@ +@media { + div { + color: red + } +} diff --git a/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.css b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.css new file mode 100644 index 000000000000..7e3b86ebce46 --- /dev/null +++ b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.css @@ -0,0 +1 @@ +@media {div {color: red}} diff --git a/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.min.css b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.min.css new file mode 100644 index 000000000000..b2c2c58239a7 --- /dev/null +++ b/crates/swc_css_codegen/tests/fixture/at-rules/media/3/output.min.css @@ -0,0 +1 @@ +@media{div{color:red}} diff --git a/crates/swc_css_parser/src/parser/at_rule.rs b/crates/swc_css_parser/src/parser/at_rule.rs index 35d47b80f9a3..0c88d4ce78a2 100644 --- a/crates/swc_css_parser/src/parser/at_rule.rs +++ b/crates/swc_css_parser/src/parser/at_rule.rs @@ -811,7 +811,14 @@ where { fn parse(&mut self) -> PResult { let span = self.input.cur_span()?; - let media = self.parse()?; + + let media = if !is!(self, "{") { + let media_query_list = self.parse()?; + + Some(media_query_list) + } else { + None + }; expect!(self, "{"); diff --git a/crates/swc_css_parser/tests/fixture/at-rule/media/input.css b/crates/swc_css_parser/tests/fixture/at-rule/media/input.css index 10607fa86ae6..3eb33ce7379d 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/media/input.css +++ b/crates/swc_css_parser/tests/fixture/at-rule/media/input.css @@ -108,3 +108,6 @@ @media ONLY screen AND (color) {} @media ((min-width: 800px) AND (min-width: 800px)) OR (min-width: 800px) {} @media (min-width: 800px) AND ((min-width: 800px) OR (min-width: 800px)) {} + +@media {} +@media {} diff --git a/crates/swc_css_parser/tests/fixture/at-rule/media/output.json b/crates/swc_css_parser/tests/fixture/at-rule/media/output.json index ed19fa6f1c82..59add77d018f 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/media/output.json +++ b/crates/swc_css_parser/tests/fixture/at-rule/media/output.json @@ -2,7 +2,7 @@ "type": "Stylesheet", "span": { "start": 0, - "end": 3935, + "end": 3959, "ctxt": 0 }, "rules": [ @@ -9801,6 +9801,26 @@ ] }, "rules": [] + }, + { + "type": "MediaRule", + "span": { + "start": 3936, + "end": 3945, + "ctxt": 0 + }, + "media": null, + "rules": [] + }, + { + "type": "MediaRule", + "span": { + "start": 3946, + "end": 3958, + "ctxt": 0 + }, + "media": null, + "rules": [] } ] } diff --git a/crates/swc_css_parser/tests/fixture/at-rule/media/span.rust-debug b/crates/swc_css_parser/tests/fixture/at-rule/media/span.rust-debug index 8d1d0b556e89..91d40493737b 100644 --- a/crates/swc_css_parser/tests/fixture/at-rule/media/span.rust-debug +++ b/crates/swc_css_parser/tests/fixture/at-rule/media/span.rust-debug @@ -6,9 +6,9 @@ error: Stylesheet 3 | | 4 | | @media all {} ... | -109 | | @media ((min-width: 800px) AND (min-width: 800px)) OR (min-width: 800px) {} -110 | | @media (min-width: 800px) AND ((min-width: 800px) OR (min-width: 800px)) {} - | |____________________________________________________________________________^ +112 | | @media {} +113 | | @media {} + | |_____________^ error: Rule --> $DIR/tests/fixture/at-rule/media/input.css:1:1 @@ -11098,3 +11098,39 @@ error: Ident 110 | @media (min-width: 800px) AND ((min-width: 800px) OR (min-width: 800px)) {} | ^^ +error: Rule + --> $DIR/tests/fixture/at-rule/media/input.css:112:1 + | +112 | @media {} + | ^^^^^^^^^ + +error: AtRule + --> $DIR/tests/fixture/at-rule/media/input.css:112:1 + | +112 | @media {} + | ^^^^^^^^^ + +error: MediaRule + --> $DIR/tests/fixture/at-rule/media/input.css:112:1 + | +112 | @media {} + | ^^^^^^^^^ + +error: Rule + --> $DIR/tests/fixture/at-rule/media/input.css:113:1 + | +113 | @media {} + | ^^^^^^^^^^^^ + +error: AtRule + --> $DIR/tests/fixture/at-rule/media/input.css:113:1 + | +113 | @media {} + | ^^^^^^^^^^^^ + +error: MediaRule + --> $DIR/tests/fixture/at-rule/media/input.css:113:1 + | +113 | @media {} + | ^^^^^^^^^^^^ + diff --git a/crates/swc_css_visit/src/lib.rs b/crates/swc_css_visit/src/lib.rs index 365a3f4a7232..43a63937b7cc 100644 --- a/crates/swc_css_visit/src/lib.rs +++ b/crates/swc_css_visit/src/lib.rs @@ -465,7 +465,7 @@ define!({ pub struct MediaRule { pub span: Span, - pub media: MediaQueryList, + pub media: Option, pub rules: Vec, }