diff --git a/crates/swc_css_modules/tests/fixture.rs b/crates/swc_css_modules/tests/fixture.rs index 80d3a29adb3a..96d164b1c603 100644 --- a/crates/swc_css_modules/tests/fixture.rs +++ b/crates/swc_css_modules/tests/fixture.rs @@ -55,6 +55,7 @@ fn compile(input: PathBuf) { &mut errors, ) .unwrap(); + let _result = swc_css_modules::imports::analyze_imports(&ss); let transform_result = swc_css_modules::compile(&mut ss, TestConfig {}); diff --git a/crates/swc_css_modules/tests/with-compat/vercel/010/input.css b/crates/swc_css_modules/tests/with-compat/vercel/010/input.css new file mode 100644 index 000000000000..230cea04e34b --- /dev/null +++ b/crates/swc_css_modules/tests/with-compat/vercel/010/input.css @@ -0,0 +1,3 @@ +.quickstart .buttons :global(> *) { + color: red +} \ No newline at end of file diff --git a/crates/swc_css_modules/tests/with-compat/vercel/010/output.css b/crates/swc_css_modules/tests/with-compat/vercel/010/output.css new file mode 100644 index 000000000000..775d0a9b3599 --- /dev/null +++ b/crates/swc_css_modules/tests/with-compat/vercel/010/output.css @@ -0,0 +1,3 @@ +.__local__quickstart .__local__buttons > * { + color: red; +} diff --git a/crates/swc_css_parser/src/parser/mod.rs b/crates/swc_css_parser/src/parser/mod.rs index cca37a26f2c0..720913f41fa6 100644 --- a/crates/swc_css_parser/src/parser/mod.rs +++ b/crates/swc_css_parser/src/parser/mod.rs @@ -76,6 +76,8 @@ struct Ctx { in_page_at_rule: bool, in_container_at_rule: bool, in_font_feature_values_at_rule: bool, + + in_global_or_local_selector: bool, } impl Default for Ctx { @@ -92,6 +94,7 @@ impl Default for Ctx { in_page_at_rule: false, in_container_at_rule: false, in_font_feature_values_at_rule: false, + in_global_or_local_selector: false, } } } diff --git a/crates/swc_css_parser/src/parser/selectors/mod.rs b/crates/swc_css_parser/src/parser/selectors/mod.rs index 814638208e35..b3ee3e8a359e 100644 --- a/crates/swc_css_parser/src/parser/selectors/mod.rs +++ b/crates/swc_css_parser/src/parser/selectors/mod.rs @@ -5,6 +5,7 @@ use swc_css_ast::*; use super::{input::ParserInput, PResult, Parser}; use crate::{ error::{Error, ErrorKind}, + parser::Ctx, Parse, }; @@ -456,7 +457,11 @@ where } } - if nesting_selector.is_none() && type_selector.is_none() && subclass_selectors.is_empty() { + if !self.ctx.in_global_or_local_selector + && nesting_selector.is_none() + && type_selector.is_none() + && subclass_selectors.is_empty() + { return Err(Error::new(start_span, ErrorKind::InvalidSelector)); } @@ -862,7 +867,11 @@ where js_word!("local") | js_word!("global") if self.config.css_modules => { self.input.skip_ws(); - let selector_list = self.parse()?; + let ctx = Ctx { + in_global_or_local_selector: true, + ..self.ctx + }; + let selector_list = self.with_ctx(ctx).parse_as::()?; self.input.skip_ws();