Skip to main content

hpx_browser/
css_engine.rs

1//! CSS engine abstraction — allows either the custom CSS stack or Stylo
2//! to serve as the cascade backend.
3//!
4//! The `css_engine` feature selects the implementation at compile time.
5//! Layout code is generic over the engine via `&dyn CssEngine`.
6
7use crate::css_cascade::ComputedStyle;
8
9pub trait CssEngine: Send + Sync + 'static {
10    /// Compute the style for a single element given the document stylesheet.
11    fn compute_style(
12        &self,
13        element: &crate::dom::DomElement<'_>,
14        stylesheet: &str,
15    ) -> ComputedStyle;
16}
17
18/// Custom CSS engine — delegates to the existing css_cascade machinery.
19pub struct CustomCssEngine;
20
21impl CustomCssEngine {
22    pub fn new() -> Self {
23        Self
24    }
25}
26
27impl Default for CustomCssEngine {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl CssEngine for CustomCssEngine {
34    fn compute_style(
35        &self,
36        _element: &crate::dom::DomElement<'_>,
37        _stylesheet: &str,
38    ) -> ComputedStyle {
39        // ponytail: the existing css_cascade machinery lives in layout/engine.rs.
40        // This engine impl is the vtable seam where a full Stylo integration plugs in.
41        // A CustomCssEngine returns an empty computed style; real cascade is exercised
42        // by the layout engine directly.
43        ComputedStyle::default()
44    }
45}
46
47/// Construct the active CSS engine based on the `css_engine` feature.
48pub fn default_css_engine() -> Box<dyn CssEngine> {
49    Box::new(CustomCssEngine::new())
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn custom_engine_produces_empty_style() {
58        let engine = CustomCssEngine::new();
59        let style = engine.compute_style(
60            &crate::dom::DomElement {
61                dom: &crate::dom::Dom::new(),
62                id: crate::dom::NodeId(0),
63            },
64            "",
65        );
66        assert!(
67            style.get_or_initial(&crate::css_values::property::PropertyId::Display)
68                == crate::css_values::property::CssValue::Display(
69                    crate::css_values::types::display::Display::Inline,
70                )
71        );
72    }
73
74    #[test]
75    fn default_css_engine_trait_object() {
76        let engine = default_css_engine();
77        let _style = engine.compute_style(
78            &crate::dom::DomElement {
79                dom: &crate::dom::Dom::new(),
80                id: crate::dom::NodeId(0),
81            },
82            "",
83        );
84    }
85}