css_knife/
visit_selectors.rs

1use lightningcss::{
2    selector::Selector,
3    values::string::CowArcStr,
4    visit_types,
5    visitor::{VisitTypes, Visitor},
6};
7use parcel_selectors::parser::Component;
8
9use crate::short_classes::{CSSToken, ClassContainer};
10use lightningcss::stylesheet::StyleSheet;
11
12#[derive(Clone, PartialEq, Eq, Default)]
13pub struct ClassVisitor {
14    container: ClassContainer,
15}
16
17impl ClassVisitor {
18    pub fn show(&self, stylesheet: StyleSheet) {
19        self.container.into_file(stylesheet);
20    }
21
22    pub fn get(&self, class: &str) -> Option<String> {
23        self.container.get(class.to_owned(), CSSToken::Class)
24    }
25}
26
27impl<'i> Visitor<'i> for ClassVisitor {
28    type Error = ();
29
30    fn visit_types(&self) -> VisitTypes {
31        visit_types!(SELECTORS | DASHED_IDENTS)
32    }
33
34    #[allow(clippy::collapsible_match)]
35    fn visit_selector(
36        &mut self,
37        selector: &mut Selector<'i>,
38    ) -> Result<(), Self::Error> {
39        let iter = selector.iter_mut_raw_match_order();
40        for i in iter {
41            match i {
42                Component::Class(c) => {
43                    if let Some(n) =
44                        self.container.add(c.0.to_string(), CSSToken::Class)
45                    {
46                        c.0 = CowArcStr::from(n);
47                    }
48                }
49                Component::Negation(selectors)
50                | Component::Is(selectors)
51                | Component::Where(selectors)
52                | Component::Has(selectors)
53                | Component::Any(_, selectors) => {
54                    for i in selectors.iter_mut() {
55                        self.visit_selector(i)?;
56                    }
57                }
58                Component::Slotted(selectors) => {
59                    self.visit_selector(selectors)?;
60                }
61                Component::Host(selector) => {
62                    if let Some(selector) = selector {
63                        self.visit_selector(selector)?;
64                    }
65                }
66                _ => (),
67            }
68        }
69        Ok(())
70    }
71
72    fn visit_dashed_ident(
73        &mut self,
74        ident: &mut lightningcss::values::ident::DashedIdent,
75    ) -> Result<(), Self::Error> {
76        if let Some(n) = self.container.add(
77            ident.0.to_string(),
78            crate::short_classes::CSSToken::CustomProperty,
79        ) {
80            let n = format!("--{}", n);
81            ident.0 = CowArcStr::from(n);
82        }
83
84        Ok(())
85    }
86}