wip: more tests!
This commit is contained in:
1 parent
662f58c8bc
commit
9c4abcbea0
10 files changed
+203
-26
No files matched your search
@@ -157,6 +157,28 @@ impl<'b: 'static> VirtualDom {
|
||||
|
||||
/// Insert a new template into the VirtualDom's template registry
|
||||
fn register_template(&mut self, template: &'b VNode<'b>) {
|
||||
// First, make sure we mark the template as seen, regardless if we process it
|
||||
self.templates
|
||||
.insert(template.template.id, template.template);
|
||||
|
||||
// If it's all dynamic nodes, then we don't need to register it
|
||||
// Quickly run through and see if it's all just dynamic nodes
|
||||
let dynamic_roots = template
|
||||
.template
|
||||
.roots
|
||||
.iter()
|
||||
.filter(|root| {
|
||||
matches!(
|
||||
root,
|
||||
TemplateNode::Dynamic(_) | TemplateNode::DynamicText(_)
|
||||
)
|
||||
})
|
||||
.count();
|
||||
|
||||
if dynamic_roots == template.template.roots.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
for node in template.template.roots {
|
||||
self.create_static_node(template, node);
|
||||
}
|
||||
@@ -165,9 +187,6 @@ impl<'b: 'static> VirtualDom {
|
||||
name: template.template.id,
|
||||
m: template.template.roots.len(),
|
||||
});
|
||||
|
||||
self.templates
|
||||
.insert(template.template.id, template.template);
|
||||
}
|
||||
|
||||
pub(crate) fn create_static_node(
|
||||
|
||||
@@ -155,8 +155,7 @@ impl<'a, 'b> IntoDynNode<'a> for () {
|
||||
}
|
||||
impl<'a, 'b> IntoDynNode<'a> for VNode<'a> {
|
||||
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||
// DynamicNode::Fragment { nodes: cx., inner: () }
|
||||
todo!()
|
||||
DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([self])))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +168,15 @@ impl<'a, 'b, 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),
|
||||
_ => DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0)))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
|
||||
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
|
||||
DynamicNode::Fragment(VFragment::NonEmpty(cx.bump().alloc([self.call(cx)])))
|
||||
|
||||
@@ -15,6 +15,25 @@ impl<'a> Mutations<'a> {
|
||||
template_mutations: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A useful tool for testing mutations
|
||||
///
|
||||
/// Rewrites IDs to just be "template", so you can compare the mutations
|
||||
pub fn santize(mut self) -> Self {
|
||||
for edit in self
|
||||
.template_mutations
|
||||
.iter_mut()
|
||||
.chain(self.edits.iter_mut())
|
||||
{
|
||||
match edit {
|
||||
Mutation::LoadTemplate { name, .. } => *name = "template",
|
||||
Mutation::SaveTemplate { name, .. } => *name = "template",
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for Mutations<'a> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{any_props::AnyProps, arena::ElementId, ScopeId, ScopeState, UiEvent};
|
||||
use crate::{any_props::AnyProps, arena::ElementId, Element, ScopeId, ScopeState, UiEvent};
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
cell::{Cell, RefCell},
|
||||
@@ -10,7 +10,7 @@ pub type TemplateId = &'static str;
|
||||
///
|
||||
/// The dynamic parts of the template are stored separately from the static parts. This allows faster diffing by skipping
|
||||
/// static parts of the template.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VNode<'a> {
|
||||
// The ID assigned for the root of this template
|
||||
pub node_id: Cell<ElementId>,
|
||||
@@ -47,6 +47,23 @@ impl<'a> VNode<'a> {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn empty() -> Element<'a> {
|
||||
Ok(VNode {
|
||||
node_id: Cell::new(ElementId(0)),
|
||||
key: None,
|
||||
parent: None,
|
||||
root_ids: &[],
|
||||
dynamic_nodes: &[],
|
||||
dynamic_attrs: &[],
|
||||
template: Template {
|
||||
id: "dioxus-empty",
|
||||
roots: &[],
|
||||
node_paths: &[],
|
||||
attr_paths: &[],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn template_from_dynamic_node(
|
||||
cx: &'a ScopeState,
|
||||
node: DynamicNode<'a>,
|
||||
|
||||
@@ -20,7 +20,7 @@ impl VirtualDom {
|
||||
pub(super) fn new_scope(&mut self, props: *const dyn AnyProps<'static>) -> &mut ScopeState {
|
||||
let parent = self.acquire_current_scope_raw();
|
||||
let entry = self.scopes.vacant_entry();
|
||||
let height = unsafe { parent.map(|f| (*f).height).unwrap_or(0) + 1 };
|
||||
let height = unsafe { parent.map(|f| (*f).height + 1).unwrap_or(0) };
|
||||
let id = ScopeId(entry.key());
|
||||
|
||||
entry.insert(ScopeState {
|
||||
|
||||
@@ -120,8 +120,27 @@ impl ScopeState {
|
||||
/// Get a handle to the currently active head node arena for this Scope
|
||||
///
|
||||
/// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
|
||||
///
|
||||
/// Panics if the tree has not been built yet.
|
||||
pub fn root_node<'a>(&'a self) -> &'a RenderReturn<'a> {
|
||||
let r: &RenderReturn = unsafe { &*self.current_frame().node.get() };
|
||||
self.try_root_node()
|
||||
.expect("The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.")
|
||||
}
|
||||
|
||||
/// Try to get a handle to the currently active head node arena for this Scope
|
||||
///
|
||||
/// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
|
||||
///
|
||||
/// Returns [`None`] if the tree has not been built yet.
|
||||
pub fn try_root_node<'a>(&'a self) -> Option<&'a RenderReturn<'a>> {
|
||||
let ptr = self.current_frame().node.get();
|
||||
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let r: &RenderReturn = unsafe { &*ptr };
|
||||
|
||||
unsafe { std::mem::transmute(r) }
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user