Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 131 additions & 131 deletions packages/styled-jsx/__tests__/__snapshots__/wasm.test.ts.snap

Large diffs are not rendered by default.

40 changes: 31 additions & 9 deletions packages/styled-jsx/transform/src/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
use std::{
collections::hash_map::DefaultHasher,
hash::{Hash, Hasher},
mem::take,
sync::Arc,
};
use std::{collections::hash_map::DefaultHasher, hash::Hasher, mem::take, sync::Arc};

use anyhow::{bail, format_err, Error, Result};
use preset_env_base::Versions;
use rustc_hash::FxHashSet;
use serde::Deserialize;
use swc_common::{errors::HANDLER, util::take::Take, FileName, SourceMap, Span, DUMMY_SP};
use swc_common::{
errors::HANDLER, util::take::Take, FileName, SourceMap, SourceMapper, Span, Spanned, DUMMY_SP,
};
use swc_ecma_ast::*;
use swc_ecma_minifier::{
eval::{EvalResult, Evaluator},
marks::Marks,
};
use swc_ecma_utils::{collect_decls, drop_span, prepend_stmt, private_ident};
use swc_ecma_utils::{collect_decls, prepend_stmt, private_ident};
use swc_ecma_visit::{Fold, FoldWith, Visit, VisitWith};

use crate::{
Expand Down Expand Up @@ -130,6 +127,31 @@ enum StyleExpr<'a> {
Ident(&'a Ident),
}

fn hash_expr_for_style<H: Hasher>(cm: &SourceMap, expr: &Expr, state: &mut H) {
if let Ok(source) = cm.span_to_snippet(expr.span()) {
if let Some(source) = source.strip_prefix('`').and_then(|s| s.strip_suffix('`')) {
state.write(source.as_bytes());
return;
}
}

let Expr::Tpl(tpl) = expr else {
return;
};

for i in 0..tpl.quasis.len() {
state.write(tpl.quasis[i].raw.as_bytes());

if let Some(expr) = tpl.exprs.get(i) {
state.write(b"${");
if let Ok(source) = cm.span_to_snippet(expr.span()) {
state.write(source.as_bytes());
}
state.write(b"}");
}
}
}

impl Fold for StyledJSXTransformer<'_> {
fn fold_jsx_element(&mut self, el: JSXElement) -> JSXElement {
if is_styled_jsx(&el) {
Expand Down Expand Up @@ -521,7 +543,7 @@ impl StyledJSXTransformer<'_> {
css_span = *span;
is_dynamic = false;
} else {
drop_span(expr.clone()).hash(&mut hasher);
hash_expr_for_style(&self.cm, expr, &mut hasher);
let mut s = String::new();
for i in 0..quasis.len() {
// TODO: Handle comments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,44 @@ export const Test2 = ()=><div className={"jsx-81a68341e430a972 " + `jsx-${styles
// external and dynamic
export const Test3 = ({ color })=><div className={`jsx-${styles.__hash}` + " " + _JSXStyle.dynamic([
[
"7113a62c00624bef",
"b940b8041b63a0fa",
[
color
]
]
])}>
<p className={`jsx-${styles.__hash}` + " " + _JSXStyle.dynamic([
[
"7113a62c00624bef",
"b940b8041b63a0fa",
[
color
]
]
])}>external and dynamic</p>
<_JSXStyle id={"7113a62c00624bef"} dynamic={[
<_JSXStyle id={"b940b8041b63a0fa"} dynamic={[
color
]}>{`p.__jsx-style-dynamic-selector{color:${color}}`}</_JSXStyle>
<_JSXStyle id={styles.__hash}>{styles}</_JSXStyle>
</div>;
// external, static and dynamic
export const Test4 = ({ color })=><div className={`jsx-${styles.__hash}` + " jsx-ceba8c9ce34e3d0c " + _JSXStyle.dynamic([
[
"8db39ad50e58394a",
"98567cd857d5ceb8",
[
color
]
]
])}>
<p className={`jsx-${styles.__hash}` + " jsx-ceba8c9ce34e3d0c " + _JSXStyle.dynamic([
[
"8db39ad50e58394a",
"98567cd857d5ceb8",
[
color
]
]
])}>external, static and dynamic</p>
<_JSXStyle id={"ceba8c9ce34e3d0c"}>{"p.jsx-ceba8c9ce34e3d0c{display:inline-block}"}</_JSXStyle>
<_JSXStyle id={"8db39ad50e58394a"} dynamic={[
<_JSXStyle id={"98567cd857d5ceb8"} dynamic={[
color
]}>{`p.__jsx-style-dynamic-selector{color:${color}}`}</_JSXStyle>
<_JSXStyle id={styles.__hash}>{styles}</_JSXStyle>
Expand All @@ -67,43 +67,43 @@ export const Test5 = ()=><div className={"jsx-df0159ebd3f9fb6f"}>
// static and dynamic
export const Test6 = ({ color })=><div className={"jsx-ceba8c9ce34e3d0c " + _JSXStyle.dynamic([
[
"4375826949b9259f",
"98567cd857d5ceb8",
[
color
]
]
])}>
<p className={"jsx-ceba8c9ce34e3d0c " + _JSXStyle.dynamic([
[
"4375826949b9259f",
"98567cd857d5ceb8",
[
color
]
]
])}>static and dynamic</p>
<_JSXStyle id={"ceba8c9ce34e3d0c"}>{"p.jsx-ceba8c9ce34e3d0c{display:inline-block}"}</_JSXStyle>
<_JSXStyle id={"4375826949b9259f"} dynamic={[
<_JSXStyle id={"98567cd857d5ceb8"} dynamic={[
color
]}>{`p.__jsx-style-dynamic-selector{color:${color}}`}</_JSXStyle>
</div>;
// dynamic only
export const Test7 = ({ color })=><div className={_JSXStyle.dynamic([
[
"c6c05a90f95d6b50",
"b940b8041b63a0fa",
[
color
]
]
])}>
<p className={_JSXStyle.dynamic([
[
"c6c05a90f95d6b50",
"b940b8041b63a0fa",
[
color
]
]
])}>dynamic only</p>
<_JSXStyle id={"c6c05a90f95d6b50"} dynamic={[
<_JSXStyle id={"b940b8041b63a0fa"} dynamic={[
color
]}>{`p.__jsx-style-dynamic-selector{color:${color}}`}</_JSXStyle>
</div>;
Expand All @@ -115,21 +115,21 @@ export const Test8 = ({ color })=>{
};
return <div className={_JSXStyle.dynamic([
[
"3a5cdfa6d75c82e1",
"4b0346d74685e510",
[
innerProps.color
]
]
])}>
<p className={_JSXStyle.dynamic([
[
"3a5cdfa6d75c82e1",
"4b0346d74685e510",
[
innerProps.color
]
]
])}>dynamic with scoped compound variable</p>
<_JSXStyle id={"3a5cdfa6d75c82e1"} dynamic={[
<_JSXStyle id={"4b0346d74685e510"} dynamic={[
innerProps.color
]}>{`p.__jsx-style-dynamic-selector{color:${innerProps.color}}`}</_JSXStyle>
</div>;
Expand All @@ -142,44 +142,44 @@ export const Test9 = ({ color })=>{
};
return <div className={_JSXStyle.dynamic([
[
"78eaf0c7b6cf1e02",
"4ace5e4208a4ea7e",
[
innerProps.color
]
]
])}>
<p className={_JSXStyle.dynamic([
[
"78eaf0c7b6cf1e02",
"4ace5e4208a4ea7e",
[
innerProps.color
]
]
])}>dynamic with compound variable</p>
<_JSXStyle id={"78eaf0c7b6cf1e02"} dynamic={[
<_JSXStyle id={"4ace5e4208a4ea7e"} dynamic={[
innerProps.color
]}>{`p.__jsx-style-dynamic-selector{color:${innerProps.color}}`}</_JSXStyle>
</div>;
};
const foo = "red";
// dynamic with constant variable
export const Test10 = ()=><div className={"jsx-568a62763d5e1d43"}>
<p className={"jsx-568a62763d5e1d43"}>dynamic with constant variable</p>
<_JSXStyle id={"568a62763d5e1d43"}>{`p.jsx-568a62763d5e1d43{color:${foo}}`}</_JSXStyle>
export const Test10 = ()=><div className={"jsx-202b7151f9e63377"}>
<p className={"jsx-202b7151f9e63377"}>dynamic with constant variable</p>
<_JSXStyle id={"202b7151f9e63377"}>{`p.jsx-202b7151f9e63377{color:${foo}}`}</_JSXStyle>
</div>;
// dynamic with complex scope
export const Test11 = ({ color })=>{
const items = Array.from({
length: 5
}).map((item, i)=><li key={i} className={_JSXStyle.dynamic([
[
"6074b9c2542c8080",
"8069b86d641a1446",
[
color
]
]
]) + " " + "item"}>
<_JSXStyle id={"6074b9c2542c8080"} dynamic={[
<_JSXStyle id={"8069b86d641a1446"} dynamic={[
color
]}>{`.item.__jsx-style-dynamic-selector{color:${color}}`}</_JSXStyle>
Item #{i + 1}
Expand Down
Loading
Loading