style/values/resolved/
mod.rs1#[cfg(feature = "gecko")]
9use crate::media_queries::Device;
10use crate::properties::{ComputedValues, LonghandId, NonCustomPropertyId};
11use crate::ArcSlice;
12use app_units::Au;
13use servo_arc::Arc;
14use smallvec::SmallVec;
15
16mod animation;
17mod color;
18mod counters;
19
20use crate::values::computed::{self, Length};
21
22#[cfg(feature = "gecko")]
24pub struct ResolvedElementInfo<'a> {
25 pub element: crate::gecko::wrapper::GeckoElement<'a>,
27}
28
29pub struct Context<'a> {
31 pub style: &'a ComputedValues,
33 #[cfg(feature = "gecko")]
36 pub device: &'a Device,
37 #[cfg(feature = "gecko")]
39 pub element_info: ResolvedElementInfo<'a>,
40 pub for_property: NonCustomPropertyId,
42 pub current_longhand: Option<LonghandId>,
45}
46
47pub trait ToResolvedValue {
55 type ResolvedValue;
57
58 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue;
60
61 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self;
63}
64
65macro_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
83trivial_to_resolved_value!(());
84trivial_to_resolved_value!(bool);
85trivial_to_resolved_value!(f32);
86trivial_to_resolved_value!(u8);
87trivial_to_resolved_value!(i8);
88trivial_to_resolved_value!(u16);
89trivial_to_resolved_value!(i16);
90trivial_to_resolved_value!(u32);
91trivial_to_resolved_value!(i32);
92trivial_to_resolved_value!(usize);
93trivial_to_resolved_value!(String);
94trivial_to_resolved_value!(Box<str>);
95trivial_to_resolved_value!(crate::OwnedStr);
96trivial_to_resolved_value!(crate::color::AbsoluteColor);
97trivial_to_resolved_value!(crate::values::generics::color::ColorMixFlags);
98trivial_to_resolved_value!(crate::Atom);
99trivial_to_resolved_value!(crate::values::AtomIdent);
100trivial_to_resolved_value!(crate::custom_properties::VariableValue);
101trivial_to_resolved_value!(crate::stylesheets::UrlExtraData);
102trivial_to_resolved_value!(computed::url::ComputedUrl);
103#[cfg(feature = "servo")]
104trivial_to_resolved_value!(crate::Namespace);
105#[cfg(feature = "servo")]
106trivial_to_resolved_value!(crate::Prefix);
107trivial_to_resolved_value!(style_traits::values::specified::AllowedNumericType);
108trivial_to_resolved_value!(computed::TimingFunction);
109
110impl 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
124impl<A, B> ToResolvedValue for (A, B)
125where
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
151impl<T> ToResolvedValue for Option<T>
152where
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
168impl<T> ToResolvedValue for SmallVec<[T; 1]>
169where
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
187impl<T> ToResolvedValue for Vec<T>
188where
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
206impl<T> ToResolvedValue for thin_vec::ThinVec<T>
207where
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
225impl<T> ToResolvedValue for Box<T>
226where
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
242impl<T> ToResolvedValue for Box<[T]>
243where
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
261impl<T> ToResolvedValue for crate::OwnedSlice<T>
262where
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
278impl<T> ToResolvedValue for Arc<T>
284where
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
300impl<T> ToResolvedValue for ArcSlice<T>
302where
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}