1use std::sync::{Arc, Mutex};
6use crate::stylesheet::CSSStyleSheet;
7
8#[derive(Debug)]
25pub struct CSSOMManager {
26 stylesheets: std::collections::HashMap<String, Arc<Mutex<CSSStyleSheet>>>,
28}
29
30impl CSSOMManager {
31 pub fn new() -> Self {
33 Self {
34 stylesheets: std::collections::HashMap::new(),
35 }
36 }
37
38 pub fn add_stylesheet(&mut self, name: &str) {
44 let sheet = CSSStyleSheet::new();
45 self.stylesheets.insert(name.to_string(), Arc::new(Mutex::new(sheet)));
46 }
47
48 pub fn add_stylesheet_from_css(&mut self, name: &str, css_text: &str) {
55 let sheet = CSSStyleSheet::from_css(css_text);
56 self.stylesheets.insert(name.to_string(), Arc::new(Mutex::new(sheet)));
57 }
58
59 pub fn get_stylesheet(&self, name: &str) -> Option<Arc<Mutex<CSSStyleSheet>>> {
61 self.stylesheets.get(name).map(Arc::clone)
62 }
63
64 pub fn remove_stylesheet(&mut self, name: &str) {
66 self.stylesheets.remove(name);
67 }
68
69 pub fn insert_rule_to_sheet(
77 &mut self,
78 sheet_name: &str,
79 rule: &str,
80 index: usize,
81 ) -> Result<u32, String> {
82 if let Some(sheet) = self.stylesheets.get(sheet_name) {
83 sheet.lock().unwrap().insert_rule(rule, index)
84 } else {
85 Err(format!("Stylesheet '{}' not found", sheet_name))
86 }
87 }
88
89 pub fn delete_rule_from_sheet(
91 &mut self,
92 sheet_name: &str,
93 index: usize,
94 ) -> Result<(), String> {
95 if let Some(sheet) = self.stylesheets.get(sheet_name) {
96 sheet.lock().unwrap().delete_rule(index)
97 } else {
98 Err(format!("Stylesheet '{}' not found", sheet_name))
99 }
100 }
101
102 pub fn get_stylesheet_for_layout(&self, name: &str) -> Option<crate::css::Stylesheet> {
106 self.stylesheets
107 .get(name)
108 .map(|sheet| sheet.lock().unwrap().internal_stylesheet())
109 }
110
111 pub fn get_stylesheet_names(&self) -> Vec<String> {
113 self.stylesheets.keys().cloned().collect()
114 }
115
116 pub fn stylesheet_count(&self) -> usize {
118 self.stylesheets.len()
119 }
120
121 pub fn clear_all(&mut self) {
123 self.stylesheets.clear();
124 }
125}
126
127impl Default for CSSOMManager {
128 fn default() -> Self {
129 Self::new()
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_new_manager() {
139 let manager = CSSOMManager::new();
140 assert_eq!(manager.stylesheet_count(), 0);
141 }
142
143 #[test]
144 fn test_add_stylesheet() {
145 let mut manager = CSSOMManager::new();
146 manager.add_stylesheet("main");
147 assert_eq!(manager.stylesheet_count(), 1);
148 assert!(manager.get_stylesheet("main").is_some());
149 }
150
151 #[test]
152 fn test_add_stylesheet_from_css() {
153 let mut manager = CSSOMManager::new();
154 manager.add_stylesheet_from_css("main", ".class { color: red; }");
155
156 let sheet = manager.get_stylesheet("main");
157 assert!(sheet.is_some());
158 assert_eq!(sheet.unwrap().lock().unwrap().rule_count(), 1);
159 }
160
161 #[test]
162 fn test_insert_rule_to_sheet() {
163 let mut manager = CSSOMManager::new();
164 manager.add_stylesheet("main");
165
166 let result = manager.insert_rule_to_sheet("main", ".class { color: red; }", 0);
167 assert!(result.is_ok());
168 }
169
170 #[test]
171 fn test_delete_rule_from_sheet() {
172 let mut manager = CSSOMManager::new();
173 manager.add_stylesheet_from_css("main", ".class { color: red; }");
174
175 let result = manager.delete_rule_from_sheet("main", 0);
176 assert!(result.is_ok());
177 assert_eq!(
178 manager.get_stylesheet("main").unwrap().lock().unwrap().rule_count(),
179 0
180 );
181 }
182
183 #[test]
184 fn test_get_stylesheet_for_layout() {
185 let mut manager = CSSOMManager::new();
186 manager.add_stylesheet_from_css("main", ".class { color: red; }");
187
188 let layout_sheet = manager.get_stylesheet_for_layout("main");
189 assert!(layout_sheet.is_some());
190 assert_eq!(layout_sheet.unwrap().rules.len(), 1);
191 }
192
193 #[test]
194 fn test_remove_stylesheet() {
195 let mut manager = CSSOMManager::new();
196 manager.add_stylesheet("main");
197 manager.remove_stylesheet("main");
198 assert_eq!(manager.stylesheet_count(), 0);
199 }
200
201 #[test]
202 fn test_clear_all() {
203 let mut manager = CSSOMManager::new();
204 manager.add_stylesheet("sheet1");
205 manager.add_stylesheet("sheet2");
206 manager.clear_all();
207 assert_eq!(manager.stylesheet_count(), 0);
208 }
209}