1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 //! Computed types for box properties.
6 
7 use crate::values::computed::length::{LengthPercentage, NonNegativeLength};
8 use crate::values::computed::{Context, Number, ToComputedValue};
9 use crate::values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
10 use crate::values::generics::box_::Perspective as GenericPerspective;
11 use crate::values::generics::box_::VerticalAlign as GenericVerticalAlign;
12 use crate::values::specified::box_ as specified;
13 
14 pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween, BreakWithin};
15 pub use crate::values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat};
16 pub use crate::values::specified::box_::{Contain, Display, Overflow};
17 pub use crate::values::specified::box_::{OverflowAnchor, OverflowClipBox, OverscrollBehavior};
18 pub use crate::values::specified::box_::{
19     ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType,
20 };
21 pub use crate::values::specified::box_::{TouchAction, TransitionProperty, WillChange};
22 
23 /// A computed value for the `vertical-align` property.
24 pub type VerticalAlign = GenericVerticalAlign<LengthPercentage>;
25 
26 /// A computed value for the `animation-iteration-count` property.
27 pub type AnimationIterationCount = GenericAnimationIterationCount<Number>;
28 
29 impl AnimationIterationCount {
30     /// Returns the value `1.0`.
31     #[inline]
one() -> Self32     pub fn one() -> Self {
33         GenericAnimationIterationCount::Number(1.0)
34     }
35 }
36 
37 /// A computed value for the `perspective` property.
38 pub type Perspective = GenericPerspective<NonNegativeLength>;
39 
40 #[allow(missing_docs)]
41 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
42 #[derive(
43     Clone,
44     Copy,
45     Debug,
46     Eq,
47     FromPrimitive,
48     Hash,
49     MallocSizeOf,
50     Parse,
51     PartialEq,
52     SpecifiedValueInfo,
53     ToCss,
54     ToResolvedValue,
55 )]
56 #[repr(u8)]
57 /// A computed value for the `float` property.
58 pub enum Float {
59     Left,
60     Right,
61     None,
62 }
63 
64 impl Float {
65     /// Returns true if `self` is not `None`.
is_floating(self) -> bool66     pub fn is_floating(self) -> bool {
67         self != Self::None
68     }
69 }
70 
71 impl ToComputedValue for SpecifiedFloat {
72     type ComputedValue = Float;
73 
74     #[inline]
to_computed_value(&self, context: &Context) -> Self::ComputedValue75     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
76         let ltr = context.style().writing_mode.is_bidi_ltr();
77         // https://drafts.csswg.org/css-logical-props/#float-clear
78         match *self {
79             SpecifiedFloat::InlineStart => {
80                 context
81                     .rule_cache_conditions
82                     .borrow_mut()
83                     .set_writing_mode_dependency(context.builder.writing_mode);
84                 if ltr {
85                     Float::Left
86                 } else {
87                     Float::Right
88                 }
89             },
90             SpecifiedFloat::InlineEnd => {
91                 context
92                     .rule_cache_conditions
93                     .borrow_mut()
94                     .set_writing_mode_dependency(context.builder.writing_mode);
95                 if ltr {
96                     Float::Right
97                 } else {
98                     Float::Left
99                 }
100             },
101             SpecifiedFloat::Left => Float::Left,
102             SpecifiedFloat::Right => Float::Right,
103             SpecifiedFloat::None => Float::None,
104         }
105     }
106 
107     #[inline]
from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat108     fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat {
109         match *computed {
110             Float::Left => SpecifiedFloat::Left,
111             Float::Right => SpecifiedFloat::Right,
112             Float::None => SpecifiedFloat::None,
113         }
114     }
115 }
116 
117 #[allow(missing_docs)]
118 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
119 #[derive(
120     Clone,
121     Copy,
122     Debug,
123     Eq,
124     FromPrimitive,
125     Hash,
126     MallocSizeOf,
127     Parse,
128     PartialEq,
129     SpecifiedValueInfo,
130     ToCss,
131     ToResolvedValue,
132 )]
133 /// A computed value for the `clear` property.
134 pub enum Clear {
135     None,
136     Left,
137     Right,
138     Both,
139 }
140 
141 impl ToComputedValue for SpecifiedClear {
142     type ComputedValue = Clear;
143 
144     #[inline]
to_computed_value(&self, context: &Context) -> Self::ComputedValue145     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
146         let ltr = context.style().writing_mode.is_bidi_ltr();
147         // https://drafts.csswg.org/css-logical-props/#float-clear
148         match *self {
149             SpecifiedClear::InlineStart => {
150                 context
151                     .rule_cache_conditions
152                     .borrow_mut()
153                     .set_writing_mode_dependency(context.builder.writing_mode);
154                 if ltr {
155                     Clear::Left
156                 } else {
157                     Clear::Right
158                 }
159             },
160             SpecifiedClear::InlineEnd => {
161                 context
162                     .rule_cache_conditions
163                     .borrow_mut()
164                     .set_writing_mode_dependency(context.builder.writing_mode);
165                 if ltr {
166                     Clear::Right
167                 } else {
168                     Clear::Left
169                 }
170             },
171             SpecifiedClear::None => Clear::None,
172             SpecifiedClear::Left => Clear::Left,
173             SpecifiedClear::Right => Clear::Right,
174             SpecifiedClear::Both => Clear::Both,
175         }
176     }
177 
178     #[inline]
from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear179     fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear {
180         match *computed {
181             Clear::None => SpecifiedClear::None,
182             Clear::Left => SpecifiedClear::Left,
183             Clear::Right => SpecifiedClear::Right,
184             Clear::Both => SpecifiedClear::Both,
185         }
186     }
187 }
188 
189 /// A computed value for the `resize` property.
190 #[allow(missing_docs)]
191 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
192 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue)]
193 #[repr(u8)]
194 pub enum Resize {
195     None,
196     Both,
197     Horizontal,
198     Vertical,
199 }
200 
201 impl ToComputedValue for specified::Resize {
202     type ComputedValue = Resize;
203 
204     #[inline]
to_computed_value(&self, context: &Context) -> Resize205     fn to_computed_value(&self, context: &Context) -> Resize {
206         let is_vertical = context.style().writing_mode.is_vertical();
207         match self {
208             specified::Resize::Inline => {
209                 context
210                     .rule_cache_conditions
211                     .borrow_mut()
212                     .set_writing_mode_dependency(context.builder.writing_mode);
213                 if is_vertical {
214                     Resize::Vertical
215                 } else {
216                     Resize::Horizontal
217                 }
218             },
219             specified::Resize::Block => {
220                 context
221                     .rule_cache_conditions
222                     .borrow_mut()
223                     .set_writing_mode_dependency(context.builder.writing_mode);
224                 if is_vertical {
225                     Resize::Horizontal
226                 } else {
227                     Resize::Vertical
228                 }
229             },
230             specified::Resize::None => Resize::None,
231             specified::Resize::Both => Resize::Both,
232             specified::Resize::Horizontal => Resize::Horizontal,
233             specified::Resize::Vertical => Resize::Vertical,
234         }
235     }
236 
237     #[inline]
from_computed_value(computed: &Resize) -> specified::Resize238     fn from_computed_value(computed: &Resize) -> specified::Resize {
239         match computed {
240             Resize::None => specified::Resize::None,
241             Resize::Both => specified::Resize::Both,
242             Resize::Horizontal => specified::Resize::Horizontal,
243             Resize::Vertical => specified::Resize::Vertical,
244         }
245     }
246 }
247