added clone: to components in view! macro to help with move dilemmaa

This commit is contained in:
Jose Quesada 2022-12-28 09:24:52 -06:00
parent 3c1e1e12d2
commit 0da8d0113c

View file

@ -490,7 +490,9 @@ fn fragment_to_tokens(cx: &Ident, _span: Span, nodes: &[Node], lazy: bool) -> To
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)
}
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 +520,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) }
}; };
@ -642,23 +642,17 @@ fn component_to_tokens(cx: &Ident, node: &NodeElement) -> TokenStream {
let span = node.name.span(); let span = node.name.span();
let component_props_name = format_ident!("{component_name}Props"); let component_props_name = format_ident!("{component_name}Props");
let children = if node.children.is_empty() { let attrs = node.attributes.iter().filter_map(|node| {
quote! {}
} else {
let children = fragment_to_tokens(cx, span, &node.children, true);
quote! { .children(Box::new(move |#cx| #children)) }
};
let props = node
.attributes
.iter()
.filter_map(|node| {
if let Node::Attribute(node) = node { if let Node::Attribute(node) = node {
Some(node) Some(node)
} else { } else {
None None
} }
}) });
let props = attrs
.clone()
.filter(|attr| !attr.key.to_string().starts_with("clone:"))
.map(|attr| { .map(|attr| {
let name = &attr.key; let name = &attr.key;
@ -676,6 +670,38 @@ fn component_to_tokens(cx: &Ident, node: &NodeElement) -> TokenStream {
} }
}); });
let items_to_clone = attrs
.filter(|attr| attr.key.to_string().starts_with("clone:"))
.map(|attr| {
let ident = attr
.key
.to_string()
.strip_prefix("clone:")
.unwrap()
.to_owned();
format_ident!("{ident}", span = attr.key.span())
})
.collect::<Vec<_>>();
let children = if node.children.is_empty() {
quote! {}
} else {
let children = fragment_to_tokens(cx, span, &node.children, true);
let clonables = items_to_clone
.iter()
.map(|ident| quote! { let #ident = #ident.clone(); });
quote! {
.children({
#(#clonables)*
Box::new(move |#cx| #children)
})
}
};
quote! { quote! {
#name( #name(
#cx, #cx,
@ -747,110 +773,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"
)
} }