1use crate::{RootRender, VdomWeak};
2use bumpalo::{Bump, BumpAllocSafe};
6/// A node is either a text node or an element.
12 /// An element potentially with attributes and children.
13 Element(ElementNode<'a>),
16/// Text nodes are just a string of text. They cannot have attributes or
18#[derive(Debug, Clone)]
19pub struct TextNode<'a> {
20 pub(crate) text: &'a str,
23/// Elements have a tag name, zero or more attributes, and zero or more
25#[derive(Debug, Clone)]
26pub struct ElementNode<'a> {
27 pub(crate) tag_name: &'a str,
28 pub(crate) listeners: &'a [Listener<'a>],
29 pub(crate) attributes: &'a [Attribute<'a>],
30 pub(crate) children: &'a [Node<'a>],
33/// An event listener callback function.
35/// It takes three parameters:
37/// 1. The virtual DOM's root rendering component.
38/// 2. A capability to scheduler virtual DOM re-rendering.
39/// 3. The event that ocurred.
40pub type ListenerCallback<'a> =
41 &'a (dyn Fn(&mut dyn RootRender, VdomWeak, web_sys::Event) + 'static);
44pub struct Listener<'a> {
45 /// The type of event to listen for.
47 /// The callback to invoke when the event happens.
48 pub callback: ListenerCallback<'a>,
51#[derive(Clone, Debug)]
52pub struct Attribute<'a> {
57impl<'a> BumpAllocSafe for Node<'a> {}
58impl<'a> BumpAllocSafe for Listener<'a> {}
59impl<'a> BumpAllocSafe for Attribute<'a> {}
61impl fmt::Debug for Listener<'_> {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 let (a, b) = self.get_callback_parts();
64 let a = a as *mut u32;
65 let b = b as *mut u32;
66 f.debug_struct("Listener")
67 .field("event", &self.event)
68 .field("callback", &(a, b))
74 /// Construct a new element node with the given tag name and children.
76 pub fn element<Listeners, Attributes, Children>(
80 attributes: Attributes,
84 Listeners: 'a + BumpAllocSafe + AsRef<[Listener<'a>]>,
85 Attributes: 'a + BumpAllocSafe + AsRef<[Attribute<'a>]>,
86 Children: 'a + BumpAllocSafe + AsRef<[Node<'a>]>,
88 let children: &'a Children = bump.alloc(children);
89 let children: &'a [Node<'a>] = children.as_ref();
91 let listeners: &'a Listeners = bump.alloc(listeners);
92 let listeners: &'a [Listener<'a>] = listeners.as_ref();
94 let attributes: &'a Attributes = bump.alloc(attributes);
95 let attributes: &'a [Attribute<'a>] = attributes.as_ref();
97 Node::Element(ElementNode {
105 /// Is this node a text node?
106 pub fn is_text(&self) -> bool {
108 Node::Text(_) => true,
113 /// Is this node an element?
114 pub fn is_element(&self) -> bool {
116 Node::Element { .. } => true,
121 /// Construct a new text node with the given text.
123 pub fn text(text: &'a str) -> Node<'a> {
124 Node::Text(TextNode { text })
128impl<'a> TextNode<'a> {
129 /// Get this text node's text content.
130 pub fn text(&self) -> &'a str {
135impl<'a> ElementNode<'a> {
136 /// Get this element's tag name.
137 pub fn tag_name(&self) -> &'a str {
141 /// Get this element's attributes.
142 pub fn attributes(&self) -> &'a [Attribute<'a>] {
146 /// Get this element's attributes.
147 pub fn children(&self) -> &'a [Node<'a>] {
152union CallbackFatPtr<'a> {
153 callback: ListenerCallback<'a>,
159 pub(crate) fn get_callback_parts(&self) -> (u32, u32) {
161 mem::size_of::<ListenerCallback>(),
162 mem::size_of::<CallbackFatPtr>()
166 let fat = CallbackFatPtr {
167 callback: self.callback,
169 let (a, b) = fat.parts;
170 debug_assert!(a != 0);
176/// Utility function for creating event listeners and downcasting the component
177/// to its `RootRender` concrete type.
178pub fn on<'a, F>(bump: &'a Bump, event: &'a str, callback: F) -> Listener<'a>
180 F: Fn(&mut dyn RootRender, VdomWeak, web_sys::Event) + 'static,
184 callback: bump.alloc(
185 move |component: &mut dyn RootRender, vdom: VdomWeak, event: web_sys::Event| {
186 callback(component, vdom, event);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list