123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- use fxhash::FxHashSet;
- use crate::{arena::ElementId, ScopeId, Template};
- /// A container for all the relevant steps to modify the Real DOM
- ///
- /// This method returns "mutations" - IE the necessary changes to get the RealDOM to match the VirtualDOM. It also
- /// includes a list of NodeRefs that need to be applied and effects that need to be triggered after the RealDOM has
- /// applied the edits.
- ///
- /// Mutations are the only link between the RealDOM and the VirtualDOM.
- #[derive(Debug, Default)]
- #[must_use = "not handling edits can lead to visual inconsistencies in UI"]
- pub struct Mutations<'a> {
- /// The ID of the subtree that these edits are targetting
- pub subtree: usize,
- /// The list of Scopes that were diffed, created, and removed during the Diff process.
- pub dirty_scopes: FxHashSet<ScopeId>,
- /// Any templates encountered while diffing the DOM.
- ///
- /// These must be loaded into a cache before applying the edits
- pub templates: Vec<Template<'a>>,
- /// Any mutations required to patch the renderer to match the layout of the VirtualDom
- pub edits: Vec<Mutation<'a>>,
- }
- impl<'a> Mutations<'a> {
- /// Rewrites IDs to just be "template", so you can compare the mutations
- ///
- /// Used really only for testing
- pub fn santize(mut self) -> Self {
- todo!()
- // self.templates
- // .iter_mut()
- // .chain(self.dom_edits.iter_mut())
- // .for_each(|edit| match edit {
- // Mutation::LoadTemplate { name, .. } => *name = "template",
- // Mutation::SaveTemplate { name, .. } => *name = "template",
- // _ => {}
- // });
- // self
- }
- /// Push a new mutation into the dom_edits list
- pub(crate) fn push(&mut self, mutation: Mutation<'static>) {
- self.edits.push(mutation)
- }
- }
- /*
- each subtree has its own numbering scheme
- */
- #[cfg_attr(
- feature = "serialize",
- derive(serde::Serialize, serde::Deserialize),
- serde(tag = "type")
- )]
- #[derive(Debug, PartialEq, Eq)]
- pub enum Mutation<'a> {
- AssignId {
- path: &'static [u8],
- id: ElementId,
- },
- CreatePlaceholder {
- id: ElementId,
- },
- CreateTextNode {
- value: &'a str,
- id: ElementId,
- },
- HydrateText {
- path: &'static [u8],
- value: &'a str,
- id: ElementId,
- },
- LoadTemplate {
- name: &'static str,
- index: usize,
- id: ElementId,
- },
- // Take the current element and replace it with the element with the given id.
- ReplaceWith {
- id: ElementId,
- m: usize,
- },
- ReplacePlaceholder {
- path: &'static [u8],
- m: usize,
- },
- /// 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,
- },
- /// Set the value of a node's attribute.
- SetAttribute {
- /// The name of the attribute to set.
- name: &'a str,
- /// The value of the attribute.
- value: &'a str,
- /// The ID of the node to set the attribute of.
- id: ElementId,
- /// The (optional) namespace of the attribute.
- /// For instance, "style" is in the "style" namespace.
- ns: Option<&'a str>,
- },
- /// Set the value of a node's attribute.
- SetBoolAttribute {
- /// The name of the attribute to set.
- name: &'a str,
- /// The value of the attribute.
- value: bool,
- /// The ID of the node to set the attribute of.
- id: ElementId,
- },
- /// Set the textcontent of a node.
- SetText {
- /// The textcontent of the node
- value: &'a str,
- /// The ID of the node to set the textcontent of.
- id: ElementId,
- },
- /// Create a new Event Listener.
- NewEventListener {
- /// The name of the event to listen for.
- 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.
- id: ElementId,
- },
- /// Remove an existing Event Listener.
- RemoveEventListener {
- /// The name of the event to remove.
- name: &'a str,
- /// The ID of the node to remove.
- id: ElementId,
- },
- /// Remove a particular node from the DOM
- Remove {
- /// The ID of the node to remove.
- id: ElementId,
- },
- /// Push the given root node onto our stack.
- PushRoot {
- /// The ID of the root node to push.
- id: ElementId,
- },
- }
|