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