switch to bubble ids on vnodes to fix nodes under fragments pointing to an invalid parent

This commit is contained in:
Evan Almloff committed 2023-09-11 15:55:58 -05:00
1 parent 992ac4a3fb
commit 35b643e23f
9 files changed
+159 -189

No files matched your search

+32 -6
View File
@@ -1,4 +1,4 @@
use crate::innerlude::BubbleId;
use crate::innerlude::{ElementRef, VNodeId};
use crate::{
any_props::AnyProps, arena::ElementId, Element, Event, LazyNodes, ScopeId, ScopeState,
};
@@ -48,7 +48,10 @@ pub struct VNode<'a> {
pub key: Option<&'a str>,
/// When rendered, this template will be linked to its parent manually
pub parent: Cell<Option<BubbleId>>,
pub(crate) parent: Cell<Option<ElementRef>>,
/// The bubble id assigned to the child that we need to update and drop when diffing happens
pub(crate) stable_id: Cell<Option<VNodeId>>,
/// The static nodes and static descriptor of the template
pub template: Cell<Template<'static>>,
@@ -70,6 +73,7 @@ impl<'a> VNode<'a> {
Some(VNode {
key: None,
parent: Default::default(),
stable_id: Default::default(),
root_ids: RefCell::new(bumpalo::collections::Vec::new_in(cx.bump())),
dynamic_nodes: &[],
dynamic_attrs: &[],
@@ -82,6 +86,30 @@ impl<'a> VNode<'a> {
})
}
/// Create a new VNode
pub fn new(
key: Option<&'a str>,
template: Template<'static>,
root_ids: bumpalo::collections::Vec<'a, ElementId>,
dynamic_nodes: &'a [DynamicNode<'a>],
dynamic_attrs: &'a [Attribute<'a>],
) -> Self {
Self {
key,
parent: Cell::new(None),
stable_id: Cell::new(None),
template: Cell::new(template),
root_ids: RefCell::new(root_ids),
dynamic_nodes,
dynamic_attrs,
}
}
/// Get the stable id of this node used for bubbling events
pub(crate) fn stable_id(&self) -> Option<VNodeId> {
self.stable_id.get()
}
/// Load a dynamic root at the given index
///
/// Returns [`None`] if the root is actually a static node (Element/Text)
@@ -318,9 +346,6 @@ 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 compile time, so these shouldn't be really used as a key
@@ -377,7 +402,7 @@ pub struct VPlaceholder {
/// The ID of this node in the real DOM
pub(crate) id: Cell<Option<ElementId>>,
/// The parent of this node
pub(crate) parent: Cell<Option<BubbleId>>,
pub(crate) parent: Cell<Option<ElementRef>>,
}
impl VPlaceholder {
@@ -729,6 +754,7 @@ impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(_cx.bump().alloc([VNode {
parent: self.parent.clone(),
stable_id: self.stable_id.clone(),
template: self.template.clone(),
root_ids: self.root_ids.clone(),
key: self.key,