tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mod.rs (9347B)


      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 //! Resolved values. These are almost always computed values, but in some cases
      6 //! there are used values.
      7 
      8 #[cfg(feature = "gecko")]
      9 use crate::media_queries::Device;
     10 use crate::properties::{ComputedValues, LonghandId, NonCustomPropertyId};
     11 use crate::ArcSlice;
     12 use app_units::Au;
     13 use servo_arc::Arc;
     14 use smallvec::SmallVec;
     15 
     16 mod animation;
     17 mod color;
     18 mod counters;
     19 
     20 use crate::values::computed::{self, Length};
     21 
     22 /// Element-specific information needed to resolve property values.
     23 #[cfg(feature = "gecko")]
     24 pub struct ResolvedElementInfo<'a> {
     25    /// Element we're resolving line-height against.
     26    pub element: crate::gecko::wrapper::GeckoElement<'a>,
     27 }
     28 
     29 /// Information needed to resolve a given value.
     30 pub struct Context<'a> {
     31    /// The style we're resolving for. This is useful to resolve currentColor.
     32    pub style: &'a ComputedValues,
     33    /// The device / document we're resolving style for. Useful to do font metrics stuff needed for
     34    /// line-height.
     35    #[cfg(feature = "gecko")]
     36    pub device: &'a Device,
     37    /// The element-specific information to resolve the value.
     38    #[cfg(feature = "gecko")]
     39    pub element_info: ResolvedElementInfo<'a>,
     40    /// The property we're resolving the value for over-all (might be a shorthand).
     41    pub for_property: NonCustomPropertyId,
     42    /// The current (physical) longhand we're resolving the value for. Guaranteed to be `Some()`
     43    /// inside `ToResolvedValue` implementations.
     44    pub current_longhand: Option<LonghandId>,
     45 }
     46 
     47 /// A trait to represent the conversion between resolved and resolved values.
     48 ///
     49 /// This trait is derivable with `#[derive(ToResolvedValue)]`.
     50 ///
     51 /// The deriving code assumes that if the type isn't generic, then the trait can
     52 /// be implemented as simple move. This means that a manual implementation with
     53 /// `ResolvedValue = Self` is bogus if it returns anything else than a clone.
     54 pub trait ToResolvedValue {
     55    /// The resolved value type we're going to be converted to.
     56    type ResolvedValue;
     57 
     58    /// Convert a resolved value to a resolved value.
     59    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue;
     60 
     61    /// Convert a resolved value to resolved value form.
     62    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self;
     63 }
     64 
     65 macro_rules! trivial_to_resolved_value {
     66    ($ty:ty) => {
     67        impl $crate::values::resolved::ToResolvedValue for $ty {
     68            type ResolvedValue = Self;
     69 
     70            #[inline]
     71            fn to_resolved_value(self, _: &Context) -> Self {
     72                self
     73            }
     74 
     75            #[inline]
     76            fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
     77                resolved
     78            }
     79        }
     80    };
     81 }
     82 
     83 trivial_to_resolved_value!(());
     84 trivial_to_resolved_value!(bool);
     85 trivial_to_resolved_value!(f32);
     86 trivial_to_resolved_value!(u8);
     87 trivial_to_resolved_value!(i8);
     88 trivial_to_resolved_value!(u16);
     89 trivial_to_resolved_value!(i16);
     90 trivial_to_resolved_value!(u32);
     91 trivial_to_resolved_value!(i32);
     92 trivial_to_resolved_value!(usize);
     93 trivial_to_resolved_value!(String);
     94 trivial_to_resolved_value!(Box<str>);
     95 trivial_to_resolved_value!(crate::OwnedStr);
     96 trivial_to_resolved_value!(crate::color::AbsoluteColor);
     97 trivial_to_resolved_value!(crate::values::generics::color::ColorMixFlags);
     98 trivial_to_resolved_value!(crate::Atom);
     99 trivial_to_resolved_value!(crate::values::AtomIdent);
    100 trivial_to_resolved_value!(crate::custom_properties::VariableValue);
    101 trivial_to_resolved_value!(crate::stylesheets::UrlExtraData);
    102 trivial_to_resolved_value!(computed::url::ComputedUrl);
    103 #[cfg(feature = "servo")]
    104 trivial_to_resolved_value!(crate::Namespace);
    105 #[cfg(feature = "servo")]
    106 trivial_to_resolved_value!(crate::Prefix);
    107 trivial_to_resolved_value!(style_traits::values::specified::AllowedNumericType);
    108 trivial_to_resolved_value!(computed::TimingFunction);
    109 
    110 impl ToResolvedValue for Au {
    111    type ResolvedValue = Length;
    112 
    113    #[inline]
    114    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    115        Length::new(self.to_f32_px()).to_resolved_value(context)
    116    }
    117 
    118    #[inline]
    119    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    120        Au::from_f32_px(Length::from_resolved_value(resolved).px())
    121    }
    122 }
    123 
    124 impl<A, B> ToResolvedValue for (A, B)
    125 where
    126    A: ToResolvedValue,
    127    B: ToResolvedValue,
    128 {
    129    type ResolvedValue = (
    130        <A as ToResolvedValue>::ResolvedValue,
    131        <B as ToResolvedValue>::ResolvedValue,
    132    );
    133 
    134    #[inline]
    135    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    136        (
    137            self.0.to_resolved_value(context),
    138            self.1.to_resolved_value(context),
    139        )
    140    }
    141 
    142    #[inline]
    143    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    144        (
    145            A::from_resolved_value(resolved.0),
    146            B::from_resolved_value(resolved.1),
    147        )
    148    }
    149 }
    150 
    151 impl<T> ToResolvedValue for Option<T>
    152 where
    153    T: ToResolvedValue,
    154 {
    155    type ResolvedValue = Option<<T as ToResolvedValue>::ResolvedValue>;
    156 
    157    #[inline]
    158    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    159        self.map(|item| item.to_resolved_value(context))
    160    }
    161 
    162    #[inline]
    163    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    164        resolved.map(T::from_resolved_value)
    165    }
    166 }
    167 
    168 impl<T> ToResolvedValue for SmallVec<[T; 1]>
    169 where
    170    T: ToResolvedValue,
    171 {
    172    type ResolvedValue = SmallVec<[<T as ToResolvedValue>::ResolvedValue; 1]>;
    173 
    174    #[inline]
    175    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    176        self.into_iter()
    177            .map(|item| item.to_resolved_value(context))
    178            .collect()
    179    }
    180 
    181    #[inline]
    182    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    183        resolved.into_iter().map(T::from_resolved_value).collect()
    184    }
    185 }
    186 
    187 impl<T> ToResolvedValue for Vec<T>
    188 where
    189    T: ToResolvedValue,
    190 {
    191    type ResolvedValue = Vec<<T as ToResolvedValue>::ResolvedValue>;
    192 
    193    #[inline]
    194    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    195        self.into_iter()
    196            .map(|item| item.to_resolved_value(context))
    197            .collect()
    198    }
    199 
    200    #[inline]
    201    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    202        resolved.into_iter().map(T::from_resolved_value).collect()
    203    }
    204 }
    205 
    206 impl<T> ToResolvedValue for thin_vec::ThinVec<T>
    207 where
    208    T: ToResolvedValue,
    209 {
    210    type ResolvedValue = thin_vec::ThinVec<<T as ToResolvedValue>::ResolvedValue>;
    211 
    212    #[inline]
    213    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    214        self.into_iter()
    215            .map(|item| item.to_resolved_value(context))
    216            .collect()
    217    }
    218 
    219    #[inline]
    220    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    221        resolved.into_iter().map(T::from_resolved_value).collect()
    222    }
    223 }
    224 
    225 impl<T> ToResolvedValue for Box<T>
    226 where
    227    T: ToResolvedValue,
    228 {
    229    type ResolvedValue = Box<<T as ToResolvedValue>::ResolvedValue>;
    230 
    231    #[inline]
    232    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    233        Box::new(T::to_resolved_value(*self, context))
    234    }
    235 
    236    #[inline]
    237    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    238        Box::new(T::from_resolved_value(*resolved))
    239    }
    240 }
    241 
    242 impl<T> ToResolvedValue for Box<[T]>
    243 where
    244    T: ToResolvedValue,
    245 {
    246    type ResolvedValue = Box<[<T as ToResolvedValue>::ResolvedValue]>;
    247 
    248    #[inline]
    249    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    250        Vec::from(self)
    251            .to_resolved_value(context)
    252            .into_boxed_slice()
    253    }
    254 
    255    #[inline]
    256    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    257        Vec::from_resolved_value(Vec::from(resolved)).into_boxed_slice()
    258    }
    259 }
    260 
    261 impl<T> ToResolvedValue for crate::OwnedSlice<T>
    262 where
    263    T: ToResolvedValue,
    264 {
    265    type ResolvedValue = crate::OwnedSlice<<T as ToResolvedValue>::ResolvedValue>;
    266 
    267    #[inline]
    268    fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
    269        self.into_box().to_resolved_value(context).into()
    270    }
    271 
    272    #[inline]
    273    fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
    274        Self::from(Box::from_resolved_value(resolved.into_box()))
    275    }
    276 }
    277 
    278 // NOTE(emilio): This is implementable more generically, but it's unlikely what
    279 // you want there, as it forces you to have an extra allocation.
    280 //
    281 // We could do that if needed, ideally with specialization for the case where
    282 // ResolvedValue = T. But we don't need it for now.
    283 impl<T> ToResolvedValue for Arc<T>
    284 where
    285    T: ToResolvedValue<ResolvedValue = T>,
    286 {
    287    type ResolvedValue = Self;
    288 
    289    #[inline]
    290    fn to_resolved_value(self, _: &Context) -> Self {
    291        self
    292    }
    293 
    294    #[inline]
    295    fn from_resolved_value(resolved: Self) -> Self {
    296        resolved
    297    }
    298 }
    299 
    300 // Same caveat as above applies.
    301 impl<T> ToResolvedValue for ArcSlice<T>
    302 where
    303    T: ToResolvedValue<ResolvedValue = T>,
    304 {
    305    type ResolvedValue = Self;
    306 
    307    #[inline]
    308    fn to_resolved_value(self, _: &Context) -> Self {
    309        self
    310    }
    311 
    312    #[inline]
    313    fn from_resolved_value(resolved: Self) -> Self {
    314        resolved
    315    }
    316 }