use std::sync::{Arc, Mutex};
use crate::stylesheet::CSSStyleSheet;
#[derive(Debug)]
pub struct CSSOMManager {
stylesheets: std::collections::HashMap<String, Arc<Mutex<CSSStyleSheet>>>,
}
impl CSSOMManager {
pub fn new() -> Self {
Self {
stylesheets: std::collections::HashMap::new(),
}
}
pub fn add_stylesheet(&mut self, name: &str) {
let sheet = CSSStyleSheet::new();
self.stylesheets.insert(name.to_string(), Arc::new(Mutex::new(sheet)));
}
pub fn add_stylesheet_from_css(&mut self, name: &str, css_text: &str) {
let sheet = CSSStyleSheet::from_css(css_text);
self.stylesheets.insert(name.to_string(), Arc::new(Mutex::new(sheet)));
}
pub fn get_stylesheet(&self, name: &str) -> Option<Arc<Mutex<CSSStyleSheet>>> {
self.stylesheets.get(name).map(Arc::clone)
}
pub fn remove_stylesheet(&mut self, name: &str) {
self.stylesheets.remove(name);
}
pub fn insert_rule_to_sheet(
&mut self,
sheet_name: &str,
rule: &str,
index: usize,
) -> Result<u32, String> {
if let Some(sheet) = self.stylesheets.get(sheet_name) {
sheet.lock().unwrap().insert_rule(rule, index)
} else {
Err(format!("Stylesheet '{}' not found", sheet_name))
}
}
pub fn delete_rule_from_sheet(
&mut self,
sheet_name: &str,
index: usize,
) -> Result<(), String> {
if let Some(sheet) = self.stylesheets.get(sheet_name) {
sheet.lock().unwrap().delete_rule(index)
} else {
Err(format!("Stylesheet '{}' not found", sheet_name))
}
}
pub fn get_stylesheet_for_layout(&self, name: &str) -> Option<crate::css::Stylesheet> {
self.stylesheets
.get(name)
.map(|sheet| sheet.lock().unwrap().internal_stylesheet())
}
pub fn get_stylesheet_names(&self) -> Vec<String> {
self.stylesheets.keys().cloned().collect()
}
pub fn stylesheet_count(&self) -> usize {
self.stylesheets.len()
}
pub fn clear_all(&mut self) {
self.stylesheets.clear();
}
}
impl Default for CSSOMManager {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_manager() {
let manager = CSSOMManager::new();
assert_eq!(manager.stylesheet_count(), 0);
}
#[test]
fn test_add_stylesheet() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet("main");
assert_eq!(manager.stylesheet_count(), 1);
assert!(manager.get_stylesheet("main").is_some());
}
#[test]
fn test_add_stylesheet_from_css() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet_from_css("main", ".class { color: red; }");
let sheet = manager.get_stylesheet("main");
assert!(sheet.is_some());
assert_eq!(sheet.unwrap().lock().unwrap().rule_count(), 1);
}
#[test]
fn test_insert_rule_to_sheet() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet("main");
let result = manager.insert_rule_to_sheet("main", ".class { color: red; }", 0);
assert!(result.is_ok());
}
#[test]
fn test_delete_rule_from_sheet() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet_from_css("main", ".class { color: red; }");
let result = manager.delete_rule_from_sheet("main", 0);
assert!(result.is_ok());
assert_eq!(
manager.get_stylesheet("main").unwrap().lock().unwrap().rule_count(),
0
);
}
#[test]
fn test_get_stylesheet_for_layout() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet_from_css("main", ".class { color: red; }");
let layout_sheet = manager.get_stylesheet_for_layout("main");
assert!(layout_sheet.is_some());
assert_eq!(layout_sheet.unwrap().rules.len(), 1);
}
#[test]
fn test_remove_stylesheet() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet("main");
manager.remove_stylesheet("main");
assert_eq!(manager.stylesheet_count(), 0);
}
#[test]
fn test_clear_all() {
let mut manager = CSSOMManager::new();
manager.add_stylesheet("sheet1");
manager.add_stylesheet("sheet2");
manager.clear_all();
assert_eq!(manager.stylesheet_count(), 0);
}
}