Skip to main content

orinium_browser/engine/css/
processor.rs

1use std::sync::mpsc::{self, Receiver, Sender};
2use std::thread;
3
4use super::parser::Parser as CssParser;
5use crate::engine::layouter::css_resolver::{CssResolver, ResolvedStyles};
6
7enum CssCommand {
8    Process { css_sources: Vec<String> },
9}
10
11pub struct CssProcessor {
12    cmd_tx: Sender<CssCommand>,
13    result_rx: Receiver<ResolvedStyles>,
14}
15
16impl CssProcessor {
17    pub fn new() -> Self {
18        let (cmd_tx, cmd_rx) = mpsc::channel::<CssCommand>();
19        let (result_tx, result_rx) = mpsc::channel::<ResolvedStyles>();
20
21        thread::spawn(move || {
22            for cmd in cmd_rx {
23                match cmd {
24                    CssCommand::Process { css_sources } => {
25                        let resolved = Self::process_all(&css_sources);
26                        let _ = result_tx.send(resolved);
27                    }
28                }
29            }
30        });
31
32        Self { cmd_tx, result_rx }
33    }
34
35    /// Send CSS source strings to the background thread for parsing and resolution.
36    /// The thread will process all sources in order and return a single combined result.
37    pub fn process(&self, css_sources: Vec<String>) {
38        let _ = self.cmd_tx.send(CssCommand::Process { css_sources });
39    }
40
41    /// Poll for a completed result. Returns `None` if no result is ready yet.
42    pub fn try_receive(&self) -> Option<ResolvedStyles> {
43        self.result_rx.try_recv().ok()
44    }
45
46    fn process_all(css_sources: &[String]) -> ResolvedStyles {
47        let mut resolved = ResolvedStyles::default();
48
49        for css in css_sources {
50            let sheet = match CssParser::new(css).parse() {
51                Ok(sheet) => sheet,
52                Err(err) => {
53                    log::error!("[CssProcessor] Failed to parse CSS: {}", err);
54                    continue;
55                }
56            };
57
58            resolved.extend(CssResolver::resolve(&sheet));
59        }
60
61        resolved
62    }
63}