Skip to main content

style/values/generics/
box.rs

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//! Generic types for box properties.
6
7use crate::derives::*;
8use crate::values::animated::ToAnimatedZero;
9use crate::Zero;
10use std::fmt::{self, Write};
11use style_traits::{CssWriter, ToCss};
12
13#[derive(
14    Animate,
15    Clone,
16    ComputeSquaredDistance,
17    Copy,
18    Debug,
19    FromPrimitive,
20    MallocSizeOf,
21    Parse,
22    PartialEq,
23    SpecifiedValueInfo,
24    ToAnimatedValue,
25    ToComputedValue,
26    ToCss,
27    ToResolvedValue,
28    ToShmem,
29    ToTyped,
30)]
31#[repr(u8)]
32#[allow(missing_docs)]
33pub enum BaselineShiftKeyword {
34    /// Lower by the offset appropriate for subscripts of the parent’s box. The UA may use the
35    /// parent’s font metrics to find this offset; otherwise it defaults to dropping by one
36    /// fifth of the parent’s used font-size.
37    Sub,
38    /// Raise by the offset appropriate for superscripts of the parent’s box. The UA may use the
39    /// parent’s font metrics to find this offset; otherwise it defaults to raising by one third
40    /// of the parent’s used font-size.
41    Super,
42    /// Align the line-over edge of the aligned subtree with the line-over edge of the line box.
43    Top,
44    /// Align the center of the aligned subtree with the center of the line box.
45    Center,
46    /// Align the line-under edge of the aligned subtree with the line-under edge of the line box.
47    Bottom,
48}
49
50/// A generic value for the `baseline-shift` property.
51/// https://drafts.csswg.org/css-inline-3/#baseline-shift
52#[derive(
53    Animate,
54    Clone,
55    ComputeSquaredDistance,
56    Copy,
57    Debug,
58    MallocSizeOf,
59    PartialEq,
60    SpecifiedValueInfo,
61    ToAnimatedValue,
62    ToComputedValue,
63    ToCss,
64    ToResolvedValue,
65    ToShmem,
66    ToTyped,
67)]
68#[repr(C, u8)]
69pub enum GenericBaselineShift<LengthPercentage> {
70    /// One of the baseline-shift keywords
71    Keyword(BaselineShiftKeyword),
72    /// Raise (positive value) or lower (negative value) by the specified length or specified percentage of the line-height.
73    Length(LengthPercentage),
74}
75
76pub use self::GenericBaselineShift as BaselineShift;
77
78impl<L: Zero> BaselineShift<L> {
79    /// Returns the initial `0` value.
80    #[inline]
81    pub fn zero() -> Self {
82        BaselineShift::Length(Zero::zero())
83    }
84}
85
86impl<L> ToAnimatedZero for BaselineShift<L> {
87    fn to_animated_zero(&self) -> Result<Self, ()> {
88        Err(())
89    }
90}
91
92/// https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override
93#[derive(
94    Animate,
95    Clone,
96    ComputeSquaredDistance,
97    Debug,
98    MallocSizeOf,
99    PartialEq,
100    SpecifiedValueInfo,
101    ToComputedValue,
102    ToAnimatedValue,
103    ToAnimatedZero,
104    ToResolvedValue,
105    ToShmem,
106    ToTyped,
107)]
108#[value_info(other_values = "auto")]
109#[repr(C, u8)]
110pub enum GenericContainIntrinsicSize<L> {
111    /// The keyword `none`.
112    None,
113    /// The keywords 'auto none',
114    AutoNone,
115    /// A non-negative length.
116    Length(L),
117    /// "auto <Length>"
118    AutoLength(L),
119}
120
121pub use self::GenericContainIntrinsicSize as ContainIntrinsicSize;
122
123impl<L: ToCss> ToCss for ContainIntrinsicSize<L> {
124    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
125    where
126        W: Write,
127    {
128        match *self {
129            Self::None => dest.write_str("none"),
130            Self::AutoNone => dest.write_str("auto none"),
131            Self::Length(ref l) => l.to_css(dest),
132            Self::AutoLength(ref l) => {
133                dest.write_str("auto ")?;
134                l.to_css(dest)
135            },
136        }
137    }
138}
139
140/// Note that we only implement -webkit-line-clamp as a single, longhand
141/// property for now, but the spec defines line-clamp as a shorthand for
142/// separate max-lines, block-ellipsis, and continue properties.
143///
144/// https://drafts.csswg.org/css-overflow-3/#line-clamp
145#[derive(
146    Clone,
147    ComputeSquaredDistance,
148    Copy,
149    Debug,
150    MallocSizeOf,
151    PartialEq,
152    SpecifiedValueInfo,
153    ToComputedValue,
154    ToAnimatedValue,
155    ToAnimatedZero,
156    ToResolvedValue,
157    ToShmem,
158    ToTyped,
159)]
160#[repr(transparent)]
161#[value_info(other_values = "none")]
162pub struct GenericLineClamp<I>(pub I);
163
164pub use self::GenericLineClamp as LineClamp;
165
166impl<I: Zero> LineClamp<I> {
167    /// Returns the `none` value.
168    pub fn none() -> Self {
169        Self(crate::Zero::zero())
170    }
171
172    /// Returns whether we're the `none` value.
173    pub fn is_none(&self) -> bool {
174        self.0.is_zero()
175    }
176}
177
178impl<I: Zero + ToCss> ToCss for LineClamp<I> {
179    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
180    where
181        W: Write,
182    {
183        if self.is_none() {
184            return dest.write_str("none");
185        }
186        self.0.to_css(dest)
187    }
188}
189
190/// A generic value for the `perspective` property.
191#[derive(
192    Animate,
193    Clone,
194    ComputeSquaredDistance,
195    Copy,
196    Debug,
197    MallocSizeOf,
198    Parse,
199    PartialEq,
200    SpecifiedValueInfo,
201    ToAnimatedValue,
202    ToAnimatedZero,
203    ToComputedValue,
204    ToCss,
205    ToResolvedValue,
206    ToShmem,
207    ToTyped,
208)]
209#[repr(C, u8)]
210pub enum GenericPerspective<NonNegativeLength> {
211    /// A non-negative length.
212    Length(NonNegativeLength),
213    /// The keyword `none`.
214    None,
215}
216
217pub use self::GenericPerspective as Perspective;
218
219impl<L> Perspective<L> {
220    /// Returns `none`.
221    #[inline]
222    pub fn none() -> Self {
223        Perspective::None
224    }
225}
226
227#[derive(
228    Clone,
229    Copy,
230    Debug,
231    MallocSizeOf,
232    Parse,
233    PartialEq,
234    SpecifiedValueInfo,
235    ToComputedValue,
236    ToCss,
237    ToResolvedValue,
238    ToShmem,
239    ToTyped,
240)]
241#[repr(u8)]
242#[allow(missing_docs)]
243pub enum PositionProperty {
244    Static = 0,
245    Relative,
246    Absolute,
247    Fixed,
248    Sticky,
249}
250
251impl PositionProperty {
252    /// Is the box absolutely positioned?
253    pub fn is_absolutely_positioned(self) -> bool {
254        matches!(self, Self::Absolute | Self::Fixed)
255    }
256}
257
258/// https://drafts.csswg.org/css-overflow-4/#overflow-clip-margin's <visual-box>. Note that the
259/// spec has special behavior for the omitted keyword, but that's rather odd, see:
260/// https://github.com/w3c/csswg-drafts/issues/13185
261#[allow(missing_docs)]
262#[derive(
263    Clone,
264    ComputeSquaredDistance,
265    Copy,
266    Debug,
267    Eq,
268    MallocSizeOf,
269    PartialEq,
270    Parse,
271    SpecifiedValueInfo,
272    ToAnimatedValue,
273    ToComputedValue,
274    ToCss,
275    ToResolvedValue,
276    ToShmem,
277    ToTyped,
278)]
279#[repr(u8)]
280pub enum OverflowClipMarginBox {
281    ContentBox,
282    PaddingBox,
283    BorderBox,
284}
285
286/// https://drafts.csswg.org/css-overflow-4/#overflow-clip-margin
287#[derive(
288    Animate,
289    Clone,
290    ComputeSquaredDistance,
291    Copy,
292    Debug,
293    Eq,
294    MallocSizeOf,
295    PartialEq,
296    SpecifiedValueInfo,
297    ToAnimatedValue,
298    ToComputedValue,
299    ToAnimatedZero,
300    ToResolvedValue,
301    ToShmem,
302    ToTyped,
303)]
304#[repr(C)]
305pub struct GenericOverflowClipMargin<L> {
306    /// The offset of the clip.
307    pub offset: L,
308    /// The box that we're clipping to.
309    #[animation(constant)]
310    pub visual_box: OverflowClipMarginBox,
311}
312
313pub use self::GenericOverflowClipMargin as OverflowClipMargin;
314
315impl<L: Zero> GenericOverflowClipMargin<L> {
316    /// Returns the `none` value.
317    pub fn zero() -> Self {
318        Self {
319            offset: Zero::zero(),
320            visual_box: OverflowClipMarginBox::PaddingBox,
321        }
322    }
323}
324
325impl<L: Zero + ToCss> ToCss for OverflowClipMargin<L> {
326    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
327    where
328        W: Write,
329    {
330        if self.visual_box == OverflowClipMarginBox::PaddingBox {
331            return self.offset.to_css(dest);
332        }
333        self.visual_box.to_css(dest)?;
334        if !self.offset.is_zero() {
335            dest.write_char(' ')?;
336            self.offset.to_css(dest)?;
337        }
338        Ok(())
339    }
340}