bloom_html/
node.rs

1use std::{fmt::Debug, sync::Arc};
2
3use bloom_core::Element;
4
5use crate::{
6    comment::{HtmlComment, HtmlCommentBuilder},
7    element::HtmlElementBuilder,
8    HtmlElement,
9};
10
11/// The Node-type to use bloom in Browser-Environments.
12/// A HtmlNode is equivalent to a browser DOM-node.
13/// It can represent an HTML Element (<div>, <span>, etc.),
14/// a text-node or a comment.
15///
16/// HtmlNodes will be mainly constructed using bloom-rsx:
17/// ```
18/// rsx!(<div id="123" on_click=|_| { alert!("clicked")} />)
19/// ```
20#[derive(Debug, PartialEq, Clone)]
21pub enum HtmlNode {
22    Element(Arc<HtmlElement>),
23    Text(String),
24    Comment(HtmlComment),
25}
26
27impl HtmlNode {
28    pub fn element(tag_name: &'static str) -> HtmlElementBuilder<&'static str> {
29        HtmlElement::new().tag_name(tag_name)
30    }
31
32    pub fn text(text: String) -> Self {
33        Self::Text(text)
34    }
35
36    pub fn comment(text: String) -> HtmlCommentBuilder<String> {
37        HtmlComment::new().text(text)
38    }
39
40    pub fn as_element(&self) -> Option<&HtmlElement> {
41        match self {
42            Self::Element(element) => Some(element),
43            _ => None,
44        }
45    }
46}
47
48impl<E> From<HtmlElement> for Element<HtmlNode, E> {
49    fn from(element: HtmlElement) -> Self {
50        Element::Node(HtmlNode::Element(Arc::new(element)), Vec::new())
51    }
52}
53
54impl<E> From<HtmlComment> for Element<HtmlNode, E> {
55    fn from(comment: HtmlComment) -> Self {
56        Element::Node(HtmlNode::Comment(comment), Vec::new())
57    }
58}
59
60impl From<HtmlElement> for HtmlNode {
61    fn from(element: HtmlElement) -> Self {
62        HtmlNode::Element(Arc::new(element))
63    }
64}
65
66impl From<HtmlComment> for HtmlNode {
67    fn from(value: HtmlComment) -> Self {
68        HtmlNode::Comment(value)
69    }
70}
71
72impl HtmlElement {
73    pub fn children<E>(self, children: Vec<Element<HtmlNode, E>>) -> Element<HtmlNode, E> {
74        Element::Node(HtmlNode::Element(Arc::new(self)), children)
75    }
76}
77
78impl HtmlNode {
79    pub fn children<E>(self, children: Vec<Element<HtmlNode, E>>) -> Element<HtmlNode, E> {
80        Element::Node(self, children)
81    }
82}
83
84impl From<String> for HtmlNode {
85    fn from(value: String) -> Self {
86        Self::Text(value)
87    }
88}
89
90impl<E> From<HtmlNode> for Element<HtmlNode, E> {
91    fn from(value: HtmlNode) -> Self {
92        Element::Node(value, Vec::new())
93    }
94}
95
96pub fn tag(tag_name: &'static str) -> HtmlElementBuilder<&'static str> {
97    HtmlElement::new().tag_name(tag_name)
98}