1use std::fmt::Write;
9
10use style_traits::CssWriter;
11use style_traits::SpecifiedValueInfo;
12use style_traits::ToCss;
13
14use crate::logical_geometry::PhysicalSide;
15use crate::values::animated::ToAnimatedZero;
16use crate::values::generics::box_::PositionProperty;
17use crate::values::generics::length::GenericAnchorSizeFunction;
18use crate::values::generics::ratio::Ratio;
19use crate::values::generics::Optional;
20use crate::values::DashedIdent;
21
22#[derive(
24 Animate,
25 Clone,
26 ComputeSquaredDistance,
27 Copy,
28 Debug,
29 Deserialize,
30 MallocSizeOf,
31 PartialEq,
32 Serialize,
33 SpecifiedValueInfo,
34 ToAnimatedValue,
35 ToAnimatedZero,
36 ToComputedValue,
37 ToResolvedValue,
38 ToShmem,
39)]
40#[repr(C)]
41pub struct GenericPosition<H, V> {
42 pub horizontal: H,
44 pub vertical: V,
46}
47
48impl<H, V> PositionComponent for Position<H, V>
49where
50 H: PositionComponent,
51 V: PositionComponent,
52{
53 #[inline]
54 fn is_center(&self) -> bool {
55 self.horizontal.is_center() && self.vertical.is_center()
56 }
57}
58
59pub use self::GenericPosition as Position;
60
61impl<H, V> Position<H, V> {
62 pub fn new(horizontal: H, vertical: V) -> Self {
64 Self {
65 horizontal,
66 vertical,
67 }
68 }
69}
70
71pub trait PositionComponent {
73 fn is_center(&self) -> bool;
76}
77
78#[derive(
82 Animate,
83 Clone,
84 ComputeSquaredDistance,
85 Copy,
86 Debug,
87 Deserialize,
88 MallocSizeOf,
89 Parse,
90 PartialEq,
91 Serialize,
92 SpecifiedValueInfo,
93 ToAnimatedZero,
94 ToAnimatedValue,
95 ToComputedValue,
96 ToCss,
97 ToResolvedValue,
98 ToShmem,
99)]
100#[repr(C, u8)]
101pub enum GenericPositionOrAuto<Pos> {
102 Position(Pos),
104 Auto,
106}
107
108pub use self::GenericPositionOrAuto as PositionOrAuto;
109
110impl<Pos> PositionOrAuto<Pos> {
111 #[inline]
113 pub fn auto() -> Self {
114 PositionOrAuto::Auto
115 }
116
117 #[inline]
119 pub fn is_auto(&self) -> bool {
120 matches!(self, PositionOrAuto::Auto)
121 }
122}
123
124#[derive(
126 Animate,
127 Clone,
128 ComputeSquaredDistance,
129 Copy,
130 Debug,
131 MallocSizeOf,
132 PartialEq,
133 Parse,
134 SpecifiedValueInfo,
135 ToAnimatedValue,
136 ToAnimatedZero,
137 ToComputedValue,
138 ToCss,
139 ToResolvedValue,
140 ToShmem,
141)]
142#[repr(C, u8)]
143pub enum GenericZIndex<I> {
144 Integer(I),
146 Auto,
148}
149
150pub use self::GenericZIndex as ZIndex;
151
152impl<Integer> ZIndex<Integer> {
153 #[inline]
155 pub fn auto() -> Self {
156 ZIndex::Auto
157 }
158
159 #[inline]
161 pub fn is_auto(self) -> bool {
162 matches!(self, ZIndex::Auto)
163 }
164
165 #[inline]
167 pub fn integer_or(self, auto: Integer) -> Integer {
168 match self {
169 ZIndex::Integer(n) => n,
170 ZIndex::Auto => auto,
171 }
172 }
173}
174
175#[derive(
177 Animate,
178 Clone,
179 ComputeSquaredDistance,
180 Copy,
181 Debug,
182 MallocSizeOf,
183 PartialEq,
184 SpecifiedValueInfo,
185 ToAnimatedValue,
186 ToComputedValue,
187 ToCss,
188 ToResolvedValue,
189 ToShmem,
190)]
191#[repr(C, u8)]
192pub enum PreferredRatio<N> {
193 #[css(skip)]
195 None,
196 Ratio(
198 #[animation(field_bound)]
199 #[css(field_bound)]
200 #[distance(field_bound)]
201 Ratio<N>,
202 ),
203}
204
205#[derive(
207 Animate,
208 Clone,
209 ComputeSquaredDistance,
210 Copy,
211 Debug,
212 MallocSizeOf,
213 PartialEq,
214 SpecifiedValueInfo,
215 ToAnimatedValue,
216 ToComputedValue,
217 ToCss,
218 ToResolvedValue,
219 ToShmem,
220)]
221#[repr(C)]
222pub struct GenericAspectRatio<N> {
223 #[animation(constant)]
225 #[css(represents_keyword)]
226 pub auto: bool,
227 #[animation(field_bound)]
229 #[css(field_bound)]
230 #[distance(field_bound)]
231 pub ratio: PreferredRatio<N>,
232}
233
234pub use self::GenericAspectRatio as AspectRatio;
235
236impl<N> AspectRatio<N> {
237 #[inline]
239 pub fn auto() -> Self {
240 AspectRatio {
241 auto: true,
242 ratio: PreferredRatio::None,
243 }
244 }
245}
246
247impl<N> ToAnimatedZero for AspectRatio<N> {
248 #[inline]
249 fn to_animated_zero(&self) -> Result<Self, ()> {
250 Err(())
251 }
252}
253
254#[derive(
263 Animate,
264 Clone,
265 ComputeSquaredDistance,
266 Debug,
267 MallocSizeOf,
268 PartialEq,
269 ToCss,
270 ToShmem,
271 ToAnimatedValue,
272 ToAnimatedZero,
273 ToComputedValue,
274 ToResolvedValue,
275)]
276#[repr(C)]
277pub enum GenericInset<P, LP> {
278 LengthPercentage(LP),
280 Auto,
282 AnchorFunction(Box<GenericAnchorFunction<P, Self>>),
286 AnchorSizeFunction(Box<GenericAnchorSizeFunction<Self>>),
290 AnchorContainingCalcFunction(LP),
293}
294
295impl<P, LP> SpecifiedValueInfo for GenericInset<P, LP>
296where
297 LP: SpecifiedValueInfo,
298{
299 fn collect_completion_keywords(f: style_traits::KeywordsCollectFn) {
300 LP::collect_completion_keywords(f);
301 f(&["auto"]);
302 if static_prefs::pref!("layout.css.anchor-positioning.enabled") {
303 f(&["anchor", "anchor-size"]);
304 }
305 }
306}
307
308impl<P, LP> GenericInset<P, LP> {
309 #[inline]
311 pub fn auto() -> Self {
312 Self::Auto
313 }
314
315 #[inline]
317 #[cfg(feature = "servo")]
318 pub fn is_auto(&self) -> bool {
319 matches!(self, Self::Auto)
320 }
321}
322
323pub use self::GenericInset as Inset;
324
325#[derive(
330 Animate,
331 Clone,
332 ComputeSquaredDistance,
333 Debug,
334 MallocSizeOf,
335 PartialEq,
336 SpecifiedValueInfo,
337 ToShmem,
338 ToAnimatedValue,
339 ToAnimatedZero,
340 ToComputedValue,
341 ToResolvedValue,
342 Serialize,
343 Deserialize,
344)]
345#[repr(C)]
346pub struct GenericAnchorFunction<Percentage, Fallback> {
347 #[animation(constant)]
350 pub target_element: DashedIdent,
351 pub side: GenericAnchorSide<Percentage>,
354 pub fallback: Optional<Fallback>,
356}
357
358impl<Percentage, Fallback> ToCss for GenericAnchorFunction<Percentage, Fallback>
359where
360 Percentage: ToCss,
361 Fallback: ToCss,
362{
363 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> std::fmt::Result
364 where
365 W: Write,
366 {
367 dest.write_str("anchor(")?;
368 if !self.target_element.is_empty() {
369 self.target_element.to_css(dest)?;
370 dest.write_str(" ")?;
371 }
372 self.side.to_css(dest)?;
373 if let Some(f) = self.fallback.as_ref() {
374 dest.write_str(", ")?;
376 f.to_css(dest)?;
377 }
378 dest.write_str(")")
379 }
380}
381
382impl<Percentage, Fallback> GenericAnchorFunction<Percentage, Fallback> {
383 pub fn valid_for(&self, side: PhysicalSide, position_property: PositionProperty) -> bool {
385 position_property.is_absolutely_positioned() && self.side.valid_for(side)
386 }
387}
388
389#[derive(
391 Animate,
392 Clone,
393 ComputeSquaredDistance,
394 Copy,
395 Debug,
396 MallocSizeOf,
397 PartialEq,
398 SpecifiedValueInfo,
399 ToCss,
400 ToShmem,
401 Parse,
402 ToAnimatedValue,
403 ToAnimatedZero,
404 ToComputedValue,
405 ToResolvedValue,
406 Serialize,
407 Deserialize,
408)]
409#[repr(u8)]
410pub enum AnchorSideKeyword {
411 Inside,
413 Outside,
415 Top,
417 Left,
419 Right,
421 Bottom,
423 Start,
427 End,
429 SelfStart,
431 SelfEnd,
433 Center,
435}
436
437impl AnchorSideKeyword {
438 fn valid_for(&self, side: PhysicalSide) -> bool {
439 match self {
440 Self::Left | Self::Right => matches!(side, PhysicalSide::Left | PhysicalSide::Right),
441 Self::Top | Self::Bottom => matches!(side, PhysicalSide::Top | PhysicalSide::Bottom),
442 Self::Inside
443 | Self::Outside
444 | Self::Start
445 | Self::End
446 | Self::SelfStart
447 | Self::SelfEnd
448 | Self::Center => true,
449 }
450 }
451}
452
453#[derive(
455 Animate,
456 Clone,
457 ComputeSquaredDistance,
458 Copy,
459 Debug,
460 MallocSizeOf,
461 PartialEq,
462 Parse,
463 SpecifiedValueInfo,
464 ToCss,
465 ToShmem,
466 ToAnimatedValue,
467 ToAnimatedZero,
468 ToComputedValue,
469 ToResolvedValue,
470 Serialize,
471 Deserialize,
472)]
473#[repr(C)]
474pub enum GenericAnchorSide<P> {
475 Keyword(AnchorSideKeyword),
477 Percentage(P),
479}
480
481impl<P> GenericAnchorSide<P> {
482 pub fn valid_for(&self, side: PhysicalSide) -> bool {
484 match self {
485 Self::Keyword(k) => k.valid_for(side),
486 Self::Percentage(_) => true,
487 }
488 }
489}