Browse Source

try to keep template indexes valid

Evan Almloff 1 year ago
parent
commit
cf04256395

+ 7 - 0
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))

+ 4 - 0
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();

+ 4 - 1
packages/core/src/nodes.rs

@@ -318,9 +318,12 @@ pub struct VComponent<'a> {
     /// The assigned Scope for this component
     pub(crate) scope: Cell<Option<ScopeId>>,
 
+    /// The bubble id assigned to the child that we need to update and drop when diffing happens
+    pub(crate) bubble_id: Cell<Option<BubbleId>>,
+
     /// 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<Option<Box<dyn AnyProps<'a> + 'a>>>,

+ 2 - 1
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(),
         })
     }