orinium_browser/engine/css/
processor.rs1use 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 pub fn process(&self, css_sources: Vec<String>) {
38 let _ = self.cmd_tx.send(CssCommand::Process { css_sources });
39 }
40
41 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}