1use {
4 crate::Node,
5 html5ever::{
6 namespace_url,
7 ns,
8 tendril::Tendril,
9 Attribute,
10 LocalName,
11 QualName,
12 },
13 rcdom::NodeData,
14 std::cell::RefCell,
15};
16
17pub trait NodeExt
19where
20 Self: Sized,
21{
22 fn children(&self) -> &RefCell<Vec<Node>>;
24 fn data(&self) -> &rcdom::NodeData;
26 fn append_children(&self, children: Vec<Node>);
28 fn append_child(&self, child: Node);
30 fn tag_name(&self) -> Option<String> {
32 match &self.data() {
33 NodeData::Doctype { name, .. } => Some(name.to_string()),
34 NodeData::Element { name, .. } => Some(name.local.to_string()),
35 _ => None,
36 }
37 }
38 fn attr(self, name: &str, value: &str) -> Self {
42 {
43 let attrs = match &self.data() {
44 NodeData::Element { attrs, .. } => attrs,
45 _ => return self,
46 };
47 let mut attrs = attrs.borrow_mut();
48 attrs.push(Attribute {
49 name: QualName::new(None, ns!(), LocalName::from(name)),
50 value: Tendril::from(value),
51 });
52 }
53 self
54 }
55 fn borrow_attr(&self, name: &str, value: &str) {
59 {
60 let attrs = match &self.data() {
61 NodeData::Element { attrs, .. } => attrs,
62 _ => return,
63 };
64 let mut attrs = attrs.borrow_mut();
65 attrs.push(Attribute {
66 name: QualName::new(None, ns!(), LocalName::from(name)),
67 value: Tendril::from(value),
68 });
69 }
70 }
71 fn attrs(mut self, attributes: Vec<(&str, &str)>) -> Self {
76 for attr in attributes {
77 self = self.attr(attr.0, attr.1);
78 }
79 self
80 }
81 fn borrow_attrs(&self, attributes: Vec<(&str, &str)>) {
86 for attr in attributes {
87 self.borrow_attr(attr.0, attr.1);
88 }
89 }
90 fn find_attribute(&self, attribute_name: &str) -> Option<usize> {
92 let attrs = match &self.data() {
93 NodeData::Element { attrs, .. } => attrs,
94 _ => return None,
95 };
96 for (idx, attr) in attrs.borrow().iter().enumerate() {
97 if attr.name
98 != QualName::new(None, ns!(), LocalName::from(attribute_name))
99 {
100 continue;
101 }
102 return Some(idx);
103 }
104 None
105 }
106 fn attribute_eq(&self, attribute_name: &str, value: &str) -> bool {
108 if let Some(index) = self.find_attribute(attribute_name) {
109 let attrs = match &self.data() {
110 NodeData::Element { attrs, .. } => attrs.borrow_mut(),
111 _ => return false,
112 };
113 return &*attrs[index].value == value;
114 }
115 false
116 }
117
118 fn add_class(&self, class_value: &str) {
121 let attribute_index = self.find_attribute("class");
122 let attrs = match self.data() {
123 NodeData::Element { attrs, .. } => attrs,
124 _ => return,
125 };
126 let mut attrs = attrs.borrow_mut();
127 match attribute_index {
128 None => {
129 attrs.push(Attribute {
130 name: QualName::new(None, ns!(), LocalName::from("class")),
131 value: Tendril::from(class_value),
132 });
133 }
134 Some(index) => {
135 let value = String::from(attrs[index].value.clone());
136 let mut value = value.split(' ').collect::<Vec<_>>();
137 if value.contains(&class_value) {
138 return;
139 }
140 value.push(class_value);
141 attrs[index].value = Tendril::from(value.join(" "));
142 }
143 };
144 }
145
146 fn remove_class(&self, class_value: &str) {
148 let attribute_index = self.find_attribute("class");
149 let attrs = match self.data() {
150 NodeData::Element { attrs, .. } => attrs,
151 _ => return,
152 };
153 let mut attrs = attrs.borrow_mut();
154 if let Some(index) = attribute_index {
155 let value = String::from(attrs[index].value.clone());
156 let mut value = value.split(' ').collect::<Vec<_>>();
157 value.retain(|x| x != &class_value);
158 attrs[index].value = Tendril::from(value.join(" "));
159 };
160 }
161
162 fn has_class(&self, class_value: &str) -> bool {
164 let attribute_index = self.find_attribute("class");
165 let attrs = match self.data() {
166 NodeData::Element { attrs, .. } => attrs,
167 _ => return false,
168 };
169 let attrs = attrs.borrow();
170 match attribute_index {
171 None => false,
172 Some(index) => {
173 attrs[index].value.split(' ').any(|x| x == class_value)
174 }
175 }
176 }
177
178 fn toggle_class(&self, class_value: &str) {
181 let attribute_index = self.find_attribute("class");
182 let attrs = match self.data() {
183 NodeData::Element { attrs, .. } => attrs,
184 _ => return,
185 };
186 let mut attrs = attrs.borrow_mut();
187 match attribute_index {
188 None => {
189 attrs.push(Attribute {
190 name: QualName::new(None, ns!(), LocalName::from("class")),
191 value: Tendril::from(class_value),
192 });
193 }
194 Some(index) => {
195 let value = String::from(attrs[index].value.clone());
196 let mut value = value.split(' ').collect::<Vec<_>>();
197 if value.contains(&class_value) {
198 return;
199 }
200 value.push(class_value);
201 attrs[index].value = Tendril::from(value.join(" "));
202 }
203 };
204 }
205
206 fn remove_attribute(&self, name: &str) {
210 let attribute_index = self.find_attribute(name);
211 let attrs = match self.data() {
212 NodeData::Element { attrs, .. } => attrs,
213 _ => return,
214 };
215 let mut attrs = attrs.borrow_mut();
216 if let Some(index) = attribute_index {
217 attrs.remove(index);
218 };
219 }
220}