2022-11-16 02:32:48 +00:00
|
|
|
use crate::{arena::ElementId, ScopeId};
|
2021-08-22 21:08:25 +00:00
|
|
|
|
2022-11-09 03:39:37 +00:00
|
|
|
#[derive(Debug)]
|
2022-11-09 18:58:11 +00:00
|
|
|
pub struct Mutations<'a> {
|
2022-11-09 03:39:37 +00:00
|
|
|
pub subtree: usize,
|
|
|
|
pub template_mutations: Vec<Mutation<'a>>,
|
2022-11-12 02:29:27 +00:00
|
|
|
pub edits: Vec<Mutation<'a>>,
|
2022-10-28 04:58:47 +00:00
|
|
|
}
|
2022-11-09 03:39:37 +00:00
|
|
|
|
2022-11-09 18:58:11 +00:00
|
|
|
impl<'a> Mutations<'a> {
|
2022-11-23 03:59:56 +00:00
|
|
|
pub fn new() -> Self {
|
2022-11-09 03:39:37 +00:00
|
|
|
Self {
|
2022-11-23 03:59:56 +00:00
|
|
|
subtree: 0,
|
2022-11-12 02:29:27 +00:00
|
|
|
edits: Vec::new(),
|
2022-11-09 03:39:37 +00:00
|
|
|
template_mutations: Vec::new(),
|
|
|
|
}
|
|
|
|
}
|
2022-11-23 05:32:26 +00:00
|
|
|
|
|
|
|
/// A useful tool for testing mutations
|
|
|
|
///
|
|
|
|
/// Rewrites IDs to just be "template", so you can compare the mutations
|
|
|
|
pub fn santize(mut self) -> Self {
|
|
|
|
for edit in self
|
|
|
|
.template_mutations
|
|
|
|
.iter_mut()
|
|
|
|
.chain(self.edits.iter_mut())
|
|
|
|
{
|
|
|
|
match edit {
|
|
|
|
Mutation::LoadTemplate { name, .. } => *name = "template",
|
|
|
|
Mutation::SaveTemplate { name, .. } => *name = "template",
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self
|
|
|
|
}
|
2022-11-09 03:39:37 +00:00
|
|
|
}
|
|
|
|
|
2022-11-09 18:58:11 +00:00
|
|
|
impl<'a> std::ops::Deref for Mutations<'a> {
|
2022-11-09 03:39:37 +00:00
|
|
|
type Target = Vec<Mutation<'a>>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
2022-11-12 02:29:27 +00:00
|
|
|
&self.edits
|
2022-11-09 03:39:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-09 18:58:11 +00:00
|
|
|
impl std::ops::DerefMut for Mutations<'_> {
|
2022-11-09 03:39:37 +00:00
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
2022-11-12 02:29:27 +00:00
|
|
|
&mut self.edits
|
2022-11-09 03:39:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
each subtree has its own numbering scheme
|
|
|
|
*/
|
2022-10-20 16:56:09 +00:00
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
#[cfg_attr(
|
|
|
|
feature = "serialize",
|
|
|
|
derive(serde::Serialize, serde::Deserialize),
|
|
|
|
serde(tag = "type")
|
|
|
|
)]
|
2022-11-12 02:29:27 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2022-10-28 04:58:47 +00:00
|
|
|
pub enum Mutation<'a> {
|
2022-11-16 02:32:48 +00:00
|
|
|
AppendChildren {
|
|
|
|
m: usize,
|
|
|
|
},
|
|
|
|
|
|
|
|
AssignId {
|
|
|
|
path: &'static [u8],
|
2022-10-28 04:58:47 +00:00
|
|
|
id: ElementId,
|
|
|
|
},
|
2022-10-20 16:56:09 +00:00
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
CreateElement {
|
2022-11-16 00:05:22 +00:00
|
|
|
name: &'a str,
|
|
|
|
},
|
2022-11-24 11:47:14 +00:00
|
|
|
CreateElementNamespace {
|
|
|
|
name: &'a str,
|
|
|
|
namespace: &'a str,
|
|
|
|
},
|
2022-11-16 02:32:48 +00:00
|
|
|
CreatePlaceholder {
|
|
|
|
id: ElementId,
|
2022-10-28 04:58:47 +00:00
|
|
|
},
|
2022-11-24 11:47:14 +00:00
|
|
|
CreateStaticPlaceholder,
|
2022-11-27 05:56:49 +00:00
|
|
|
CreateTextPlaceholder,
|
2022-11-16 09:13:39 +00:00
|
|
|
CreateStaticText {
|
|
|
|
value: &'a str,
|
|
|
|
},
|
2022-11-16 02:32:48 +00:00
|
|
|
CreateTextNode {
|
|
|
|
value: &'a str,
|
2022-11-16 09:13:39 +00:00
|
|
|
id: ElementId,
|
2022-11-02 01:42:29 +00:00
|
|
|
},
|
2022-10-28 04:58:47 +00:00
|
|
|
HydrateText {
|
|
|
|
path: &'static [u8],
|
|
|
|
value: &'a str,
|
|
|
|
id: ElementId,
|
|
|
|
},
|
2022-11-16 02:32:48 +00:00
|
|
|
LoadTemplate {
|
|
|
|
name: &'static str,
|
|
|
|
index: usize,
|
2022-11-24 07:15:01 +00:00
|
|
|
id: ElementId,
|
2022-11-16 02:32:48 +00:00
|
|
|
},
|
2022-10-28 04:58:47 +00:00
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
// Take the current element and replace it with the element with the given id.
|
|
|
|
ReplaceWith {
|
2022-10-28 04:58:47 +00:00
|
|
|
id: ElementId,
|
2022-11-16 02:32:48 +00:00
|
|
|
m: usize,
|
2022-10-28 04:58:47 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
ReplacePlaceholder {
|
2022-11-02 08:00:37 +00:00
|
|
|
path: &'static [u8],
|
2022-11-24 07:15:01 +00:00
|
|
|
m: usize,
|
2022-10-28 04:58:47 +00:00
|
|
|
},
|
|
|
|
|
2022-11-23 03:59:56 +00:00
|
|
|
/// Insert a number of nodes after a given node.
|
|
|
|
InsertAfter {
|
|
|
|
/// The ID of the node to insert after.
|
|
|
|
id: ElementId,
|
|
|
|
|
|
|
|
/// The ids of the nodes to insert after the target node.
|
|
|
|
m: usize,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Insert a number of nodes before a given node.
|
|
|
|
InsertBefore {
|
|
|
|
/// The ID of the node to insert before.
|
|
|
|
id: ElementId,
|
|
|
|
|
|
|
|
/// The ids of the nodes to insert before the target node.
|
|
|
|
m: usize,
|
|
|
|
},
|
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
SaveTemplate {
|
|
|
|
name: &'static str,
|
|
|
|
m: usize,
|
2022-10-28 04:58:47 +00:00
|
|
|
},
|
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
SetAttribute {
|
|
|
|
name: &'a str,
|
|
|
|
value: &'a str,
|
2022-10-28 04:58:47 +00:00
|
|
|
id: ElementId,
|
2022-11-16 07:31:23 +00:00
|
|
|
|
|
|
|
// value: &'bump str,
|
|
|
|
/// The (optional) namespace of the attribute.
|
|
|
|
/// For instance, "style" is in the "style" namespace.
|
|
|
|
ns: Option<&'a str>,
|
2022-10-28 04:58:47 +00:00
|
|
|
},
|
2022-11-02 01:42:29 +00:00
|
|
|
|
2022-11-24 11:47:14 +00:00
|
|
|
SetStaticAttribute {
|
|
|
|
name: &'a str,
|
|
|
|
value: &'a str,
|
|
|
|
ns: Option<&'a str>,
|
|
|
|
},
|
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
SetBoolAttribute {
|
2022-11-02 01:42:29 +00:00
|
|
|
name: &'a str,
|
2022-11-16 02:32:48 +00:00
|
|
|
value: bool,
|
2022-11-02 01:42:29 +00:00
|
|
|
id: ElementId,
|
|
|
|
},
|
|
|
|
|
2022-11-16 00:05:22 +00:00
|
|
|
SetInnerText {
|
|
|
|
value: &'a str,
|
|
|
|
},
|
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
SetText {
|
2022-11-02 01:42:29 +00:00
|
|
|
value: &'a str,
|
2022-11-16 02:32:48 +00:00
|
|
|
id: ElementId,
|
2022-11-02 01:42:29 +00:00
|
|
|
},
|
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
/// Create a new Event Listener.
|
|
|
|
NewEventListener {
|
|
|
|
/// The name of the event to listen for.
|
|
|
|
event_name: &'a str,
|
|
|
|
|
|
|
|
/// The ID of the node to attach the listener to.
|
|
|
|
scope: ScopeId,
|
|
|
|
|
|
|
|
/// The ID of the node to attach the listener to.
|
2022-11-04 00:34:42 +00:00
|
|
|
id: ElementId,
|
|
|
|
},
|
2022-11-02 01:42:29 +00:00
|
|
|
|
2022-11-16 02:32:48 +00:00
|
|
|
/// Remove an existing Event Listener.
|
|
|
|
RemoveEventListener {
|
|
|
|
/// The ID of the node to remove.
|
|
|
|
id: ElementId,
|
|
|
|
|
|
|
|
/// The name of the event to remove.
|
|
|
|
event: &'a str,
|
2022-11-02 01:42:29 +00:00
|
|
|
},
|
2022-11-24 07:15:01 +00:00
|
|
|
Remove {
|
|
|
|
id: ElementId,
|
|
|
|
},
|
2022-11-27 07:06:04 +00:00
|
|
|
|
|
|
|
PushRoot {
|
|
|
|
id: ElementId,
|
|
|
|
},
|
2021-08-22 21:08:25 +00:00
|
|
|
}
|