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 //! Values for CSS Box Alignment properties
6 //!
7 //! https://drafts.csswg.org/css-align/
8 
9 use crate::values::computed::{Context, ToComputedValue};
10 use crate::values::specified;
11 
12 pub use super::specified::{
13     AlignContent, AlignItems, AlignTracks, ContentDistribution, JustifyContent, JustifyTracks,
14     SelfAlignment,
15 };
16 pub use super::specified::{AlignSelf, JustifySelf};
17 
18 /// The computed value for the `justify-items` property.
19 ///
20 /// Need to carry around both the specified and computed value to handle the
21 /// special legacy keyword without destroying style sharing.
22 ///
23 /// In particular, `justify-items` is a reset property, so we ought to be able
24 /// to share its computed representation across elements as long as they match
25 /// the same rules. Except that it's not true if the specified value for
26 /// `justify-items` is `legacy` and the computed value of the parent has the
27 /// `legacy` modifier.
28 ///
29 /// So instead of computing `legacy` "normally" looking at get_parent_position(),
30 /// marking it as uncacheable, we carry the specified value around and handle
31 /// the special case in `StyleAdjuster` instead, only when the result of the
32 /// computation would vary.
33 ///
34 /// Note that we also need to special-case this property in matching.rs, in
35 /// order to properly handle changes to the legacy keyword... This all kinda
36 /// sucks :(.
37 ///
38 /// See the discussion in https://bugzil.la/1384542.
39 #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
40 #[repr(C)]
41 pub struct ComputedJustifyItems {
42     /// The specified value for the property. Can contain the bare `legacy`
43     /// keyword.
44     #[css(skip)]
45     pub specified: specified::JustifyItems,
46     /// The computed value for the property. Cannot contain the bare `legacy`
47     /// keyword, but note that it could contain it in combination with other
48     /// keywords like `left`, `right` or `center`.
49     pub computed: specified::JustifyItems,
50 }
51 
52 pub use self::ComputedJustifyItems as JustifyItems;
53 
54 impl JustifyItems {
55     /// Returns the `legacy` value.
legacy() -> Self56     pub fn legacy() -> Self {
57         Self {
58             specified: specified::JustifyItems::legacy(),
59             computed: specified::JustifyItems::normal(),
60         }
61     }
62 }
63 
64 impl ToComputedValue for specified::JustifyItems {
65     type ComputedValue = JustifyItems;
66 
67     /// <https://drafts.csswg.org/css-align/#valdef-justify-items-legacy>
to_computed_value(&self, _context: &Context) -> JustifyItems68     fn to_computed_value(&self, _context: &Context) -> JustifyItems {
69         use crate::values::specified::align;
70         let specified = *self;
71         let computed = if self.0 != align::AlignFlags::LEGACY {
72             *self
73         } else {
74             // If the inherited value of `justify-items` includes the
75             // `legacy` keyword, `legacy` computes to the inherited value, but
76             // we assume it computes to `normal`, and handle that special-case
77             // in StyleAdjuster.
78             Self::normal()
79         };
80 
81         JustifyItems {
82             specified,
83             computed,
84         }
85     }
86 
87     #[inline]
from_computed_value(computed: &JustifyItems) -> Self88     fn from_computed_value(computed: &JustifyItems) -> Self {
89         computed.specified
90     }
91 }
92