diff --git a/packages/rsx/src/template.rs b/packages/rsx/src/template.rs deleted file mode 100644 index 22c73ae33..000000000 --- a/packages/rsx/src/template.rs +++ /dev/null @@ -1,1064 +0,0 @@ -// use proc_macro2::TokenStream; -// use quote::TokenStreamExt; -// use quote::{quote, ToTokens}; -// use syn::{Expr, Ident, LitStr}; - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// pub fn try_parse_template( -// rsx: &str, -// location: OwnedCodeLocation, -// previous_template: Option, -// ) -> Result<(OwnedTemplate, DynamicTemplateContextBuilder), Error> { -// use crate::CallBody; - -// let call_body: CallBody = -// syn::parse_str(rsx).map_err(|e| Error::ParseError(ParseError::new(e, location.clone())))?; -// let mut template_builder = TemplateBuilder::from_roots_always(call_body.roots); -// if let Some(prev) = previous_template { -// template_builder = template_builder -// .try_switch_dynamic_context(prev) -// .ok_or_else(|| { -// Error::RecompileRequiredError(RecompileReason::Variable( -// "dynamic context updated".to_string(), -// )) -// })?; -// } -// let dyn_ctx = template_builder.dynamic_context.clone(); -// Ok((template_builder.try_into_owned(&location)?, dyn_ctx)) -// } - -// use crate::{BodyNode, ElementAttr, FormattedSegment, Segment}; - -// struct TemplateElementBuilder { -// tag: Ident, -// attributes: Vec, -// children: Vec, -// listeners: Vec, -// locally_static: bool, -// } - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// type OwndedTemplateElement = TemplateElement< -// Vec>, -// OwnedAttributeValue, -// Vec, -// Vec, -// >; - -// impl TemplateElementBuilder { -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { -// let Self { -// tag, -// attributes, -// children, -// listeners, -// .. -// } = self; -// let (element_tag, element_ns) = -// element_to_static_str(&tag.to_string()).ok_or_else(|| { -// Error::ParseError(ParseError::new( -// syn::Error::new(tag.span(), format!("unknown element: {}", tag)), -// location.clone(), -// )) -// })?; - -// let mut owned_attributes = Vec::new(); -// for a in attributes { -// owned_attributes.push(a.try_into_owned(location, element_tag, element_ns)?); -// } - -// Ok(TemplateElement::new( -// element_tag, -// element_ns, -// owned_attributes, -// children, -// listeners, -// )) -// } -// } - -// impl ToTokens for TemplateElementBuilder { -// fn to_tokens(&self, tokens: &mut TokenStream) { -// let Self { -// tag, -// attributes, -// children, -// listeners, -// .. -// } = self; -// let children = children.iter().map(|id| { -// let raw = id.0; -// quote! {TemplateNodeId(#raw)} -// }); -// tokens.append_all(quote! { -// TemplateElement::new( -// dioxus_elements::#tag::TAG_NAME, -// dioxus_elements::#tag::NAME_SPACE, -// &[#(#attributes),*], -// &[#(#children),*], -// &[#(#listeners),*], -// ) -// }) -// } -// } - -// enum AttributeName { -// Ident(Ident), -// Str(LitStr), -// } - -// struct TemplateAttributeBuilder { -// element_tag: Ident, -// name: AttributeName, -// value: TemplateAttributeValue, -// } - -// impl TemplateAttributeBuilder { -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// fn try_into_owned( -// self, -// location: &OwnedCodeLocation, -// element_tag: &'static str, -// element_ns: Option<&'static str>, -// ) -> Result, Error> { -// let Self { name, value, .. } = self; -// let (name, span, literal) = match name { -// AttributeName::Ident(name) => (name.to_string(), name.span(), false), -// AttributeName::Str(name) => (name.value(), name.span(), true), -// }; -// let (name, namespace, volatile) = attrbute_to_static_str(&name, element_tag, element_ns) -// .ok_or_else(|| { -// if literal { -// // literals will be captured when a full recompile is triggered -// Error::RecompileRequiredError(RecompileReason::Attribute(name.to_string())) -// } else { -// Error::ParseError(ParseError::new( -// syn::Error::new(span, format!("unknown attribute: {}", name)), -// location.clone(), -// )) -// } -// })?; -// let attribute = AttributeDiscription { -// name, -// namespace, -// volatile, -// }; -// Ok(TemplateAttribute { value, attribute }) -// } -// } - -// impl ToTokens for TemplateAttributeBuilder { -// fn to_tokens(&self, tokens: &mut TokenStream) { -// let Self { -// element_tag, -// name, -// value, -// } = self; -// let value = match value { -// TemplateAttributeValue::Static(val) => { -// let val = match val { -// OwnedAttributeValue::Text(txt) => quote! {StaticAttributeValue::Text(#txt)}, -// OwnedAttributeValue::Float32(f) => quote! {StaticAttributeValue::Float32(#f)}, -// OwnedAttributeValue::Float64(f) => quote! {StaticAttributeValue::Float64(#f)}, -// OwnedAttributeValue::Int32(i) => quote! {StaticAttributeValue::Int32(#i)}, -// OwnedAttributeValue::Int64(i) => quote! {StaticAttributeValue::Int64(#i)}, -// OwnedAttributeValue::Uint32(u) => quote! {StaticAttributeValue::Uint32(#u)}, -// OwnedAttributeValue::Uint64(u) => quote! {StaticAttributeValue::Uint64(#u)}, -// OwnedAttributeValue::Bool(b) => quote! {StaticAttributeValue::Bool(#b)}, -// OwnedAttributeValue::Vec3Float(f1, f2, f3) => { -// quote! {StaticAttributeValue::Vec3Float(#f1, #f2, #f3)} -// } -// OwnedAttributeValue::Vec3Int(f1, f2, f3) => { -// quote! {StaticAttributeValue::Vec3Int(#f1, #f2, #f3)} -// } -// OwnedAttributeValue::Vec3Uint(f1, f2, f3) => { -// quote! {StaticAttributeValue::Vec3Uint(#f1, #f2, #f3)} -// } -// OwnedAttributeValue::Vec4Float(f1, f2, f3, f4) => { -// quote! {StaticAttributeValue::Vec4Float(#f1, #f2, #f3, #f4)} -// } -// OwnedAttributeValue::Vec4Int(f1, f2, f3, f4) => { -// quote! {StaticAttributeValue::Vec4Int(#f1, #f2, #f3, #f4)} -// } -// OwnedAttributeValue::Vec4Uint(f1, f2, f3, f4) => { -// quote! {StaticAttributeValue::Vec4Uint(#f1, #f2, #f3, #f4)} -// } -// OwnedAttributeValue::Bytes(b) => { -// quote! {StaticAttributeValue::Bytes(&[#(#b),*])} -// } -// OwnedAttributeValue::Any(_) => todo!(), -// }; -// quote! {TemplateAttributeValue::Static(#val)} -// } -// TemplateAttributeValue::Dynamic(idx) => quote! {TemplateAttributeValue::Dynamic(#idx)}, -// }; -// match name { -// AttributeName::Ident(name) => tokens.append_all(quote! { -// TemplateAttribute{ -// attribute: dioxus_elements::#element_tag::#name, -// value: #value, -// } -// }), -// AttributeName::Str(lit) => tokens.append_all(quote! { -// TemplateAttribute{ -// attribute: dioxus::prelude::AttributeDiscription{ -// name: #lit, -// namespace: None, -// volatile: false -// }, -// value: #value, -// } -// }), -// } -// } -// } - -// enum TemplateNodeTypeBuilder { -// Element(TemplateElementBuilder), -// Text(TextTemplate>, String>), -// DynamicNode(usize), -// } - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// type OwnedTemplateNodeType = TemplateNodeType< -// Vec>, -// OwnedAttributeValue, -// Vec, -// Vec, -// Vec>, -// String, -// >; - -// impl TemplateNodeTypeBuilder { -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { -// match self { -// TemplateNodeTypeBuilder::Element(el) => { -// Ok(TemplateNodeType::Element(el.try_into_owned(location)?)) -// } -// TemplateNodeTypeBuilder::Text(txt) => Ok(TemplateNodeType::Text(txt)), -// TemplateNodeTypeBuilder::DynamicNode(idx) => Ok(TemplateNodeType::DynamicNode(idx)), -// } -// } -// } - -// impl ToTokens for TemplateNodeTypeBuilder { -// fn to_tokens(&self, tokens: &mut TokenStream) { -// match self { -// TemplateNodeTypeBuilder::Element(el) => tokens.append_all(quote! { -// TemplateNodeType::Element(#el) -// }), -// TemplateNodeTypeBuilder::Text(txt) => { -// let mut length = 0; - -// let segments = txt.segments.iter().map(|seg| match seg { -// TextTemplateSegment::Static(s) => { -// length += s.len(); -// quote!(TextTemplateSegment::Static(#s)) -// } -// TextTemplateSegment::Dynamic(idx) => quote!(TextTemplateSegment::Dynamic(#idx)), -// }); - -// tokens.append_all(quote! { -// TemplateNodeType::Text(TextTemplate::new(&[#(#segments),*], #length)) -// }); -// } -// TemplateNodeTypeBuilder::DynamicNode(idx) => tokens.append_all(quote! { -// TemplateNodeType::DynamicNode(#idx) -// }), -// } -// } -// } - -// struct TemplateNodeBuilder { -// id: TemplateNodeId, -// depth: usize, -// parent: Option, -// node_type: TemplateNodeTypeBuilder, -// fully_static: bool, -// } - -// impl TemplateNodeBuilder { -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { -// let TemplateNodeBuilder { -// id, -// node_type, -// parent, -// depth, -// .. -// } = self; -// let node_type = node_type.try_into_owned(location)?; -// Ok(OwnedTemplateNode { -// id, -// node_type, -// parent, -// depth, -// }) -// } - -// fn to_tokens(&self, tokens: &mut TokenStream) { -// let Self { -// id, -// node_type, -// parent, -// depth, -// .. -// } = self; -// let raw_id = id.0; -// let parent = match parent { -// Some(id) => { -// let id = id.0; -// quote! {Some(TemplateNodeId(#id))} -// } -// None => quote! {None}, -// }; - -// tokens.append_all(quote! { -// TemplateNode { -// id: TemplateNodeId(#raw_id), -// node_type: #node_type, -// parent: #parent, -// depth: #depth, -// } -// }) -// } -// } - -// #[derive(Default)] -// pub struct TemplateBuilder { -// nodes: Vec, -// root_nodes: Vec, -// dynamic_context: DynamicTemplateContextBuilder, -// } - -// impl TemplateBuilder { -// /// Create a template builder from nodes if it would improve performance to do so. -// pub fn from_roots(roots: Vec) -> Option { -// let mut builder = Self::default(); - -// for (i, root) in roots.into_iter().enumerate() { -// let id = builder.build_node(root, None, vec![i], 0); -// builder.root_nodes.push(id); -// } - -// // only build a template if there is at least one static node -// if builder -// .nodes -// .iter() -// .all(|r| matches!(&r.node_type, TemplateNodeTypeBuilder::DynamicNode(_))) -// { -// None -// } else { -// Some(builder) -// } -// } - -// /// Create a template builder from nodes regardless of performance. -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// fn from_roots_always(roots: Vec) -> Self { -// let mut builder = Self::default(); - -// for (i, root) in roots.into_iter().enumerate() { -// let id = builder.build_node(root, None, vec![i], 0); -// builder.root_nodes.push(id); -// } - -// builder -// } - -// fn build_node( -// &mut self, -// node: BodyNode, -// parent: Option, -// path: Vec, -// depth: usize, -// ) -> TemplateNodeId { -// let id = TemplateNodeId(self.nodes.len()); -// match node { -// BodyNode::Element(el) => { -// let mut locally_static = true; -// let mut attributes = Vec::new(); -// let mut listeners = Vec::new(); -// for attr in el.attributes { -// match attr.attr { -// ElementAttr::AttrText { name, value } => { -// if let Some(static_value) = value.to_static() { -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Ident(name), -// value: TemplateAttributeValue::Static( -// OwnedAttributeValue::Text(static_value), -// ), -// }) -// } else { -// locally_static = false; -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Ident(name), -// value: TemplateAttributeValue::Dynamic( -// self.dynamic_context.add_attr(quote!(#value)), -// ), -// }) -// } -// } -// ElementAttr::CustomAttrText { name, value } => { -// if let Some(static_value) = value.to_static() { -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Str(name), -// value: TemplateAttributeValue::Static( -// OwnedAttributeValue::Text(static_value), -// ), -// }) -// } else { -// locally_static = false; -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Str(name), -// value: TemplateAttributeValue::Dynamic( -// self.dynamic_context.add_attr(quote!(#value)), -// ), -// }) -// } -// } -// ElementAttr::AttrExpression { name, value } => { -// locally_static = false; -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Ident(name), -// value: TemplateAttributeValue::Dynamic( -// self.dynamic_context.add_attr(quote!(#value)), -// ), -// }) -// } -// ElementAttr::CustomAttrExpression { name, value } => { -// locally_static = false; -// attributes.push(TemplateAttributeBuilder { -// element_tag: el.name.clone(), -// name: AttributeName::Str(name), -// value: TemplateAttributeValue::Dynamic( -// self.dynamic_context.add_attr(quote!(#value)), -// ), -// }) -// } -// ElementAttr::EventTokens { name, tokens } => { -// locally_static = false; -// listeners.push(self.dynamic_context.add_listener(name, tokens)) -// } -// } -// } -// if let Some(key) = el.key { -// self.dynamic_context.add_key(quote!( -// dioxus::core::exports::bumpalo::format!(in __bump, "{}", #key) -// .into_bump_str() -// )); -// } -// self.nodes.push(TemplateNodeBuilder { -// id, -// node_type: TemplateNodeTypeBuilder::Element(TemplateElementBuilder { -// tag: el.name, -// attributes, -// children: Vec::new(), -// listeners, -// locally_static, -// }), -// parent, -// depth, -// fully_static: false, -// }); -// let children: Vec<_> = el -// .children -// .into_iter() -// .enumerate() -// .map(|(i, child)| { -// let mut new_path = path.clone(); -// new_path.push(i); -// self.build_node(child, Some(id), new_path, depth + 1) -// }) -// .collect(); -// let children_fully_static = children.iter().all(|c| self.nodes[c.0].fully_static); -// let parent = &mut self.nodes[id.0]; -// parent.fully_static = locally_static && children_fully_static; -// if let TemplateNodeTypeBuilder::Element(element) = &mut parent.node_type { -// element.children = children; -// } -// } - -// BodyNode::Component(comp) => { -// self.nodes.push(TemplateNodeBuilder { -// id, -// node_type: TemplateNodeTypeBuilder::DynamicNode( -// self.dynamic_context.add_node(BodyNode::Component(comp)), -// ), -// parent, -// depth, -// fully_static: false, -// }); -// } - -// BodyNode::Text(txt) => { -// let mut segments = Vec::new(); -// let mut length = 0; -// let mut fully_static = true; - -// for segment in txt.segments { -// segments.push(match segment { -// Segment::Literal(lit) => { -// length += lit.len(); -// TextTemplateSegment::Static(lit) -// } -// Segment::Formatted(fmted) => { -// fully_static = false; -// TextTemplateSegment::Dynamic(self.dynamic_context.add_text(fmted)) -// } -// }) -// } - -// self.nodes.push(TemplateNodeBuilder { -// id, -// node_type: TemplateNodeTypeBuilder::Text(TextTemplate::new(segments, length)), -// parent, -// depth, -// fully_static, -// }); -// } - -// BodyNode::RawExpr(expr) => { -// self.nodes.push(TemplateNodeBuilder { -// id, -// node_type: TemplateNodeTypeBuilder::DynamicNode( -// self.dynamic_context.add_node(BodyNode::RawExpr(expr)), -// ), -// parent, -// depth, -// fully_static: false, -// }); -// } -// } -// id -// } - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// pub fn try_switch_dynamic_context( -// mut self, -// dynamic_context: DynamicTemplateContextBuilder, -// ) -> Option { -// let attribute_mapping: HashMap = dynamic_context -// .attributes -// .iter() -// .enumerate() -// .map(|(i, ts)| (ts.to_string(), i)) -// .collect(); -// let text_mapping: HashMap = dynamic_context -// .text -// .iter() -// .enumerate() -// .map(|(i, ts)| (ts.to_token_stream().to_string(), i)) -// .collect(); -// let listener_mapping: HashMap<(String, Expr), usize> = dynamic_context -// .listeners -// .iter() -// .enumerate() -// .map(|(i, ts)| (ts.clone(), i)) -// .collect(); -// let node_mapping: HashMap = dynamic_context -// .nodes -// .iter() -// .enumerate() -// .map(|(i, ts)| (ts.to_token_stream().to_string(), i)) -// .collect(); - -// for node in &mut self.nodes { -// match &mut node.node_type { -// TemplateNodeTypeBuilder::Element(element) => { -// for listener in &mut element.listeners { -// *listener = -// *listener_mapping.get(&self.dynamic_context.listeners[*listener])?; -// } -// for attribute in &mut element.attributes { -// if let TemplateAttributeValue::Dynamic(idx) = &mut attribute.value { -// *idx = *attribute_mapping -// .get(&self.dynamic_context.attributes[*idx].to_string())?; -// } -// } -// } -// TemplateNodeTypeBuilder::Text(txt) => { -// for seg in &mut txt.segments { -// if let TextTemplateSegment::Dynamic(idx) = seg { -// *idx = *text_mapping.get( -// &self.dynamic_context.text[*idx] -// .to_token_stream() -// .to_string(), -// )?; -// } -// } -// } -// TemplateNodeTypeBuilder::DynamicNode(idx) => { -// *idx = *node_mapping.get( -// &self.dynamic_context.nodes[*idx] -// .to_token_stream() -// .to_string(), -// )?; -// } -// } -// } -// self.dynamic_context = dynamic_context; - -// Some(self) -// } - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// pub fn try_into_owned(self, location: &OwnedCodeLocation) -> Result { -// let mut nodes = Vec::new(); -// let dynamic_mapping = self.dynamic_mapping(&nodes); -// let dynamic_path = self.dynamic_path(); -// for node in self.nodes { -// nodes.push(node.try_into_owned(location)?); -// } - -// Ok(OwnedTemplate { -// nodes, -// root_nodes: self.root_nodes, -// dynamic_mapping, -// dynamic_path, -// }) -// } - -// #[cfg(any(feature = "hot-reload", debug_assertions))] -// pub fn dynamic_mapping( -// &self, -// resolved_nodes: &Vec, -// ) -> OwnedDynamicNodeMapping { -// let dynamic_context = &self.dynamic_context; -// let mut node_mapping = vec![None; dynamic_context.nodes.len()]; -// let nodes = &self.nodes; -// for n in nodes { -// if let TemplateNodeTypeBuilder::DynamicNode(idx) = &n.node_type { -// node_mapping[*idx] = Some(n.id) -// } -// } -// let mut text_mapping = vec![Vec::new(); dynamic_context.text.len()]; -// for n in nodes { -// if let TemplateNodeTypeBuilder::Text(txt) = &n.node_type { -// for seg in &txt.segments { -// match seg { -// TextTemplateSegment::Static(_) => (), -// TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id), -// } -// } -// } -// } -// let mut attribute_mapping = vec![Vec::new(); dynamic_context.attributes.len()]; -// for n in nodes { -// if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { -// for (i, attr) in el.attributes.iter().enumerate() { -// match attr.value { -// TemplateAttributeValue::Static(_) => (), -// TemplateAttributeValue::Dynamic(idx) => { -// attribute_mapping[idx].push((n.id, i)); -// } -// } -// } -// } -// } -// let mut listener_mapping = Vec::new(); -// for n in nodes { -// if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { -// if !el.listeners.is_empty() { -// listener_mapping.push(n.id); -// } -// } -// } - -// let mut volatile_mapping = Vec::new(); -// for n in resolved_nodes { -// if let TemplateNodeType::Element(el) = &n.node_type { -// for (i, attr) in el.attributes.iter().enumerate() { -// if attr.attribute.volatile { -// volatile_mapping.push((n.id, i)); -// } -// } -// } -// } - -// OwnedDynamicNodeMapping::new( -// node_mapping, -// text_mapping, -// attribute_mapping, -// volatile_mapping, -// listener_mapping, -// ) -// } - -// fn dynamic_path(&self) -> Option { -// let mut last_seg: Option = None; -// let mut nodes_to_insert_after = Vec::new(); -// // iterating from the last root to the first -// for root in self.root_nodes.iter().rev() { -// let root_node = &self.nodes[root.0]; -// if let TemplateNodeTypeBuilder::DynamicNode(_) = root_node.node_type { -// match &mut last_seg { -// // if there has been no static nodes, we can append the child to the parent node -// None => nodes_to_insert_after.push(*root), -// // otherwise we insert the child before the last static node -// Some(seg) => { -// seg.ops.push(UpdateOp::InsertBefore(*root)); -// } -// } -// } else if let Some(mut new) = self.construct_path_segment(*root) { -// if let Some(last) = last_seg.take() { -// match new.traverse { -// OwnedTraverse::Halt => { -// new.traverse = OwnedTraverse::NextSibling(Box::new(last)); -// } -// OwnedTraverse::FirstChild(b) => { -// new.traverse = OwnedTraverse::Both(Box::new((*b, last))); -// } -// _ => unreachable!(), -// } -// } else { -// for node in nodes_to_insert_after.drain(..) { -// new.ops.push(UpdateOp::InsertAfter(node)); -// } -// } -// last_seg = Some(new); -// } else if let Some(last) = last_seg.take() { -// last_seg = Some(OwnedPathSeg { -// ops: Vec::new(), -// traverse: OwnedTraverse::NextSibling(Box::new(last)), -// }); -// } -// } -// last_seg -// } - -// fn construct_path_segment(&self, node_id: TemplateNodeId) -> Option { -// let n = &self.nodes[node_id.0]; -// if n.fully_static { -// return None; -// } -// match &n.node_type { -// TemplateNodeTypeBuilder::Element(el) => { -// let mut last_seg: Option = None; -// let mut children_to_append = Vec::new(); -// // iterating from the last child to the first -// for child in el.children.iter().rev() { -// let child_node = &self.nodes[child.0]; -// if let TemplateNodeTypeBuilder::DynamicNode(_) = child_node.node_type { -// match &mut last_seg { -// // if there has been no static nodes, we can append the child to the parent node -// None => children_to_append.push(*child), -// // otherwise we insert the child before the last static node -// Some(seg) => { -// seg.ops.push(UpdateOp::InsertBefore(*child)); -// } -// } -// } else if let Some(mut new) = self.construct_path_segment(*child) { -// if let Some(last) = last_seg.take() { -// match new.traverse { -// OwnedTraverse::Halt => { -// new.traverse = OwnedTraverse::NextSibling(Box::new(last)); -// } -// OwnedTraverse::FirstChild(b) => { -// new.traverse = OwnedTraverse::Both(Box::new((*b, last))); -// } -// _ => unreachable!(), -// } -// } -// last_seg = Some(new); -// } else if let Some(last) = last_seg.take() { -// last_seg = Some(OwnedPathSeg { -// ops: Vec::new(), -// traverse: OwnedTraverse::NextSibling(Box::new(last)), -// }); -// } -// } -// let mut ops = Vec::new(); -// if !el.locally_static || n.parent.is_none() { -// ops.push(UpdateOp::StoreNode(node_id)); -// } -// for child in children_to_append.into_iter().rev() { -// ops.push(UpdateOp::AppendChild(child)); -// } -// Some(OwnedPathSeg { -// ops, -// traverse: match last_seg { -// Some(last) => OwnedTraverse::FirstChild(Box::new(last)), -// None => OwnedTraverse::Halt, -// }, -// }) -// } -// TemplateNodeTypeBuilder::Text(_) => Some(OwnedPathSeg { -// ops: vec![UpdateOp::StoreNode(n.id)], -// traverse: dioxus_core::OwnedTraverse::Halt, -// }), -// TemplateNodeTypeBuilder::DynamicNode(_) => unreachable!( -// "constructing path segment for dynamic nodes is handled in the parent node" -// ), -// } -// } -// } - -// impl ToTokens for TemplateBuilder { -// fn to_tokens(&self, tokens: &mut TokenStream) { -// let Self { -// nodes, -// root_nodes, -// dynamic_context, -// } = self; - -// let mut node_mapping = vec![None; dynamic_context.nodes.len()]; -// for n in nodes { -// if let TemplateNodeTypeBuilder::DynamicNode(idx) = &n.node_type { -// node_mapping[*idx] = Some(n.id); -// } -// } -// let mut text_mapping = vec![Vec::new(); dynamic_context.text.len()]; -// for n in nodes { -// if let TemplateNodeTypeBuilder::Text(txt) = &n.node_type { -// for seg in &txt.segments { -// match seg { -// TextTemplateSegment::Static(_) => (), -// TextTemplateSegment::Dynamic(idx) => text_mapping[*idx].push(n.id), -// } -// } -// } -// } -// let mut attribute_mapping = vec![Vec::new(); dynamic_context.attributes.len()]; -// for n in nodes { -// if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { -// for (i, attr) in el.attributes.iter().enumerate() { -// match attr.value { -// TemplateAttributeValue::Static(_) => (), -// TemplateAttributeValue::Dynamic(idx) => { -// attribute_mapping[idx].push((n.id, i)); -// } -// } -// } -// } -// } -// let mut listener_mapping = Vec::new(); -// for n in nodes { -// if let TemplateNodeTypeBuilder::Element(el) = &n.node_type { -// if !el.listeners.is_empty() { -// listener_mapping.push(n.id); -// } -// } -// } - -// let root_nodes = root_nodes.iter().map(|id| { -// let raw = id.0; -// quote! { TemplateNodeId(#raw) } -// }); -// let node_mapping_quoted = node_mapping.iter().map(|op| match op { -// Some(id) => { -// let raw_id = id.0; -// quote! {Some(TemplateNodeId(#raw_id))} -// } -// None => quote! {None}, -// }); -// let text_mapping_quoted = text_mapping.iter().map(|inner| { -// let raw = inner.iter().map(|id| id.0); -// quote! {&[#(TemplateNodeId(#raw)),*]} -// }); -// let attribute_mapping_quoted = attribute_mapping.iter().map(|inner| { -// let raw = inner.iter().map(|(id, _)| id.0); -// let indecies = inner.iter().map(|(_, idx)| idx); -// quote! {&[#((TemplateNodeId(#raw), #indecies)),*]} -// }); -// let listener_mapping_quoted = listener_mapping.iter().map(|id| { -// let raw = id.0; -// quote! {TemplateNodeId(#raw)} -// }); -// let mut nodes_quoted = TokenStream::new(); -// for n in nodes { -// n.to_tokens(&mut nodes_quoted); -// quote! {,}.to_tokens(&mut nodes_quoted); -// } - -// let dynamic_path = match self.dynamic_path() { -// Some(seg) => { -// let seg = quote_owned_segment(seg); -// quote! {Some(#seg)} -// } -// None => quote! {None}, -// }; - -// let quoted = quote! { -// { -// const __NODES: dioxus::prelude::StaticTemplateNodes = &[#nodes_quoted]; -// const __TEXT_MAPPING: &'static [&'static [dioxus::prelude::TemplateNodeId]] = &[#(#text_mapping_quoted),*]; -// const __ATTRIBUTE_MAPPING: &'static [&'static [(dioxus::prelude::TemplateNodeId, usize)]] = &[#(#attribute_mapping_quoted),*]; -// const __ROOT_NODES: &'static [dioxus::prelude::TemplateNodeId] = &[#(#root_nodes),*]; -// const __NODE_MAPPING: &'static [Option] = &[#(#node_mapping_quoted),*]; -// const __NODES_WITH_LISTENERS: &'static [dioxus::prelude::TemplateNodeId] = &[#(#listener_mapping_quoted),*]; -// static __VOLITALE_MAPPING_INNER: dioxus::core::exports::once_cell::sync::Lazy> = dioxus::core::exports::once_cell::sync::Lazy::new(||{ -// // check each property to see if it is volatile -// let mut volatile = Vec::new(); -// for n in __NODES { -// if let TemplateNodeType::Element(el) = &n.node_type { -// for (i, attr) in el.attributes.iter().enumerate() { -// if attr.attribute.volatile { -// volatile.push((n.id, i)); -// } -// } -// } -// } -// volatile -// }); -// static __VOLITALE_MAPPING: &'static dioxus::core::exports::once_cell::sync::Lazy> = &__VOLITALE_MAPPING_INNER; -// static __STATIC_VOLITALE_MAPPING: dioxus::prelude::LazyStaticVec<(dioxus::prelude::TemplateNodeId, usize)> = LazyStaticVec(__VOLITALE_MAPPING); -// static __TEMPLATE: dioxus::prelude::Template = Template::Static(&StaticTemplate { -// nodes: __NODES, -// root_nodes: __ROOT_NODES, -// dynamic_mapping: StaticDynamicNodeMapping::new(__NODE_MAPPING, __TEXT_MAPPING, __ATTRIBUTE_MAPPING, __STATIC_VOLITALE_MAPPING, __NODES_WITH_LISTENERS), -// dynamic_path: #dynamic_path, -// }); - -// let __bump = __cx.bump(); -// __cx.template_ref(dioxus::prelude::TemplateId(get_line_num!()), __TEMPLATE.clone(), #dynamic_context) -// } -// }; - -// tokens.append_all(quoted) -// } -// } - -// #[derive(Default, Clone, Debug)] -// pub struct DynamicTemplateContextBuilder { -// nodes: Vec, -// text: Vec, -// attributes: Vec, -// listeners: Vec<(String, Expr)>, -// key: Option, -// } - -// impl DynamicTemplateContextBuilder { -// fn add_node(&mut self, node: BodyNode) -> usize { -// let node_id = self.nodes.len(); - -// self.nodes.push(node); - -// node_id -// } - -// fn add_text(&mut self, text: FormattedSegment) -> usize { -// let text_id = self.text.len(); - -// self.text.push(text); - -// text_id -// } - -// fn add_attr(&mut self, attr: TokenStream) -> usize { -// let attr_id = self.attributes.len(); - -// self.attributes.push(attr); - -// attr_id -// } - -// fn add_listener(&mut self, name: Ident, listener: Expr) -> usize { -// let listener_id = self.listeners.len(); - -// self.listeners.push((name.to_string(), listener)); - -// listener_id -// } - -// fn add_key(&mut self, key: TokenStream) { -// self.key = Some(key); -// } -// } - -// impl ToTokens for DynamicTemplateContextBuilder { -// fn to_tokens(&self, tokens: &mut TokenStream) { -// let nodes = &self.nodes; -// let text = &self.text; -// let attributes = &self.attributes; -// let listeners_names = self -// .listeners -// .iter() -// .map(|(n, _)| syn::parse_str::(n).expect(n)); -// let listeners_exprs = self.listeners.iter().map(|(_, e)| e); -// let key = match &self.key { -// Some(k) => quote!(Some(#k)), -// None => quote!(None), -// }; -// tokens.append_all(quote! { -// TemplateContext { -// nodes: __cx.bump().alloc([#(#nodes),*]), -// text_segments: __cx.bump().alloc([#(&*dioxus::core::exports::bumpalo::format!(in __bump, "{}", #text).into_bump_str()),*]), -// attributes: __cx.bump().alloc([#({#attributes}.into_value(__cx.bump())),*]), -// listeners: __cx.bump().alloc([#(dioxus_elements::on::#listeners_names(__cx, #listeners_exprs)),*]), -// key: #key, -// } -// }) -// } -// } - -// fn quote_owned_segment(seg: OwnedPathSeg) -> proc_macro2::TokenStream { -// let OwnedPathSeg { ops, traverse } = seg; - -// let ops = ops -// .into_iter() -// .map(|op| match op { -// UpdateOp::StoreNode(id) => { -// let id = quote_template_node_id(id); -// quote!(UpdateOp::StoreNode(#id)) -// } -// UpdateOp::InsertBefore(id) => { -// let id = quote_template_node_id(id); -// quote!(UpdateOp::InsertBefore(#id)) -// } -// UpdateOp::InsertAfter(id) => { -// let id = quote_template_node_id(id); -// quote!(UpdateOp::InsertAfter(#id)) -// } -// UpdateOp::AppendChild(id) => { -// let id = quote_template_node_id(id); -// quote!(UpdateOp::AppendChild(#id)) -// } -// }) -// .collect::>(); - -// let traverse = quote_owned_traverse(traverse); - -// quote! { -// StaticPathSeg { -// ops: &[#(#ops),*], -// traverse: #traverse, -// } -// } -// } - -// fn quote_owned_traverse(traverse: OwnedTraverse) -> proc_macro2::TokenStream { -// match traverse { -// OwnedTraverse::Halt => { -// quote! {StaticTraverse::Halt} -// } -// OwnedTraverse::FirstChild(seg) => { -// let seg = quote_owned_segment(*seg); -// quote! {StaticTraverse::FirstChild(&#seg)} -// } -// OwnedTraverse::NextSibling(seg) => { -// let seg = quote_owned_segment(*seg); -// quote! {StaticTraverse::NextSibling(&#seg)} -// } -// OwnedTraverse::Both(b) => { -// let (child, sibling) = *b; -// let child = quote_owned_segment(child); -// let sibling = quote_owned_segment(sibling); -// quote! {StaticTraverse::Both(&(#child, #sibling))} -// } -// } -// } - -// fn quote_template_node_id(id: TemplateNodeId) -> proc_macro2::TokenStream { -// let raw = id.0; -// quote! { -// TemplateNodeId(#raw) -// } -// }