1use std::{collections::HashMap, fmt::Debug, sync::Arc};
2
3use crate::{DomRef, EventHandler};
4
5pub struct HtmlElement {
7 pub(crate) tag_name: &'static str,
8 pub(crate) attributes: HashMap<String, String>,
9 pub(crate) callbacks: HashMap<String, EventHandler>,
10 pub(crate) dom_ref: Option<Arc<DomRef>>,
11}
12
13impl Debug for HtmlElement {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 f.debug_struct("HtmlElement")
16 .field("tag_name", &self.tag_name)
17 .field("attributes", &self.attributes)
18 .field("callbacks", &"Callbacks")
19 .field("dom_ref", &self.dom_ref)
20 .finish()
21 }
22}
23
24impl HtmlElement {
25 pub fn new() -> HtmlElementBuilder<()> {
30 HtmlElementBuilder {
31 tag_name: (),
32 attributes: HashMap::new(),
33 callbacks: HashMap::new(),
34 dom_ref: None,
35 }
36 }
37
38 pub fn tag_name(&self) -> &str {
39 &self.tag_name
40 }
41
42 pub fn attributes(&self) -> &HashMap<String, String> {
46 &self.attributes
47 }
48
49 pub fn callbacks(&self) -> &HashMap<String, EventHandler> {
53 &self.callbacks
54 }
55
56 pub fn dom_ref(&self) -> &Option<Arc<DomRef>> {
58 &self.dom_ref
59 }
60}
61
62pub struct HtmlElementBuilder<T> {
63 pub(crate) tag_name: T,
64 pub(crate) attributes: HashMap<String, String>,
65 pub(crate) callbacks: HashMap<String, EventHandler>,
66 pub(crate) dom_ref: Option<Arc<DomRef>>,
67}
68
69impl HtmlElementBuilder<()> {
70 pub fn tag_name(self, tag_name: &'static str) -> HtmlElementBuilder<&'static str> {
71 HtmlElementBuilder {
72 tag_name,
73 attributes: self.attributes,
74 callbacks: self.callbacks,
75 dom_ref: self.dom_ref,
76 }
77 }
78}
79
80impl<T> HtmlElementBuilder<T> {
81 pub fn attr<K, V>(mut self, key: K, value: V) -> Self
87 where
88 K: Into<String>,
89 V: Into<String>,
90 V: Into<String>,
91 {
92 self.attributes.insert(key.into(), value.into());
93 self
94 }
95
96 pub fn on<K, C>(mut self, key: K, handler: C) -> Self
102 where
103 K: Into<String>,
104 C: Fn(web_sys::Event) + Send + Sync + 'static,
105 {
106 self.callbacks.insert(key.into(), Box::new(handler));
107 self
108 }
109
110 pub fn dom_ref(mut self, dom_ref: Arc<DomRef>) -> Self {
113 self.dom_ref = Some(dom_ref);
114 self
115 }
116}
117
118impl HtmlElementBuilder<&'static str> {
119 pub fn build(self) -> HtmlElement {
120 HtmlElement {
121 tag_name: self.tag_name,
122 attributes: self.attributes,
123 callbacks: self.callbacks,
124 dom_ref: self.dom_ref,
125 }
126 }
127}
128
129impl PartialEq for HtmlElement {
130 fn eq(&self, other: &Self) -> bool {
131 self.tag_name == other.tag_name
132 && self.attributes == other.attributes
133 && self.callbacks.is_empty()
134 && other.callbacks.is_empty()
135 && self.dom_ref == other.dom_ref
136 }
137}