Skip to content

Commit

Permalink
Merge branch 'main' into feature/styled-dom
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/yak-swc/yak_swc/src/lib.rs
  • Loading branch information
jantimon committed Dec 4, 2024
2 parents d5f216a + 3d6e505 commit 735c0bd
Show file tree
Hide file tree
Showing 106 changed files with 1,326 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .changeset/bright-pumas-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
5 changes: 5 additions & 0 deletions .changeset/itchy-brooms-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"yak-swc": patch
---

fix a parsing bug for unquoted urls inside url()
5 changes: 5 additions & 0 deletions .changeset/silver-hairs-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"yak-swc": minor
---

allow to define the prefix for generated names
48 changes: 46 additions & 2 deletions packages/yak-swc/css_in_js_parser/src/parse_css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub struct ParserState {
pub current_scopes: Vec<CssScope>,
pub current_declaration: Declaration,
pub pending_css_segment: String,
pub paren_depth: usize,
}

impl ParserState {
Expand All @@ -23,6 +24,7 @@ impl ParserState {
current_scopes: Vec::new(),
current_declaration: Declaration::new(),
pending_css_segment: String::new(),
paren_depth: 0,
}
}
}
Expand Down Expand Up @@ -97,6 +99,7 @@ pub fn parse_css(
state.current_comment_state = CommentStateType::None;
state.is_inside_property_value = false;
state.is_inside_at_rule = false;
state.paren_depth = 0;
state.current_declaration = Declaration::new();
state.pending_css_segment.clone() + css_string
} else {
Expand Down Expand Up @@ -171,9 +174,20 @@ pub fn parse_css(
}
}

// Detect parens outside of strings for property values
// e.g.
// .foo { background: url('https://example.com'); }
if state.is_inside_string.is_none() && state.is_inside_property_value {
if current_character == '(' {
state.paren_depth += 1;
} else if current_character == ')' && state.paren_depth > 0 {
state.paren_depth -= 1;
}
}

// Inside a string, just add the character to the current code no matter what
// e.g. content: "{ ; } @ !"
if state.is_inside_string.is_some() {
if state.is_inside_string.is_some() || state.paren_depth > 0 {
current_code.push(current_character);
state.current_declaration.value.push(current_character);
char_position += 1;
Expand Down Expand Up @@ -389,6 +403,19 @@ mod tests {
assert_debug_snapshot!((state, declarations));
}

#[test]
fn test_parse_css_incomplete_css_1_ending_inside_parens_string() {
let (state, declarations) = parse_css(
r#"
.foo {
.fancy {
background: url(https://example.com
"#,
None,
);
assert_debug_snapshot!((state, declarations));
}

#[test]
fn test_parse_css_incomplete_css_1_ending_outside_a_comment() {
let (state, declarations) = parse_css(
Expand Down Expand Up @@ -437,7 +464,7 @@ mod tests {
}
}
}
background: url("https://example.com");
background: url(https://example.com);
body {
padding: 0;
}
Expand Down Expand Up @@ -494,4 +521,21 @@ mod tests {
);
assert_debug_snapshot!((state, declarations));
}

#[test]
fn test_parse_css_with_dynamic_values() {
let (state1, _) = parse_css(
r#"
.foo {
transform: translate(-50%, -50%) rotate("#,
None,
);
let (state2, _) = parse_css(r#"20deg) translate(0, -88px) rotate("#, Some(state1));
let (_, declarations3) = parse_css(r#"90deg);"#, Some(state2));
assert_eq!(declarations3.len(), 1);
assert_eq!(
declarations3[0].value.trim(),
"translate(-50%, -50%) rotate(20deg) translate(0, -88px) rotate(90deg)"
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "",
paren_depth: 0,
},
[
Declaration {
Expand Down Expand Up @@ -58,7 +59,7 @@ expression: "(state, declarations)"
},
Declaration {
property: "background",
value: "url(\"https://example.com\")",
value: "url(https://example.com)",
scope: [
CssScope {
name: ".foo",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "",
paren_depth: 0,
},
[
Declaration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "",
paren_depth: 0,
},
[],
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "background: url(\"https://example.com\n ",
paren_depth: 1,
},
[],
)
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "background: url('https://example.com\n ",
paren_depth: 1,
},
[],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
source: css_in_js_parser/src/parse_css.rs
expression: "(state, declarations)"
---
(
ParserState {
is_inside_string: None,
current_comment_state: None,
is_inside_property_value: true,
is_inside_at_rule: false,
current_scopes: [
CssScope {
name: ".foo",
scope_type: Selector,
},
CssScope {
name: ".fancy",
scope_type: Selector,
},
],
current_declaration: Declaration {
property: "background",
value: "url(https://example.com\n ",
scope: [],
closed: false,
},
pending_css_segment: "background: url(https://example.com\n ",
paren_depth: 1,
},
[],
)
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "color: blue\n",
paren_depth: 0,
},
[],
)
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "",
paren_depth: 0,
},
[
Declaration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "color: orange\n",
paren_depth: 0,
},
[],
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ expression: "(state1, state2, all_declarations)"
closed: false,
},
pending_css_segment: "color: orange\n",
paren_depth: 0,
},
ParserState {
is_inside_string: None,
Expand All @@ -40,6 +41,7 @@ expression: "(state1, state2, all_declarations)"
closed: false,
},
pending_css_segment: "",
paren_depth: 0,
},
[
Declaration {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: css_in_js_parser/src/parse_css.rs
assertion_line: 496
expression: "(state, declarations)"
---
(
Expand All @@ -22,6 +21,7 @@ expression: "(state, declarations)"
closed: false,
},
pending_css_segment: "color: orange\n",
paren_depth: 0,
},
[],
)
43 changes: 39 additions & 4 deletions packages/yak-swc/yak_swc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub struct Config {
/// To ensure that the hash is consistent accross multiple systems the relative path
/// from the base dir to the source file is used.
pub base_path: String,
/// Prefix for the generated css identifier
pub prefix: Option<String>,
}

pub struct TransformVisitor<GenericComments>
Expand Down Expand Up @@ -108,7 +110,12 @@ impl<GenericComments> TransformVisitor<GenericComments>
where
GenericComments: Comments,
{
pub fn new(comments: Option<GenericComments>, filename: String, dev_mode: bool) -> Self {
pub fn new(
comments: Option<GenericComments>,
filename: String,
dev_mode: bool,
prefix: Option<String>,
) -> Self {
Self {
current_css_state: None,
current_declaration: vec![],
Expand All @@ -118,7 +125,7 @@ where
variables: VariableVisitor::new(),
yak_library_imports: YakImportVisitor::new(),
yak_transformed_library_imports: FxHashSet::default(),
naming_convention: NamingConvention::new(filename.clone(), dev_mode),
naming_convention: NamingConvention::new(filename.clone(), dev_mode, prefix),
variable_name_selector_mapping: FxHashMap::default(),
expression_replacement: None,
css_module_identifier: None,
Expand Down Expand Up @@ -1011,6 +1018,7 @@ pub fn process_transform(program: Program, metadata: TransformPluginProgramMetad
metadata.comments,
deterministic_path,
config.dev_mode,
config.prefix,
)))
}

Expand Down Expand Up @@ -1038,7 +1046,7 @@ mod tests {
use swc_ecma_transforms_testing::FixtureTestConfig;

#[testing::fixture("tests/fixture/**/input.tsx")]
fn fixture(input: PathBuf) {
fn fixture_dev(input: PathBuf) {
test_fixture(
Syntax::Typescript(TsSyntax {
tsx: true,
Expand All @@ -1049,17 +1057,44 @@ mod tests {
Some(tester.comments.clone()),
"path/input.tsx".to_string(),
true,
None,
))
},
&input,
&input.with_file_name("output.tsx"),
&input.with_file_name("output.dev.tsx"),
FixtureTestConfig {
module: None,
sourcemap: false,
allow_error: true,
},
)
}

#[testing::fixture("tests/fixture/**/input.tsx")]
fn fixture_prod(input: PathBuf) {
test_fixture(
Syntax::Typescript(TsSyntax {
tsx: true,
..Default::default()
}),
&|tester| {
visit_mut_pass(TransformVisitor::new(
Some(tester.comments.clone()),
"path/input.tsx".to_string(),
false,
None,
))
},
&input,
&input.with_file_name("output.prod.tsx"),
FixtureTestConfig {
module: None,
sourcemap: false,
allow_error: true,
},
)
}

#[testing::fixture("tests/fixture/**/input.yak.tsx")]
fn fixture_yak(input: PathBuf) {
test_fixture(
Expand Down
Loading

0 comments on commit 735c0bd

Please sign in to comment.