mod.old.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //! Virtual Node Support
  2. //!
  3. //! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very*
  4. //! cheap and *very* fast to construct - building a full tree should be quick.
  5. use std::fmt::{Debug, Formatter};
  6. mod arbitrary_value;
  7. mod component;
  8. mod element;
  9. mod factory;
  10. mod fragment;
  11. mod placeholder;
  12. mod suspense;
  13. mod template;
  14. mod text;
  15. pub use arbitrary_value::*;
  16. pub use component::*;
  17. pub use element::*;
  18. pub use factory::*;
  19. pub use fragment::*;
  20. pub use suspense::*;
  21. pub use template::*;
  22. pub use text::*;
  23. use self::placeholder::VPlaceholder;
  24. /// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM.
  25. ///
  26. /// VNodes are designed to be lightweight and used with with a bump allocator. To create a VNode, you can use either of:
  27. ///
  28. /// - the `rsx!` macro
  29. /// - the [`NodeFactory`] API
  30. pub enum VNode<'src> {
  31. /// Text VNodes are simply bump-allocated (or static) string slices
  32. ///
  33. /// # Example
  34. ///
  35. /// ```rust, ignore
  36. /// let mut vdom = VirtualDom::new();
  37. /// let node = vdom.render_vnode(rsx!( "hello" ));
  38. ///
  39. /// if let VNode::Text(vtext) = node {
  40. /// assert_eq!(vtext.text, "hello");
  41. /// assert_eq!(vtext.dom_id.get(), None);
  42. /// assert_eq!(vtext.is_static, true);
  43. /// }
  44. /// ```
  45. Text(&'src VText<'src>),
  46. /// Element VNodes are VNodes that may contain attributes, listeners, a key, a tag, and children.
  47. ///
  48. /// # Example
  49. ///
  50. /// ```rust, ignore
  51. /// let mut vdom = VirtualDom::new();
  52. ///
  53. /// let node = vdom.render_vnode(rsx!{
  54. /// div {
  55. /// key: "a",
  56. /// onclick: |e| log::info!("clicked"),
  57. /// hidden: "true",
  58. /// style: { background_color: "red" },
  59. /// "hello"
  60. /// }
  61. /// });
  62. ///
  63. /// if let VNode::Element(velement) = node {
  64. /// assert_eq!(velement.tag_name, "div");
  65. /// assert_eq!(velement.namespace, None);
  66. /// assert_eq!(velement.key, Some("a"));
  67. /// }
  68. /// ```
  69. Element(&'src VElement<'src>),
  70. /// Fragment nodes may contain many VNodes without a single root.
  71. ///
  72. /// # Example
  73. ///
  74. /// ```rust, ignore
  75. /// rsx!{
  76. /// a {}
  77. /// link {}
  78. /// style {}
  79. /// "asd"
  80. /// Example {}
  81. /// }
  82. /// ```
  83. Fragment(&'src VFragment<'src>),
  84. /// Component nodes represent a mounted component with props, children, and a key.
  85. ///
  86. /// # Example
  87. ///
  88. /// ```rust, ignore
  89. /// fn Example(cx: Scope) -> Element {
  90. /// ...
  91. /// }
  92. ///
  93. /// let mut vdom = VirtualDom::new();
  94. ///
  95. /// let node = vdom.render_vnode(rsx!( Example {} ));
  96. ///
  97. /// if let VNode::Component(vcomp) = node {
  98. /// assert_eq!(vcomp.user_fc, Example as *const ());
  99. /// }
  100. /// ```
  101. Component(&'src VComponent<'src>),
  102. /// Templetes ase generated by the rsx macro to eleminate diffing static nodes.
  103. ///
  104. ///
  105. ///
  106. ///
  107. ///
  108. ///
  109. Template(&'src VTemplate<'src>),
  110. }
  111. /// An Element's unique identifier.
  112. ///
  113. /// `ElementId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
  114. /// unmounted, then the `ElementId` will be reused for a new component.
  115. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
  116. #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
  117. #[cfg_attr(feature = "serialize", serde(transparent))]
  118. pub struct ElementId(pub usize);
  119. impl<'src> VNode<'src> {
  120. /// Get the VNode's "key" used in the keyed diffing algorithm.
  121. pub fn key(&self) -> Option<&'src str> {
  122. match &self {
  123. VNode::Element(el) => el.key,
  124. VNode::Component(c) => c.key,
  125. VNode::Fragment(f) => f.key,
  126. VNode::Template(t) => t.key,
  127. VNode::Text(_t) => None,
  128. }
  129. }
  130. /// Get the ElementID of the mounted VNode.
  131. ///
  132. /// Panics if the mounted ID is None or if the VNode is not represented by a single Element.
  133. pub fn mounted_id(&self) -> ElementId {
  134. self.try_mounted_id().unwrap()
  135. }
  136. /// Try to get the ElementID of the mounted VNode.
  137. ///
  138. /// Returns None if the VNode is not mounted, or if the VNode cannot be presented by a mounted ID (Fragment/Component)
  139. pub fn try_mounted_id(&self) -> Option<ElementId> {
  140. match &self {
  141. VNode::Text(el) => el.id.get(),
  142. VNode::Element(el) => el.id.get(),
  143. VNode::Fragment(_) => None,
  144. VNode::Component(_) => None,
  145. VNode::Template(_) => None,
  146. }
  147. }
  148. // Create an "owned" version of the vnode.
  149. pub(crate) fn decouple(&self) -> VNode<'src> {
  150. match *self {
  151. VNode::Text(t) => VNode::Text(t),
  152. VNode::Element(e) => VNode::Element(e),
  153. VNode::Component(c) => VNode::Component(c),
  154. VNode::Fragment(f) => VNode::Fragment(f),
  155. VNode::Template(t) => VNode::Template(t),
  156. }
  157. }
  158. }
  159. impl Debug for VNode<'_> {
  160. fn fmt(&self, s: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
  161. match &self {
  162. VNode::Element(el) => s
  163. .debug_struct("VNode::Element")
  164. .field("name", &el.tag)
  165. .field("key", &el.key)
  166. .field("attrs", &el.attributes)
  167. .field("children", &el.children)
  168. .field("id", &el.id)
  169. .finish(),
  170. VNode::Text(t) => s
  171. .debug_struct("VNode::Text")
  172. .field("text", &t.text)
  173. .field("id", &t.id)
  174. .finish(),
  175. VNode::Fragment(frag) => s
  176. .debug_struct("VNode::Fragment")
  177. .field("children", &frag.children)
  178. .finish(),
  179. VNode::Component(comp) => s
  180. .debug_struct("VNode::Component")
  181. .field("name", &comp.fn_name)
  182. .field("fnptr", &comp.user_fc)
  183. .field("key", &comp.key)
  184. .field("scope", &comp.scope)
  185. .finish(),
  186. VNode::Template(temp) => s
  187. .debug_struct("VNode::Templates")
  188. .field("template_id", &temp.template.id)
  189. .finish(),
  190. }
  191. }
  192. }