style/values/resolved/
mod.rs1use app_units::Au;
9#[cfg(feature = "gecko")]
10use crate::media_queries::Device;
11use crate::properties::ComputedValues;
12use crate::ArcSlice;
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}
41
42pub trait ToResolvedValue {
50 type ResolvedValue;
52
53 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue;
55
56 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self;
58}
59
60macro_rules! trivial_to_resolved_value {
61 ($ty:ty) => {
62 impl $crate::values::resolved::ToResolvedValue for $ty {
63 type ResolvedValue = Self;
64
65 #[inline]
66 fn to_resolved_value(self, _: &Context) -> Self {
67 self
68 }
69
70 #[inline]
71 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
72 resolved
73 }
74 }
75 };
76}
77
78trivial_to_resolved_value!(());
79trivial_to_resolved_value!(bool);
80trivial_to_resolved_value!(f32);
81trivial_to_resolved_value!(u8);
82trivial_to_resolved_value!(i8);
83trivial_to_resolved_value!(u16);
84trivial_to_resolved_value!(i16);
85trivial_to_resolved_value!(u32);
86trivial_to_resolved_value!(i32);
87trivial_to_resolved_value!(usize);
88trivial_to_resolved_value!(String);
89trivial_to_resolved_value!(Box<str>);
90trivial_to_resolved_value!(crate::OwnedStr);
91trivial_to_resolved_value!(crate::color::AbsoluteColor);
92trivial_to_resolved_value!(crate::values::generics::color::ColorMixFlags);
93trivial_to_resolved_value!(crate::Atom);
94trivial_to_resolved_value!(crate::values::AtomIdent);
95trivial_to_resolved_value!(crate::custom_properties::VariableValue);
96trivial_to_resolved_value!(crate::stylesheets::UrlExtraData);
97trivial_to_resolved_value!(computed::url::ComputedUrl);
98#[cfg(feature = "servo")]
99trivial_to_resolved_value!(crate::Namespace);
100#[cfg(feature = "servo")]
101trivial_to_resolved_value!(crate::Prefix);
102trivial_to_resolved_value!(style_traits::values::specified::AllowedNumericType);
103trivial_to_resolved_value!(computed::TimingFunction);
104
105impl ToResolvedValue for Au {
106 type ResolvedValue = Length;
107
108 #[inline]
109 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
110 Length::new(self.to_f32_px()).to_resolved_value(context)
111 }
112
113 #[inline]
114 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
115 Au::from_f32_px(Length::from_resolved_value(resolved).px())
116 }
117}
118
119impl<A, B> ToResolvedValue for (A, B)
120where
121 A: ToResolvedValue,
122 B: ToResolvedValue,
123{
124 type ResolvedValue = (
125 <A as ToResolvedValue>::ResolvedValue,
126 <B as ToResolvedValue>::ResolvedValue,
127 );
128
129 #[inline]
130 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
131 (
132 self.0.to_resolved_value(context),
133 self.1.to_resolved_value(context),
134 )
135 }
136
137 #[inline]
138 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
139 (
140 A::from_resolved_value(resolved.0),
141 B::from_resolved_value(resolved.1),
142 )
143 }
144}
145
146impl<T> ToResolvedValue for Option<T>
147where
148 T: ToResolvedValue,
149{
150 type ResolvedValue = Option<<T as ToResolvedValue>::ResolvedValue>;
151
152 #[inline]
153 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
154 self.map(|item| item.to_resolved_value(context))
155 }
156
157 #[inline]
158 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
159 resolved.map(T::from_resolved_value)
160 }
161}
162
163impl<T> ToResolvedValue for SmallVec<[T; 1]>
164where
165 T: ToResolvedValue,
166{
167 type ResolvedValue = SmallVec<[<T as ToResolvedValue>::ResolvedValue; 1]>;
168
169 #[inline]
170 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
171 self.into_iter()
172 .map(|item| item.to_resolved_value(context))
173 .collect()
174 }
175
176 #[inline]
177 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
178 resolved.into_iter().map(T::from_resolved_value).collect()
179 }
180}
181
182impl<T> ToResolvedValue for Vec<T>
183where
184 T: ToResolvedValue,
185{
186 type ResolvedValue = Vec<<T as ToResolvedValue>::ResolvedValue>;
187
188 #[inline]
189 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
190 self.into_iter()
191 .map(|item| item.to_resolved_value(context))
192 .collect()
193 }
194
195 #[inline]
196 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
197 resolved.into_iter().map(T::from_resolved_value).collect()
198 }
199}
200
201impl<T> ToResolvedValue for thin_vec::ThinVec<T>
202where
203 T: ToResolvedValue,
204{
205 type ResolvedValue = thin_vec::ThinVec<<T as ToResolvedValue>::ResolvedValue>;
206
207 #[inline]
208 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
209 self.into_iter()
210 .map(|item| item.to_resolved_value(context))
211 .collect()
212 }
213
214 #[inline]
215 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
216 resolved.into_iter().map(T::from_resolved_value).collect()
217 }
218}
219
220impl<T> ToResolvedValue for Box<T>
221where
222 T: ToResolvedValue,
223{
224 type ResolvedValue = Box<<T as ToResolvedValue>::ResolvedValue>;
225
226 #[inline]
227 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
228 Box::new(T::to_resolved_value(*self, context))
229 }
230
231 #[inline]
232 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
233 Box::new(T::from_resolved_value(*resolved))
234 }
235}
236
237impl<T> ToResolvedValue for Box<[T]>
238where
239 T: ToResolvedValue,
240{
241 type ResolvedValue = Box<[<T as ToResolvedValue>::ResolvedValue]>;
242
243 #[inline]
244 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
245 Vec::from(self)
246 .to_resolved_value(context)
247 .into_boxed_slice()
248 }
249
250 #[inline]
251 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
252 Vec::from_resolved_value(Vec::from(resolved)).into_boxed_slice()
253 }
254}
255
256impl<T> ToResolvedValue for crate::OwnedSlice<T>
257where
258 T: ToResolvedValue,
259{
260 type ResolvedValue = crate::OwnedSlice<<T as ToResolvedValue>::ResolvedValue>;
261
262 #[inline]
263 fn to_resolved_value(self, context: &Context) -> Self::ResolvedValue {
264 self.into_box().to_resolved_value(context).into()
265 }
266
267 #[inline]
268 fn from_resolved_value(resolved: Self::ResolvedValue) -> Self {
269 Self::from(Box::from_resolved_value(resolved.into_box()))
270 }
271}
272
273impl<T> ToResolvedValue for Arc<T>
279where
280 T: ToResolvedValue<ResolvedValue = T>,
281{
282 type ResolvedValue = Self;
283
284 #[inline]
285 fn to_resolved_value(self, _: &Context) -> Self {
286 self
287 }
288
289 #[inline]
290 fn from_resolved_value(resolved: Self) -> Self {
291 resolved
292 }
293}
294
295impl<T> ToResolvedValue for ArcSlice<T>
297where
298 T: ToResolvedValue<ResolvedValue = T>,
299{
300 type ResolvedValue = Self;
301
302 #[inline]
303 fn to_resolved_value(self, _: &Context) -> Self {
304 self
305 }
306
307 #[inline]
308 fn from_resolved_value(resolved: Self) -> Self {
309 resolved
310 }
311}