merge master
This commit is contained in:
1 parent
67921cacc3
commit
e5a5850354
105 files changed
+1415
-2106
No files matched your search
@@ -81,12 +81,12 @@ impl VirtualDom {
|
||||
self.ensure_drop_safety(id);
|
||||
|
||||
if let Some(root) = self.scopes[id.0].as_ref().try_root_node() {
|
||||
if let RenderReturn::Sync(Ok(node)) = unsafe { root.extend_lifetime_ref() } {
|
||||
if let RenderReturn::Sync(Some(node)) = unsafe { root.extend_lifetime_ref() } {
|
||||
self.drop_scope_inner(node)
|
||||
}
|
||||
}
|
||||
if let Some(root) = unsafe { self.scopes[id.0].as_ref().previous_frame().try_load_node() } {
|
||||
if let RenderReturn::Sync(Ok(node)) = unsafe { root.extend_lifetime_ref() } {
|
||||
if let RenderReturn::Sync(Some(node)) = unsafe { root.extend_lifetime_ref() } {
|
||||
self.drop_scope_inner(node)
|
||||
}
|
||||
}
|
||||
@@ -115,10 +115,14 @@ impl VirtualDom {
|
||||
nodes.iter().for_each(|node| self.drop_scope_inner(node))
|
||||
}
|
||||
DynamicNode::Placeholder(t) => {
|
||||
self.try_reclaim(t.id.get().unwrap());
|
||||
if let Some(id) = t.id.get() {
|
||||
self.try_reclaim(id);
|
||||
}
|
||||
}
|
||||
DynamicNode::Text(t) => {
|
||||
self.try_reclaim(t.id.get().unwrap());
|
||||
if let Some(id) = t.id.get() {
|
||||
self.try_reclaim(id);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -356,8 +356,8 @@ impl<'b> VirtualDom {
|
||||
use RenderReturn::*;
|
||||
|
||||
match return_nodes {
|
||||
Sync(Ok(t)) => self.mount_component(scope, template, t, idx),
|
||||
Sync(Err(_e)) => todo!("Propogate error upwards"),
|
||||
Sync(Some(t)) => self.mount_component(scope, template, t, idx),
|
||||
Sync(None) => todo!("Propogate error upwards"),
|
||||
Async(_) => self.mount_component_placeholder(template, idx, scope),
|
||||
}
|
||||
}
|
||||
|
||||
+118
-68
@@ -33,32 +33,35 @@ impl<'b> VirtualDom {
|
||||
use RenderReturn::{Async, Sync};
|
||||
|
||||
match (old, new) {
|
||||
(Sync(Ok(l)), Sync(Ok(r))) => self.diff_node(l, r),
|
||||
(Sync(Some(l)), Sync(Some(r))) => self.diff_node(l, r),
|
||||
|
||||
// Err cases
|
||||
(Sync(Ok(l)), Sync(Err(e))) => self.diff_ok_to_err(l, e),
|
||||
(Sync(Err(e)), Sync(Ok(r))) => self.diff_err_to_ok(e, r),
|
||||
(Sync(Err(_eo)), Sync(Err(_en))) => { /* nothing */ }
|
||||
(Sync(Some(l)), Sync(None)) => self.diff_ok_to_err(l),
|
||||
(Sync(None), Sync(Some(r))) => self.diff_err_to_ok(r),
|
||||
(Sync(None), Sync(None)) => { /* nothing */ }
|
||||
|
||||
// Async
|
||||
(Sync(Ok(_l)), Async(_)) => todo!(),
|
||||
(Sync(Err(_e)), Async(_)) => todo!(),
|
||||
(Async(_), Sync(Ok(_r))) => todo!(),
|
||||
(Async(_), Sync(Err(_e))) => { /* nothing */ }
|
||||
(Sync(Some(_l)), Async(_)) => todo!(),
|
||||
(Sync(None), Async(_)) => todo!(),
|
||||
(Async(_), Sync(Some(_r))) => todo!(),
|
||||
(Async(_), Sync(None)) => { /* nothing */ }
|
||||
(Async(_), Async(_)) => { /* nothing */ }
|
||||
};
|
||||
}
|
||||
self.scope_stack.pop();
|
||||
}
|
||||
|
||||
fn diff_ok_to_err(&mut self, _l: &'b VNode<'b>, _e: &anyhow::Error) {}
|
||||
fn diff_err_to_ok(&mut self, _e: &anyhow::Error, _l: &'b VNode<'b>) {}
|
||||
fn diff_ok_to_err(&mut self, _l: &'b VNode<'b>) {}
|
||||
fn diff_err_to_ok(&mut self, _l: &'b VNode<'b>) {}
|
||||
|
||||
fn diff_node(&mut self, left_template: &'b VNode<'b>, right_template: &'b VNode<'b>) {
|
||||
// If hot reloading is enabled, we need to make sure we're using the latest template
|
||||
#[cfg(debug_assertions)]
|
||||
if let Some(template) = self.templates.get(right_template.template.get().name) {
|
||||
right_template.template.set(*template);
|
||||
let prev_template = right_template.template.get();
|
||||
if *template != prev_template {
|
||||
right_template.template.set(*template);
|
||||
}
|
||||
}
|
||||
|
||||
// If the templates are the same, we don't need to do anything, nor do we want to
|
||||
@@ -161,22 +164,7 @@ impl<'b> VirtualDom {
|
||||
|
||||
// Replace components that have different render fns
|
||||
if left.render_fn != right.render_fn {
|
||||
let created = self.create_component_node(right_template, right, idx);
|
||||
let head = unsafe {
|
||||
self.scopes[left.scope.get().unwrap().0]
|
||||
.root_node()
|
||||
.extend_lifetime_ref()
|
||||
};
|
||||
let last = match head {
|
||||
RenderReturn::Sync(Ok(node)) => self.find_last_element(node),
|
||||
_ => todo!(),
|
||||
};
|
||||
self.mutations.push(Mutation::InsertAfter {
|
||||
id: last,
|
||||
m: created,
|
||||
});
|
||||
self.remove_component_node(left, true);
|
||||
return;
|
||||
return self.replace_vcomponent(right_template, right, idx, left);
|
||||
}
|
||||
|
||||
// Make sure the new vcomponent has the right scopeid associated to it
|
||||
@@ -209,6 +197,26 @@ impl<'b> VirtualDom {
|
||||
});
|
||||
}
|
||||
|
||||
fn replace_vcomponent(
|
||||
&mut self,
|
||||
right_template: &'b VNode<'b>,
|
||||
right: &'b VComponent<'b>,
|
||||
idx: usize,
|
||||
left: &'b VComponent<'b>,
|
||||
) {
|
||||
let m = self.create_component_node(right_template, right, idx);
|
||||
|
||||
self.remove_component_node(left, true);
|
||||
|
||||
// We want to optimize the replace case to use one less mutation if possible
|
||||
// Since mutations are done in reverse, the last node removed will be the first in the stack
|
||||
// Instead of *just* removing it, we can use the replace mutation
|
||||
match self.mutations.edits.pop().unwrap() {
|
||||
Mutation::Remove { id } => self.mutations.push(Mutation::ReplaceWith { id, m }),
|
||||
at => panic!("Expected remove mutation from remove_node {:#?}", at),
|
||||
};
|
||||
}
|
||||
|
||||
/// Lightly diff the two templates, checking only their roots.
|
||||
///
|
||||
/// The goal here is to preserve any existing component state that might exist. This is to preserve some React-like
|
||||
@@ -681,7 +689,7 @@ impl<'b> VirtualDom {
|
||||
Component(comp) => {
|
||||
let scope = comp.scope.get().unwrap();
|
||||
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
|
||||
RenderReturn::Sync(Ok(node)) => self.push_all_real_nodes(node),
|
||||
RenderReturn::Sync(Some(node)) => self.push_all_real_nodes(node),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
@@ -719,11 +727,21 @@ impl<'b> VirtualDom {
|
||||
fn replace(&mut self, left: &'b VNode<'b>, right: impl IntoIterator<Item = &'b VNode<'b>>) {
|
||||
let m = self.create_children(right);
|
||||
|
||||
let id = self.find_last_element(left);
|
||||
|
||||
self.mutations.push(Mutation::InsertAfter { id, m });
|
||||
let pre_edits = self.mutations.edits.len();
|
||||
|
||||
self.remove_node(left, true);
|
||||
|
||||
// We should always have a remove mutation
|
||||
// Eventually we don't want to generate placeholders, so this might not be true. But it's true today
|
||||
assert!(self.mutations.edits.len() > pre_edits);
|
||||
|
||||
// We want to optimize the replace case to use one less mutation if possible
|
||||
// Since mutations are done in reverse, the last node removed will be the first in the stack
|
||||
// Instead of *just* removing it, we can use the replace mutation
|
||||
match self.mutations.edits.pop().unwrap() {
|
||||
Mutation::Remove { id } => self.mutations.push(Mutation::ReplaceWith { id, m }),
|
||||
_ => panic!("Expected remove mutation from remove_node"),
|
||||
};
|
||||
}
|
||||
|
||||
fn node_to_placeholder(&mut self, l: &'b [VNode<'b>], r: &'b VPlaceholder) {
|
||||
@@ -732,24 +750,45 @@ impl<'b> VirtualDom {
|
||||
|
||||
r.id.set(Some(placeholder));
|
||||
|
||||
let id = self.find_last_element(&l[0]);
|
||||
|
||||
self.mutations
|
||||
.push(Mutation::CreatePlaceholder { id: placeholder });
|
||||
|
||||
self.mutations.push(Mutation::InsertAfter { id, m: 1 });
|
||||
|
||||
self.remove_nodes(l);
|
||||
|
||||
// We want to optimize the replace case to use one less mutation if possible
|
||||
// Since mutations are done in reverse, the last node removed will be the first in the stack
|
||||
// Instead of *just* removing it, we can use the replace mutation
|
||||
match self.mutations.edits.pop().unwrap() {
|
||||
Mutation::Remove { id } => self.mutations.push(Mutation::ReplaceWith { id, m: 1 }),
|
||||
_ => panic!("Expected remove mutation from remove_node"),
|
||||
};
|
||||
}
|
||||
|
||||
/// Remove these nodes from the dom
|
||||
/// Wont generate mutations for the inner nodes
|
||||
fn remove_nodes(&mut self, nodes: &'b [VNode<'b>]) {
|
||||
nodes.iter().for_each(|node| self.remove_node(node, true));
|
||||
nodes
|
||||
.iter()
|
||||
.rev()
|
||||
.for_each(|node| self.remove_node(node, true));
|
||||
}
|
||||
|
||||
fn remove_node(&mut self, node: &'b VNode<'b>, gen_muts: bool) {
|
||||
// Clean up any attributes that have claimed a static node as dynamic for mount/unmounta
|
||||
// Will not generate mutations!
|
||||
self.reclaim_attributes(node);
|
||||
|
||||
// Remove the nested dynamic nodes
|
||||
// We don't generate mutations for these, as they will be removed by the parent (in the next line)
|
||||
// But we still need to make sure to reclaim them from the arena and drop their hooks, etc
|
||||
self.remove_nested_dyn_nodes(node);
|
||||
|
||||
// Clean up the roots, assuming we need to generate mutations for these
|
||||
// This is done last in order to preserve Node ID reclaim order (reclaim in reverse order of claim)
|
||||
self.reclaim_roots(node, gen_muts);
|
||||
}
|
||||
|
||||
fn reclaim_roots(&mut self, node: &VNode, gen_muts: bool) {
|
||||
for (idx, _) in node.template.get().roots.iter().enumerate() {
|
||||
if let Some(dy) = node.dynamic_root(idx) {
|
||||
self.remove_dynamic_node(dy, gen_muts);
|
||||
@@ -761,17 +800,9 @@ impl<'b> VirtualDom {
|
||||
self.reclaim(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (idx, dyn_node) in node.dynamic_nodes.iter().enumerate() {
|
||||
// Roots are cleaned up automatically above
|
||||
if node.template.get().node_paths[idx].len() == 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.remove_dynamic_node(dyn_node, false);
|
||||
}
|
||||
|
||||
// we clean up nodes with dynamic attributes, provided the node is unique and not a root node
|
||||
fn reclaim_attributes(&mut self, node: &VNode) {
|
||||
let mut id = None;
|
||||
for (idx, attr) in node.dynamic_attrs.iter().enumerate() {
|
||||
// We'll clean up the root nodes either way, so don't worry
|
||||
@@ -791,49 +822,69 @@ impl<'b> VirtualDom {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_nested_dyn_nodes(&mut self, node: &VNode) {
|
||||
for (idx, dyn_node) in node.dynamic_nodes.iter().enumerate() {
|
||||
// Roots are cleaned up automatically above
|
||||
if node.template.get().node_paths[idx].len() == 1 {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.remove_dynamic_node(dyn_node, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_dynamic_node(&mut self, node: &DynamicNode, gen_muts: bool) {
|
||||
match node {
|
||||
Component(comp) => self.remove_component_node(comp, gen_muts),
|
||||
Text(t) => self.remove_text_node(t),
|
||||
Placeholder(t) => self.remove_placeholder(t),
|
||||
Text(t) => self.remove_text_node(t, gen_muts),
|
||||
Placeholder(t) => self.remove_placeholder(t, gen_muts),
|
||||
Fragment(nodes) => nodes
|
||||
.iter()
|
||||
.for_each(|node| self.remove_node(node, gen_muts)),
|
||||
};
|
||||
}
|
||||
|
||||
fn remove_placeholder(&mut self, t: &VPlaceholder) {
|
||||
fn remove_placeholder(&mut self, t: &VPlaceholder, gen_muts: bool) {
|
||||
if let Some(id) = t.id.take() {
|
||||
if gen_muts {
|
||||
self.mutations.push(Mutation::Remove { id });
|
||||
}
|
||||
self.reclaim(id)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_text_node(&mut self, t: &VText) {
|
||||
fn remove_text_node(&mut self, t: &VText, gen_muts: bool) {
|
||||
if let Some(id) = t.id.take() {
|
||||
if gen_muts {
|
||||
self.mutations.push(Mutation::Remove { id });
|
||||
}
|
||||
self.reclaim(id)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_component_node(&mut self, comp: &VComponent, gen_muts: bool) {
|
||||
if let Some(scope) = comp.scope.take() {
|
||||
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
|
||||
RenderReturn::Sync(Ok(t)) => self.remove_node(t, gen_muts),
|
||||
_ => todo!("cannot handle nonstandard nodes"),
|
||||
};
|
||||
let scope = comp.scope.take().unwrap();
|
||||
|
||||
let props = self.scopes[scope.0].props.take();
|
||||
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
|
||||
RenderReturn::Sync(Some(t)) => {
|
||||
println!("Removing component node sync {:?}", gen_muts);
|
||||
self.remove_node(t, gen_muts)
|
||||
}
|
||||
_ => todo!("cannot handle nonstandard nodes"),
|
||||
};
|
||||
|
||||
self.dirty_scopes.remove(&DirtyScope {
|
||||
height: self.scopes[scope.0].height,
|
||||
id: scope,
|
||||
});
|
||||
let props = self.scopes[scope.0].props.take();
|
||||
|
||||
*comp.props.borrow_mut() = unsafe { std::mem::transmute(props) };
|
||||
self.dirty_scopes.remove(&DirtyScope {
|
||||
height: self.scopes[scope.0].height,
|
||||
id: scope,
|
||||
});
|
||||
|
||||
// make sure to wipe any of its props and listeners
|
||||
self.ensure_drop_safety(scope);
|
||||
self.scopes.remove(scope.0);
|
||||
}
|
||||
*comp.props.borrow_mut() = unsafe { std::mem::transmute(props) };
|
||||
|
||||
// make sure to wipe any of its props and listeners
|
||||
self.ensure_drop_safety(scope);
|
||||
self.scopes.remove(scope.0);
|
||||
}
|
||||
|
||||
fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId {
|
||||
@@ -845,7 +896,7 @@ impl<'b> VirtualDom {
|
||||
Some(Component(comp)) => {
|
||||
let scope = comp.scope.get().unwrap();
|
||||
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
|
||||
RenderReturn::Sync(Ok(t)) => self.find_first_element(t),
|
||||
RenderReturn::Sync(Some(t)) => self.find_first_element(t),
|
||||
_ => todo!("cannot handle nonstandard nodes"),
|
||||
}
|
||||
}
|
||||
@@ -861,7 +912,7 @@ impl<'b> VirtualDom {
|
||||
Some(Component(comp)) => {
|
||||
let scope = comp.scope.get().unwrap();
|
||||
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
|
||||
RenderReturn::Sync(Ok(t)) => self.find_last_element(t),
|
||||
RenderReturn::Sync(Some(t)) => self.find_last_element(t),
|
||||
_ => todo!("cannot handle nonstandard nodes"),
|
||||
}
|
||||
}
|
||||
@@ -889,7 +940,6 @@ fn matching_components<'a>(
|
||||
left: &'a VNode<'a>,
|
||||
right: &'a VNode<'a>,
|
||||
) -> Option<Vec<(&'a VComponent<'a>, &'a VComponent<'a>)>> {
|
||||
return None;
|
||||
let left_template = left.template.get();
|
||||
let right_template = right.template.get();
|
||||
if left_template.roots.len() != right_template.roots.len() {
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::ScopeId;
|
||||
/// A boundary that will capture any errors from child components
|
||||
#[allow(dead_code)]
|
||||
pub struct ErrorBoundary {
|
||||
error: RefCell<Option<(anyhow::Error, ScopeId)>>,
|
||||
error: RefCell<Option<ScopeId>>,
|
||||
id: ScopeId,
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ use crate::innerlude::*;
|
||||
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
|
||||
#[allow(non_upper_case_globals, non_snake_case)]
|
||||
pub fn Fragment<'a>(cx: Scope<'a, FragmentProps<'a>>) -> Element {
|
||||
let children = cx.props.0.as_ref().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
Ok(VNode {
|
||||
let children = cx.props.0.as_ref()?;
|
||||
Some(VNode {
|
||||
key: children.key,
|
||||
parent: children.parent,
|
||||
template: children.template.clone(),
|
||||
@@ -95,7 +95,7 @@ impl<'a> Properties for FragmentProps<'a> {
|
||||
type Builder = FragmentBuilder<'a, false>;
|
||||
const IS_STATIC: bool = false;
|
||||
fn builder() -> Self::Builder {
|
||||
FragmentBuilder(VNode::empty())
|
||||
FragmentBuilder(None)
|
||||
}
|
||||
unsafe fn memoize(&self, _other: &Self) -> bool {
|
||||
false
|
||||
|
||||
@@ -34,10 +34,10 @@ pub(crate) mod innerlude {
|
||||
pub use crate::scopes::*;
|
||||
pub use crate::virtual_dom::*;
|
||||
|
||||
/// An [`Element`] is a possibly-errored [`VNode`] created by calling `render` on [`Scope`] or [`ScopeState`].
|
||||
/// An [`Element`] is a possibly-none [`VNode`] created by calling `render` on [`Scope`] or [`ScopeState`].
|
||||
///
|
||||
/// An Errored [`Element`] will propagate the error to the nearest error boundary.
|
||||
pub type Element<'a> = Result<VNode<'a>, anyhow::Error>;
|
||||
pub type Element<'a> = Option<VNode<'a>>;
|
||||
|
||||
/// A [`Component`] is a function that takes a [`Scope`] and returns an [`Element`].
|
||||
///
|
||||
|
||||
@@ -46,7 +46,7 @@ pub struct VNode<'a> {
|
||||
|
||||
/// The IDs for the roots of this template - to be used when moving the template around and removing it from
|
||||
/// the actual Dom
|
||||
pub root_ids: &'a [Cell<Option<ElementId>>],
|
||||
pub root_ids: bumpalo::collections::Vec<'a, Cell<Option<ElementId>>>,
|
||||
|
||||
/// The dynamic parts of the template
|
||||
pub dynamic_nodes: &'a [DynamicNode<'a>],
|
||||
@@ -58,10 +58,10 @@ pub struct VNode<'a> {
|
||||
impl<'a> VNode<'a> {
|
||||
/// Create a template with no nodes that will be skipped over during diffing
|
||||
pub fn empty() -> Element<'a> {
|
||||
Ok(VNode {
|
||||
Some(VNode {
|
||||
key: None,
|
||||
parent: None,
|
||||
root_ids: &[],
|
||||
root_ids: bumpalo::collections::Vec::new_in(&Bump::new()),
|
||||
dynamic_nodes: &[],
|
||||
dynamic_attrs: &[],
|
||||
template: Cell::new(Template {
|
||||
@@ -525,16 +525,6 @@ impl<'a> IntoDynNode<'a> for DynamicNode<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// An element that's an error is currently lost into the ether
|
||||
impl<'a> IntoDynNode<'a> for Element<'a> {
|
||||
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||
match self {
|
||||
Ok(val) => val.into_vnode(_cx),
|
||||
_ => DynamicNode::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
|
||||
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||
match self {
|
||||
@@ -547,7 +537,7 @@ impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
|
||||
impl<'a> IntoDynNode<'a> for &Element<'a> {
|
||||
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||
match self.as_ref() {
|
||||
Ok(val) => val.clone().into_vnode(_cx),
|
||||
Some(val) => val.clone().into_vnode(_cx),
|
||||
_ => DynamicNode::default(),
|
||||
}
|
||||
}
|
||||
@@ -601,7 +591,7 @@ impl<'a> IntoTemplate<'a> for VNode<'a> {
|
||||
impl<'a> IntoTemplate<'a> for Element<'a> {
|
||||
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
|
||||
match self {
|
||||
Ok(val) => val.into_template(_cx),
|
||||
Some(val) => val.into_template(_cx),
|
||||
_ => VNode::empty().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ impl VirtualDom {
|
||||
|
||||
fiber.waiting_on.borrow_mut().remove(&id);
|
||||
|
||||
if let RenderReturn::Sync(Ok(template)) = ret {
|
||||
if let RenderReturn::Sync(Some(template)) = ret {
|
||||
let mutations_ref = &mut fiber.mutations.borrow_mut();
|
||||
let mutations = &mut **mutations_ref;
|
||||
let template: &VNode = unsafe { std::mem::transmute(template) };
|
||||
|
||||
@@ -390,7 +390,7 @@ impl<'src> ScopeState {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(element)
|
||||
Some(element)
|
||||
}
|
||||
|
||||
/// Create a dynamic text node using [`Arguments`] and the [`ScopeState`]'s internal [`Bump`] allocator
|
||||
|
||||
@@ -463,7 +463,7 @@ impl VirtualDom {
|
||||
self.register_template(template);
|
||||
// iterating a slab is very inefficient, but this is a rare operation that will only happen during development so it's fine
|
||||
for (_, scope) in &self.scopes {
|
||||
if let Some(RenderReturn::Sync(Ok(sync))) = scope.try_root_node() {
|
||||
if let Some(RenderReturn::Sync(Some(sync))) = scope.try_root_node() {
|
||||
if sync.template.get().name == template.name {
|
||||
let height = scope.height;
|
||||
self.dirty_scopes.insert(DirtyScope {
|
||||
@@ -498,7 +498,7 @@ impl VirtualDom {
|
||||
pub fn rebuild(&mut self) -> Mutations {
|
||||
match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } {
|
||||
// Rebuilding implies we append the created elements to the root
|
||||
RenderReturn::Sync(Ok(node)) => {
|
||||
RenderReturn::Sync(Some(node)) => {
|
||||
let m = self.create_scope(ScopeId(0), node);
|
||||
self.mutations.edits.push(Mutation::AppendChildren {
|
||||
id: ElementId(0),
|
||||
@@ -506,7 +506,7 @@ impl VirtualDom {
|
||||
});
|
||||
}
|
||||
// If an error occurs, we should try to render the default error component and context where the error occured
|
||||
RenderReturn::Sync(Err(e)) => panic!("Cannot catch errors during rebuild {:?}", e),
|
||||
RenderReturn::Sync(None) => panic!("Cannot catch errors during rebuild"),
|
||||
RenderReturn::Async(_) => unreachable!("Root scope cannot be an async component"),
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user