Merge branch 'master' into pr/atty303/1349

This commit is contained in:
Evan Almloff committed 2024-01-06 08:52:37 -06:00
commit e5df83ceec
278 files changed
+11299 -3674

No files matched your search

+64 -32
View File
@@ -1,3 +1,4 @@
use crate::innerlude::{ElementRef, VNodeId};
use crate::{
any_props::AnyProps, arena::ElementId, Element, Event, LazyNodes, ScopeId, ScopeState,
};
@@ -47,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: Option<ElementId>,
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>>,
@@ -68,7 +72,8 @@ impl<'a> VNode<'a> {
pub fn empty(cx: &'a ScopeState) -> Element<'a> {
Some(VNode {
key: None,
parent: None,
parent: Default::default(),
stable_id: Default::default(),
root_ids: RefCell::new(bumpalo::collections::Vec::new_in(cx.bump())),
dynamic_nodes: &[],
dynamic_attrs: &[],
@@ -81,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)
@@ -319,7 +348,7 @@ pub struct VComponent<'a> {
/// 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>>>,
@@ -372,6 +401,8 @@ impl<'a> VText<'a> {
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<ElementRef>>,
}
impl VPlaceholder {
@@ -720,52 +751,52 @@ pub trait IntoDynNode<'a, A = ()> {
/// Consume this item along with a scopestate and produce a DynamicNode
///
/// You can use the bump alloactor of the scopestate to creat the dynamic node
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a>;
fn into_dyn_node(self, cx: &'a ScopeState) -> DynamicNode<'a>;
}
impl<'a> IntoDynNode<'a> for () {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::default()
}
}
impl<'a> IntoDynNode<'a> for VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(_cx.bump().alloc([self]))
}
}
impl<'a> IntoDynNode<'a> for DynamicNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
self
}
}
impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self {
Some(val) => val.into_vnode(_cx),
Some(val) => val.into_dyn_node(_cx),
None => DynamicNode::default(),
}
}
}
impl<'a> IntoDynNode<'a> for &Element<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self.as_ref() {
Some(val) => val.clone().into_vnode(_cx),
Some(val) => val.clone().into_dyn_node(_cx),
_ => DynamicNode::default(),
}
}
}
impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(cx.bump().alloc([cx.render(self).unwrap()]))
}
}
impl<'a, 'b> IntoDynNode<'b> for &'a str {
fn into_vnode(self, cx: &'b ScopeState) -> DynamicNode<'b> {
fn into_dyn_node(self, cx: &'b ScopeState) -> DynamicNode<'b> {
DynamicNode::Text(VText {
value: cx.bump().alloc_str(self),
id: Default::default(),
@@ -774,24 +805,25 @@ impl<'a, 'b> IntoDynNode<'b> for &'a str {
}
impl IntoDynNode<'_> for String {
fn into_vnode(self, cx: &ScopeState) -> DynamicNode {
fn into_dyn_node(self, cx: &ScopeState) -> DynamicNode {
DynamicNode::Text(VText {
value: cx.bump().alloc(self),
value: cx.bump().alloc_str(&self),
id: Default::default(),
})
}
}
impl<'b> IntoDynNode<'b> for Arguments<'_> {
fn into_vnode(self, cx: &'b ScopeState) -> DynamicNode<'b> {
fn into_dyn_node(self, cx: &'b ScopeState) -> DynamicNode<'b> {
cx.text_node(self)
}
}
impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(_cx.bump().alloc([VNode {
parent: self.parent,
parent: self.parent.clone(),
stable_id: self.stable_id.clone(),
template: self.template.clone(),
root_ids: self.root_ids.clone(),
key: self.key,
@@ -801,24 +833,24 @@ impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
}
}
pub trait IntoTemplate<'a> {
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a>;
pub trait IntoVNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> VNode<'a>;
}
impl<'a> IntoTemplate<'a> for VNode<'a> {
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
impl<'a> IntoVNode<'a> for VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> VNode<'a> {
self
}
}
impl<'a> IntoTemplate<'a> for Element<'a> {
fn into_template(self, cx: &'a ScopeState) -> VNode<'a> {
impl<'a> IntoVNode<'a> for Element<'a> {
fn into_vnode(self, cx: &'a ScopeState) -> VNode<'a> {
match self {
Some(val) => val.into_template(cx),
Some(val) => val.into_vnode(cx),
_ => VNode::empty(cx).unwrap(),
}
}
}
impl<'a, 'b> IntoTemplate<'a> for LazyNodes<'a, 'b> {
fn into_template(self, cx: &'a ScopeState) -> VNode<'a> {
impl<'a, 'b> IntoVNode<'a> for LazyNodes<'a, 'b> {
fn into_vnode(self, cx: &'a ScopeState) -> VNode<'a> {
cx.render(self).unwrap()
}
}
@@ -828,12 +860,12 @@ pub struct FromNodeIterator;
impl<'a, T, I> IntoDynNode<'a, FromNodeIterator> for T
where
T: Iterator<Item = I>,
I: IntoTemplate<'a>,
I: IntoVNode<'a>,
{
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
fn into_dyn_node(self, cx: &'a ScopeState) -> DynamicNode<'a> {
let mut nodes = bumpalo::collections::Vec::new_in(cx.bump());
nodes.extend(self.into_iter().map(|node| node.into_template(cx)));
nodes.extend(self.into_iter().map(|node| node.into_vnode(cx)));
match nodes.into_bump_slice() {
children if children.is_empty() => DynamicNode::default(),
@@ -861,8 +893,8 @@ impl<'a> IntoAttributeValue<'a> for &'a str {
}
impl<'a> IntoAttributeValue<'a> for String {
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a> {
AttributeValue::Text(bump.alloc(self))
fn into_value(self, cx: &'a Bump) -> AttributeValue<'a> {
AttributeValue::Text(cx.alloc_str(&self))
}
}