Files
dioxus/packages/core/src.old/nodes/mod.old.rs
T

208 lines
6.2 KiB
Rust

//! Virtual Node Support
//!
//! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very*
//! cheap and *very* fast to construct - building a full tree should be quick.
use std::fmt::{Debug, Formatter};
mod arbitrary_value;
mod component;
mod element;
mod factory;
mod fragment;
mod placeholder;
mod suspense;
mod template;
mod text;
pub use arbitrary_value::*;
pub use component::*;
pub use element::*;
pub use factory::*;
pub use fragment::*;
pub use suspense::*;
pub use template::*;
pub use text::*;
use self::placeholder::VPlaceholder;
/// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM.
///
/// VNodes are designed to be lightweight and used with with a bump allocator. To create a VNode, you can use either of:
///
/// - the `rsx!` macro
/// - the [`NodeFactory`] API
pub enum VNode<'src> {
/// Text VNodes are simply bump-allocated (or static) string slices
///
/// # Example
///
/// ```rust, ignore
/// let mut vdom = VirtualDom::new();
/// let node = vdom.render_vnode(rsx!( "hello" ));
///
/// if let VNode::Text(vtext) = node {
/// assert_eq!(vtext.text, "hello");
/// assert_eq!(vtext.dom_id.get(), None);
/// assert_eq!(vtext.is_static, true);
/// }
/// ```
Text(&'src VText<'src>),
/// Element VNodes are VNodes that may contain attributes, listeners, a key, a tag, and children.
///
/// # Example
///
/// ```rust, ignore
/// let mut vdom = VirtualDom::new();
///
/// let node = vdom.render_vnode(rsx!{
/// div {
/// key: "a",
/// onclick: |e| log::info!("clicked"),
/// hidden: "true",
/// style: { background_color: "red" },
/// "hello"
/// }
/// });
///
/// if let VNode::Element(velement) = node {
/// assert_eq!(velement.tag_name, "div");
/// assert_eq!(velement.namespace, None);
/// assert_eq!(velement.key, Some("a"));
/// }
/// ```
Element(&'src VElement<'src>),
/// Fragment nodes may contain many VNodes without a single root.
///
/// # Example
///
/// ```rust, ignore
/// rsx!{
/// a {}
/// link {}
/// style {}
/// "asd"
/// Example {}
/// }
/// ```
Fragment(&'src VFragment<'src>),
/// Component nodes represent a mounted component with props, children, and a key.
///
/// # Example
///
/// ```rust, ignore
/// fn Example(cx: Scope) -> Element {
/// ...
/// }
///
/// let mut vdom = VirtualDom::new();
///
/// let node = vdom.render_vnode(rsx!( Example {} ));
///
/// if let VNode::Component(vcomp) = node {
/// assert_eq!(vcomp.user_fc, Example as *const ());
/// }
/// ```
Component(&'src VComponent<'src>),
/// Templetes ase generated by the rsx macro to eleminate diffing static nodes.
///
///
///
///
///
///
Template(&'src VTemplate<'src>),
}
/// An Element's unique identifier.
///
/// `ElementId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
/// unmounted, then the `ElementId` will be reused for a new component.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", serde(transparent))]
pub struct ElementId(pub usize);
impl<'src> VNode<'src> {
/// Get the VNode's "key" used in the keyed diffing algorithm.
pub fn key(&self) -> Option<&'src str> {
match &self {
VNode::Element(el) => el.key,
VNode::Component(c) => c.key,
VNode::Fragment(f) => f.key,
VNode::Template(t) => t.key,
VNode::Text(_t) => None,
}
}
/// Get the ElementID of the mounted VNode.
///
/// Panics if the mounted ID is None or if the VNode is not represented by a single Element.
pub fn mounted_id(&self) -> ElementId {
self.try_mounted_id().unwrap()
}
/// Try to get the ElementID of the mounted VNode.
///
/// Returns None if the VNode is not mounted, or if the VNode cannot be presented by a mounted ID (Fragment/Component)
pub fn try_mounted_id(&self) -> Option<ElementId> {
match &self {
VNode::Text(el) => el.id.get(),
VNode::Element(el) => el.id.get(),
VNode::Fragment(_) => None,
VNode::Component(_) => None,
VNode::Template(_) => None,
}
}
// Create an "owned" version of the vnode.
pub(crate) fn decouple(&self) -> VNode<'src> {
match *self {
VNode::Text(t) => VNode::Text(t),
VNode::Element(e) => VNode::Element(e),
VNode::Component(c) => VNode::Component(c),
VNode::Fragment(f) => VNode::Fragment(f),
VNode::Template(t) => VNode::Template(t),
}
}
}
impl Debug for VNode<'_> {
fn fmt(&self, s: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match &self {
VNode::Element(el) => s
.debug_struct("VNode::Element")
.field("name", &el.tag)
.field("key", &el.key)
.field("attrs", &el.attributes)
.field("children", &el.children)
.field("id", &el.id)
.finish(),
VNode::Text(t) => s
.debug_struct("VNode::Text")
.field("text", &t.text)
.field("id", &t.id)
.finish(),
VNode::Fragment(frag) => s
.debug_struct("VNode::Fragment")
.field("children", &frag.children)
.finish(),
VNode::Component(comp) => s
.debug_struct("VNode::Component")
.field("name", &comp.fn_name)
.field("fnptr", &comp.user_fc)
.field("key", &comp.key)
.field("scope", &comp.scope)
.finish(),
VNode::Template(temp) => s
.debug_struct("VNode::Templates")
.field("template_id", &temp.template.id)
.finish(),
}
}
}