Ver código fonte

feat: more diffing iteration

Jonathan Kelley 2 anos atrás
pai
commit
67012c38df

+ 30 - 11
packages/core/src/diff.rs

@@ -1013,8 +1013,6 @@ impl<'a, 'b, R: Renderer<'b>> DiffState<'a, 'b, R> {
                 self.remove_nodes(el.children, false);
                 self.scopes.collect_garbage(id);
             }
-
-            // | VNode::Placeholder(_)
             VNode::Text(_) => {
                 let id = old
                     .try_mounted_id()
@@ -1023,7 +1021,6 @@ impl<'a, 'b, R: Renderer<'b>> DiffState<'a, 'b, R> {
                 self.mutations.replace_with(id, nodes_created as u32);
                 self.scopes.collect_garbage(id);
             }
-
             VNode::Fragment(f) => {
                 self.replace_inner(&f.children[0], nodes_created);
                 self.remove_nodes(f.children.iter().skip(1), true);
@@ -1169,9 +1166,14 @@ impl<'a, 'b, R: Renderer<'b>> DiffState<'a, 'b, R> {
                     let scope_id = el.scope.get().unwrap();
                     search_node = Some(self.scopes.root_node(scope_id));
                 }
-                VNode::Template(c) => {
-                    todo!()
-                } // VNode::Placeholder(_) => todo!(),
+                VNode::Template(template) => match &template.template.roots[0] {
+                    TemplateNode::Text(_) | TemplateNode::Element { .. } => {
+                        break Some(template.root_ids.last().unwrap().get());
+                    }
+                    TemplateNode::Dynamic(el) => {
+                        search_node = Some(&template.dynamic_nodes[*el].node)
+                    }
+                },
             }
         }
     }
@@ -1187,9 +1189,14 @@ impl<'a, 'b, R: Renderer<'b>> DiffState<'a, 'b, R> {
                     let scope = el.scope.get().expect("element to have a scope assigned");
                     search_node = Some(self.scopes.root_node(scope));
                 }
-                VNode::Template(t) => {
-                    todo!()
-                } // VNode::Placeholder(_) => todo!(),
+                VNode::Template(template) => match &template.template.roots[0] {
+                    TemplateNode::Text(_) | TemplateNode::Element { .. } => {
+                        break Some(template.root_ids[0].get());
+                    }
+                    TemplateNode::Dynamic(el) => {
+                        search_node = Some(&template.dynamic_nodes[*el].node)
+                    }
+                },
             }
         }
     }
@@ -1215,8 +1222,20 @@ impl<'a, 'b, R: Renderer<'b>> DiffState<'a, 'b, R> {
                 self.push_all_real_nodes(root)
             }
 
-            VNode::Template(c) => {
-                todo!()
+            VNode::Template(template) => {
+                let mut added = 0;
+                for (idx, root) in template.template.roots.iter().enumerate() {
+                    match root {
+                        TemplateNode::Text(_) | TemplateNode::Element { .. } => {
+                            self.mutations.push_root(template.root_ids[idx].get());
+                            added += 1;
+                        }
+                        TemplateNode::Dynamic(did) => {
+                            added += self.push_all_real_nodes(&template.dynamic_nodes[*did].node);
+                        }
+                    }
+                }
+                added
             }
         }
     }

+ 13 - 8
packages/core/src/nodes/factory.rs

@@ -238,14 +238,19 @@ impl<'a> NodeFactory<'a> {
         listeners: &'a [Listener<'a>],
         key: Option<Arguments>,
     ) -> VNode<'a> {
-        VNode::Template(self.bump.alloc(VTemplate {
-            key: None,
-            node_id: Cell::new(ElementId(0)),
-            template,
-            dynamic_nodes: self.bump.alloc([]),
-            dynamic_attrs: self.bump.alloc([]),
-            listeners,
-        }))
+        VNode::Template(
+            self.bump.alloc(VTemplate {
+                key: None,
+                node_id: Cell::new(ElementId(0)),
+                template,
+                dynamic_nodes: self.bump.alloc([]),
+                dynamic_attrs: self.bump.alloc([]),
+                listeners,
+                root_ids:
+                    bumpalo::vec![in self.bump; Cell::new(ElementId(0)); template.roots.len()]
+                        .into_bump_slice(),
+            }),
+        )
     }
 }
 

+ 3 - 4
packages/core/src/nodes/template.rs

@@ -9,10 +9,9 @@ pub struct VTemplate<'a> {
     // The ID assigned for all nodes in this template
     pub node_id: Cell<ElementId>,
 
-    // Position this template for fragments and stuff
-    pub head_id: Cell<ElementId>,
-
-    pub tail_id: Cell<ElementId>,
+    // All the IDs for the roots of this template
+    // Non-assigned IDs are set to 0
+    pub root_ids: &'a [Cell<ElementId>],
 
     pub template: Template<'static>,