accessibility_tree/style/properties/
mod.rs

1pub use self::definitions::ComputedValues;
2use self::definitions::LonghandId;
3pub use self::definitions::{property_data_by_name, LonghandDeclaration};
4pub use self::definitions::{ComputedValuesForEarlyCascade, ComputedValuesForLateCascade};
5use crate::geom::{flow_relative, physical};
6use crate::style::errors::PropertyParseError;
7use crate::style::values::{self, CssWideKeyword, Direction, Display, WritingMode};
8use crate::style::values::{CascadeContext, EarlyCascadeContext};
9use cssparser::{Color, RGBA};
10use std::sync::Arc;
11
12#[macro_use]
13mod macros;
14
15mod definitions;
16
17impl ComputedValues {
18    pub fn anonymous_inheriting_from(parent_style: Option<&Self>) -> Arc<Self> {
19        Self::new(parent_style, None)
20    }
21
22    pub fn post_cascade_fixups(&mut self) {
23        let b = Arc::make_mut(&mut self.border);
24        b.border_top_width.fixup(b.border_top_style);
25        b.border_left_width.fixup(b.border_left_style);
26        b.border_bottom_width.fixup(b.border_bottom_style);
27        b.border_right_width.fixup(b.border_right_style);
28
29        Display::fixup(self);
30    }
31
32    pub fn writing_mode(&self) -> (WritingMode, Direction) {
33        // FIXME: For now, this is the only supported mode
34        (WritingMode::HorizontalTb, Direction::Ltr)
35    }
36
37    pub fn box_offsets(&self) -> flow_relative::Sides<values::LengthOrPercentageOrAuto> {
38        physical::Sides {
39            top: self.box_.top,
40            left: self.box_.left,
41            bottom: self.box_.bottom,
42            right: self.box_.right,
43        }
44        .to_flow_relative(self.writing_mode())
45    }
46
47    pub fn box_size(&self) -> flow_relative::Vec2<values::LengthOrPercentageOrAuto> {
48        physical::Vec2 {
49            x: self.box_.width,
50            y: self.box_.height,
51        }
52        .size_to_flow_relative(self.writing_mode())
53    }
54
55    pub fn padding(&self) -> flow_relative::Sides<values::LengthOrPercentage> {
56        physical::Sides {
57            top: self.padding.padding_top,
58            left: self.padding.padding_left,
59            bottom: self.padding.padding_bottom,
60            right: self.padding.padding_right,
61        }
62        .to_flow_relative(self.writing_mode())
63    }
64
65    pub fn border_width(&self) -> flow_relative::Sides<values::LengthOrPercentage> {
66        physical::Sides {
67            top: self.border.border_top_width.0,
68            left: self.border.border_left_width.0,
69            bottom: self.border.border_bottom_width.0,
70            right: self.border.border_right_width.0,
71        }
72        .to_flow_relative(self.writing_mode())
73    }
74
75    pub fn margin(&self) -> flow_relative::Sides<values::LengthOrPercentageOrAuto> {
76        physical::Sides {
77            top: self.margin.margin_top,
78            left: self.margin.margin_left,
79            bottom: self.margin.margin_bottom,
80            right: self.margin.margin_right,
81        }
82        .to_flow_relative(self.writing_mode())
83    }
84
85    pub fn to_rgba(&self, color: Color) -> RGBA {
86        match color {
87            Color::RGBA(rgba) => rgba,
88            Color::CurrentColor => self.color.color,
89        }
90    }
91}
92
93pub trait Phase {
94    fn select(&self, p: PerPhase<bool>) -> bool;
95    fn cascade(&mut self, declaration: &LonghandDeclaration);
96}
97
98impl Phase for EarlyCascadeContext<'_> {
99    fn select(&self, p: PerPhase<bool>) -> bool {
100        p.early
101    }
102
103    fn cascade(&mut self, declaration: &LonghandDeclaration) {
104        declaration.if_early_cascade_into(self)
105    }
106}
107
108impl Phase for CascadeContext<'_> {
109    fn select(&self, p: PerPhase<bool>) -> bool {
110        p.late
111    }
112
113    fn cascade(&mut self, declaration: &LonghandDeclaration) {
114        declaration.if_late_cascade_into(self)
115    }
116}
117
118#[derive(Default, Copy, Clone, Debug)]
119pub struct PerPhase<T> {
120    pub early: T,
121    pub late: T,
122}
123
124type FnParseProperty = for<'i, 't> fn(
125    &mut cssparser::Parser<'i, 't>,
126    &mut Vec<LonghandDeclaration>,
127) -> Result<PerPhase<bool>, PropertyParseError<'i>>;
128
129pub struct PropertyData {
130    pub longhands: &'static [LonghandId],
131    pub parse: FnParseProperty,
132}
133
134trait ValueOrInitial<T> {
135    fn into<F>(self, id: LonghandId, constructor: F) -> LonghandDeclaration
136    where
137        F: Fn(T) -> LonghandDeclaration;
138}
139
140impl<T> ValueOrInitial<T> for T {
141    fn into<F>(self, _id: LonghandId, constructor: F) -> LonghandDeclaration
142    where
143        F: Fn(T) -> LonghandDeclaration,
144    {
145        constructor(self)
146    }
147}
148
149impl<T> ValueOrInitial<T> for Option<T> {
150    fn into<F>(self, id: LonghandId, constructor: F) -> LonghandDeclaration
151    where
152        F: Fn(T) -> LonghandDeclaration,
153    {
154        match self {
155            Some(value) => constructor(value),
156            None => LonghandDeclaration::CssWide(id, CssWideKeyword::Initial),
157        }
158    }
159}