sauron_core/vdom/
element.rs1use super::attribute::{AttributeName, Namespace, Tag};
2use super::{Attribute, Node};
3
4use crate::vdom::AttributeValue;
5use crate::vdom::Leaf;
6use crate::vdom::Value;
7use derive_where::derive_where;
8use indexmap::IndexMap;
9
10#[derive_where(Clone, Debug, PartialEq, Eq)]
24pub struct Element<MSG> {
25 pub namespace: Option<Namespace>,
28 pub tag: Tag,
30 pub(crate) attrs: Vec<Attribute<MSG>>,
32 pub(crate) children: Vec<Node<MSG>>,
34 pub self_closing: bool,
36}
37
38impl<MSG> Element<MSG> {
39 pub fn new(
41 namespace: Option<Namespace>,
42 tag: Tag,
43 attrs: impl IntoIterator<Item = Attribute<MSG>>,
44 children: impl IntoIterator<Item = Node<MSG>>,
45 self_closing: bool,
46 ) -> Self {
47 let children = children
49 .into_iter()
50 .flat_map(|child| match child {
51 Node::Leaf(Leaf::NodeList(node_list)) => node_list,
52 _ => vec![child],
53 })
54 .collect();
55 Self {
56 namespace,
57 tag,
58 attrs: attrs.into_iter().collect(),
59 children,
60 self_closing,
61 }
62 }
63
64 pub fn add_attributes(&mut self, attrs: impl IntoIterator<Item = Attribute<MSG>>) {
66 self.attrs.extend(attrs)
67 }
68
69 pub fn add_children(&mut self, children: impl IntoIterator<Item = Node<MSG>>) {
71 self.children.extend(children);
72 }
73
74 pub fn children(&self) -> &[Node<MSG>] {
76 &self.children
77 }
78
79 pub fn children_mut(&mut self) -> &mut [Node<MSG>] {
81 &mut self.children
82 }
83
84 pub fn swap_remove_child(&mut self, index: usize) -> Node<MSG> {
92 self.children.swap_remove(index)
93 }
94
95 pub fn swap_children(&mut self, a: usize, b: usize) {
105 self.children.swap(a, b)
106 }
107
108 pub fn take_children(self) -> Vec<Node<MSG>> {
110 self.children
111 }
112
113 pub fn attributes(&self) -> &[Attribute<MSG>] {
115 &self.attrs
116 }
117
118 pub fn take_attributes(self) -> Vec<Attribute<MSG>> {
120 self.attrs
121 }
122
123 pub fn namespace(&self) -> Option<&Namespace> {
125 self.namespace.as_ref()
126 }
127
128 pub fn tag(&self) -> &Tag {
130 &self.tag
131 }
132
133 pub fn take_tag(self) -> Tag {
135 self.tag
136 }
137
138 pub fn set_tag(&mut self, tag: Tag) {
140 self.tag = tag;
141 }
142
143 pub fn remove_attribute(&mut self, name: &AttributeName) {
145 self.attrs.retain(|att| att.name != *name)
146 }
147
148 pub fn set_attributes(&mut self, attrs: impl IntoIterator<Item = Attribute<MSG>>) {
151 for attr in attrs {
152 self.remove_attribute(&attr.name);
153 self.attrs.push(attr);
154 }
155 }
156
157 pub fn merge_attributes(&mut self, new_attrs: impl IntoIterator<Item = Attribute<MSG>>) {
159 for new_att in new_attrs {
160 if let Some(existing_attr) = self.attrs.iter_mut().find(|att| att.name == new_att.name)
161 {
162 existing_attr.value.extend(new_att.value);
163 } else {
164 self.attrs.push(new_att);
165 }
166 }
167 }
168
169 pub fn attribute_value(&self, name: &AttributeName) -> Option<Vec<&AttributeValue<MSG>>> {
171 let result: Vec<&AttributeValue<MSG>> = self
172 .attrs
173 .iter()
174 .filter(|att| att.name == *name)
175 .flat_map(|att| att.value())
176 .collect();
177
178 if result.is_empty() {
179 None
180 } else {
181 Some(result)
182 }
183 }
184
185 pub fn first_value(&self, att_name: &AttributeName) -> Option<&Value> {
187 self.attribute_value(att_name)
188 .and_then(|att_values| att_values.first().and_then(|v| v.get_simple()))
189 }
190
191 pub fn group_indexed_attributes_per_name<'a>(
194 attrs: &'a [Attribute<MSG>],
195 ) -> IndexMap<&'a AttributeName, Vec<(usize, &'a Attribute<MSG>)>> {
196 let mut grouped: IndexMap<&'a AttributeName, Vec<(usize, &'a Attribute<MSG>)>> =
197 IndexMap::new();
198 for (i, attr) in attrs.iter().enumerate() {
199 if let Some(existing) = grouped.get_mut(&attr.name) {
200 existing.push((i, attr));
201 } else {
202 grouped.insert(&attr.name, vec![(i, attr)]);
203 }
204 }
205 grouped
206 }
207
208 pub fn has_mount_callback(&self) -> bool {
210 self.attributes().iter().any(|a| a.is_mount_callback())
211 }
212}