fixed move dilema on component children

This commit is contained in:
Jose Quesada 2022-12-27 20:14:10 -06:00
parent a3f090c4df
commit 4dd5768a66

View file

@ -154,7 +154,7 @@ pub(crate) fn render_view(cx: &Ident, nodes: &[Node], mode: Mode) -> TokenStream
} else if nodes.len() == 1 { } else if nodes.len() == 1 {
node_to_tokens(cx, &nodes[0]) node_to_tokens(cx, &nodes[0])
} else { } else {
fragment_to_tokens(cx, Span::call_site(), nodes, false) fragment_to_tokens(cx, Span::call_site(), nodes, false).0
} }
} }
@ -461,36 +461,70 @@ fn set_class_attribute_ssr(
} }
} }
fn fragment_to_tokens(cx: &Ident, _span: Span, nodes: &[Node], lazy: bool) -> TokenStream { fn fragment_to_tokens(
cx: &Ident,
_span: Span,
nodes: &[Node],
lazy: bool,
) -> (TokenStream, Option<TokenStream>) {
let nodes = nodes.iter().map(|node| { let nodes = nodes.iter().map(|node| {
let node = node_to_tokens(cx, node); let node = node_to_tokens(cx, node);
quote! { quote! {
#node.into_view(#cx) #node
} }
}); });
if lazy { if lazy {
quote! { let (view_names, exprs): (Vec<_>, Vec<_>) = nodes
{ .clone()
leptos::Fragment::lazy(|| vec![ .enumerate()
#(#nodes),* .map(|(i, expr)| {
]) let lazy_view_enumerated = format_ident!("__expr_{i}");
}
} (
lazy_view_enumerated.clone(),
quote! {
let #lazy_view_enumerated = #expr;
let #lazy_view_enumerated
= leptos::LazyView::new(move |cx| #lazy_view_enumerated.into_view(cx));
},
)
})
.unzip();
let expr_names = view_names.iter();
(
quote! {
{
leptos::Fragment::lazy(|| vec![
#(#expr_names.get_view(#cx)),*
])
}
},
Some(exprs.into_iter().collect()),
)
} else { } else {
quote! { (
{ quote! {
leptos::Fragment::new(vec![ {
#(#nodes),* leptos::Fragment::new(vec![
]) #(#nodes.into_view(#cx)),*
} ])
} }
},
None,
)
} }
} }
fn node_to_tokens(cx: &Ident, node: &Node) -> TokenStream { fn node_to_tokens(cx: &Ident, node: &Node) -> TokenStream {
match node { match node {
Node::Fragment(fragment) => fragment_to_tokens(cx, Span::call_site(), &fragment.children, false), Node::Fragment(fragment) => {
fragment_to_tokens(cx, Span::call_site(), &fragment.children, false).0
}
Node::Comment(_) | Node::Doctype(_) => quote! {}, Node::Comment(_) | Node::Doctype(_) => quote! {},
Node::Text(node) => { Node::Text(node) => {
let value = node.value.as_ref(); let value = node.value.as_ref();
@ -518,12 +552,10 @@ fn element_to_tokens(cx: &Ident, node: &NodeElement) -> TokenStream {
} else if is_svg_element(&tag) { } else if is_svg_element(&tag) {
let name = &node.name; let name = &node.name;
quote! { leptos::leptos_dom::svg::#name(#cx) } quote! { leptos::leptos_dom::svg::#name(#cx) }
} } else if is_math_ml_element(&tag) {
else if is_math_ml_element(&tag) {
let name = &node.name; let name = &node.name;
quote! { leptos::leptos_dom::math::#name(#cx) } quote! { leptos::leptos_dom::math::#name(#cx) }
} } else {
else {
let name = &node.name; let name = &node.name;
quote! { leptos::leptos_dom::#name(#cx) } quote! { leptos::leptos_dom::#name(#cx) }
}; };
@ -537,7 +569,7 @@ fn element_to_tokens(cx: &Ident, node: &NodeElement) -> TokenStream {
let children = node.children.iter().map(|node| { let children = node.children.iter().map(|node| {
let child = match node { let child = match node {
Node::Fragment(fragment) => { Node::Fragment(fragment) => {
fragment_to_tokens(cx, Span::call_site(), &fragment.children, false) fragment_to_tokens(cx, Span::call_site(), &fragment.children, false).0
} }
Node::Text(node) => { Node::Text(node) => {
let value = node.value.as_ref(); let value = node.value.as_ref();
@ -645,8 +677,15 @@ fn component_to_tokens(cx: &Ident, node: &NodeElement) -> TokenStream {
let children = if node.children.is_empty() { let children = if node.children.is_empty() {
quote! {} quote! {}
} else { } else {
let children = fragment_to_tokens(cx, span, &node.children, true); let (children, exprs) = fragment_to_tokens(cx, span, &node.children, true);
quote! { .children(Box::new(move |#cx| #children)) }
let exprs = exprs.unwrap();
quote! { .children(Box::new({
#exprs
move |#cx| #children
}))}
}; };
let props = node let props = node
@ -747,110 +786,118 @@ fn is_self_closing(node: &NodeElement) -> bool {
fn camel_case_tag_name(tag_name: &str) -> String { fn camel_case_tag_name(tag_name: &str) -> String {
let mut chars = tag_name.chars(); let mut chars = tag_name.chars();
let first = chars.next(); let first = chars.next();
first.map(|f| f.to_ascii_uppercase()).into_iter() first
.map(|f| f.to_ascii_uppercase())
.into_iter()
.chain(chars) .chain(chars)
.collect() .collect()
} }
fn is_svg_element(tag: &str) -> bool { fn is_svg_element(tag: &str) -> bool {
matches!(tag, "animate" | matches!(
"animateMotion" | tag,
"animateTransform" | "animate"
"circle" | | "animateMotion"
"clipPath" | | "animateTransform"
"defs" | | "circle"
"desc" | | "clipPath"
"discard" | | "defs"
"ellipse" | | "desc"
"feBlend" | | "discard"
"feColorMatrix" | | "ellipse"
"feComponentTransfer" | | "feBlend"
"feComposite" | | "feColorMatrix"
"feConvolveMatrix" | | "feComponentTransfer"
"feDiffuseLighting" | | "feComposite"
"feDisplacementMap" | | "feConvolveMatrix"
"feDistantLight" | | "feDiffuseLighting"
"feDropShadow" | | "feDisplacementMap"
"feFlood" | | "feDistantLight"
"feFuncA" | | "feDropShadow"
"feFuncB" | | "feFlood"
"feFuncG" | | "feFuncA"
"feFuncR" | | "feFuncB"
"feGaussianBlur" | | "feFuncG"
"feImage" | | "feFuncR"
"feMerge" | | "feGaussianBlur"
"feMergeNode" | | "feImage"
"feMorphology" | | "feMerge"
"feOffset" | | "feMergeNode"
"fePointLight" | | "feMorphology"
"feSpecularLighting" | | "feOffset"
"feSpotLight" | | "fePointLight"
"feTile" | | "feSpecularLighting"
"feTurbulence" | | "feSpotLight"
"filter" | | "feTile"
"foreignObject" | | "feTurbulence"
"g" | | "filter"
"hatch" | | "foreignObject"
"hatchpath" | | "g"
"image" | | "hatch"
"line" | | "hatchpath"
"linearGradient" | | "image"
"marker" | | "line"
"mask" | | "linearGradient"
"metadata" | | "marker"
"mpath" | | "mask"
"path" | | "metadata"
"pattern" | | "mpath"
"polygon" | | "path"
"polyline" | | "pattern"
"radialGradient" | | "polygon"
"rect" | | "polyline"
"script" | | "radialGradient"
"set" | | "rect"
"stop" | | "script"
"style" | | "set"
"svg" | | "stop"
"switch" | | "style"
"symbol" | | "svg"
"text" | | "switch"
"textPath" | | "symbol"
"title" | | "text"
"tspan" | | "textPath"
"use" | | "title"
"use_" | | "tspan"
"view") | "use"
| "use_"
| "view"
)
} }
fn is_math_ml_element(tag: &str) -> bool { fn is_math_ml_element(tag: &str) -> bool {
matches!(tag, "math" | matches!(
"mi" | tag,
"mn" | "math"
"mo" | | "mi"
"ms" | | "mn"
"mspace" | | "mo"
"mtext" | | "ms"
"menclose" | | "mspace"
"merror" | | "mtext"
"mfenced" | | "menclose"
"mfrac" | | "merror"
"mpadded" | | "mfenced"
"mphantom" | | "mfrac"
"mroot" | | "mpadded"
"mrow" | | "mphantom"
"msqrt" | | "mroot"
"mstyle" | | "mrow"
"mmultiscripts" | | "msqrt"
"mover" | | "mstyle"
"mprescripts" | | "mmultiscripts"
"msub" | | "mover"
"msubsup" | | "mprescripts"
"msup" | | "msub"
"munder" | | "msubsup"
"munderover" | | "msup"
"mtable" | | "munder"
"mtd" | | "munderover"
"mtr" | | "mtable"
"maction" | | "mtd"
"annotation" | | "mtr"
"semantics") | "maction"
} | "annotation"
| "semantics"
)
}