From 6bccdfc331792297e64972754b2564843e395762 Mon Sep 17 00:00:00 2001 From: ahabhgk Date: Sat, 4 May 2024 15:08:12 +0800 Subject: [PATCH] fix: local with at-rules bugs --- README.md | 2 +- src/dependencies.rs | 34 ++++++++----------- tests/test.rs | 81 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 044105d..6ead9fd 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Lexes CSS modules returning their dependencies metadata. - [x] CSS: - [x] @import - - [x] url, image-set + - [x] url(), image-set() - [ ] CSS Modules - [x] :local, :local(), :global, :global() - [x] local scope by default diff --git a/src/dependencies.rs b/src/dependencies.rs index 4e68380..4c8d61b 100644 --- a/src/dependencies.rs +++ b/src/dependencies.rs @@ -182,7 +182,7 @@ impl CssModulesModeData { self.current = CssModulesMode::Global; } - pub fn set_none(&mut self) { + pub fn set_default(&mut self) { self.current = CssModulesMode::None; } } @@ -575,18 +575,13 @@ impl<'s, D: HandleDependency<'s>, W: HandleWarning<'s>> Visitor<'s> for LexDepen return Some(()); } self.scope = Scope::InAtImport(ImportData::new(start)); - } else if name == "@media" - || name == "@supports" - || name == "@layer" - || name == "@container" - { - self.is_next_rule_prelude = true; } else if self.mode_data.is_some() && name == "@property" { self.lex_local_property_decl(lexer)?; + } else if self.mode_data.is_some() && name == "@scope" { + self.is_next_rule_prelude = true; + } else if self.mode_data.is_some() { + self.is_next_rule_prelude = false; } - // else if self.allow_mode_switch { - // self.is_next_rule_prelude = false; - // } Some(()) } @@ -728,7 +723,7 @@ impl<'s, D: HandleDependency<'s>, W: HandleWarning<'s>> Visitor<'s> for LexDepen Some(last) if matches!(last.kind, BalancedItemKind::Global) => { mode_data.set_global() } - _ => mode_data.set_none(), + _ => mode_data.set_default(), }; self.handle_dependency .handle_dependency(Dependency::Replace { @@ -820,17 +815,15 @@ impl<'s, D: HandleDependency<'s>, W: HandleWarning<'s>> Visitor<'s> for LexDepen self.allow_import_at_rule = false; self.scope = Scope::InBlock; self.block_nesting_level = 1; - if self.mode_data.is_some() { - self.is_next_rule_prelude = self.is_next_nested_syntax(lexer)?; - } } Scope::InBlock => { self.block_nesting_level += 1; - if self.mode_data.is_some() { - self.is_next_rule_prelude = self.is_next_nested_syntax(lexer)?; - } } - _ => {} + _ => return Some(()), + } + if let Some(mode_data) = &mut self.mode_data { + mode_data.set_default(); + self.is_next_rule_prelude = self.is_next_nested_syntax(lexer)?; } Some(()) } @@ -840,9 +833,8 @@ impl<'s, D: HandleDependency<'s>, W: HandleWarning<'s>> Visitor<'s> for LexDepen self.block_nesting_level -= 1; if self.block_nesting_level == 0 { self.scope = Scope::TopLevel; - if let Some(mode_data) = &mut self.mode_data { + if self.mode_data.is_some() { self.is_next_rule_prelude = true; - mode_data.set_none(); } } else if self.mode_data.is_some() { self.is_next_rule_prelude = self.is_next_nested_syntax(lexer)?; @@ -908,7 +900,7 @@ impl<'s, D: HandleDependency<'s>, W: HandleWarning<'s>> Visitor<'s> for LexDepen fn comma(&mut self, _: &mut Lexer, _: Pos, _: Pos) -> Option<()> { if let Some(mode_data) = &mut self.mode_data { - mode_data.set_none(); + mode_data.set_default(); } Some(()) } diff --git a/tests/test.rs b/tests/test.rs index f1ee315..40d82d4 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -790,25 +790,33 @@ fn css_modules_pseudo() { #[test] fn css_modules_nesting() { let input = indoc! {r#" - .first-nested { - .first-nested-nested { + .nested { + .nested-nested { color: red; } } - .first-nested-at-rule { + .nested-at-rule { @media screen { - .first-nested-nested-at-rule-deep { + .nested-nested-at-rule-deep { color: red; } } } + :global .nested2 { + .nested2-nested { + color: red; + } + } "#}; let (dependencies, warnings) = collect_css_modules_dependencies(input); assert!(warnings.is_empty()); - assert_local_ident_dependency(input, &dependencies[0], "first-nested"); - assert_local_ident_dependency(input, &dependencies[1], "first-nested-nested"); - assert_local_ident_dependency(input, &dependencies[2], "first-nested-at-rule"); - assert_local_ident_dependency(input, &dependencies[3], "first-nested-nested-at-rule-deep"); + assert_local_ident_dependency(input, &dependencies[0], "nested"); + assert_local_ident_dependency(input, &dependencies[1], "nested-nested"); + assert_local_ident_dependency(input, &dependencies[2], "nested-at-rule"); + assert_local_ident_dependency(input, &dependencies[3], "nested-nested-at-rule-deep"); + assert_replace_dependency(input, &dependencies[4], "", ":global "); + assert_local_ident_dependency(input, &dependencies[5], "nested2-nested"); + assert_eq!(dependencies.len(), 6); } #[test] @@ -841,7 +849,6 @@ fn css_modules_local_var() { assert_local_var_decl_dependency(input, &dependencies[2], "local-color"); assert_local_ident_dependency(input, &dependencies[3], "globalVars"); assert_replace_dependency(input, &dependencies[4], "", ":global "); - dbg!(dependencies, warnings); } #[test] @@ -883,6 +890,62 @@ fn css_modules_property() { assert_local_var_dependency(input, &dependencies[2], "my-color"); } +#[test] +fn css_modules_at_rule_1() { + let input = indoc! {r#" + @layer framework.container { + .class { + color: red; + } + } + "#}; + let (dependencies, warnings) = collect_css_modules_dependencies(input); + assert!(warnings.is_empty()); + assert_local_ident_dependency(input, &dependencies[0], "class"); + assert_eq!(dependencies.len(), 1); +} + +#[test] +fn css_modules_at_rule_2() { + let input = indoc! {r#" + @page { + .class { + color: red; + } + } + @page :left, :top { + .class2 { + color: red; + } + } + "#}; + let (dependencies, warnings) = collect_css_modules_dependencies(input); + assert!(warnings.is_empty()); + assert_local_ident_dependency(input, &dependencies[0], "class"); + assert_local_ident_dependency(input, &dependencies[1], "class2"); + assert_eq!(dependencies.len(), 2); +} + +#[test] +fn css_modules_at_rule_3() { + let input = indoc! {r#" + .article-body { + color: red; + } + @scope (.article-body) to (figure) { + .img { + background-color: goldenrod; + } + } + "#}; + let (dependencies, warnings) = collect_css_modules_dependencies(input); + assert!(warnings.is_empty()); + assert_local_ident_dependency(input, &dependencies[0], "article-body"); + assert_local_ident_dependency(input, &dependencies[1], "article-body"); + assert_local_ident_dependency(input, &dependencies[2], "img"); + assert_eq!(dependencies.len(), 3); +} + #[test] fn icss_export_unexpected() { let input = ":export {\n/sl/ash;";