diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index b2be8e60e..3cbfe9440 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -272,9 +272,9 @@ impl<'b> VirtualDom { use DynamicNode::*; match node { Text(text) => self.create_dynamic_text(template, text, idx), - Fragment(frag) => self.create_fragment(frag), Placeholder(frag) => self.create_placeholder(frag, template, idx), Component(component) => self.create_component_node(template, component, idx), + Fragment(frag) => frag.iter().map(|child| self.create(child)).sum(), } } @@ -326,45 +326,46 @@ impl<'b> VirtualDom { 0 } - pub(crate) fn create_fragment(&mut self, nodes: &'b [VNode<'b>]) -> usize { - nodes.iter().map(|child| self.create(child)).sum() - } - pub(super) fn create_component_node( &mut self, template: &'b VNode<'b>, component: &'b VComponent<'b>, idx: usize, ) -> usize { - let scope = match component.props.take() { - Some(props) => { - let unbounded_props: Box = unsafe { std::mem::transmute(props) }; - let scope = self.new_scope(unbounded_props, component.name); - scope.id - } - - // Component is coming back, it probably still exists, right? - None => component.scope.get().unwrap(), - }; - - component.scope.set(Some(scope)); - - let return_nodes = unsafe { self.run_scope(scope).extend_lifetime_ref() }; - use RenderReturn::*; - match return_nodes { - Ready(t) => self.mount_component(scope, template, t, idx), - Aborted(t) => { - self.mutations - .push(Mutation::CreatePlaceholder { id: ElementId(999) }); + // Load up a ScopeId for this vcomponent + let scope = self.load_scope_from_vcomponent(component); - 1 - } + match unsafe { self.run_scope(scope).extend_lifetime_ref() } { + Ready(t) => self.mount_component(scope, template, t, idx), + Aborted(t) => self.mount_aborted(template, t), Async(_) => self.mount_component_placeholder(template, idx, scope), } } + fn mount_aborted(&mut self, parent: &'b VNode<'b>, placeholder: &VPlaceholder) -> usize { + let id = self.next_element(parent, &[]); + + self.mutations.push(Mutation::CreatePlaceholder { id }); + + placeholder.id.set(Some(id)); + + 1 + } + + /// Load a scope from a vcomponent. If the props don't exist, that means the component is currently "live" + fn load_scope_from_vcomponent(&mut self, component: &VComponent) -> ScopeId { + component + .props + .take() + .map(|props| { + let unbounded_props: Box = unsafe { std::mem::transmute(props) }; + self.new_scope(unbounded_props, component.name).id + }) + .unwrap_or_else(|| component.scope.get().unwrap()) + } + fn mount_component( &mut self, scope: ScopeId, diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index e7c8c0e13..8e7a372af 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -27,8 +27,6 @@ pub enum RenderReturn<'a> { /// /// In its place we've produced a placeholder to locate its spot in the dom when /// it recovers. - /// - /// The old nodes are kept around Aborted(VPlaceholder), /// An ongoing future that will resolve to a [`Element`] diff --git a/packages/core/tests/error_boundary.rs b/packages/core/tests/error_boundary.rs index 7cc1122cd..7dbfca343 100644 --- a/packages/core/tests/error_boundary.rs +++ b/packages/core/tests/error_boundary.rs @@ -6,16 +6,24 @@ fn catches_panic() { let mut dom = VirtualDom::new(app); let a = dom.rebuild(); + + dbg!(a); } fn app(cx: Scope) -> Element { cx.render(rsx! { div { - PanicChild {} + h1 { "Title" } + + NoneChild {} } }) } +fn NoneChild(cx: Scope) -> Element { + None +} + fn PanicChild(cx: Scope) -> Element { panic!("Rendering panicked for whatever reason");