1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- use fxhash::FxHashMap;
- use crate::innerlude::{VNode, VText};
- /// A Patch encodes an operation that modifies a real DOM element.
- ///
- /// To update the real DOM that a user sees you'll want to first diff your
- /// old virtual dom and new virtual dom.
- ///
- /// This diff operation will generate `Vec<Patch>` with zero or more patches that, when
- /// applied to your real DOM, will make your real DOM look like your new virtual dom.
- ///
- /// Each Patch has a u32 node index that helps us identify the real DOM node that it applies to.
- ///
- /// Our old virtual dom's nodes are indexed depth first, as shown in this illustration
- /// (0 being the root node, 1 being it's first child, 2 being it's first child's first child).
- ///
- /// ```text
- /// .─.
- /// ( 0 )
- /// `┬'
- /// ┌────┴──────┐
- /// │ │
- /// ▼ ▼
- /// .─. .─.
- /// ( 1 ) ( 4 )
- /// `┬' `─'
- /// ┌────┴───┐ ├─────┬─────┐
- /// │ │ │ │ │
- /// ▼ ▼ ▼ ▼ ▼
- /// .─. .─. .─. .─. .─.
- /// ( 2 ) ( 3 ) ( 5 ) ( 6 ) ( 7 )
- /// `─' `─' `─' `─' `─'
- /// ```
- ///
- /// The patching process is tested in a real browser in crates/virtual-dom-rs/tests/diff_patch.rs
- // #[derive(serde::Serialize, serde::Deserialize)]
- pub enum Patch<'a> {
- /// Append a vector of child nodes to a parent node id.
- AppendChildren(NodeIdx, Vec<&'a VNode<'a>>),
- /// For a `node_i32`, remove all children besides the first `len`
- TruncateChildren(NodeIdx, usize),
- /// Replace a node with another node. This typically happens when a node's tag changes.
- /// ex: <div> becomes <span>
- Replace(NodeIdx, &'a VNode<'a>),
- /// Add attributes that the new node has that the old node does not
- AddAttributes(NodeIdx, FxHashMap<&'a str, &'a str>),
- /// Remove attributes that the old node had that the new node doesn't
- RemoveAttributes(NodeIdx, Vec<&'a str>),
- /// Change the text of a Text node.
- ChangeText(NodeIdx, &'a VText<'a>),
- }
- type NodeIdx = usize;
- impl<'a> Patch<'a> {
- /// Every Patch is meant to be applied to a specific node within the DOM. Get the
- /// index of the DOM node that this patch should apply to. DOM nodes are indexed
- /// depth first with the root node in the tree having index 0.
- pub fn node_idx(&self) -> usize {
- match self {
- Patch::AppendChildren(node_idx, _) => *node_idx,
- Patch::TruncateChildren(node_idx, _) => *node_idx,
- Patch::Replace(node_idx, _) => *node_idx,
- Patch::AddAttributes(node_idx, _) => *node_idx,
- Patch::RemoveAttributes(node_idx, _) => *node_idx,
- Patch::ChangeText(node_idx, _) => *node_idx,
- }
- }
- }
- pub struct PatchList<'a> {
- patches: Vec<Patch<'a>>,
- }
|