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_::{
15     AnimationName, AnimationTimeline, Appearance, BreakBetween, BreakWithin,
16     Clear as SpecifiedClear, Contain, Display, Float as SpecifiedFloat, Overflow, OverflowAnchor,
17     OverflowClipBox, OverscrollBehavior, ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness,
18     ScrollSnapType, ScrollbarGutter, TouchAction, TransitionProperty, WillChange,
19 };
20 
21 /// A computed value for the `vertical-align` property.
22 pub type VerticalAlign = GenericVerticalAlign<LengthPercentage>;
23 
24 /// A computed value for the `animation-iteration-count` property.
25 pub type AnimationIterationCount = GenericAnimationIterationCount<Number>;
26 
27 impl AnimationIterationCount {
28     /// Returns the value `1.0`.
29     #[inline]
one() -> Self30     pub fn one() -> Self {
31         GenericAnimationIterationCount::Number(1.0)
32     }
33 }
34 
35 /// A computed value for the `perspective` property.
36 pub type Perspective = GenericPerspective<NonNegativeLength>;
37 
38 #[allow(missing_docs)]
39 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
40 #[derive(
41     Clone,
42     Copy,
43     Debug,
44     Eq,
45     FromPrimitive,
46     Hash,
47     MallocSizeOf,
48     Parse,
49     PartialEq,
50     SpecifiedValueInfo,
51     ToCss,
52     ToResolvedValue,
53 )]
54 #[repr(u8)]
55 /// A computed value for the `float` property.
56 pub enum Float {
57     Left,
58     Right,
59     None,
60 }
61 
62 impl Float {
63     /// Returns true if `self` is not `None`.
is_floating(self) -> bool64     pub fn is_floating(self) -> bool {
65         self != Self::None
66     }
67 }
68 
69 impl ToComputedValue for SpecifiedFloat {
70     type ComputedValue = Float;
71 
72     #[inline]
to_computed_value(&self, context: &Context) -> Self::ComputedValue73     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
74         let ltr = context.style().writing_mode.is_bidi_ltr();
75         // https://drafts.csswg.org/css-logical-props/#float-clear
76         match *self {
77             SpecifiedFloat::InlineStart => {
78                 context
79                     .rule_cache_conditions
80                     .borrow_mut()
81                     .set_writing_mode_dependency(context.builder.writing_mode);
82                 if ltr {
83                     Float::Left
84                 } else {
85                     Float::Right
86                 }
87             },
88             SpecifiedFloat::InlineEnd => {
89                 context
90                     .rule_cache_conditions
91                     .borrow_mut()
92                     .set_writing_mode_dependency(context.builder.writing_mode);
93                 if ltr {
94                     Float::Right
95                 } else {
96                     Float::Left
97                 }
98             },
99             SpecifiedFloat::Left => Float::Left,
100             SpecifiedFloat::Right => Float::Right,
101             SpecifiedFloat::None => Float::None,
102         }
103     }
104 
105     #[inline]
from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat106     fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat {
107         match *computed {
108             Float::Left => SpecifiedFloat::Left,
109             Float::Right => SpecifiedFloat::Right,
110             Float::None => SpecifiedFloat::None,
111         }
112     }
113 }
114 
115 #[allow(missing_docs)]
116 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
117 #[derive(
118     Clone,
119     Copy,
120     Debug,
121     Eq,
122     FromPrimitive,
123     Hash,
124     MallocSizeOf,
125     Parse,
126     PartialEq,
127     SpecifiedValueInfo,
128     ToCss,
129     ToResolvedValue,
130 )]
131 /// A computed value for the `clear` property.
132 pub enum Clear {
133     None,
134     Left,
135     Right,
136     Both,
137 }
138 
139 impl ToComputedValue for SpecifiedClear {
140     type ComputedValue = Clear;
141 
142     #[inline]
to_computed_value(&self, context: &Context) -> Self::ComputedValue143     fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
144         let ltr = context.style().writing_mode.is_bidi_ltr();
145         // https://drafts.csswg.org/css-logical-props/#float-clear
146         match *self {
147             SpecifiedClear::InlineStart => {
148                 context
149                     .rule_cache_conditions
150                     .borrow_mut()
151                     .set_writing_mode_dependency(context.builder.writing_mode);
152                 if ltr {
153                     Clear::Left
154                 } else {
155                     Clear::Right
156                 }
157             },
158             SpecifiedClear::InlineEnd => {
159                 context
160                     .rule_cache_conditions
161                     .borrow_mut()
162                     .set_writing_mode_dependency(context.builder.writing_mode);
163                 if ltr {
164                     Clear::Right
165                 } else {
166                     Clear::Left
167                 }
168             },
169             SpecifiedClear::None => Clear::None,
170             SpecifiedClear::Left => Clear::Left,
171             SpecifiedClear::Right => Clear::Right,
172             SpecifiedClear::Both => Clear::Both,
173         }
174     }
175 
176     #[inline]
from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear177     fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear {
178         match *computed {
179             Clear::None => SpecifiedClear::None,
180             Clear::Left => SpecifiedClear::Left,
181             Clear::Right => SpecifiedClear::Right,
182             Clear::Both => SpecifiedClear::Both,
183         }
184     }
185 }
186 
187 /// A computed value for the `resize` property.
188 #[allow(missing_docs)]
189 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
190 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue)]
191 #[repr(u8)]
192 pub enum Resize {
193     None,
194     Both,
195     Horizontal,
196     Vertical,
197 }
198 
199 impl ToComputedValue for specified::Resize {
200     type ComputedValue = Resize;
201 
202     #[inline]
to_computed_value(&self, context: &Context) -> Resize203     fn to_computed_value(&self, context: &Context) -> Resize {
204         let is_vertical = context.style().writing_mode.is_vertical();
205         match self {
206             specified::Resize::Inline => {
207                 context
208                     .rule_cache_conditions
209                     .borrow_mut()
210                     .set_writing_mode_dependency(context.builder.writing_mode);
211                 if is_vertical {
212                     Resize::Vertical
213                 } else {
214                     Resize::Horizontal
215                 }
216             },
217             specified::Resize::Block => {
218                 context
219                     .rule_cache_conditions
220                     .borrow_mut()
221                     .set_writing_mode_dependency(context.builder.writing_mode);
222                 if is_vertical {
223                     Resize::Horizontal
224                 } else {
225                     Resize::Vertical
226                 }
227             },
228             specified::Resize::None => Resize::None,
229             specified::Resize::Both => Resize::Both,
230             specified::Resize::Horizontal => Resize::Horizontal,
231             specified::Resize::Vertical => Resize::Vertical,
232         }
233     }
234 
235     #[inline]
from_computed_value(computed: &Resize) -> specified::Resize236     fn from_computed_value(computed: &Resize) -> specified::Resize {
237         match computed {
238             Resize::None => specified::Resize::None,
239             Resize::Both => specified::Resize::Both,
240             Resize::Horizontal => specified::Resize::Horizontal,
241             Resize::Vertical => specified::Resize::Vertical,
242         }
243     }
244 }
245