Skip to main content

iris_cssom/
lib.rs

1//! Iris CSSOM — CSS Object Model implementation.
2//!
3//! Parse CSS strings, compute resolved styles for elements,
4//! support CSS Modules (scoped class names), and provide
5//! CSSOM Web API surfaces (CSSStyleSheet, CSSRule, etc.).
6
7mod parser;
8pub mod computed;
9pub mod css_modules;
10pub mod web_api;
11
12pub use parser::*;
13pub use computed::*;
14pub use css_modules::*;
15pub use web_api::*;
16
17use std::collections::HashMap;
18
19/// A single CSS declaration (property: value).
20#[derive(Debug, Clone, PartialEq)]
21pub struct Declaration {
22    pub property: String,
23    pub value: String,
24}
25
26/// A CSS rule: selector + declarations.
27#[derive(Debug, Clone)]
28pub struct CssRule {
29    pub selectors: Vec<String>,
30    pub declarations: Vec<Declaration>,
31}
32
33/// A parsed stylesheet (list of rules).
34#[derive(Debug, Clone, Default)]
35pub struct StyleSheet {
36    pub rules: Vec<CssRule>,
37}
38
39impl StyleSheet {
40    /// Parse a CSS string into a StyleSheet.
41    pub fn parse(css: &str) -> Result<Self, String> {
42        parser::parse_css(css)
43    }
44
45    /// Query all declarations matching a given class name.
46    pub fn declarations_for_class(&self, class: &str) -> Vec<Declaration> {
47        let mut result = Vec::new();
48        let class_selector = format!(".{}", class);
49        for rule in &self.rules {
50            if rule.selectors.iter().any(|s| s == &class_selector || s.contains(&class_selector)) {
51                result.extend(rule.declarations.clone());
52            }
53        }
54        result
55    }
56
57    /// Query all declarations matching a given tag name.
58    pub fn declarations_for_tag(&self, tag: &str) -> Vec<Declaration> {
59        let mut result = Vec::new();
60        for rule in &self.rules {
61            if rule.selectors.iter().any(|s| s == tag) {
62                result.extend(rule.declarations.clone());
63            }
64        }
65        result
66    }
67
68    /// Compute the full set of resolved declarations for a set of class names and tag.
69    pub fn compute(&self, classes: &[String], tag: &str) -> HashMap<String, String> {
70        let mut map = HashMap::new();
71        for class in classes {
72            for decl in self.declarations_for_class(class) {
73                map.insert(decl.property, decl.value);
74            }
75        }
76        for decl in self.declarations_for_tag(tag) {
77            map.entry(decl.property).or_insert(decl.value);
78        }
79        map
80    }
81}