feat: rip out mutations for templates
This commit is contained in:
1 parent
3b166c9edd
commit
85657d3906
33 files changed
+270
-314
No files matched your search
@@ -7,7 +7,7 @@ use crate::mutations::Mutation::*;
|
|||||||
use crate::nodes::VNode;
|
use crate::nodes::VNode;
|
||||||
use crate::nodes::{DynamicNode, TemplateNode};
|
use crate::nodes::{DynamicNode, TemplateNode};
|
||||||
use crate::virtual_dom::VirtualDom;
|
use crate::virtual_dom::VirtualDom;
|
||||||
use crate::{AttributeValue, ElementId, ScopeId, SuspenseContext, TemplateAttribute};
|
use crate::{AttributeValue, ElementId, ScopeId, SuspenseContext};
|
||||||
|
|
||||||
impl<'b> VirtualDom {
|
impl<'b> VirtualDom {
|
||||||
/// Create a new template [`VNode`] and write it to the [`Mutations`] buffer.
|
/// Create a new template [`VNode`] and write it to the [`Mutations`] buffer.
|
||||||
@@ -224,81 +224,7 @@ impl<'b> VirtualDom {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for node in template.template.roots {
|
self.mutations.templates.push(template.template);
|
||||||
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() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_dynamic_node(
|
pub(crate) fn create_dynamic_node(
|
||||||
@@ -404,7 +330,7 @@ impl<'b> VirtualDom {
|
|||||||
) -> usize {
|
) -> usize {
|
||||||
// Keep track of how many mutations are in the buffer in case we need to split them out if a suspense boundary
|
// Keep track of how many mutations are in the buffer in case we need to split them out if a suspense boundary
|
||||||
// is encountered
|
// 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
|
// Create the component's root element
|
||||||
let created = self.create_scope(scope, new);
|
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
|
// Note that we break off dynamic mutations only - since static mutations aren't rendered immediately
|
||||||
let split_off = unsafe {
|
let split_off = unsafe {
|
||||||
std::mem::transmute::<Vec<Mutation>, Vec<Mutation>>(
|
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.created_on_stack.set(created);
|
||||||
boundary
|
boundary
|
||||||
.waiting_on
|
.waiting_on
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use fxhash::FxHashSet;
|
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
|
/// 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.
|
/// The list of Scopes that were diffed, created, and removed during the Diff process.
|
||||||
pub dirty_scopes: FxHashSet<ScopeId>,
|
pub dirty_scopes: FxHashSet<ScopeId>,
|
||||||
|
|
||||||
/// Any mutations required to build the templates using [`Mutations`]
|
/// Any templates encountered while diffing the DOM.
|
||||||
pub template_edits: Vec<Mutation<'a>>,
|
///
|
||||||
|
/// 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
|
/// 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> {
|
impl<'a> Mutations<'a> {
|
||||||
@@ -30,21 +32,22 @@ impl<'a> Mutations<'a> {
|
|||||||
///
|
///
|
||||||
/// Used really only for testing
|
/// Used really only for testing
|
||||||
pub fn santize(mut self) -> Self {
|
pub fn santize(mut self) -> Self {
|
||||||
self.template_edits
|
todo!()
|
||||||
.iter_mut()
|
// self.templates
|
||||||
.chain(self.dom_edits.iter_mut())
|
// .iter_mut()
|
||||||
.for_each(|edit| match edit {
|
// .chain(self.dom_edits.iter_mut())
|
||||||
Mutation::LoadTemplate { name, .. } => *name = "template",
|
// .for_each(|edit| match edit {
|
||||||
Mutation::SaveTemplate { name, .. } => *name = "template",
|
// Mutation::LoadTemplate { name, .. } => *name = "template",
|
||||||
_ => {}
|
// Mutation::SaveTemplate { name, .. } => *name = "template",
|
||||||
});
|
// _ => {}
|
||||||
|
// });
|
||||||
|
|
||||||
self
|
// self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push a new mutation into the dom_edits list
|
/// Push a new mutation into the dom_edits list
|
||||||
pub(crate) fn push(&mut self, mutation: Mutation<'static>) {
|
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)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Mutation<'a> {
|
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 {
|
AssignId {
|
||||||
path: &'static [u8],
|
path: &'static [u8],
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
},
|
},
|
||||||
|
|
||||||
CreateElement {
|
|
||||||
name: &'a str,
|
|
||||||
},
|
|
||||||
CreateElementNamespace {
|
|
||||||
name: &'a str,
|
|
||||||
namespace: &'a str,
|
|
||||||
},
|
|
||||||
CreatePlaceholder {
|
CreatePlaceholder {
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
},
|
},
|
||||||
CreateStaticPlaceholder,
|
|
||||||
CreateTextPlaceholder,
|
|
||||||
CreateStaticText {
|
|
||||||
value: &'a str,
|
|
||||||
},
|
|
||||||
CreateTextNode {
|
CreateTextNode {
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
@@ -131,15 +114,6 @@ pub enum Mutation<'a> {
|
|||||||
m: usize,
|
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.
|
/// Set the value of a node's attribute.
|
||||||
SetAttribute {
|
SetAttribute {
|
||||||
/// The name of the attribute to set.
|
/// The name of the attribute to set.
|
||||||
@@ -155,19 +129,6 @@ pub enum Mutation<'a> {
|
|||||||
ns: Option<&'a str>,
|
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.
|
/// Set the value of a node's attribute.
|
||||||
SetBoolAttribute {
|
SetBoolAttribute {
|
||||||
/// The name of the attribute to set.
|
/// The name of the attribute to set.
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ impl<'a> VNode<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Template<'a> {
|
pub struct Template<'a> {
|
||||||
pub id: &'a str,
|
pub id: &'a str,
|
||||||
@@ -71,6 +72,7 @@ pub struct Template<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||||
pub enum TemplateNode<'a> {
|
pub enum TemplateNode<'a> {
|
||||||
Element {
|
Element {
|
||||||
tag: &'a str,
|
tag: &'a str,
|
||||||
@@ -126,11 +128,12 @@ pub struct VText<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum TemplateAttribute<'a> {
|
pub enum TemplateAttribute<'a> {
|
||||||
Static {
|
Static {
|
||||||
name: &'static str,
|
name: &'a str,
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
namespace: Option<&'static str>,
|
namespace: Option<&'a str>,
|
||||||
volatile: bool,
|
volatile: bool,
|
||||||
},
|
},
|
||||||
Dynamic(usize),
|
Dynamic(usize),
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ impl VirtualDom {
|
|||||||
// Rebuilding implies we append the created elements to the root
|
// Rebuilding implies we append the created elements to the root
|
||||||
RenderReturn::Sync(Ok(node)) => {
|
RenderReturn::Sync(Ok(node)) => {
|
||||||
let m = self.create_scope(ScopeId(0), 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
|
// 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(Err(e)) => panic!("Cannot catch errors during rebuild {:?}", e),
|
||||||
@@ -534,12 +534,12 @@ impl VirtualDom {
|
|||||||
let context = scope.has_context::<SuspenseContext>().unwrap();
|
let context = scope.has_context::<SuspenseContext>().unwrap();
|
||||||
|
|
||||||
self.mutations
|
self.mutations
|
||||||
.template_edits
|
.templates
|
||||||
.extend(context.mutations.borrow_mut().template_edits.drain(..));
|
.extend(context.mutations.borrow_mut().templates.drain(..));
|
||||||
|
|
||||||
self.mutations
|
self.mutations
|
||||||
.dom_edits
|
.edits
|
||||||
.extend(context.mutations.borrow_mut().dom_edits.drain(..));
|
.extend(context.mutations.borrow_mut().edits.drain(..));
|
||||||
|
|
||||||
// TODO: count how many nodes are on the stack?
|
// TODO: count how many nodes are on the stack?
|
||||||
self.mutations.push(Mutation::ReplaceWith {
|
self.mutations.push(Mutation::ReplaceWith {
|
||||||
@@ -559,7 +559,7 @@ impl VirtualDom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the current mutations length so we can split them into boundary
|
// 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
|
// Run the scope and get the mutations
|
||||||
self.run_scope(dirty.id);
|
self.run_scope(dirty.id);
|
||||||
@@ -578,8 +578,8 @@ impl VirtualDom {
|
|||||||
boundary_mut
|
boundary_mut
|
||||||
.mutations
|
.mutations
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.dom_edits
|
.edits
|
||||||
.extend(self.mutations.dom_edits.split_off(mutations_to_this_point));
|
.extend(self.mutations.edits.split_off(mutations_to_this_point));
|
||||||
|
|
||||||
// Attach suspended leaves
|
// Attach suspended leaves
|
||||||
boundary
|
boundary
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fn attrs_cycle() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
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(1,) },
|
||||||
AppendChildren { m: 1 },
|
AppendChildren { m: 1 },
|
||||||
@@ -32,7 +32,7 @@ fn attrs_cycle() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
AssignId { path: &[0,], id: ElementId(3,) },
|
AssignId { path: &[0,], id: ElementId(3,) },
|
||||||
@@ -44,7 +44,7 @@ fn attrs_cycle() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
||||||
ReplaceWith { id: ElementId(2), m: 1 }
|
ReplaceWith { id: ElementId(2), m: 1 }
|
||||||
@@ -53,7 +53,7 @@ fn attrs_cycle() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||||
AssignId { path: &[0], id: ElementId(1) },
|
AssignId { path: &[0], id: ElementId(1) },
|
||||||
@@ -66,7 +66,7 @@ fn attrs_cycle() {
|
|||||||
// we take the node taken by attributes since we reused it
|
// we take the node taken by attributes since we reused it
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
ReplaceWith { id: ElementId(2), m: 1 }
|
ReplaceWith { id: ElementId(2), m: 1 }
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
|||||||
fn bool_test() {
|
fn bool_test() {
|
||||||
let mut app = VirtualDom::new(|cx| cx.render(rsx!(div { hidden: false })));
|
let mut app = VirtualDom::new(|cx| cx.render(rsx!(div { hidden: false })));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
app.rebuild().santize().dom_edits,
|
app.rebuild().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
SetBoolAttribute { name: "hidden", value: false, id: ElementId(1,) },
|
SetBoolAttribute { name: "hidden", value: false, id: ElementId(1,) },
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fn test_borrowed_state() {
|
|||||||
let mut dom = VirtualDom::new(Parent);
|
let mut dom = VirtualDom::new(Parent);
|
||||||
|
|
||||||
assert_eq!(
|
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(1,) },
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fn state_shares() {
|
|||||||
|
|
||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.rebuild().santize().dom_edits,
|
dom.rebuild().santize().edits,
|
||||||
[
|
[
|
||||||
CreateTextNode { value: "Value is 0", id: ElementId(1,) },
|
CreateTextNode { value: "Value is 0", id: ElementId(1,) },
|
||||||
AppendChildren { m: 1 },
|
AppendChildren { m: 1 },
|
||||||
@@ -37,7 +37,7 @@ fn state_shares() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(2));
|
dom.mark_dirty(ScopeId(2));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[SetText { value: "Value is 2", id: ElementId(1,) },]
|
[SetText { value: "Value is 2", id: ElementId(1,) },]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ fn state_shares() {
|
|||||||
dom.mark_dirty(ScopeId(2));
|
dom.mark_dirty(ScopeId(2));
|
||||||
let edits = dom.render_immediate();
|
let edits = dom.render_immediate();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.santize().dom_edits,
|
edits.santize().edits,
|
||||||
[SetText { value: "Value is 3", id: ElementId(1,) },]
|
[SetText { value: "Value is 3", id: ElementId(1,) },]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ fn test_original_diff() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// create template
|
// create template
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -36,7 +36,7 @@ fn test_original_diff() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
// add to root
|
// add to root
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
@@ -67,7 +67,7 @@ fn create() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// create template
|
// create template
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -99,7 +99,7 @@ fn create_list() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// create template
|
// create template
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -123,7 +123,7 @@ fn create_simple() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// create template
|
// create template
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -160,7 +160,7 @@ fn create_components() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// The "child" template
|
// The "child" template
|
||||||
CreateElement { name: "h1" },
|
CreateElement { name: "h1" },
|
||||||
@@ -196,7 +196,7 @@ fn anchors() {
|
|||||||
// note that the template under "false" doesn't show up since it's not loaded
|
// note that the template under "false" doesn't show up since it's not loaded
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// create each template
|
// create each template
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -207,7 +207,7 @@ fn anchors() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
CreatePlaceholder { id: ElementId(2) },
|
CreatePlaceholder { id: ElementId(2) },
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fn multiroot() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.rebuild().santize().template_edits,
|
dom.rebuild().santize().templates,
|
||||||
[
|
[
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
CreateStaticText { value: "Hello a" },
|
CreateStaticText { value: "Hello a" },
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fn empty_fragment_creates_nothing() {
|
|||||||
let edits = vdom.rebuild();
|
let edits = vdom.rebuild();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
CreatePlaceholder { id: ElementId(1) },
|
CreatePlaceholder { id: ElementId(1) },
|
||||||
AppendChildren { m: 1 }
|
AppendChildren { m: 1 }
|
||||||
@@ -32,7 +32,7 @@ fn root_fragments_work() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.rebuild().dom_edits.last().unwrap(),
|
vdom.rebuild().edits.last().unwrap(),
|
||||||
&AppendChildren { m: 2 }
|
&AppendChildren { m: 2 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ fn fragments_nested() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.rebuild().dom_edits.last().unwrap(),
|
vdom.rebuild().edits.last().unwrap(),
|
||||||
&AppendChildren { m: 8 }
|
&AppendChildren { m: 8 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ fn fragments_across_components() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
VirtualDom::new(app).rebuild().dom_edits.last().unwrap(),
|
VirtualDom::new(app).rebuild().edits.last().unwrap(),
|
||||||
&AppendChildren { m: 8 }
|
&AppendChildren { m: 8 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ fn list_fragments() {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
VirtualDom::new(app).rebuild().dom_edits.last().unwrap(),
|
VirtualDom::new(app).rebuild().edits.last().unwrap(),
|
||||||
&AppendChildren { m: 7 }
|
&AppendChildren { m: 7 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ fn list_renders() {
|
|||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
// Create the outer div
|
// Create the outer div
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
@@ -51,7 +51,7 @@ fn list_renders() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
// Load the outer div
|
// Load the outer div
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fn nested_passthru_creates() {
|
|||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
AppendChildren { m: 1 },
|
AppendChildren { m: 1 },
|
||||||
@@ -64,7 +64,7 @@ fn nested_passthru_creates_add() {
|
|||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.rebuild().santize().dom_edits,
|
dom.rebuild().santize().edits,
|
||||||
[
|
[
|
||||||
// load 1
|
// load 1
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
@@ -92,11 +92,11 @@ fn dynamic_node_as_root() {
|
|||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
|
|
||||||
// Since the roots were all dynamic, they should not cause any template muations
|
// 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
|
// The root node is text, so we just create it on the spot
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
CreateTextNode { value: "123", id: ElementId(1) },
|
CreateTextNode { value: "123", id: ElementId(1) },
|
||||||
CreateTextNode { value: "456", id: ElementId(2) },
|
CreateTextNode { value: "456", id: ElementId(2) },
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ fn cycling_elements() {
|
|||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||||
AppendChildren { m: 1 },
|
AppendChildren { m: 1 },
|
||||||
@@ -23,7 +23,7 @@ fn cycling_elements() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
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
|
// notice that the IDs cycle back to ElementId(1), preserving a minimal memory footprint
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||||
@@ -42,7 +42,7 @@ fn cycling_elements() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ fn component_swap() {
|
|||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||||
@@ -75,7 +75,7 @@ fn component_swap() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
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(6) },
|
||||||
ReplaceWith { id: ElementId(5), m: 1 }
|
ReplaceWith { id: ElementId(5), m: 1 }
|
||||||
@@ -84,7 +84,7 @@ fn component_swap() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||||
ReplaceWith { id: ElementId(6), m: 1 }
|
ReplaceWith { id: ElementId(6), m: 1 }
|
||||||
@@ -93,7 +93,7 @@ fn component_swap() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
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(6) },
|
||||||
ReplaceWith { id: ElementId(5), m: 1 }
|
ReplaceWith { id: ElementId(5), m: 1 }
|
||||||
|
|||||||
@@ -14,19 +14,19 @@ fn text_diff() {
|
|||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().dom_edits,
|
vdom.render_immediate().edits,
|
||||||
[SetText { value: "hello 1", id: ElementId(2) }]
|
[SetText { value: "hello 1", id: ElementId(2) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().dom_edits,
|
vdom.render_immediate().edits,
|
||||||
[SetText { value: "hello 2", id: ElementId(2) }]
|
[SetText { value: "hello 2", id: ElementId(2) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().dom_edits,
|
vdom.render_immediate().edits,
|
||||||
[SetText { value: "hello 3", id: ElementId(2) }]
|
[SetText { value: "hello 3", id: ElementId(2) }]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ fn element_swap() {
|
|||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().santize().dom_edits,
|
vdom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||||
@@ -57,7 +57,7 @@ fn element_swap() {
|
|||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().santize().dom_edits,
|
vdom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||||
@@ -66,7 +66,7 @@ fn element_swap() {
|
|||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().santize().dom_edits,
|
vdom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
ReplaceWith { id: ElementId(1,), m: 1 },
|
ReplaceWith { id: ElementId(1,), m: 1 },
|
||||||
@@ -75,7 +75,7 @@ fn element_swap() {
|
|||||||
|
|
||||||
vdom.mark_dirty(ScopeId(0));
|
vdom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vdom.render_immediate().santize().dom_edits,
|
vdom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||||
ReplaceWith { id: ElementId(2,), m: 1 },
|
ReplaceWith { id: ElementId(2,), m: 1 },
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fn keyed_diffing_out_of_order() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
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(1,) },
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
@@ -39,7 +39,7 @@ fn keyed_diffing_out_of_order() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().dom_edits,
|
dom.render_immediate().edits,
|
||||||
[
|
[
|
||||||
PushRoot { id: ElementId(7,) },
|
PushRoot { id: ElementId(7,) },
|
||||||
InsertBefore { id: ElementId(5,), m: 1 },
|
InsertBefore { id: ElementId(5,), m: 1 },
|
||||||
@@ -64,7 +64,7 @@ fn keyed_diffing_out_of_order_adds() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().dom_edits,
|
dom.render_immediate().edits,
|
||||||
[
|
[
|
||||||
PushRoot { id: ElementId(5,) },
|
PushRoot { id: ElementId(5,) },
|
||||||
PushRoot { id: ElementId(4,) },
|
PushRoot { id: ElementId(4,) },
|
||||||
@@ -90,7 +90,7 @@ fn keyed_diffing_out_of_order_adds_3() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().dom_edits,
|
dom.render_immediate().edits,
|
||||||
[
|
[
|
||||||
PushRoot { id: ElementId(5,) },
|
PushRoot { id: ElementId(5,) },
|
||||||
PushRoot { id: ElementId(4,) },
|
PushRoot { id: ElementId(4,) },
|
||||||
@@ -116,7 +116,7 @@ fn keyed_diffing_out_of_order_adds_4() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().dom_edits,
|
dom.render_immediate().edits,
|
||||||
[
|
[
|
||||||
PushRoot { id: ElementId(5,) },
|
PushRoot { id: ElementId(5,) },
|
||||||
PushRoot { id: ElementId(4,) },
|
PushRoot { id: ElementId(4,) },
|
||||||
@@ -142,7 +142,7 @@ fn keyed_diffing_out_of_order_adds_5() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().dom_edits,
|
dom.render_immediate().edits,
|
||||||
[
|
[
|
||||||
PushRoot { id: ElementId(5,) },
|
PushRoot { id: ElementId(5,) },
|
||||||
InsertBefore { id: ElementId(4,), m: 1 },
|
InsertBefore { id: ElementId(4,), m: 1 },
|
||||||
@@ -167,7 +167,7 @@ fn keyed_diffing_additions() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
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(6) },
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(7) },
|
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));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
// create 11, 12
|
// create 11, 12
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||||
@@ -222,7 +222,7 @@ fn keyed_diffing_additions_and_moves_in_middle() {
|
|||||||
// LIS: 4, 5, 6
|
// LIS: 4, 5, 6
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
// create 5, 6
|
// create 5, 6
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||||
@@ -256,7 +256,7 @@ fn controlled_keyed_diffing_out_of_order() {
|
|||||||
// LIS: 5, 6
|
// LIS: 5, 6
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
// remove 7
|
// remove 7
|
||||||
Remove { id: ElementId(4,) },
|
Remove { id: ElementId(4,) },
|
||||||
@@ -289,7 +289,7 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
Remove { id: ElementId(5,) },
|
Remove { id: ElementId(5,) },
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(5) },
|
||||||
@@ -318,7 +318,7 @@ fn remove_list() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
Remove { id: ElementId(3) },
|
Remove { id: ElementId(3) },
|
||||||
Remove { id: ElementId(4) },
|
Remove { id: ElementId(4) },
|
||||||
@@ -343,7 +343,7 @@ fn no_common_keys() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
Remove { id: ElementId(2) },
|
Remove { id: ElementId(2) },
|
||||||
Remove { id: ElementId(3) },
|
Remove { id: ElementId(3) },
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ fn list_creates_one_by_one() {
|
|||||||
|
|
||||||
// load the div and then assign the empty fragment as a placeholder
|
// load the div and then assign the empty fragment as a placeholder
|
||||||
assert_eq!(
|
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(1,) },
|
||||||
AssignId { path: &[0], id: ElementId(2,) },
|
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
|
// Rendering the first item should replace the placeholder with an element
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(3,) },
|
||||||
HydrateText { path: &[0], value: "0", id: ElementId(4,) },
|
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
|
// Rendering the next item should insert after the previous
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
HydrateText { path: &[0], value: "1", id: ElementId(5,) },
|
HydrateText { path: &[0], value: "1", id: ElementId(5,) },
|
||||||
@@ -50,7 +50,7 @@ fn list_creates_one_by_one() {
|
|||||||
// ... and again!
|
// ... and again!
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
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(6,) },
|
||||||
HydrateText { path: &[0], value: "2", id: ElementId(7,) },
|
HydrateText { path: &[0], value: "2", id: ElementId(7,) },
|
||||||
@@ -61,7 +61,7 @@ fn list_creates_one_by_one() {
|
|||||||
// once more
|
// once more
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(8,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(8,) },
|
||||||
HydrateText { path: &[0], value: "3", id: ElementId(9,) },
|
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
|
// load the div and then assign the empty fragment as a placeholder
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.rebuild().santize().dom_edits,
|
dom.rebuild().santize().edits,
|
||||||
[
|
[
|
||||||
// The container
|
// The container
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
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
|
// Rendering the first item should replace the placeholder with an element
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[Remove { id: ElementId(6) }]
|
[Remove { id: ElementId(6) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove div(2)
|
// Remove div(2)
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[Remove { id: ElementId(4) }]
|
[Remove { id: ElementId(4) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ fn removes_one_by_one() {
|
|||||||
// todo: this should just be a remove with no placeholder
|
// todo: this should just be a remove with no placeholder
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
CreatePlaceholder { id: ElementId(3) },
|
CreatePlaceholder { id: ElementId(3) },
|
||||||
ReplaceWith { id: ElementId(2), m: 1 }
|
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
|
// todo: this should actually be append to, but replace placeholder is fine for now
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||||
HydrateText { path: &[0], value: "0", id: ElementId(4) },
|
HydrateText { path: &[0], value: "0", id: ElementId(4) },
|
||||||
@@ -161,7 +161,7 @@ fn list_shrink_multiroot() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(
|
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(1,) },
|
||||||
AssignId { path: &[0,], id: ElementId(2,) },
|
AssignId { path: &[0,], id: ElementId(2,) },
|
||||||
@@ -171,7 +171,7 @@ fn list_shrink_multiroot() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
||||||
HydrateText { path: &[0], value: "0", id: ElementId(4) },
|
HydrateText { path: &[0], value: "0", id: ElementId(4) },
|
||||||
@@ -183,7 +183,7 @@ fn list_shrink_multiroot() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2) },
|
||||||
HydrateText { path: &[0], value: "1", id: ElementId(7) },
|
HydrateText { path: &[0], value: "1", id: ElementId(7) },
|
||||||
@@ -195,7 +195,7 @@ fn list_shrink_multiroot() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(10) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(10) },
|
||||||
HydrateText { path: &[0], value: "2", id: ElementId(11) },
|
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
|
// load the div and then assign the empty fragment as a placeholder
|
||||||
assert_eq!(
|
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(1) },
|
||||||
//
|
//
|
||||||
@@ -250,19 +250,19 @@ fn removes_one_by_one_multiroot() {
|
|||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[Remove { id: ElementId(10) }, Remove { id: ElementId(12) }]
|
[Remove { id: ElementId(10) }, Remove { id: ElementId(12) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[Remove { id: ElementId(6) }, Remove { id: ElementId(8) }]
|
[Remove { id: ElementId(6) }, Remove { id: ElementId(8) }]
|
||||||
);
|
);
|
||||||
|
|
||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.render_immediate().santize().dom_edits,
|
dom.render_immediate().santize().edits,
|
||||||
[
|
[
|
||||||
Remove { id: ElementId(4) },
|
Remove { id: ElementId(4) },
|
||||||
CreatePlaceholder { id: ElementId(5) },
|
CreatePlaceholder { id: ElementId(5) },
|
||||||
@@ -282,7 +282,7 @@ fn two_equal_fragments_are_equal_static() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_ = dom.rebuild();
|
_ = dom.rebuild();
|
||||||
assert!(dom.render_immediate().dom_edits.is_empty());
|
assert!(dom.render_immediate().edits.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -296,7 +296,7 @@ fn two_equal_fragments_are_equal() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_ = dom.rebuild();
|
_ = dom.rebuild();
|
||||||
assert!(dom.render_immediate().dom_edits.is_empty());
|
assert!(dom.render_immediate().edits.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -315,9 +315,9 @@ fn remove_many() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let edits = dom.rebuild().santize();
|
let edits = dom.rebuild().santize();
|
||||||
assert!(edits.template_edits.is_empty());
|
assert!(edits.templates.is_empty());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
CreatePlaceholder { id: ElementId(1,) },
|
CreatePlaceholder { id: ElementId(1,) },
|
||||||
AppendChildren { m: 1 },
|
AppendChildren { m: 1 },
|
||||||
@@ -327,7 +327,7 @@ fn remove_many() {
|
|||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
let edits = dom.render_immediate().santize();
|
let edits = dom.render_immediate().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
|
HydrateText { path: &[0,], value: "hello 0", id: ElementId(3,) },
|
||||||
@@ -338,7 +338,7 @@ fn remove_many() {
|
|||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
let edits = dom.render_immediate().santize();
|
let edits = dom.render_immediate().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1,) },
|
||||||
HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
|
HydrateText { path: &[0,], value: "hello 1", id: ElementId(4,) },
|
||||||
@@ -355,7 +355,7 @@ fn remove_many() {
|
|||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
let edits = dom.render_immediate().santize();
|
let edits = dom.render_immediate().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
Remove { id: ElementId(1,) },
|
Remove { id: ElementId(1,) },
|
||||||
Remove { id: ElementId(5,) },
|
Remove { id: ElementId(5,) },
|
||||||
@@ -369,7 +369,7 @@ fn remove_many() {
|
|||||||
dom.mark_dirty(ScopeId(0));
|
dom.mark_dirty(ScopeId(0));
|
||||||
let edits = dom.render_immediate().santize();
|
let edits = dom.render_immediate().santize();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(2,) },
|
||||||
HydrateText { path: &[0,], value: "hello 0", id: ElementId(10,) },
|
HydrateText { path: &[0,], value: "hello 0", id: ElementId(10,) },
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ fn dual_stream() {
|
|||||||
|
|
||||||
use Mutation::*;
|
use Mutation::*;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.template_edits,
|
edits.templates,
|
||||||
[
|
[
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
SetStaticAttribute { name: "class", value: "asd", ns: None },
|
SetStaticAttribute { name: "class", value: "asd", ns: None },
|
||||||
@@ -66,7 +66,7 @@ fn dual_stream() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
SetAttribute { name: "class", value: "123", id: ElementId(1), ns: None },
|
SetAttribute { name: "class", value: "123", id: ElementId(1), ns: None },
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ fn manual_diffing() {
|
|||||||
*value.lock().unwrap() = "goodbye";
|
*value.lock().unwrap() = "goodbye";
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
dom.rebuild().santize().dom_edits,
|
dom.rebuild().santize().edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(3) },
|
||||||
HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
|
HydrateText { path: &[0], value: "goodbye", id: ElementId(4) },
|
||||||
@@ -62,7 +62,7 @@ fn events_generate() {
|
|||||||
let edits = dom.render_immediate();
|
let edits = dom.render_immediate();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
edits.dom_edits,
|
edits.edits,
|
||||||
[
|
[
|
||||||
CreatePlaceholder { id: ElementId(2) },
|
CreatePlaceholder { id: ElementId(2) },
|
||||||
ReplaceWith { id: ElementId(1), m: 1 }
|
ReplaceWith { id: ElementId(1), m: 1 }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ async fn it_works() {
|
|||||||
|
|
||||||
// We should at least get the top-level template in before pausing for the children
|
// We should at least get the top-level template in before pausing for the children
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mutations.template_edits,
|
mutations.templates,
|
||||||
[
|
[
|
||||||
CreateElement { name: "div" },
|
CreateElement { name: "div" },
|
||||||
CreateStaticText { value: "Waiting for child..." },
|
CreateStaticText { value: "Waiting for child..." },
|
||||||
@@ -25,7 +25,7 @@ async fn it_works() {
|
|||||||
|
|
||||||
// And we should load it in and assign the placeholder properly
|
// And we should load it in and assign the placeholder properly
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
mutations.dom_edits,
|
mutations.edits,
|
||||||
[
|
[
|
||||||
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
LoadTemplate { name: "template", index: 0, id: ElementId(1) },
|
||||||
// hmmmmmmmmm.... with suspense how do we guarantee that IDs increase linearly?
|
// hmmmmmmmmm.... with suspense how do we guarantee that IDs increase linearly?
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ impl DesktopController {
|
|||||||
{
|
{
|
||||||
let edits = dom.rebuild();
|
let edits = dom.rebuild();
|
||||||
let mut queue = edit_queue.lock().unwrap();
|
let mut queue = edit_queue.lock().unwrap();
|
||||||
queue.push(serde_json::to_string(&edits.template_edits).unwrap());
|
queue.push(serde_json::to_string(&edits.templates).unwrap());
|
||||||
queue.push(serde_json::to_string(&edits.dom_edits).unwrap());
|
queue.push(serde_json::to_string(&edits.edits).unwrap());
|
||||||
proxy.send_event(UserWindowEvent::EditsReady).unwrap();
|
proxy.send_event(UserWindowEvent::EditsReady).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +79,8 @@ impl DesktopController {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut queue = edit_queue.lock().unwrap();
|
let mut queue = edit_queue.lock().unwrap();
|
||||||
queue.push(serde_json::to_string(&muts.template_edits).unwrap());
|
queue.push(serde_json::to_string(&muts.templates).unwrap());
|
||||||
queue.push(serde_json::to_string(&muts.dom_edits).unwrap());
|
queue.push(serde_json::to_string(&muts.edits).unwrap());
|
||||||
let _ = proxy.send_event(UserWindowEvent::EditsReady);
|
let _ = proxy.send_event(UserWindowEvent::EditsReady);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ fn create_rows(c: &mut Criterion) {
|
|||||||
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let g = dom.rebuild();
|
let g = dom.rebuild();
|
||||||
assert!(g.dom_edits.len() > 1);
|
assert!(g.edits.len() > 1);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,14 @@ pub mod events;
|
|||||||
pub mod geometry;
|
pub mod geometry;
|
||||||
mod global_attributes;
|
mod global_attributes;
|
||||||
pub mod input_data;
|
pub mod input_data;
|
||||||
|
mod render_template;
|
||||||
#[cfg(feature = "wasm-bind")]
|
#[cfg(feature = "wasm-bind")]
|
||||||
mod web_sys_bind;
|
mod web_sys_bind;
|
||||||
|
|
||||||
pub use elements::*;
|
pub use elements::*;
|
||||||
pub use events::*;
|
pub use events::*;
|
||||||
pub use global_attributes::*;
|
pub use global_attributes::*;
|
||||||
|
pub use render_template::*;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::events::*;
|
pub use crate::events::*;
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use dioxus_core::{Template, TemplateAttribute, TemplateNode};
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
/// Render a template to an HTML string
|
||||||
|
///
|
||||||
|
/// Useful for sending over the wire. Can be used to with innerHtml to create templates with little work
|
||||||
|
pub fn render_template_to_html(template: &Template) -> String {
|
||||||
|
let mut out = String::new();
|
||||||
|
|
||||||
|
for root in template.roots {
|
||||||
|
render_template_node(root, &mut out).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_template_node(node: &TemplateNode, out: &mut String) -> std::fmt::Result {
|
||||||
|
match node {
|
||||||
|
TemplateNode::Element {
|
||||||
|
tag,
|
||||||
|
attrs,
|
||||||
|
children,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
write!(out, "<{tag}")?;
|
||||||
|
for attr in *attrs {
|
||||||
|
if let TemplateAttribute::Static { name, value, .. } = attr {
|
||||||
|
write!(out, "{}=\"{}\"", name, value)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for child in *children {
|
||||||
|
render_template_node(child, out)?;
|
||||||
|
}
|
||||||
|
write!(out, "</{tag}>")?;
|
||||||
|
}
|
||||||
|
TemplateNode::Text(t) => write!(out, "{t}")?,
|
||||||
|
TemplateNode::Dynamic(_) => write!(out, "<pre hidden />")?,
|
||||||
|
TemplateNode::DynamicText(t) => write!(out, "<!-- --> {t} <!-- -->")?,
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use js_sys::Function;
|
use js_sys::Function;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use web_sys::Element;
|
use web_sys::{Element, Node};
|
||||||
|
|
||||||
#[wasm_bindgen(module = "/src/interpreter.js")]
|
#[wasm_bindgen(module = "/src/interpreter.js")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -12,29 +12,17 @@ extern "C" {
|
|||||||
pub fn new(arg: Element) -> Interpreter;
|
pub fn new(arg: Element) -> Interpreter;
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn AppendChildren(this: &Interpreter, many: u32);
|
pub fn SaveTemplate(this: &Interpreter, nodes: Vec<Node>, name: &str);
|
||||||
|
|
||||||
|
#[wasm_bindgen(method)]
|
||||||
|
pub fn MountToRoot(this: &Interpreter);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn AssignId(this: &Interpreter, path: &[u8], id: u32);
|
pub fn AssignId(this: &Interpreter, path: &[u8], id: u32);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn CreateElement(this: &Interpreter, tag: &str);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn CreateElementNs(this: &Interpreter, tag: &str, ns: &str);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn CreatePlaceholder(this: &Interpreter, id: u32);
|
pub fn CreatePlaceholder(this: &Interpreter, id: u32);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn CreateStaticPlaceholder(this: &Interpreter);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn CreateTextPlaceholder(this: &Interpreter);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn CreateStaticText(this: &Interpreter, value: &str);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn CreateTextNode(this: &Interpreter, value: JsValue, id: u32);
|
pub fn CreateTextNode(this: &Interpreter, value: JsValue, id: u32);
|
||||||
|
|
||||||
@@ -56,15 +44,9 @@ extern "C" {
|
|||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn InsertBefore(this: &Interpreter, id: u32, n: u32);
|
pub fn InsertBefore(this: &Interpreter, id: u32, n: u32);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn SaveTemplate(this: &Interpreter, name: &str, m: u32);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn SetAttribute(this: &Interpreter, id: u32, name: &str, value: JsValue, ns: Option<&str>);
|
pub fn SetAttribute(this: &Interpreter, id: u32, name: &str, value: JsValue, ns: Option<&str>);
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn SetStaticAttribute(this: &Interpreter, name: &str, value: JsValue, ns: Option<&str>);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
pub fn SetBoolAttribute(this: &Interpreter, id: u32, name: &str, value: bool);
|
pub fn SetBoolAttribute(this: &Interpreter, id: u32, name: &str, value: bool);
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,13 @@ export class Interpreter {
|
|||||||
pop() {
|
pop() {
|
||||||
return this.stack.pop();
|
return this.stack.pop();
|
||||||
}
|
}
|
||||||
|
SaveTemplate(nodes, name) {
|
||||||
|
this.templates[name] = nodes;
|
||||||
|
console.log(this.templates);
|
||||||
|
}
|
||||||
|
MountToRoot() {
|
||||||
|
this.AppendChildren(this.stack.length - 1);
|
||||||
|
}
|
||||||
SetNode(id, node) {
|
SetNode(id, node) {
|
||||||
this.nodes[id] = node;
|
this.nodes[id] = node;
|
||||||
}
|
}
|
||||||
@@ -132,25 +139,12 @@ export class Interpreter {
|
|||||||
this.nodes[root] = node;
|
this.nodes[root] = node;
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
}
|
}
|
||||||
CreateElement(tag) {
|
|
||||||
const el = document.createElement(tag);
|
|
||||||
this.stack.push(el);
|
|
||||||
}
|
|
||||||
CreateElementNs(tag, ns) {
|
|
||||||
let el = document.createElementNS(ns, tag);
|
|
||||||
this.stack.push(el);
|
|
||||||
}
|
|
||||||
CreatePlaceholder(root) {
|
CreatePlaceholder(root) {
|
||||||
let el = document.createElement("pre");
|
let el = document.createElement("pre");
|
||||||
el.hidden = true;
|
el.hidden = true;
|
||||||
this.stack.push(el);
|
this.stack.push(el);
|
||||||
this.nodes[root] = el;
|
this.nodes[root] = el;
|
||||||
}
|
}
|
||||||
CreateStaticPlaceholder() {
|
|
||||||
let el = document.createElement("pre");
|
|
||||||
el.hidden = true;
|
|
||||||
this.stack.push(el);
|
|
||||||
}
|
|
||||||
NewEventListener(event_name, root, handler, bubbles) {
|
NewEventListener(event_name, root, handler, bubbles) {
|
||||||
const element = this.nodes[root];
|
const element = this.nodes[root];
|
||||||
element.setAttribute("data-dioxus-id", `${root}`);
|
element.setAttribute("data-dioxus-id", `${root}`);
|
||||||
@@ -168,10 +162,6 @@ export class Interpreter {
|
|||||||
const node = this.nodes[id];
|
const node = this.nodes[id];
|
||||||
this.SetAttributeInner(node, field, value, ns);
|
this.SetAttributeInner(node, field, value, ns);
|
||||||
}
|
}
|
||||||
SetStaticAttribute(field, value, ns) {
|
|
||||||
const node = this.top();
|
|
||||||
this.SetAttributeInner(node, field, value, ns);
|
|
||||||
}
|
|
||||||
SetAttributeInner(node, field, value, ns) {
|
SetAttributeInner(node, field, value, ns) {
|
||||||
const name = field;
|
const name = field;
|
||||||
if (ns === "style") {
|
if (ns === "style") {
|
||||||
@@ -262,15 +252,6 @@ export class Interpreter {
|
|||||||
this.nodes[id] = node;
|
this.nodes[id] = node;
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
}
|
}
|
||||||
SaveTemplate(name, m) {
|
|
||||||
this.templates[name] = this.stack.splice(this.stack.length - m);
|
|
||||||
}
|
|
||||||
CreateStaticText(text) {
|
|
||||||
this.CreateTextNode(text);
|
|
||||||
}
|
|
||||||
CreateTextPlaceholder() {
|
|
||||||
this.CreateRawText("placeholder");
|
|
||||||
}
|
|
||||||
handleEdit(edit) {
|
handleEdit(edit) {
|
||||||
console.log(edit);
|
console.log(edit);
|
||||||
switch (edit.type) {
|
switch (edit.type) {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ impl<S: State> RealDom<S> {
|
|||||||
let mut nodes_updated = Vec::new();
|
let mut nodes_updated = Vec::new();
|
||||||
nodes_updated.push((RealNodeId::ElementId(ElementId(0)), NodeMask::ALL));
|
nodes_updated.push((RealNodeId::ElementId(ElementId(0)), NodeMask::ALL));
|
||||||
for mutations in mutations_vec {
|
for mutations in mutations_vec {
|
||||||
for e in mutations.dom_edits {
|
for e in mutations.edits {
|
||||||
use dioxus_core::DomEdit::*;
|
use dioxus_core::DomEdit::*;
|
||||||
match e {
|
match e {
|
||||||
AppendChildren { root, children } => {
|
AppendChildren { root, children } => {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl PersistantElementIter {
|
|||||||
pub fn prune<S: State>(&mut self, mutations: &Mutations, rdom: &RealDom<S>) -> bool {
|
pub fn prune<S: State>(&mut self, mutations: &Mutations, rdom: &RealDom<S>) -> bool {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
let ids_removed: Vec<_> = mutations
|
let ids_removed: Vec<_> = mutations
|
||||||
.dom_edits
|
.edits
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
// nodes within templates will never be removed
|
// nodes within templates will never be removed
|
||||||
@@ -97,7 +97,7 @@ impl PersistantElementIter {
|
|||||||
for (el_id, child_idx) in self.stack.iter_mut() {
|
for (el_id, child_idx) in self.stack.iter_mut() {
|
||||||
if let NodePosition::InChild(child_idx) = child_idx {
|
if let NodePosition::InChild(child_idx) = child_idx {
|
||||||
if let NodeType::Element { children, .. } = &rdom[*el_id].node_data.node_type {
|
if let NodeType::Element { children, .. } = &rdom[*el_id].node_data.node_type {
|
||||||
for m in &mutations.dom_edits {
|
for m in &mutations.edits {
|
||||||
match m {
|
match m {
|
||||||
DomEdit::Remove { root } => {
|
DomEdit::Remove { root } => {
|
||||||
let id = rdom.resolve_maybe_id(*root);
|
let id = rdom.resolve_maybe_id(*root);
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ impl FocusState {
|
|||||||
if self.focus_iter.prune(mutations, rdom) {
|
if self.focus_iter.prune(mutations, rdom) {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
for m in &mutations.dom_edits {
|
for m in &mutations.edits {
|
||||||
match m {
|
match m {
|
||||||
dioxus_core::DomEdit::ReplaceWith { root, .. } => remove_children(
|
dioxus_core::DomEdit::ReplaceWith { root, .. } => remove_children(
|
||||||
&mut [&mut self.last_focused_id],
|
&mut [&mut self.last_focused_id],
|
||||||
|
|||||||
+67
-11
@@ -7,7 +7,7 @@
|
|||||||
//! - tests to ensure dyn_into works for various event types.
|
//! - tests to ensure dyn_into works for various event types.
|
||||||
//! - Partial delegation?>
|
//! - Partial delegation?>
|
||||||
|
|
||||||
use dioxus_core::{ElementId, Mutation, Mutations};
|
use dioxus_core::{ElementId, Mutation, Mutations, Template, TemplateAttribute, TemplateNode};
|
||||||
use dioxus_html::{event_bubbles, CompositionData, FormData};
|
use dioxus_html::{event_bubbles, CompositionData, FormData};
|
||||||
use dioxus_interpreter_js::Interpreter;
|
use dioxus_interpreter_js::Interpreter;
|
||||||
use futures_channel::mpsc;
|
use futures_channel::mpsc;
|
||||||
@@ -19,6 +19,7 @@ use web_sys::{Document, Element, Event, HtmlElement};
|
|||||||
use crate::Config;
|
use crate::Config;
|
||||||
|
|
||||||
pub struct WebsysDom {
|
pub struct WebsysDom {
|
||||||
|
document: Document,
|
||||||
interpreter: Interpreter,
|
interpreter: Interpreter,
|
||||||
handler: Closure<dyn FnMut(&Event)>,
|
handler: Closure<dyn FnMut(&Event)>,
|
||||||
root: Element,
|
root: Element,
|
||||||
@@ -35,6 +36,7 @@ impl WebsysDom {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
document,
|
||||||
interpreter: Interpreter::new(root.clone()),
|
interpreter: Interpreter::new(root.clone()),
|
||||||
root,
|
root,
|
||||||
handler: Closure::wrap(Box::new(move |event: &web_sys::Event| {
|
handler: Closure::wrap(Box::new(move |event: &web_sys::Event| {
|
||||||
@@ -43,20 +45,78 @@ impl WebsysDom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mount(&mut self) {
|
||||||
|
self.interpreter.MountToRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_templates(&mut self, templates: &[Template]) {
|
||||||
|
log::debug!("Loading templates {:?}", templates);
|
||||||
|
|
||||||
|
for template in templates {
|
||||||
|
let mut roots = vec![];
|
||||||
|
|
||||||
|
for root in template.roots {
|
||||||
|
roots.push(self.create_template_node(root))
|
||||||
|
}
|
||||||
|
|
||||||
|
self.interpreter.SaveTemplate(roots, template.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_template_node(&self, v: &TemplateNode) -> web_sys::Node {
|
||||||
|
match v {
|
||||||
|
TemplateNode::Element {
|
||||||
|
tag,
|
||||||
|
namespace,
|
||||||
|
attrs,
|
||||||
|
children,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let el = match namespace {
|
||||||
|
Some(ns) => self.document.create_element_ns(Some(ns), tag).unwrap(),
|
||||||
|
None => self.document.create_element(tag).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for attr in *attrs {
|
||||||
|
if let TemplateAttribute::Static {
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
namespace,
|
||||||
|
volatile,
|
||||||
|
} = attr
|
||||||
|
{
|
||||||
|
match namespace {
|
||||||
|
Some(ns) => el.set_attribute_ns(Some(ns), name, value).unwrap(),
|
||||||
|
None => el.set_attribute(name, value).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for child in *children {
|
||||||
|
el.append_child(&self.create_template_node(child));
|
||||||
|
}
|
||||||
|
|
||||||
|
el.dyn_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
TemplateNode::Text(t) => self.document.create_text_node(t).dyn_into().unwrap(),
|
||||||
|
TemplateNode::DynamicText(_) => self.document.create_text_node("p").dyn_into().unwrap(),
|
||||||
|
TemplateNode::Dynamic(_) => {
|
||||||
|
let el = self.document.create_element("pre").unwrap();
|
||||||
|
el.toggle_attribute("hidden");
|
||||||
|
el.dyn_into().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_edits(&mut self, mut edits: Vec<Mutation>) {
|
pub fn apply_edits(&mut self, mut edits: Vec<Mutation>) {
|
||||||
use Mutation::*;
|
use Mutation::*;
|
||||||
let i = &self.interpreter;
|
let i = &self.interpreter;
|
||||||
|
|
||||||
for edit in edits.drain(..) {
|
for edit in edits.drain(..) {
|
||||||
match edit {
|
match edit {
|
||||||
AppendChildren { m } => i.AppendChildren(m as u32),
|
|
||||||
AssignId { path, id } => i.AssignId(path, id.0 as u32),
|
AssignId { path, id } => i.AssignId(path, id.0 as u32),
|
||||||
CreateElement { name } => i.CreateElement(name),
|
|
||||||
CreateElementNamespace { name, namespace } => i.CreateElementNs(name, namespace),
|
|
||||||
CreatePlaceholder { id } => i.CreatePlaceholder(id.0 as u32),
|
CreatePlaceholder { id } => i.CreatePlaceholder(id.0 as u32),
|
||||||
CreateStaticPlaceholder => i.CreateStaticPlaceholder(),
|
|
||||||
CreateTextPlaceholder => i.CreateTextPlaceholder(),
|
|
||||||
CreateStaticText { value } => i.CreateStaticText(value),
|
|
||||||
CreateTextNode { value, id } => i.CreateTextNode(value.into(), id.0 as u32),
|
CreateTextNode { value, id } => i.CreateTextNode(value.into(), id.0 as u32),
|
||||||
HydrateText { path, value, id } => i.HydrateText(path, value, id.0 as u32),
|
HydrateText { path, value, id } => i.HydrateText(path, value, id.0 as u32),
|
||||||
LoadTemplate { name, index, id } => i.LoadTemplate(name, index as u32, id.0 as u32),
|
LoadTemplate { name, index, id } => i.LoadTemplate(name, index as u32, id.0 as u32),
|
||||||
@@ -64,16 +124,12 @@ impl WebsysDom {
|
|||||||
ReplacePlaceholder { path, m } => i.ReplacePlaceholder(path, m as u32),
|
ReplacePlaceholder { path, m } => i.ReplacePlaceholder(path, m as u32),
|
||||||
InsertAfter { id, m } => i.InsertAfter(id.0 as u32, m as u32),
|
InsertAfter { id, m } => i.InsertAfter(id.0 as u32, m as u32),
|
||||||
InsertBefore { id, m } => i.InsertBefore(id.0 as u32, m as u32),
|
InsertBefore { id, m } => i.InsertBefore(id.0 as u32, m as u32),
|
||||||
SaveTemplate { name, m } => i.SaveTemplate(name, m as u32),
|
|
||||||
SetAttribute {
|
SetAttribute {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
id,
|
id,
|
||||||
ns,
|
ns,
|
||||||
} => i.SetAttribute(id.0 as u32, name, value.into(), ns),
|
} => i.SetAttribute(id.0 as u32, name, value.into(), ns),
|
||||||
SetStaticAttribute { name, value, ns } => {
|
|
||||||
i.SetStaticAttribute(name, value.into(), ns)
|
|
||||||
}
|
|
||||||
SetBoolAttribute { name, value, id } => {
|
SetBoolAttribute { name, value, id } => {
|
||||||
i.SetBoolAttribute(id.0 as u32, name, value)
|
i.SetBoolAttribute(id.0 as u32, name, value)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-9
@@ -189,17 +189,20 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
|
|||||||
|
|
||||||
log::info!("rebuilding app");
|
log::info!("rebuilding app");
|
||||||
|
|
||||||
if should_hydrate {
|
// if should_hydrate {
|
||||||
} else {
|
// } else {
|
||||||
let edits = dom.rebuild();
|
let edits = dom.rebuild();
|
||||||
websys_dom.apply_edits(edits.template_edits);
|
|
||||||
websys_dom.apply_edits(edits.dom_edits);
|
log::debug!("Initial edits {:#?}", edits);
|
||||||
}
|
|
||||||
|
websys_dom.load_templates(&edits.templates);
|
||||||
|
websys_dom.apply_edits(edits.edits);
|
||||||
|
websys_dom.mount();
|
||||||
|
|
||||||
let mut work_loop = ric_raf::RafLoop::new();
|
let mut work_loop = ric_raf::RafLoop::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
log::trace!("waiting for work");
|
log::debug!("waiting for work");
|
||||||
|
|
||||||
// if virtualdom has nothing, wait for it to have something before requesting idle time
|
// if virtualdom has nothing, wait for it to have something before requesting idle time
|
||||||
// if there is work then this future resolves immediately.
|
// if there is work then this future resolves immediately.
|
||||||
@@ -240,6 +243,7 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
|
|||||||
let deadline = work_loop.wait_for_idle_time().await;
|
let deadline = work_loop.wait_for_idle_time().await;
|
||||||
|
|
||||||
// run the virtualdom work phase until the frame deadline is reached
|
// run the virtualdom work phase until the frame deadline is reached
|
||||||
|
// let deadline = gloo_timers::future::sleep(Duration::from_millis(10000));
|
||||||
let edits = dom.render_with_deadline(deadline).await;
|
let edits = dom.render_with_deadline(deadline).await;
|
||||||
|
|
||||||
// wait for the animation frame to fire so we can apply our changes
|
// wait for the animation frame to fire so we can apply our changes
|
||||||
@@ -247,8 +251,8 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
|
|||||||
|
|
||||||
log::debug!("edits {:#?}", edits);
|
log::debug!("edits {:#?}", edits);
|
||||||
|
|
||||||
websys_dom.apply_edits(edits.template_edits);
|
websys_dom.load_templates(&edits.templates);
|
||||||
websys_dom.apply_edits(edits.dom_edits);
|
websys_dom.apply_edits(edits.edits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fn makes_tree() {
|
|||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
let muts = dom.rebuild();
|
let muts = dom.rebuild();
|
||||||
|
|
||||||
dbg!(muts.dom_edits);
|
dbg!(muts.edits);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen_test]
|
#[wasm_bindgen_test]
|
||||||
|
|||||||
Reference in new issue
Block a user