accessibility_tree/style/values/
box_.rs

1use crate::style::errors::PropertyParseError;
2use crate::style::properties::ComputedValues;
3use cssparser::Parser;
4use std::sync::Arc;
5
6/// <https://drafts.csswg.org/css-display-3/#the-display-properties>
7#[derive(Copy, Clone, Eq, PartialEq, SpecifiedAsComputed)]
8pub enum Display {
9    None,
10    Contents,
11    GeneratingBox(DisplayGeneratingBox),
12}
13
14#[allow(dead_code)]
15fn _static_assert_size_of() {
16    let _ = std::mem::transmute::<Display, [u8; 2]>;
17}
18
19#[derive(Copy, Clone, Eq, PartialEq)]
20pub enum DisplayGeneratingBox {
21    OutsideInside {
22        outside: DisplayOutside,
23        inside: DisplayInside,
24        // list_item: bool,
25    },
26    // Layout-internal display types go here:
27    // <https://drafts.csswg.org/css-display-3/#layout-specific-display>
28}
29
30/// <https://drafts.csswg.org/css-display-3/#outer-role>
31#[derive(Copy, Clone, Eq, PartialEq)]
32pub enum DisplayOutside {
33    Inline,
34    Block,
35}
36
37/// <https://drafts.csswg.org/css-display-3/#inner-model>
38#[derive(Copy, Clone, Eq, PartialEq)]
39pub enum DisplayInside {
40    Flow,
41    FlowRoot,
42}
43
44impl Display {
45    pub const INITIAL: Self = Display::GeneratingBox(DisplayGeneratingBox::OutsideInside {
46        outside: DisplayOutside::Inline,
47        inside: DisplayInside::Flow,
48    });
49
50    /// <https://drafts.csswg.org/css-display-3/#blockify>
51    pub fn blockify(&self) -> Self {
52        match *self {
53            Display::GeneratingBox(value) => Display::GeneratingBox(match value {
54                DisplayGeneratingBox::OutsideInside { outside: _, inside } => {
55                    DisplayGeneratingBox::OutsideInside {
56                        outside: DisplayOutside::Block,
57                        inside,
58                    }
59                } // other => other,
60            }),
61            other => other,
62        }
63    }
64
65    /// <https://drafts.csswg.org/css2/visuren.html#dis-pos-flo>
66    pub fn fixup(style: &mut ComputedValues) {
67        style.specified_display = style.box_.display;
68        if style.box_.position.is_absolutely_positioned() || style.box_.float.is_floating() {
69            let display = style.box_.display.blockify();
70            if display != style.box_.display {
71                Arc::make_mut(&mut style.box_).display = display
72            }
73        }
74    }
75}
76
77impl super::Parse for Display {
78    fn parse<'i, 't>(parser: &mut Parser<'i, 't>) -> Result<Self, PropertyParseError<'i>> {
79        let ident = parser.expect_ident()?;
80        match &**ident {
81            "none" => Ok(Display::None),
82            "contents" => Ok(Display::Contents),
83            "block" => Ok(Display::GeneratingBox(
84                DisplayGeneratingBox::OutsideInside {
85                    outside: DisplayOutside::Block,
86                    inside: DisplayInside::Flow,
87                },
88            )),
89            "flow-root" => Ok(Display::GeneratingBox(
90                DisplayGeneratingBox::OutsideInside {
91                    outside: DisplayOutside::Block,
92                    inside: DisplayInside::FlowRoot,
93                },
94            )),
95            "inline" => Ok(Display::GeneratingBox(
96                DisplayGeneratingBox::OutsideInside {
97                    outside: DisplayOutside::Inline,
98                    inside: DisplayInside::Flow,
99                },
100            )),
101            _ => {
102                let token = cssparser::Token::Ident(ident.clone());
103                Err(parser.new_unexpected_token_error(token))
104            }
105        }
106    }
107}
108
109/// <https://drafts.csswg.org/css2/visuren.html#propdef-float>
110#[derive(Copy, Clone, Eq, Parse, PartialEq, SpecifiedAsComputed)]
111pub enum Float {
112    None,
113    Left,
114    Right,
115}
116
117impl Float {
118    pub fn is_floating(self) -> bool {
119        match self {
120            Float::None => false,
121            Float::Left | Float::Right => true,
122        }
123    }
124}
125
126/// <https://drafts.csswg.org/css-position-3/#position-property>
127#[derive(Copy, Clone, Eq, Parse, PartialEq, SpecifiedAsComputed)]
128pub enum Position {
129    Static,
130    Relative,
131    Absolute,
132}
133
134impl Position {
135    pub fn is_relatively_positioned(self) -> bool {
136        self == Position::Relative
137    }
138
139    pub fn is_absolutely_positioned(self) -> bool {
140        self == Position::Absolute
141    }
142}