node_html_parser/dom/element/
class_list.rs1use super::main::HTMLElement;
2
3impl HTMLElement {
4 fn ensure_class_cache(&mut self) {
5 if self.class_cache.is_none() {
6 let list = self.get_attribute("class").unwrap_or_default();
7 let tokens: Vec<String> = list
8 .split_whitespace()
9 .filter(|s| !s.is_empty())
10 .map(|s| s.to_string())
11 .collect();
12 self.class_cache = Some(tokens);
13 }
14 }
15 pub fn class_list(&mut self) -> Vec<String> {
16 self.ensure_class_cache();
17 self.class_cache.clone().unwrap()
18 }
19 pub fn class_list_view(&self) -> Vec<&str> {
20 self.get_attr("class")
21 .map(|s| s.split_whitespace().collect())
22 .unwrap_or_else(Vec::new)
23 }
24 pub fn class_list_contains(&mut self, token: &str) -> bool {
25 self.ensure_class_cache();
26 self.class_cache
27 .as_ref()
28 .unwrap()
29 .iter()
30 .any(|c| c == token)
31 }
32 pub fn class_list_add(&mut self, token: &str) {
33 self.ensure_class_cache();
34 if let Some(v) = self.class_cache.as_mut() {
35 if v.iter().any(|c| c == token) {
36 return;
37 }
38 let mut new_tokens = v.clone();
39 new_tokens.push(token.to_string());
40 let new_val = new_tokens.join(" ");
41 self.set_attributes(&[("class".to_string(), new_val)]);
42 self.class_cache = Some(new_tokens);
43 }
44 }
45 pub fn class_list_remove(&mut self, token: &str) {
46 self.ensure_class_cache();
47 if let Some(v) = self.class_cache.as_mut() {
48 if !v.iter().any(|c| c == token) {
49 return;
50 }
51 let new_tokens: Vec<String> =
52 v.iter().filter(|c| c.as_str() != token).cloned().collect();
53 let new_val = new_tokens.join(" ");
54 self.set_attributes(&[("class".to_string(), new_val.clone())]);
55 self.class_cache = if new_val.is_empty() {
56 None
57 } else {
58 Some(new_tokens)
59 };
60 }
61 }
62 pub fn class_list_toggle(&mut self, token: &str) {
63 if self.class_list_contains(token) {
64 self.class_list_remove(token);
65 } else {
66 self.class_list_add(token);
67 }
68 }
69 pub fn class_list_replace(&mut self, old: &str, new: &str) {
70 self.ensure_class_cache();
71 if let Some(v) = self.class_cache.as_mut() {
72 if !v.iter().any(|c| c == old) {
73 return;
74 }
75 let mut new_tokens: Vec<String> = Vec::with_capacity(v.len());
76 for c in v.iter() {
77 if c == old {
78 new_tokens.push(new.to_string());
79 } else {
80 new_tokens.push(c.clone());
81 }
82 }
83 let new_val = new_tokens.join(" ");
84 self.set_attributes(&[("class".to_string(), new_val.clone())]);
85 self.class_cache = Some(new_tokens);
86 }
87 }
88
89 fn sync_class_attr(&mut self) {
90 if let Some(cache) = &self.class_cache {
91 let joined = cache.join(" ");
92 self.set_attr("class", &joined);
93 }
94 }
95}