From cf042563956b5c0be94bcf4ea0ff3ea651a54b16 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 31 Aug 2023 16:14:14 -0500 Subject: [PATCH] try to keep template indexes valid --- packages/core/src/arena.rs | 7 +++++++ packages/core/src/diff.rs | 4 ++++ packages/core/src/nodes.rs | 5 ++++- packages/core/src/scopes.rs | 3 ++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs index 667c7123d..52ea1f245 100644 --- a/packages/core/src/arena.rs +++ b/packages/core/src/arena.rs @@ -77,6 +77,10 @@ impl VirtualDom { pub(crate) fn update_template(&mut self, el: ElementId, node: &VNode) { let bubble_id = self.elements[el.0].unwrap(); + self.update_template_bubble(bubble_id, node) + } + + pub(crate) fn update_template_bubble(&mut self, bubble_id: BubbleId, node: &VNode) { let node: *const VNode = node as *const _; self.element_refs[bubble_id.0].template = unsafe { std::mem::transmute(node) }; } @@ -128,6 +132,9 @@ impl VirtualDom { self.drop_scope(f, true); } c.props.take(); + if let Some(bubble_id) = c.bubble_id.get() { + self.element_refs.remove(bubble_id.0); + } } DynamicNode::Fragment(nodes) => { nodes.iter().for_each(|node| self.drop_scope_inner(node)) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 5e015dbb3..b394f5e83 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -214,6 +214,10 @@ impl<'b> VirtualDom { let scope_id = left.scope.get().unwrap(); right.scope.set(Some(scope_id)); + if let Some(bubble_id) = left.bubble_id.get() { + right.bubble_id.set(Some(bubble_id)); + self.update_template_bubble(bubble_id, parent.unwrap().template); + } // copy out the box for both let old = self.scopes[scope_id.0].props.as_ref(); diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 1cf15a28c..f3a27eecf 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -318,9 +318,12 @@ pub struct VComponent<'a> { /// The assigned Scope for this component pub(crate) scope: Cell>, + /// The bubble id assigned to the child that we need to update and drop when diffing happens + pub(crate) bubble_id: Cell>, + /// The function pointer of the component, known at compile time /// - /// It is possible that components get folded at comppile time, so these shouldn't be really used as a key + /// It is possible that components get folded at compile time, so these shouldn't be really used as a key pub(crate) render_fn: *const (), pub(crate) props: RefCell + 'a>>>, diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 996529a0d..a9c8e4f1f 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -455,7 +455,8 @@ impl<'src> ScopeState { render_fn: component as *const (), static_props: P::IS_STATIC, props: RefCell::new(Some(extended)), - scope: Cell::new(None), + bubble_id: Default::default(), + scope: Default::default(), }) }