From bea452c1d367e6722ac66e9c94e8a5b121f5eba8 Mon Sep 17 00:00:00 2001 From: Luke Chu Date: Wed, 30 Jun 2021 19:45:08 +0000 Subject: [PATCH 1/2] NodeId start at 1 --- packages/sycamore/src/generic_node/dom_node.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/sycamore/src/generic_node/dom_node.rs b/packages/sycamore/src/generic_node/dom_node.rs index 30066cd6c..24d1cabf0 100644 --- a/packages/sycamore/src/generic_node/dom_node.rs +++ b/packages/sycamore/src/generic_node/dom_node.rs @@ -32,9 +32,15 @@ extern "C" { #[derive(Clone, PartialEq, Eq, Hash)] struct NodeId(usize); +impl Default for NodeId { + fn default() -> Self { + Self(0) + } +} + impl NodeId { fn new_with_node(node: &Node) -> Self { - thread_local!(static NODE_ID_COUNTER: Cell = Cell::new(0)); + thread_local!(static NODE_ID_COUNTER: Cell = Cell::new(1)); // 0 is reserved for default value. let id = NODE_ID_COUNTER.with(|x| { let tmp = x.get(); From d42624278b74168809e3a0fe26f15d57662bac1e Mon Sep 17 00:00:00 2001 From: Luke Chu Date: Wed, 30 Jun 2021 19:55:42 +0000 Subject: [PATCH 2/2] Get node id lazily --- .../sycamore/src/generic_node/dom_node.rs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/sycamore/src/generic_node/dom_node.rs b/packages/sycamore/src/generic_node/dom_node.rs index 24d1cabf0..31071f292 100644 --- a/packages/sycamore/src/generic_node/dom_node.rs +++ b/packages/sycamore/src/generic_node/dom_node.rs @@ -17,10 +17,10 @@ use crate::template::Template; // TODO: remove js snippet #[wasm_bindgen(inline_js = "\ export function set_node_id(node, id) {\ - node.__sycamoreNodeId = id\ + node.$$$nodeId = id\ }\ export function get_node_id(node) {\ - return node.__sycamoreNodeId\ + return node.$$$nodeId\ }\ ")] extern "C" { @@ -29,7 +29,7 @@ extern "C" { } /// An unique id for every node. -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] struct NodeId(usize); impl Default for NodeId { @@ -57,7 +57,7 @@ impl NodeId { /// _This API requires the following crate features to be activated: `dom`_ #[derive(Clone)] pub struct DomNode { - id: NodeId, + id: Cell, node: Rc, } @@ -69,11 +69,23 @@ impl DomNode { pub fn unchecked_into(self) -> T { (*self.node).clone().unchecked_into() } + + fn get_node_id(&self) -> NodeId { + if self.id.get().0 == 0 { + // self.id not yet initialized. + if let Some(id) = get_node_id(&self.node) { + self.id.set(NodeId(id)); + } else { + self.id.set(NodeId::new_with_node(&self.node)); + } + } + self.id.get() + } } impl PartialEq for DomNode { fn eq(&self, other: &Self) -> bool { - self.id == other.id + self.node == other.node } } @@ -81,7 +93,7 @@ impl Eq for DomNode {} impl Hash for DomNode { fn hash(&self, state: &mut H) { - self.id.hash(state); + self.get_node_id().hash(state); } } @@ -127,7 +139,7 @@ impl GenericNode for DomNode { .unwrap(), ); DomNode { - id: NodeId::new_with_node(&node), + id: Default::default(), node, } } @@ -135,7 +147,7 @@ impl GenericNode for DomNode { fn text_node(text: &str) -> Self { let node = Rc::new(document().create_text_node(text).into()); DomNode { - id: NodeId::new_with_node(&node), + id: Default::default(), node, } } @@ -143,7 +155,7 @@ impl GenericNode for DomNode { fn marker() -> Self { let node = Rc::new(document().create_comment("").into()); DomNode { - id: NodeId::new_with_node(&node), + id: Default::default(), node, } } @@ -186,14 +198,14 @@ impl GenericNode for DomNode { fn parent_node(&self) -> Option { self.node.parent_node().map(|node| Self { - id: NodeId(get_node_id(&node).unwrap()), + id: Default::default(), node: Rc::new(node), }) } fn next_sibling(&self) -> Option { self.node.next_sibling().map(|node| Self { - id: NodeId(get_node_id(&node).unwrap()), + id: Default::default(), node: Rc::new(node), }) } @@ -237,7 +249,7 @@ pub fn render_to(template: impl FnOnce() -> Template, parent: &Node) { let scope = create_root(|| { insert( &DomNode { - id: NodeId::new_with_node(parent), + id: Default::default(), node: Rc::new(parent.clone()), }, template(), @@ -302,7 +314,7 @@ pub fn hydrate_to(template: impl FnOnce() -> Template, parent: &Node) { let scope = create_root(|| { insert( &DomNode { - id: NodeId::new_with_node(&parent), + id: Default::default(), node: Rc::new(parent.clone()), }, template(),