feat: rip out mutations for templates

This commit is contained in:
Jonathan Kelley committed 2022-12-01 00:46:15 -05:00
1 parent 3b166c9edd
commit 85657d3906
33 files changed
+270 -314

No files matched your search

+5 -79
View File
@@ -7,7 +7,7 @@ use crate::mutations::Mutation::*;
use crate::nodes::VNode;
use crate::nodes::{DynamicNode, TemplateNode};
use crate::virtual_dom::VirtualDom;
use crate::{AttributeValue, ElementId, ScopeId, SuspenseContext, TemplateAttribute};
use crate::{AttributeValue, ElementId, ScopeId, SuspenseContext};
impl<'b> VirtualDom {
/// Create a new template [`VNode`] and write it to the [`Mutations`] buffer.
@@ -224,81 +224,7 @@ impl<'b> VirtualDom {
return;
}
for node in template.template.roots {
self.create_static_node(node);
}
self.mutations.template_edits.push(SaveTemplate {
name: template.template.id,
m: template.template.roots.len(),
});
}
// todo: we shouldn't have any of instructions for building templates - renderers should be able to work with the
// template type directly, right?
pub(crate) fn create_static_node(&mut self, node: &'b TemplateNode<'static>) {
match *node {
// Todo: create the children's template
TemplateNode::Dynamic(_) => self
.mutations
.template_edits
.push(CreateStaticPlaceholder {}),
TemplateNode::Text(value) => self
.mutations
.template_edits
.push(CreateStaticText { value }),
TemplateNode::DynamicText { .. } => {
self.mutations.template_edits.push(CreateTextPlaceholder)
}
TemplateNode::Element {
attrs,
children,
namespace,
tag,
..
} => {
match namespace {
Some(namespace) => self.mutations.template_edits.push(CreateElementNamespace {
name: tag,
namespace,
}),
None => self
.mutations
.template_edits
.push(CreateElement { name: tag }),
}
self.mutations
.template_edits
.extend(attrs.iter().filter_map(|attr| match attr {
TemplateAttribute::Static {
name,
value,
namespace,
..
} => Some(SetStaticAttribute {
name,
value,
ns: *namespace,
}),
_ => None,
}));
if children.is_empty() {
return;
}
children
.iter()
.for_each(|child| self.create_static_node(child));
self.mutations
.template_edits
.push(AppendChildren { m: children.len() })
}
}
self.mutations.templates.push(template.template);
}
pub(crate) fn create_dynamic_node(
@@ -404,7 +330,7 @@ impl<'b> VirtualDom {
) -> usize {
// Keep track of how many mutations are in the buffer in case we need to split them out if a suspense boundary
// is encountered
let mutations_to_this_point = self.mutations.dom_edits.len();
let mutations_to_this_point = self.mutations.edits.len();
// Create the component's root element
let created = self.create_scope(scope, new);
@@ -430,10 +356,10 @@ impl<'b> VirtualDom {
// Note that we break off dynamic mutations only - since static mutations aren't rendered immediately
let split_off = unsafe {
std::mem::transmute::<Vec<Mutation>, Vec<Mutation>>(
self.mutations.dom_edits.split_off(mutations_to_this_point),
self.mutations.edits.split_off(mutations_to_this_point),
)
};
boundary.mutations.borrow_mut().dom_edits.extend(split_off);
boundary.mutations.borrow_mut().edits.extend(split_off);
boundary.created_on_stack.set(created);
boundary
.waiting_on
+17 -56
View File
@@ -1,6 +1,6 @@
use fxhash::FxHashSet;
use crate::{arena::ElementId, ScopeId};
use crate::{arena::ElementId, ScopeId, Template};
/// A container for all the relevant steps to modify the Real DOM
///
@@ -18,11 +18,13 @@ pub struct Mutations<'a> {
/// The list of Scopes that were diffed, created, and removed during the Diff process.
pub dirty_scopes: FxHashSet<ScopeId>,
/// Any mutations required to build the templates using [`Mutations`]
pub template_edits: Vec<Mutation<'a>>,
/// Any templates encountered while diffing the DOM.
///
/// These must be loaded into a cache before applying the edits
pub templates: Vec<Template<'a>>,
/// Any mutations required to patch the renderer to match the layout of the VirtualDom
pub dom_edits: Vec<Mutation<'a>>,
pub edits: Vec<Mutation<'a>>,
}
impl<'a> Mutations<'a> {
@@ -30,21 +32,22 @@ impl<'a> Mutations<'a> {
///
/// Used really only for testing
pub fn santize(mut self) -> Self {
self.template_edits
.iter_mut()
.chain(self.dom_edits.iter_mut())
.for_each(|edit| match edit {
Mutation::LoadTemplate { name, .. } => *name = "template",
Mutation::SaveTemplate { name, .. } => *name = "template",
_ => {}
});
todo!()
// self.templates
// .iter_mut()
// .chain(self.dom_edits.iter_mut())
// .for_each(|edit| match edit {
// Mutation::LoadTemplate { name, .. } => *name = "template",
// Mutation::SaveTemplate { name, .. } => *name = "template",
// _ => {}
// });
self
// self
}
/// Push a new mutation into the dom_edits list
pub(crate) fn push(&mut self, mutation: Mutation<'static>) {
self.dom_edits.push(mutation)
self.edits.push(mutation)
}
}
@@ -59,34 +62,14 @@ each subtree has its own numbering scheme
)]
#[derive(Debug, PartialEq, Eq)]
pub enum Mutation<'a> {
/// Pop the topmost node from our stack and append them to the node
/// at the top of the stack.
AppendChildren {
/// How many nodes should be popped from the stack.
/// The node remaining on the stack will be the target for the append.
m: usize,
},
AssignId {
path: &'static [u8],
id: ElementId,
},
CreateElement {
name: &'a str,
},
CreateElementNamespace {
name: &'a str,
namespace: &'a str,
},
CreatePlaceholder {
id: ElementId,
},
CreateStaticPlaceholder,
CreateTextPlaceholder,
CreateStaticText {
value: &'a str,
},
CreateTextNode {
value: &'a str,
id: ElementId,
@@ -131,15 +114,6 @@ pub enum Mutation<'a> {
m: usize,
},
/// Save the top m nodes as a placeholder
SaveTemplate {
/// The name of the template that we're saving
name: &'static str,
/// How many nodes are being saved into this template
m: usize,
},
/// Set the value of a node's attribute.
SetAttribute {
/// The name of the attribute to set.
@@ -155,19 +129,6 @@ pub enum Mutation<'a> {
ns: Option<&'a str>,
},
/// Set the value of a node's attribute.
SetStaticAttribute {
/// The name of the attribute to set.
name: &'a str,
/// The value of the attribute.
value: &'a str,
/// The (optional) namespace of the attribute.
/// For instance, "style" is in the "style" namespace.
ns: Option<&'a str>,
},
/// Set the value of a node's attribute.
SetBoolAttribute {
/// The name of the attribute to set.
+5 -2
View File
@@ -62,6 +62,7 @@ impl<'a> VNode<'a> {
}
}
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[derive(Debug, Clone, Copy)]
pub struct Template<'a> {
pub id: &'a str,
@@ -71,6 +72,7 @@ pub struct Template<'a> {
}
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub enum TemplateNode<'a> {
Element {
tag: &'a str,
@@ -126,11 +128,12 @@ pub struct VText<'a> {
}
#[derive(Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub enum TemplateAttribute<'a> {
Static {
name: &'static str,
name: &'a str,
value: &'a str,
namespace: Option<&'static str>,
namespace: Option<&'a str>,
volatile: bool,
},
Dynamic(usize),
+8 -8
View File
@@ -490,7 +490,7 @@ impl VirtualDom {
// Rebuilding implies we append the created elements to the root
RenderReturn::Sync(Ok(node)) => {
let m = self.create_scope(ScopeId(0), node);
self.mutations.push(Mutation::AppendChildren { m });
// self.mutations.push(Mutation::AppendChildren { m });
}
// 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),
@@ -534,12 +534,12 @@ impl VirtualDom {
let context = scope.has_context::<SuspenseContext>().unwrap();
self.mutations
.template_edits
.extend(context.mutations.borrow_mut().template_edits.drain(..));
.templates
.extend(context.mutations.borrow_mut().templates.drain(..));
self.mutations
.dom_edits
.extend(context.mutations.borrow_mut().dom_edits.drain(..));
.edits
.extend(context.mutations.borrow_mut().edits.drain(..));
// TODO: count how many nodes are on the stack?
self.mutations.push(Mutation::ReplaceWith {
@@ -559,7 +559,7 @@ impl VirtualDom {
}
// Save the current mutations length so we can split them into boundary
let mutations_to_this_point = self.mutations.dom_edits.len();
let mutations_to_this_point = self.mutations.edits.len();
// Run the scope and get the mutations
self.run_scope(dirty.id);
@@ -578,8 +578,8 @@ impl VirtualDom {
boundary_mut
.mutations
.borrow_mut()
.dom_edits
.extend(self.mutations.dom_edits.split_off(mutations_to_this_point));
.edits
.extend(self.mutations.edits.split_off(mutations_to_this_point));
// Attach suspended leaves
boundary
+5 -5
View File
@@ -23,7 +23,7 @@ fn attrs_cycle() {
});
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
AppendChildren { m: 1 },
@@ -32,7 +32,7 @@ fn attrs_cycle() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
AssignId { path: &[0,], id: ElementId(3,) },
@@ -44,7 +44,7 @@ fn attrs_cycle() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
ReplaceWith { id: ElementId(2), m: 1 }
@@ -53,7 +53,7 @@ fn attrs_cycle() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
AssignId { path: &[0], id: ElementId(1) },
@@ -66,7 +66,7 @@ fn attrs_cycle() {
// we take the node taken by attributes since we reused it
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
ReplaceWith { id: ElementId(2), m: 1 }
+1 -1
View File
@@ -5,7 +5,7 @@ use dioxus::prelude::*;
fn bool_test() {
let mut app = VirtualDom::new(|cx| cx.render(rsx!(div { hidden: false })));
assert_eq!(
app.rebuild().santize().dom_edits,
app.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
SetBoolAttribute { name: "hidden", value: false, id: ElementId(1,) },
+1 -1
View File
@@ -8,7 +8,7 @@ fn test_borrowed_state() {
let mut dom = VirtualDom::new(Parent);
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
+3 -3
View File
@@ -20,7 +20,7 @@ fn state_shares() {
let mut dom = VirtualDom::new(app);
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
CreateTextNode { value: "Value is 0", id: ElementId(1,) },
AppendChildren { m: 1 },
@@ -37,7 +37,7 @@ fn state_shares() {
dom.mark_dirty(ScopeId(2));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[SetText { value: "Value is 2", id: ElementId(1,) },]
);
@@ -45,7 +45,7 @@ fn state_shares() {
dom.mark_dirty(ScopeId(2));
let edits = dom.render_immediate();
assert_eq!(
edits.santize().dom_edits,
edits.santize().edits,
[SetText { value: "Value is 3", id: ElementId(1,) },]
);
}
+8 -8
View File
@@ -23,7 +23,7 @@ fn test_original_diff() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// create template
CreateElement { name: "div" },
@@ -36,7 +36,7 @@ fn test_original_diff() {
);
assert_eq!(
edits.dom_edits,
edits.edits,
[
// add to root
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
@@ -67,7 +67,7 @@ fn create() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// create template
CreateElement { name: "div" },
@@ -99,7 +99,7 @@ fn create_list() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// create template
CreateElement { name: "div" },
@@ -123,7 +123,7 @@ fn create_simple() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// create template
CreateElement { name: "div" },
@@ -160,7 +160,7 @@ fn create_components() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// The "child" template
CreateElement { name: "h1" },
@@ -196,7 +196,7 @@ fn anchors() {
// note that the template under "false" doesn't show up since it's not loaded
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// create each template
CreateElement { name: "div" },
@@ -207,7 +207,7 @@ fn anchors() {
);
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
CreatePlaceholder { id: ElementId(2) },
+1 -1
View File
@@ -12,7 +12,7 @@ fn multiroot() {
});
assert_eq!(
dom.rebuild().santize().template_edits,
dom.rebuild().santize().templates,
[
CreateElement { name: "div" },
CreateStaticText { value: "Hello a" },
+5 -5
View File
@@ -14,7 +14,7 @@ fn empty_fragment_creates_nothing() {
let edits = vdom.rebuild();
assert_eq!(
edits.dom_edits,
edits.edits,
[
CreatePlaceholder { id: ElementId(1) },
AppendChildren { m: 1 }
@@ -32,7 +32,7 @@ fn root_fragments_work() {
});
assert_eq!(
vdom.rebuild().dom_edits.last().unwrap(),
vdom.rebuild().edits.last().unwrap(),
&AppendChildren { m: 2 }
);
}
@@ -59,7 +59,7 @@ fn fragments_nested() {
});
assert_eq!(
vdom.rebuild().dom_edits.last().unwrap(),
vdom.rebuild().edits.last().unwrap(),
&AppendChildren { m: 8 }
);
}
@@ -84,7 +84,7 @@ fn fragments_across_components() {
}
assert_eq!(
VirtualDom::new(app).rebuild().dom_edits.last().unwrap(),
VirtualDom::new(app).rebuild().edits.last().unwrap(),
&AppendChildren { m: 8 }
);
}
@@ -98,7 +98,7 @@ fn list_fragments() {
))
}
assert_eq!(
VirtualDom::new(app).rebuild().dom_edits.last().unwrap(),
VirtualDom::new(app).rebuild().edits.last().unwrap(),
&AppendChildren { m: 7 }
);
}
+2 -2
View File
@@ -28,7 +28,7 @@ fn list_renders() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.template_edits,
edits.templates,
[
// Create the outer div
CreateElement { name: "div" },
@@ -51,7 +51,7 @@ fn list_renders() {
);
assert_eq!(
edits.dom_edits,
edits.edits,
[
// Load the outer div
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
+4 -4
View File
@@ -26,7 +26,7 @@ fn nested_passthru_creates() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
AppendChildren { m: 1 },
@@ -64,7 +64,7 @@ fn nested_passthru_creates_add() {
let mut dom = VirtualDom::new(app);
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
// load 1
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
@@ -92,11 +92,11 @@ fn dynamic_node_as_root() {
let edits = dom.rebuild().santize();
// Since the roots were all dynamic, they should not cause any template muations
assert_eq!(edits.template_edits, []);
assert_eq!(edits.templates, []);
// The root node is text, so we just create it on the spot
assert_eq!(
edits.dom_edits,
edits.edits,
[
CreateTextNode { value: "123", id: ElementId(1) },
CreateTextNode { value: "456", id: ElementId(2) },
+4 -4
View File
@@ -14,7 +14,7 @@ fn cycling_elements() {
let edits = dom.rebuild().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
AppendChildren { m: 1 },
@@ -23,7 +23,7 @@ fn cycling_elements() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
ReplaceWith { id: ElementId(1,), m: 1 },
@@ -33,7 +33,7 @@ fn cycling_elements() {
// notice that the IDs cycle back to ElementId(1), preserving a minimal memory footprint
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
ReplaceWith { id: ElementId(2,), m: 1 },
@@ -42,7 +42,7 @@ fn cycling_elements() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
ReplaceWith { id: ElementId(1,), m: 1 },
+4 -4
View File
@@ -61,7 +61,7 @@ fn component_swap() {
let mut dom = VirtualDom::new(app);
let edits = dom.rebuild().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
@@ -75,7 +75,7 @@ fn component_swap() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
ReplaceWith { id: ElementId(5), m: 1 }
@@ -84,7 +84,7 @@ fn component_swap() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
ReplaceWith { id: ElementId(6), m: 1 }
@@ -93,7 +93,7 @@ fn component_swap() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
ReplaceWith { id: ElementId(5), m: 1 }
+7 -7
View File
@@ -14,19 +14,19 @@ fn text_diff() {
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().dom_edits,
vdom.render_immediate().edits,
[SetText { value: "hello 1", id: ElementId(2) }]
);
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().dom_edits,
vdom.render_immediate().edits,
[SetText { value: "hello 2", id: ElementId(2) }]
);
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().dom_edits,
vdom.render_immediate().edits,
[SetText { value: "hello 3", id: ElementId(2) }]
);
}
@@ -48,7 +48,7 @@ fn element_swap() {
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().santize().dom_edits,
vdom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
ReplaceWith { id: ElementId(1,), m: 1 },
@@ -57,7 +57,7 @@ fn element_swap() {
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().santize().dom_edits,
vdom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
ReplaceWith { id: ElementId(2,), m: 1 },
@@ -66,7 +66,7 @@ fn element_swap() {
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().santize().dom_edits,
vdom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
ReplaceWith { id: ElementId(1,), m: 1 },
@@ -75,7 +75,7 @@ fn element_swap() {
vdom.mark_dirty(ScopeId(0));
assert_eq!(
vdom.render_immediate().santize().dom_edits,
vdom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
ReplaceWith { id: ElementId(2,), m: 1 },
+13 -13
View File
@@ -21,7 +21,7 @@ fn keyed_diffing_out_of_order() {
});
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
@@ -39,7 +39,7 @@ fn keyed_diffing_out_of_order() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().dom_edits,
dom.render_immediate().edits,
[
PushRoot { id: ElementId(7,) },
InsertBefore { id: ElementId(5,), m: 1 },
@@ -64,7 +64,7 @@ fn keyed_diffing_out_of_order_adds() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().dom_edits,
dom.render_immediate().edits,
[
PushRoot { id: ElementId(5,) },
PushRoot { id: ElementId(4,) },
@@ -90,7 +90,7 @@ fn keyed_diffing_out_of_order_adds_3() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().dom_edits,
dom.render_immediate().edits,
[
PushRoot { id: ElementId(5,) },
PushRoot { id: ElementId(4,) },
@@ -116,7 +116,7 @@ fn keyed_diffing_out_of_order_adds_4() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().dom_edits,
dom.render_immediate().edits,
[
PushRoot { id: ElementId(5,) },
PushRoot { id: ElementId(4,) },
@@ -142,7 +142,7 @@ fn keyed_diffing_out_of_order_adds_5() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().dom_edits,
dom.render_immediate().edits,
[
PushRoot { id: ElementId(5,) },
InsertBefore { id: ElementId(4,), m: 1 },
@@ -167,7 +167,7 @@ fn keyed_diffing_additions() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(6) },
LoadTemplate { name: "template", index: 0, id: ElementId(7) },
@@ -192,7 +192,7 @@ fn keyed_diffing_additions_and_moves_on_ends() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
// create 11, 12
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -222,7 +222,7 @@ fn keyed_diffing_additions_and_moves_in_middle() {
// LIS: 4, 5, 6
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
// create 5, 6
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -256,7 +256,7 @@ fn controlled_keyed_diffing_out_of_order() {
// LIS: 5, 6
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
// remove 7
Remove { id: ElementId(4,) },
@@ -289,7 +289,7 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
Remove { id: ElementId(5,) },
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
@@ -318,7 +318,7 @@ fn remove_list() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
Remove { id: ElementId(3) },
Remove { id: ElementId(4) },
@@ -343,7 +343,7 @@ fn no_common_keys() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
Remove { id: ElementId(2) },
Remove { id: ElementId(3) },
+26 -26
View File
@@ -17,7 +17,7 @@ fn list_creates_one_by_one() {
// load the div and then assign the empty fragment as a placeholder
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
AssignId { path: &[0], id: ElementId(2,) },
@@ -28,7 +28,7 @@ fn list_creates_one_by_one() {
// Rendering the first item should replace the placeholder with an element
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
HydrateText { path: &[0], value: "0", id: ElementId(4,) },
@@ -39,7 +39,7 @@ fn list_creates_one_by_one() {
// Rendering the next item should insert after the previous
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
HydrateText { path: &[0], value: "1", id: ElementId(5,) },
@@ -50,7 +50,7 @@ fn list_creates_one_by_one() {
// ... and again!
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(6,) },
HydrateText { path: &[0], value: "2", id: ElementId(7,) },
@@ -61,7 +61,7 @@ fn list_creates_one_by_one() {
// once more
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(8,) },
HydrateText { path: &[0], value: "3", id: ElementId(9,) },
@@ -86,7 +86,7 @@ fn removes_one_by_one() {
// load the div and then assign the empty fragment as a placeholder
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
// The container
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
@@ -108,14 +108,14 @@ fn removes_one_by_one() {
// Rendering the first item should replace the placeholder with an element
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[Remove { id: ElementId(6) }]
);
// Remove div(2)
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[Remove { id: ElementId(4) }]
);
@@ -123,7 +123,7 @@ fn removes_one_by_one() {
// todo: this should just be a remove with no placeholder
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
CreatePlaceholder { id: ElementId(3) },
ReplaceWith { id: ElementId(2), m: 1 }
@@ -134,7 +134,7 @@ fn removes_one_by_one() {
// todo: this should actually be append to, but replace placeholder is fine for now
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
HydrateText { path: &[0], value: "0", id: ElementId(4) },
@@ -161,7 +161,7 @@ fn list_shrink_multiroot() {
});
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
AssignId { path: &[0,], id: ElementId(2,) },
@@ -171,7 +171,7 @@ fn list_shrink_multiroot() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
HydrateText { path: &[0], value: "0", id: ElementId(4) },
@@ -183,7 +183,7 @@ fn list_shrink_multiroot() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
HydrateText { path: &[0], value: "1", id: ElementId(7) },
@@ -195,7 +195,7 @@ fn list_shrink_multiroot() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(10) },
HydrateText { path: &[0], value: "2", id: ElementId(11) },
@@ -223,7 +223,7 @@ fn removes_one_by_one_multiroot() {
// load the div and then assign the empty fragment as a placeholder
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
//
@@ -250,19 +250,19 @@ fn removes_one_by_one_multiroot() {
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[Remove { id: ElementId(10) }, Remove { id: ElementId(12) }]
);
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[Remove { id: ElementId(6) }, Remove { id: ElementId(8) }]
);
dom.mark_dirty(ScopeId(0));
assert_eq!(
dom.render_immediate().santize().dom_edits,
dom.render_immediate().santize().edits,
[
Remove { id: ElementId(4) },
CreatePlaceholder { id: ElementId(5) },
@@ -282,7 +282,7 @@ fn two_equal_fragments_are_equal_static() {
});
_ = dom.rebuild();
assert!(dom.render_immediate().dom_edits.is_empty());
assert!(dom.render_immediate().edits.is_empty());
}
#[test]
@@ -296,7 +296,7 @@ fn two_equal_fragments_are_equal() {
});
_ = dom.rebuild();
assert!(dom.render_immediate().dom_edits.is_empty());
assert!(dom.render_immediate().edits.is_empty());
}
#[test]
@@ -315,9 +315,9 @@ fn remove_many() {
});
let edits = dom.rebuild().santize();
assert!(edits.template_edits.is_empty());
assert!(edits.templates.is_empty());
assert_eq!(
edits.dom_edits,
edits.edits,
[
CreatePlaceholder { id: ElementId(1,) },
AppendChildren { m: 1 },
@@ -327,7 +327,7 @@ fn remove_many() {
dom.mark_dirty(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
@@ -338,7 +338,7 @@ fn remove_many() {
dom.mark_dirty(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
@@ -355,7 +355,7 @@ fn remove_many() {
dom.mark_dirty(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
Remove { id: ElementId(1,) },
Remove { id: ElementId(5,) },
@@ -369,7 +369,7 @@ fn remove_many() {
dom.mark_dirty(ScopeId(0));
let edits = dom.render_immediate().santize();
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
HydrateText { path: &[0,], value: "hello 0", id: ElementId(10,) },
+2 -2
View File
@@ -30,7 +30,7 @@ fn dual_stream() {
use Mutation::*;
assert_eq!(
edits.template_edits,
edits.templates,
[
CreateElement { name: "div" },
SetStaticAttribute { name: "class", value: "asd", ns: None },
@@ -66,7 +66,7 @@ fn dual_stream() {
);
assert_eq!(
edits.dom_edits,
edits.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
SetAttribute { name: "class", value: "123", id: ElementId(1), ns: None },
+2 -2
View File
@@ -28,7 +28,7 @@ fn manual_diffing() {
*value.lock().unwrap() = "goodbye";
assert_eq!(
dom.rebuild().santize().dom_edits,
dom.rebuild().santize().edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
@@ -62,7 +62,7 @@ fn events_generate() {
let edits = dom.render_immediate();
assert_eq!(
edits.dom_edits,
edits.edits,
[
CreatePlaceholder { id: ElementId(2) },
ReplaceWith { id: ElementId(1), m: 1 }
+2 -2
View File
@@ -13,7 +13,7 @@ async fn it_works() {
// We should at least get the top-level template in before pausing for the children
assert_eq!(
mutations.template_edits,
mutations.templates,
[
CreateElement { name: "div" },
CreateStaticText { value: "Waiting for child..." },
@@ -25,7 +25,7 @@ async fn it_works() {
// And we should load it in and assign the placeholder properly
assert_eq!(
mutations.dom_edits,
mutations.edits,
[
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
// hmmmmmmmmm.... with suspense how do we guarantee that IDs increase linearly?