Skip to main content

orinium_browser/engine/css/
processor.rs

1use super::parser::Parser as CssParser;
2use crate::engine::background_worker::BackgroundWorker;
3use crate::engine::layouter::css_resolver::{CssResolver, ResolvedStyles, append_resolved_styles};
4use crate::{perf_scope, profile_log};
5
6enum CssCommand {
7    Process { css_sources: Vec<String> },
8}
9
10#[derive(Debug)]
11pub struct CssProcessor {
12    worker: BackgroundWorker<CssCommand, ResolvedStyles>,
13}
14
15impl Default for CssProcessor {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl CssProcessor {
22    pub fn new() -> Self {
23        Self {
24            worker: BackgroundWorker::new(1, |cmd| match cmd {
25                CssCommand::Process { css_sources } => Self::process_all(&css_sources),
26            }),
27        }
28    }
29
30    /// Send CSS source strings to the background thread for parsing and resolution.
31    /// The thread will process all sources in order and return a single combined result.
32    pub fn process(&self, css_sources: Vec<String>) {
33        self.worker.send(CssCommand::Process { css_sources });
34    }
35
36    /// Poll for a completed result. Returns `None` if no result is ready yet.
37    pub fn try_receive(&self) -> Option<ResolvedStyles> {
38        self.worker.try_receive()
39    }
40
41    fn process_all(css_sources: &[String]) -> ResolvedStyles {
42        perf_scope!(total);
43        let mut resolved = ResolvedStyles::default();
44
45        #[cfg(any(feature = "profile", debug_assertions))]
46        let mut parse_time = std::time::Duration::ZERO;
47        #[cfg(any(feature = "profile", debug_assertions))]
48        let mut resolve_time = std::time::Duration::ZERO;
49
50        for css in css_sources {
51            perf_scope!(parse);
52            let sheet = CssParser::new(css).parse_lossy();
53            #[cfg(any(feature = "profile", debug_assertions))]
54            {
55                parse_time += parse.elapsed();
56            }
57
58            perf_scope!(resolve);
59            let resolved_sheet = CssResolver::resolve(&sheet);
60            #[cfg(any(feature = "profile", debug_assertions))]
61            {
62                resolve_time += resolve.elapsed();
63            }
64
65            append_resolved_styles(&mut resolved, resolved_sheet);
66        }
67
68        profile_log!(
69            target: "CssRun",
70            log::Level::Info,
71            "[CssResolve] sources: {} | total: {:?} | parse: {:?} | resolve: {:?}",
72            css_sources.len(),
73            total.elapsed(),
74            parse_time,
75            resolve_time,
76        );
77        resolved
78    }
79}