diff --git a/Cargo.toml b/Cargo.toml index a0964be7..f9a3ab82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,6 @@ with-trace = ["sauron-core/with-trace"] # lets you use node! macro to write html like code in the view with-node-macro = ["sauron-macro"] html-parser = ["sauron-html-parser"] -use-template = ["sauron-core/use-template"] use-skipdiff = ["sauron-core/use-skipdiff"] diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 96ab10ef..642f99a1 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -26,7 +26,6 @@ with-interning = [] # use caching of strings when crossing rust to js, for faste ensure-check = [] #do checking if pending msgs, patches, cmds, has been processed accordingly to ensure proper order and synchronized dom state ensure-attr-set = [] #ensure attributes is reflected into the element by explicitly calling the element corresponding methods aside fro just setting its attribute by name test-fixtures = [] #include the test-fixtures for updating the program with the supplied vdom -use-template = [] #use the templated view and building before hand use-skipdiff = [] #use skipdiff to selectively skip attributes that can not change with-trace = [] #take measurement on each section when using template to render component diff --git a/crates/core/src/dom/component.rs b/crates/core/src/dom/component.rs index c069627a..c571263c 100644 --- a/crates/core/src/dom/component.rs +++ b/crates/core/src/dom/component.rs @@ -11,8 +11,6 @@ pub use stateful_component::{stateful_component, StatefulComponent, StatefulMode #[cfg(feature = "with-dom")] mod stateful_component; -#[cfg(feature = "use-template")] -pub(crate) mod template; /// A component has a view and can update itself. /// diff --git a/crates/core/src/dom/component/template.rs b/crates/core/src/dom/component/template.rs deleted file mode 100644 index a184b9fc..00000000 --- a/crates/core/src/dom/component/template.rs +++ /dev/null @@ -1,374 +0,0 @@ -use std::{any::TypeId, cell::RefCell, collections::hash_map, collections::HashMap, rc::Rc}; - -use wasm_bindgen::JsCast; - -use crate::{ - dom::{ - document, dom_node::intern, dom_node::DomInner, Application, DomAttr, DomAttrValue, - DomNode, GroupedDomAttrValues, Program, StatelessModel, - }, - vdom::{self, Attribute, AttributeValue, Leaf}, -}; - -thread_local! { - static TEMPLATE_LOOKUP: RefCell> = RefCell::new(HashMap::new()); -} - -/// if the template is already registered, return the dom template -/// if not, create the dom template and add it -pub fn register_template(type_id: TypeId, vdom_template: &vdom::Node) -> DomNode { - if let Some(template) = lookup_template(type_id) { - template - } else { - let template = create_dom_node_no_listeners(vdom_template); - add_template(type_id, &template); - template - } -} - -pub fn add_template(type_id: TypeId, template: &DomNode) { - TEMPLATE_LOOKUP.with_borrow_mut(|map| { - if let hash_map::Entry::Vacant(e) = map.entry(type_id) { - e.insert(template.deep_clone()); - } else { - // already added - } - }) -} - -/// lookup for the template -pub fn lookup_template(type_id: TypeId) -> Option { - TEMPLATE_LOOKUP.with_borrow(|map| map.get(&type_id).map(|existing| existing.deep_clone())) -} - -#[cfg(feature = "with-debug")] -#[derive(Clone, Copy, Default, Debug)] -pub struct Section { - lookup: f64, - diffing: f64, - convert_patch: f64, - apply_patch: f64, - total: f64, - len: usize, -} - -#[allow(unused)] -#[cfg(feature = "with-debug")] -impl Section { - pub fn average(&self) -> Section { - let div = self.len as f64; - Section { - lookup: self.lookup / div, - diffing: self.diffing / div, - convert_patch: self.convert_patch / div, - apply_patch: self.apply_patch / div, - total: self.total / div, - len: self.len, - } - } - - pub fn percentile(&self) -> Section { - let div = 100.0 / self.total; - Section { - lookup: self.lookup * div, - diffing: self.diffing * div, - convert_patch: self.convert_patch * div, - apply_patch: self.apply_patch * div, - total: self.total * div, - len: self.len, - } - } -} - -#[cfg(feature = "with-trace")] -thread_local!(pub static TIME_SPENT: RefCell> = const { RefCell::new(vec![]) }); - -#[cfg(feature = "with-trace")] -pub fn add_time_trace(section: Section) { - TIME_SPENT.with_borrow_mut(|v| { - v.push(section); - }) -} - -#[allow(unused)] -#[cfg(feature = "with-debug")] -fn total(values: &[Section]) -> Section { - let len = values.len(); - let mut sum = Section::default(); - for v in values.iter() { - sum.lookup += v.lookup; - sum.diffing += v.diffing; - sum.convert_patch += v.convert_patch; - sum.apply_patch += v.apply_patch; - sum.total += v.total; - sum.len = len; - } - sum -} - -#[allow(unused)] -#[cfg(feature = "with-trace")] -pub fn total_time_spent() -> Section { - TIME_SPENT.with_borrow(|values| total(values)) -} - -#[allow(unused)] -#[cfg(feature = "with-trace")] -pub fn clear_time_spent() { - TIME_SPENT.with_borrow_mut(|values| values.clear()) -} - -pub(crate) fn create_dom_node_no_listeners(vnode: &vdom::Node) -> DomNode { - match vnode { - vdom::Node::Element(element_node) => create_element_node_no_listeners(element_node), - vdom::Node::Leaf(leaf_node) => create_leaf_node_no_listeners(leaf_node), - } -} - -fn create_fragment_node_no_listeners(nodes: &[vdom::Node]) -> DomNode { - let fragment = document().create_document_fragment(); - let dom_node = DomNode { - inner: DomInner::Fragment { - fragment, - children: Rc::new(RefCell::new(vec![])), - }, - }; - let children = nodes - .iter() - .map(|node| create_dom_node_no_listeners(node)) - .collect(); - dom_node.append_children(children); - dom_node -} - -fn create_leaf_node_no_listeners(leaf: &Leaf) -> DomNode { - match leaf { - Leaf::Text(txt) => DomNode { - inner: DomInner::Text(document().create_text_node(txt)), - }, - Leaf::Symbol(symbol) => DomNode { - inner: DomInner::Symbol(symbol.clone()), - }, - Leaf::Comment(comment) => DomNode { - inner: DomInner::Comment(document().create_comment(comment)), - }, - Leaf::DocType(_doctype) => { - panic!( - "It looks like you are using doctype in the middle of an app, - doctype is only used in rendering" - ); - } - Leaf::Fragment(nodes) => create_fragment_node_no_listeners(nodes), - // NodeList that goes here is only possible when it is the root_node, - // since node_list as children will be unrolled into as child_elements of the parent - // We need to wrap this node_list into doc_fragment since root_node is only 1 element - Leaf::NodeList(node_list) => create_fragment_node_no_listeners(node_list), - Leaf::StatefulComponent(_lc) => { - unreachable!("Component should not be created here") - } - Leaf::StatelessComponent(_comp) => { - unreachable!("stateless component should not be here") - } - Leaf::TemplatedView(_) => todo!(), - } -} - -fn create_element_node_no_listeners(elm: &vdom::Element) -> DomNode { - let document = document(); - let element = if let Some(namespace) = elm.namespace() { - document - .create_element_ns(Some(intern(namespace)), intern(elm.tag())) - .expect("Unable to create element") - } else { - document - .create_element(intern(elm.tag())) - .expect("create element") - }; - // TODO: dispatch the mount event recursively after the dom node is mounted into - // the root node - let attrs = Attribute::merge_attributes_of_same_name(elm.attributes().iter()); - let attrs = attrs - .iter() - .map(|a| convert_attr_except_listener(a)) - .collect::>(); - - for att in attrs { - set_element_dom_attr_except_listeners(&element, att); - } - - let dom_node = DomNode { - inner: DomInner::Element { - element, - listeners: Rc::new(RefCell::new(None)), - children: Rc::new(RefCell::new(vec![])), - has_mount_callback: elm.has_mount_callback(), - }, - }; - let children = elm - .children() - .iter() - .map(|child| create_dom_node_no_listeners(child)) - .collect(); - dom_node.append_children(children); - dom_node -} - -pub(crate) fn convert_attr_except_listener(attr: &Attribute) -> DomAttr { - DomAttr { - namespace: attr.namespace, - name: attr.name, - value: attr - .value - .iter() - .filter_map(|v| convert_attr_value_except_listener(v)) - .collect(), - } -} - -/// Note: Used only templates -/// set the lement with dom attr except for the event listeners -pub(crate) fn set_element_dom_attr_except_listeners(element: &web_sys::Element, attr: DomAttr) { - let attr_name = intern(attr.name); - let attr_namespace = attr.namespace; - - let GroupedDomAttrValues { - listeners: _, - plain_values, - styles, - } = attr.group_values(); - DomAttr::set_element_style(element, attr_name, styles); - DomAttr::set_element_simple_values(element, attr_name, attr_namespace, plain_values); -} - -fn convert_attr_value_except_listener( - attr_value: &AttributeValue, -) -> Option { - match attr_value { - AttributeValue::Simple(v) => Some(DomAttrValue::Simple(v.clone())), - AttributeValue::Style(v) => Some(DomAttrValue::Style(v.clone())), - AttributeValue::EventListener(_v) => None, - AttributeValue::ComponentEventListener(_v) => None, - AttributeValue::Empty => None, - } -} - -impl Program -where - APP: Application, -{ - pub(crate) fn create_stateless_component_with_template( - &self, - comp: &StatelessModel, - ) -> DomNode { - #[cfg(feature = "with-trace")] - let t1 = crate::dom::now(); - let comp_view = &comp.view; - let vdom_template = comp_view.template(); - let skip_diff = comp_view.skip_diff(); - match (vdom_template, skip_diff) { - (Some(vdom_template), Some(skip_diff)) => { - //TODO: something is wrong with the chain of elements here - //from base node to it's children - // disabling template for stateless component for now - let template = register_template(comp.type_id, &vdom_template); - let real_comp_view = comp_view.unwrap_template_ref(); - #[cfg(feature = "with-trace")] - let t2 = crate::dom::now(); - let patches = - self.create_patches_with_skip_diff(&vdom_template, real_comp_view, &skip_diff); - #[cfg(feature = "with-trace")] - let t3 = crate::dom::now(); - let dom_patches = self - .convert_patches(&template, &patches) - .expect("convert patches"); - #[cfg(feature = "with-trace")] - let t4 = crate::dom::now(); - self.apply_dom_patches(dom_patches).expect("patch template"); - #[cfg(feature = "with-trace")] - let t5 = crate::dom::now(); - - #[cfg(feature = "with-trace")] - add_time_trace(Section { - lookup: t2 - t1, - diffing: t3 - t2, - convert_patch: t4 - t3, - apply_patch: t5 - t4, - total: t5 - t1, - ..Default::default() - }); - template - } - _ => { - log::warn!( - "template and skip_diff is not found, fallback to no template and skip_diff" - ); - self.create_stateless_component(comp) - } - } - } - - pub(crate) fn create_initial_view_with_template(&self) -> DomNode { - let app_view = self.app_context.app.borrow().view(); - let vdom_template = app_view.template(); - let skip_diff = app_view.skip_diff(); - let real_view = app_view.unwrap_template(); - match (vdom_template, skip_diff) { - (Some(vdom_template), Some(skip_diff)) => { - let patches = - self.create_patches_with_skip_diff(&vdom_template, &real_view, &skip_diff); - let type_id = TypeId::of::(); - let dom_template = register_template(type_id, &vdom_template); - let dom_patches = self - .convert_patches(&dom_template, &patches) - .expect("convert patches"); - self.apply_dom_patches(dom_patches) - .expect("template patching"); - dom_template - } - _ => { - log::warn!( - "template and skip_diff is not found, fallback to no template and skip_diff" - ); - self.create_initial_view() - } - } - } -} - -impl DomNode { - pub(crate) fn deep_clone(&self) -> DomNode { - DomNode { - inner: self.inner.deep_clone(), - } - } -} - -impl DomInner { - fn deep_clone(&self) -> Self { - match self { - Self::Element { element, .. } => { - let node = element.clone_node_with_deep(true).expect("deep_clone"); - let element: web_sys::Element = node.unchecked_into(); - let child_nodes = element.child_nodes(); - let children_count = child_nodes.length(); - let children = (0..children_count) - .map(|i| { - let child = child_nodes.get(i).expect("child"); - DomNode::from(child) - }) - .collect(); - DomInner::Element { - element, - listeners: Rc::new(RefCell::new(None)), - children: Rc::new(RefCell::new(children)), - has_mount_callback: false, - } - } - Self::Text(_) => todo!(), - Self::Symbol(_) => todo!(), - Self::Comment(_) => todo!(), - Self::Fragment { .. } => todo!(), - Self::StatefulComponent { .. } => unreachable!("can not deep clone stateful component"), - } - } -} diff --git a/crates/core/src/dom/dom_node.rs b/crates/core/src/dom/dom_node.rs index 91790071..e7e464a3 100644 --- a/crates/core/src/dom/dom_node.rs +++ b/crates/core/src/dom/dom_node.rs @@ -714,14 +714,7 @@ where } } Leaf::StatelessComponent(comp) => { - #[cfg(feature = "use-template")] - { - self.create_stateless_component_with_template(comp) - } - #[cfg(not(feature = "use-template"))] - { self.create_stateless_component(comp) - } } Leaf::TemplatedView(view) => { unreachable!("template view should not be created: {:#?}", view) diff --git a/crates/core/src/dom/program.rs b/crates/core/src/dom/program.rs index f0b87286..47f3bae7 100644 --- a/crates/core/src/dom/program.rs +++ b/crates/core/src/dom/program.rs @@ -29,6 +29,16 @@ use web_sys; pub(crate) use app_context::AppContext; pub use mount_procedure::{MountAction, MountProcedure, MountTarget}; + + +thread_local! { + static CANCEL_CNT: RefCell = RefCell::new(0); +} + +thread_local! { + static UPDATE_CNT: RefCell = RefCell::new(0); +} + mod app_context; mod mount_procedure; @@ -340,9 +350,6 @@ where *self.mount_node.borrow_mut() = Some(mount_node); self.pre_mount(); - #[cfg(feature = "use-template")] - let created_node = self.create_initial_view_with_template(); - #[cfg(not(feature = "use-template"))] let created_node = self.create_initial_view(); let mount_node: DomNode = match mount_procedure.target { @@ -434,6 +441,27 @@ where /// execute DOM changes in order to reflect the APP's view into the browser representation pub fn update_dom(&mut self) -> Result<(), JsValue> { let t1 = now(); + //#[cfg(all(feature = "with-measure", feature = "with-debug"))] + if let Some(last_update) = self.last_update.borrow().as_ref() { + let frame_time = (1000_f64 / 60_f64).floor(); // 1s in 60 frames + let time_delta = t1 - last_update; + let remaining = frame_time - time_delta; + if time_delta < frame_time { + log::warn!("update is {remaining} too soon!... time_delta: {time_delta}, frame_time: {frame_time}"); + let mut program = self.clone(); + //#[cfg(feature = "with-debounce")] + crate::dom::request_timeout_callback( + move||{ + program.update_dom().unwrap(); + }, remaining.round() as i32).unwrap(); + log::info!("update is cancelled.."); + CANCEL_CNT.with_borrow_mut(|c|*c += 1); + return Ok(()) + } + } + log::info!("Doing and update..."); + UPDATE_CNT.with_borrow_mut(|c|*c += 1); + log::info!("ratio(cancelled/update): {}/{}", CANCEL_CNT.with_borrow(|c|*c), UPDATE_CNT.with_borrow(|c|*c)); // a new view is created due to the app update let view = self.app_context.view(); let t2 = now(); @@ -484,15 +512,6 @@ where weak_count, }; - #[cfg(all(feature = "with-trace", feature = "use-template"))] - { - let total = crate::dom::component::template::total_time_spent(); - log::info!("total: {:#?}", total); - log::info!("average: {:#?}", total.average()); - log::info!("percentile: {:#?}", total.percentile()); - crate::dom::component::template::clear_time_spent(); - } - if measurements.total_time > 16.0 { #[cfg(all(feature = "with-measure", feature = "with-debug"))] { @@ -500,15 +519,6 @@ where } } - #[cfg(all(feature = "with-measure", feature = "with-debug"))] - if let Some(last_update) = self.last_update.borrow().as_ref() { - let frame_time = (1000_f64 / 60_f64).floor(); // 1s in 60 frames - let time_delta = t3 - last_update; - let _remaining = frame_time - time_delta; - if time_delta < frame_time { - log::warn!("update is {_remaining} too soon!... time_delta: {time_delta}, frame_time: {frame_time}"); - } - } // tell the app about the performance measurement and only if there was patches applied #[cfg(feature = "with-measure")] diff --git a/crates/core/src/vdom/map_msg.rs b/crates/core/src/vdom/map_msg.rs index 505cf986..46a54047 100644 --- a/crates/core/src/vdom/map_msg.rs +++ b/crates/core/src/vdom/map_msg.rs @@ -4,7 +4,6 @@ use crate::vdom::Element; use crate::vdom::Leaf; use crate::vdom::Node; use crate::vdom::TemplatedView; -use std::rc::Rc; impl Node { /// map the msg of this node such that Node becomes Node @@ -130,7 +129,6 @@ impl TemplatedView { { TemplatedView { view: Box::new(self.view.map_msg(cb.clone())), - template: Rc::new(move || (self.template)().map_msg(cb.clone())), skip_diff: self.skip_diff, } } diff --git a/crates/core/src/vdom/node.rs b/crates/core/src/vdom/node.rs index 7af8fa3a..fa42a0cd 100644 --- a/crates/core/src/vdom/node.rs +++ b/crates/core/src/vdom/node.rs @@ -301,14 +301,6 @@ impl Node { .and_then(|att_values| att_values.first().and_then(|v| v.get_simple())) } - /// return the template view if this node has one - pub fn template(&self) -> Option> { - match self { - Self::Leaf(Leaf::TemplatedView(view)) => Some((view.template)()), - _ => None, - } - } - /// return the skip diff if this node has one pub fn skip_diff(&self) -> Option { match self { diff --git a/crates/core/src/vdom/templated_view.rs b/crates/core/src/vdom/templated_view.rs index 90db9b14..5b02e498 100644 --- a/crates/core/src/vdom/templated_view.rs +++ b/crates/core/src/vdom/templated_view.rs @@ -7,8 +7,6 @@ use std::rc::Rc; pub struct TemplatedView { /// The view node pub view: Box>, - /// The extracted template derived from the view node - pub template: Rc Node>, /// The skip_diff generated from the view node pub skip_diff: Rc SkipDiff>, } @@ -17,7 +15,6 @@ impl Clone for TemplatedView { fn clone(&self) -> Self { Self { view: self.view.clone(), - template: Rc::clone(&self.template), skip_diff: Rc::clone(&self.skip_diff), } } @@ -27,7 +24,6 @@ impl fmt::Debug for TemplatedView { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("TemplatedView") .field("view", &self.view) - .field("template", &(self.template)()) .field("skip_diff", &(self.skip_diff)()) .finish() } diff --git a/crates/macro/src/extract_template.rs b/crates/macro/src/extract_template.rs deleted file mode 100644 index 28f078bf..00000000 --- a/crates/macro/src/extract_template.rs +++ /dev/null @@ -1,150 +0,0 @@ -use crate::extract_skip_diff::is_literal_attribute; -use proc_macro2::TokenStream; -use quote::quote; -use rstml::node::{KeyedAttributeValue, Node, NodeAttribute, NodeBlock}; -use sauron_core::html::lookup; - -pub fn to_token_stream(input: proc_macro::TokenStream) -> TokenStream { - match rstml::parse(input) { - Ok(nodes) => from_multiple_nodes(nodes), - Err(error) => error.to_compile_error(), - } -} - -fn from_multiple_nodes(mut nodes: Vec) -> TokenStream { - let only_one_node = nodes.len() == 1; - if only_one_node { - let node_tokens = from_single_node(nodes.remove(0)); - quote! { - #node_tokens - } - } else { - let children_tokens = nodes_to_tokens(nodes); - quote! { - sauron::html::node_list([ - #children_tokens - ]) - } - } -} - -fn from_single_node(node: Node) -> TokenStream { - match node { - Node::Element(elm) => { - let open_tag = elm.open_tag; - let tag = open_tag.name.to_string(); - - let self_closing = lookup::is_self_closing(&tag); - let namespace = lookup::tag_namespace(&tag); - let static_attrs: Vec<&NodeAttribute> = open_tag - .attributes - .iter() - .filter(|a| is_literal_attribute(a)) - .collect(); - let attributes = node_attributes(&static_attrs); - let children = nodes_to_tokens(elm.children); - let ns = if let Some(namespace) = namespace { - quote! { Some(#namespace) } - } else { - quote! { None } - }; - quote! { - sauron::html::element_ns(#ns, #tag, [#attributes], [#children], #self_closing) - } - } - Node::Fragment(fragment) => from_multiple_nodes(fragment.children), - Node::Text(node_text) => { - let text = node_text.value_string(); - quote! { - sauron::Node::Leaf(sauron::vdom::Leaf::Text(#text.into())) - } - } - Node::RawText(raw_text) => { - let text = raw_text.to_token_stream_string(); - quote! { - sauron::Node::Leaf(sauron::vdom::Leaf::Text(#text.into())) - } - } - Node::Comment(comment) => { - let comment_text = comment.value.value(); - quote! { - sauron::Node::Leaf(sauron::vdom::Leaf::Comment(#comment_text.into())) - } - } - Node::Doctype(doctype) => { - let value = doctype.value.to_token_stream_string(); - quote! { - sauron::Node::Leaf(sauron::vdom::Leaf::DocType(#value.into())) - } - } - Node::Block(block) => match block { - NodeBlock::Invalid { .. } => { - quote! { - compile_error!("invalid block: {:?}", #block); - } - } - NodeBlock::ValidBlock(_block) => { - quote! { - sauron::html::node_list([]) - } - } - }, - } -} - -fn nodes_to_tokens(nodes: Vec) -> TokenStream { - let mut tokens = TokenStream::new(); - for node in nodes { - let node_token = from_single_node(node); - tokens.extend(quote! { - #node_token, - }); - } - - tokens -} - -fn node_attributes(attributes: &[&NodeAttribute]) -> TokenStream { - let mut tokens = TokenStream::new(); - for attr in attributes { - let attr_token = attribute_to_tokens(attr); - tokens.extend(quote! { - #attr_token, - }); - } - tokens -} - -fn attribute_to_tokens(attribute: &NodeAttribute) -> TokenStream { - match attribute { - NodeAttribute::Block(block) => { - quote! { - #[allow(unused_braces)] - #block - } - } - NodeAttribute::Attribute(attribute) => { - let attr = attribute.key.to_string(); - let value = &attribute.possible_value; - match value { - KeyedAttributeValue::Binding(binding) => { - quote! { - compile_error!("Function binding is not supported! {:?}",#binding) - } - } - KeyedAttributeValue::Value(value) => { - let value = &value.value; - quote! { - #[allow(unused_braces)] - sauron::html::attributes::attr(#attr, #value) - } - } - KeyedAttributeValue::None => { - quote! { - sauron::html::attributes::empty_attr() - } - } - } - } - } -} diff --git a/crates/macro/src/lib.rs b/crates/macro/src/lib.rs index de6e4814..ad38263f 100644 --- a/crates/macro/src/lib.rs +++ b/crates/macro/src/lib.rs @@ -14,7 +14,6 @@ use quote::ToTokens; mod extract_skip_diff; -mod extract_template; mod jss; mod node; mod view; @@ -210,25 +209,6 @@ pub fn extract_skip_diff(input: proc_macro::TokenStream) -> proc_macro::TokenStr extract_skip_diff::to_token_stream(input).into() } -/// extract template by including only attributes and elements that is static str -/// ```rust -/// use sauron_macro::extract_template; -/// use sauron::*; -/// -/// let template: Node<()> = extract_template!{
    }; -/// assert_eq!(template, node!{
      }, "same template as the view"); -/// -/// let template: Node<()> = extract_template!{

      Hello world!

      }; -/// assert_eq!(template, node!{

      Hello world!

      }, "raw texts"); -/// -/// let name = "bob"; -/// let template: Node<()> = extract_template!{

      {text(format!("Hello {}!", name))}

      }; -/// assert_eq!(template, node!{

      }, "formated text"); -/// ``` -#[proc_macro] -pub fn extract_template(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - extract_template::to_token_stream(input).into() -} /// build a css string /// diff --git a/crates/macro/src/view.rs b/crates/macro/src/view.rs index 0ca7b0ac..7a34e340 100644 --- a/crates/macro/src/view.rs +++ b/crates/macro/src/view.rs @@ -7,12 +7,10 @@ use quote::quote; pub fn to_token_stream(input: proc_macro::TokenStream) -> TokenStream { let view = crate::node::to_token_stream(input.clone()); let skip_diff = crate::extract_skip_diff::to_token_stream(input.clone()); - let template = crate::extract_template::to_token_stream(input); quote! { fn view(&self) -> Node { ::sauron::Node::Leaf(sauron::vdom::Leaf::TemplatedView(sauron::vdom::TemplatedView{ view: Box::new(#view), - template: std::rc::Rc::new(||#template), skip_diff: std::rc::Rc::new(||#skip_diff), })) } diff --git a/examples/js-performance-benchmark-sauron/Cargo.toml b/examples/js-performance-benchmark-sauron/Cargo.toml index 9ea696ae..c7cead2b 100644 --- a/examples/js-performance-benchmark-sauron/Cargo.toml +++ b/examples/js-performance-benchmark-sauron/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] rand = { version = "0.8.5", features = ["small_rng"] } getrandom = { version = "0.2.7", features = ["js"] } -sauron = { path = "../../../sauron", features = ["with-debug", "with-measure", "use-template", "use-skipdiff"] } +sauron = { path = "../../../sauron", features = ["with-debug", "with-measure", "use-skipdiff"] } log = "0.4" console_log = "0.2" console_error_panic_hook = "0.1" diff --git a/src/lib.rs b/src/lib.rs index 633e7d60..7fae66c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,6 @@ pub mod prelude { pub use sauron_core::*; pub use sauron_macro::extract_skip_diff; - pub use sauron_macro::extract_template; pub use sauron_macro::view; #[cfg(feature = "with-node-macro")]