Refactor Mutations and simplify Templates (#578)

* update mutations to be path based rather than renderer integrated
This commit is contained in:
Demonthos authored and GitHub committed 2022-10-18 14:42:45 -07:00
1 parent 020c4bf0f8
commit 3b7b503333
44 files changed
+2643 -3134

No files matched your search

+102 -213
View File
@@ -44,57 +44,53 @@ impl Debug for Mutations<'_> {
serde(tag = "type")
)]
pub enum DomEdit<'bump> {
/// Push the given root node onto our stack.
PushRoot {
/// The ID of the root node to push.
root: u64,
},
/// 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.
many: u32,
/// The parent to append nodes to.
root: Option<u64>,
/// The ids of the children to append.
children: Vec<u64>,
},
/// Replace a given (single) node with a handful of nodes currently on the stack.
ReplaceWith {
/// The ID of the node to be replaced.
root: u64,
root: Option<u64>,
/// How many nodes should be popped from the stack to replace the target node.
m: u32,
/// The ids of the nodes to replace the root with.
nodes: Vec<u64>,
},
/// Insert a number of nodes after a given node.
InsertAfter {
/// The ID of the node to insert after.
root: u64,
root: Option<u64>,
/// How many nodes should be popped from the stack to insert after the target node.
n: u32,
/// The ids of the nodes to insert after the target node.
nodes: Vec<u64>,
},
/// Insert a number of nodes before a given node.
InsertBefore {
/// The ID of the node to insert before.
root: u64,
root: Option<u64>,
/// How many nodes should be popped from the stack to insert before the target node.
n: u32,
/// The ids of the nodes to insert before the target node.
nodes: Vec<u64>,
},
/// Remove a particular node from the DOM
Remove {
/// The ID of the node to remove.
root: u64,
root: Option<u64>,
},
/// Create a new purely-text node
CreateTextNode {
/// The ID the new node should have.
root: u64,
root: Option<u64>,
/// The textcontent of the node
text: &'bump str,
@@ -103,82 +99,35 @@ pub enum DomEdit<'bump> {
/// Create a new purely-element node
CreateElement {
/// The ID the new node should have.
root: u64,
root: Option<u64>,
/// The tagname of the node
tag: &'bump str,
/// The number of children nodes that will follow this message.
children: u32,
},
/// Create a new purely-comment node with a given namespace
CreateElementNs {
/// The ID the new node should have.
root: u64,
root: Option<u64>,
/// The namespace of the node
tag: &'bump str,
/// The namespace of the node (like `SVG`)
ns: &'static str,
/// The number of children nodes that will follow this message.
children: u32,
},
/// Create a new placeholder node.
/// In most implementations, this will either be a hidden div or a comment node.
CreatePlaceholder {
/// The ID the new node should have.
root: u64,
},
/// Create a new purely-text node in a template
CreateTextNodeTemplate {
/// The ID the new node should have.
root: u64,
/// The textcontent of the noden
text: &'bump str,
/// If the id of the node must be kept in the refrences
locally_static: bool,
},
/// Create a new purely-element node in a template
CreateElementTemplate {
/// The ID the new node should have.
root: u64,
/// The tagname of the node
tag: &'bump str,
/// If the id of the node must be kept in the refrences
locally_static: bool,
/// If any children of this node must be kept in the references
fully_static: bool,
},
/// Create a new purely-comment node with a given namespace in a template
CreateElementNsTemplate {
/// The ID the new node should have.
root: u64,
/// The namespace of the node
tag: &'bump str,
/// The namespace of the node (like `SVG`)
ns: &'static str,
/// If the id of the node must be kept in the refrences
locally_static: bool,
/// If any children of this node must be kept in the references
fully_static: bool,
},
/// Create a new placeholder node.
/// In most implementations, this will either be a hidden div or a comment node. in a template
/// Always both locally and fully static
CreatePlaceholderTemplate {
/// The ID the new node should have.
root: u64,
root: Option<u64>,
},
/// Create a new Event Listener.
@@ -190,13 +139,13 @@ pub enum DomEdit<'bump> {
scope: ScopeId,
/// The ID of the node to attach the listener to.
root: u64,
root: Option<u64>,
},
/// Remove an existing Event Listener.
RemoveEventListener {
/// The ID of the node to remove.
root: u64,
root: Option<u64>,
/// The name of the event to remove.
event: &'static str,
@@ -205,7 +154,7 @@ pub enum DomEdit<'bump> {
/// Set the textcontent of a node.
SetText {
/// The ID of the node to set the textcontent of.
root: u64,
root: Option<u64>,
/// The textcontent of the node
text: &'bump str,
@@ -214,7 +163,7 @@ pub enum DomEdit<'bump> {
/// Set the value of a node's attribute.
SetAttribute {
/// The ID of the node to set the attribute of.
root: u64,
root: Option<u64>,
/// The name of the attribute to set.
field: &'static str,
@@ -231,7 +180,7 @@ pub enum DomEdit<'bump> {
/// Remove an attribute from a node.
RemoveAttribute {
/// The ID of the node to remove.
root: u64,
root: Option<u64>,
/// The name of the attribute to remove.
name: &'static str,
@@ -240,45 +189,50 @@ pub enum DomEdit<'bump> {
ns: Option<&'bump str>,
},
/// Manually pop a root node from the stack.
PopRoot {},
/// Clones a node.
CloneNode {
/// The ID of the node to clone.
id: Option<u64>,
/// Enter a TemplateRef tree
EnterTemplateRef {
/// The ID of the node to enter.
root: u64,
/// The ID of the new node.
new_id: u64,
},
/// Exit a TemplateRef tree
ExitTemplateRef {},
/// Clones the children of a node. (allows cloning fragments)
CloneNodeChildren {
/// The ID of the node to clone.
id: Option<u64>,
/// Create a refrence to a template node.
CreateTemplateRef {
/// The ID of the new template refrence.
id: u64,
/// The ID of the template the node is refrencing.
template_id: u64,
/// The ID of the new node.
new_ids: Vec<u64>,
},
/// Create a new templete.
/// IMPORTANT: When adding nodes to a templete, id's will reset to zero, so they must be allocated on a different stack.
/// It is recommended to use Cow<NativeNode>.
CreateTemplate {
/// The ID of the new template.
/// Navigates to the last node to the first child of the current node.
FirstChild {},
/// Navigates to the last node to the last child of the current node.
NextSibling {},
/// Navigates to the last node to the parent of the current node.
ParentNode {},
/// Stores the last node with a new id.
StoreWithId {
/// The ID of the node to store.
id: u64,
},
/// Finish a templete
FinishTemplate {
/// The number of root nodes in the template
len: u32,
/// Manually set the last node.
SetLastNode {
/// The ID to set the last node to.
id: u64,
},
}
use rustc_hash::FxHashSet;
use DomEdit::*;
#[allow(unused)]
impl<'a> Mutations<'a> {
pub(crate) fn new() -> Self {
Self {
@@ -288,44 +242,29 @@ impl<'a> Mutations<'a> {
}
}
// Navigation
pub(crate) fn push_root(&mut self, root: impl Into<u64>) {
let id = root.into();
self.edits.push(PushRoot { root: id });
pub(crate) fn replace_with(&mut self, root: Option<u64>, nodes: Vec<u64>) {
self.edits.push(ReplaceWith { nodes, root });
}
// Navigation
pub(crate) fn pop_root(&mut self) {
self.edits.push(PopRoot {});
pub(crate) fn insert_after(&mut self, root: Option<u64>, nodes: Vec<u64>) {
self.edits.push(InsertAfter { nodes, root });
}
pub(crate) fn replace_with(&mut self, root: impl Into<u64>, m: u32) {
let root = root.into();
self.edits.push(ReplaceWith { m, root });
pub(crate) fn insert_before(&mut self, root: Option<u64>, nodes: Vec<u64>) {
self.edits.push(InsertBefore { nodes, root });
}
pub(crate) fn insert_after(&mut self, root: impl Into<u64>, n: u32) {
let root = root.into();
self.edits.push(InsertAfter { n, root });
}
pub(crate) fn insert_before(&mut self, root: impl Into<u64>, n: u32) {
let root = root.into();
self.edits.push(InsertBefore { n, root });
}
pub(crate) fn append_children(&mut self, n: u32) {
self.edits.push(AppendChildren { many: n });
pub(crate) fn append_children(&mut self, root: Option<u64>, children: Vec<u64>) {
self.edits.push(AppendChildren { root, children });
}
// Remove Nodes from the dom
pub(crate) fn remove(&mut self, id: impl Into<u64>) {
self.edits.push(Remove { root: id.into() });
pub(crate) fn remove(&mut self, id: Option<u64>) {
self.edits.push(Remove { root: id });
}
// Create
pub(crate) fn create_text_node(&mut self, text: &'a str, id: impl Into<u64>) {
let id = id.into();
pub(crate) fn create_text_node(&mut self, text: &'a str, id: Option<u64>) {
self.edits.push(CreateTextNode { text, root: id });
}
@@ -333,66 +272,27 @@ impl<'a> Mutations<'a> {
&mut self,
tag: &'static str,
ns: Option<&'static str>,
id: impl Into<u64>,
id: Option<u64>,
children: u32,
) {
let id = id.into();
match ns {
Some(ns) => self.edits.push(CreateElementNs { root: id, ns, tag }),
None => self.edits.push(CreateElement { root: id, tag }),
}
}
// placeholders are nodes that don't get rendered but still exist as an "anchor" in the real dom
pub(crate) fn create_placeholder(&mut self, id: impl Into<u64>) {
let id = id.into();
self.edits.push(CreatePlaceholder { root: id });
}
// Create
pub(crate) fn create_text_node_template(
&mut self,
text: &'a str,
id: impl Into<u64>,
locally_static: bool,
) {
let id = id.into();
self.edits.push(CreateTextNodeTemplate {
text,
root: id,
locally_static,
});
}
pub(crate) fn create_element_template(
&mut self,
tag: &'static str,
ns: Option<&'static str>,
id: impl Into<u64>,
locally_static: bool,
fully_static: bool,
) {
let id = id.into();
match ns {
Some(ns) => self.edits.push(CreateElementNsTemplate {
Some(ns) => self.edits.push(CreateElementNs {
root: id,
ns,
tag,
locally_static,
fully_static,
children,
}),
None => self.edits.push(CreateElementTemplate {
None => self.edits.push(CreateElement {
root: id,
tag,
locally_static,
fully_static,
children,
}),
}
}
// placeholders are nodes that don't get rendered but still exist as an "anchor" in the real dom
pub(crate) fn create_placeholder_template(&mut self, id: impl Into<u64>) {
let id = id.into();
self.edits.push(CreatePlaceholderTemplate { root: id });
pub(crate) fn create_placeholder(&mut self, id: Option<u64>) {
self.edits.push(CreatePlaceholder { root: id });
}
// events
@@ -403,13 +303,7 @@ impl<'a> Mutations<'a> {
..
} = listener;
let element_id = match mounted_node.get().unwrap() {
GlobalNodeId::TemplateId {
template_ref_id: _,
template_node_id,
} => template_node_id.into(),
GlobalNodeId::VNodeId(id) => id.into(),
};
let element_id = Some(mounted_node.get().unwrap().into());
self.edits.push(NewEventListener {
scope,
@@ -418,21 +312,16 @@ impl<'a> Mutations<'a> {
});
}
pub(crate) fn remove_event_listener(&mut self, event: &'static str, root: impl Into<u64>) {
self.edits.push(RemoveEventListener {
event,
root: root.into(),
});
pub(crate) fn remove_event_listener(&mut self, event: &'static str, root: Option<u64>) {
self.edits.push(RemoveEventListener { event, root });
}
// modify
pub(crate) fn set_text(&mut self, text: &'a str, root: impl Into<u64>) {
let root = root.into();
pub(crate) fn set_text(&mut self, text: &'a str, root: Option<u64>) {
self.edits.push(SetText { text, root });
}
pub(crate) fn set_attribute(&mut self, attribute: &'a Attribute<'a>, root: impl Into<u64>) {
let root = root.into();
pub(crate) fn set_attribute(&mut self, attribute: &'a Attribute<'a>, root: Option<u64>) {
let Attribute {
value, attribute, ..
} = attribute;
@@ -445,8 +334,7 @@ impl<'a> Mutations<'a> {
});
}
pub(crate) fn remove_attribute(&mut self, attribute: &Attribute, root: impl Into<u64>) {
let root = root.into();
pub(crate) fn remove_attribute(&mut self, attribute: &Attribute, root: Option<u64>) {
let Attribute { attribute, .. } = attribute;
self.edits.push(RemoveAttribute {
@@ -460,31 +348,32 @@ impl<'a> Mutations<'a> {
self.dirty_scopes.insert(scope);
}
pub(crate) fn create_templete(&mut self, id: impl Into<u64>) {
self.edits.push(CreateTemplate { id: id.into() });
pub(crate) fn clone_node(&mut self, id: Option<u64>, new_id: u64) {
self.edits.push(CloneNode { id, new_id });
}
pub(crate) fn finish_templete(&mut self, len: u32) {
self.edits.push(FinishTemplate { len });
pub(crate) fn clone_node_children(&mut self, id: Option<u64>, new_ids: Vec<u64>) {
self.edits.push(CloneNodeChildren { id, new_ids });
}
pub(crate) fn create_template_ref(&mut self, id: impl Into<u64>, template_id: u64) {
self.edits.push(CreateTemplateRef {
id: id.into(),
template_id,
})
pub(crate) fn first_child(&mut self) {
self.edits.push(FirstChild {});
}
pub(crate) fn enter_template_ref(&mut self, id: impl Into<u64>) {
self.edits.push(EnterTemplateRef { root: id.into() });
pub(crate) fn next_sibling(&mut self) {
self.edits.push(NextSibling {});
}
pub(crate) fn exit_template_ref(&mut self) {
if let Some(&DomEdit::EnterTemplateRef { .. }) = self.edits.last() {
self.edits.pop();
} else {
self.edits.push(ExitTemplateRef {});
}
pub(crate) fn parent_node(&mut self) {
self.edits.push(ParentNode {});
}
pub(crate) fn store_with_id(&mut self, id: u64) {
self.edits.push(StoreWithId { id });
}
pub(crate) fn set_last_node(&mut self, id: u64) {
self.edits.push(SetLastNode { id });
}
}