This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew/dom_bundle/
traits.rs

1use web_sys::Element;
2
3use super::{BNode, BSubtree, DomSlot};
4use crate::html::AnyScope;
5
6/// A Reconcile Target.
7///
8/// When a [Reconcilable] is attached, a reconcile target is created to store additional
9/// information.
10pub(super) trait ReconcileTarget {
11    /// Remove self from parent.
12    ///
13    /// Parent to detach is `true` if the parent element will also be detached.
14    fn detach(self, root: &BSubtree, parent: &Element, parent_to_detach: bool);
15
16    /// Move elements from one parent to another parent.
17    /// This is for example used by `VSuspense` to preserve component state without detaching
18    /// (which destroys component state).
19    fn shift(&self, next_parent: &Element, slot: DomSlot) -> DomSlot;
20}
21
22/// This trait provides features to update a tree by calculating a difference against another tree.
23pub(super) trait Reconcilable {
24    type Bundle: ReconcileTarget;
25
26    /// Attach a virtual node to the DOM tree.
27    ///
28    /// Parameters:
29    /// - `root`: bundle of the subtree root
30    /// - `parent_scope`: the parent `Scope` used for passing messages to the parent `Component`.
31    /// - `parent`: the parent node in the DOM.
32    /// - `slot`: to find where to put the node.
33    ///
34    /// Returns a reference to the newly inserted element.
35    /// The [`DomSlot`] points the first element (if there are multiple nodes created),
36    /// or is the passed in `slot` if there are no element is created.
37    fn attach(
38        self,
39
40        root: &BSubtree,
41        parent_scope: &AnyScope,
42        parent: &Element,
43        slot: DomSlot,
44    ) -> (DomSlot, Self::Bundle);
45
46    /// Scoped diff apply to other tree.
47    ///
48    /// Virtual rendering for the node. It uses parent node and existing
49    /// children (virtual and DOM) to check the difference and apply patches to
50    /// the actual DOM representation.
51    ///
52    /// Parameters:
53    /// - `parent_scope`: the parent `Scope` used for passing messages to the parent `Component`.
54    /// - `parent`: the parent node in the DOM.
55    /// - `slot`: the slot in `parent`'s children where to put the node.
56    /// - `bundle`: the node that this node will be replacing in the DOM. This method will remove
57    ///   the `bundle` from the `parent` if it is of the wrong kind, and otherwise reuse it.
58    ///
59    /// Returns a reference to the newly inserted element.
60    fn reconcile_node(
61        self,
62
63        root: &BSubtree,
64        parent_scope: &AnyScope,
65        parent: &Element,
66        slot: DomSlot,
67        bundle: &mut BNode,
68    ) -> DomSlot;
69
70    fn reconcile(
71        self,
72        root: &BSubtree,
73        parent_scope: &AnyScope,
74        parent: &Element,
75        slot: DomSlot,
76        bundle: &mut Self::Bundle,
77    ) -> DomSlot;
78
79    /// Replace an existing bundle by attaching self and detaching the existing one
80    fn replace(
81        self,
82
83        root: &BSubtree,
84        parent_scope: &AnyScope,
85        parent: &Element,
86        slot: DomSlot,
87        bundle: &mut BNode,
88    ) -> DomSlot
89    where
90        Self: Sized,
91        Self::Bundle: Into<BNode>,
92    {
93        let (self_ref, self_) = self.attach(root, parent_scope, parent, slot);
94        let ancestor = std::mem::replace(bundle, self_.into());
95        ancestor.detach(root, parent, false);
96        self_ref
97    }
98}
99
100#[cfg(feature = "hydration")]
101mod feat_hydration {
102    use super::*;
103    use crate::dom_bundle::Fragment;
104
105    pub(in crate::dom_bundle) trait Hydratable: Reconcilable {
106        /// hydrates current tree.
107        ///
108        /// Returns a reference to the first node of the hydrated tree.
109        ///
110        /// # Important
111        ///
112        /// DOM tree is hydrated from top to bottom. This is different than [`Reconcilable`].
113        fn hydrate(
114            self,
115            root: &BSubtree,
116            parent_scope: &AnyScope,
117            parent: &Element,
118            fragment: &mut Fragment,
119        ) -> Self::Bundle;
120    }
121}
122
123#[cfg(feature = "hydration")]
124pub(in crate::dom_bundle) use feat_hydration::*;