mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-11 07:14:16 +00:00
fixed move dilema on component children
This commit is contained in:
parent
a3f090c4df
commit
4dd5768a66
1 changed files with 171 additions and 124 deletions
|
@ -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"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue