box.rs (7134B)
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 //! Generic types for box properties. 6 7 use crate::derives::*; 8 use crate::values::animated::ToAnimatedZero; 9 use crate::Zero; 10 use std::fmt::{self, Write}; 11 use style_traits::{CssWriter, ToCss}; 12 13 #[derive( 14 Animate, 15 Clone, 16 ComputeSquaredDistance, 17 Copy, 18 Debug, 19 FromPrimitive, 20 MallocSizeOf, 21 Parse, 22 PartialEq, 23 SpecifiedValueInfo, 24 ToAnimatedValue, 25 ToComputedValue, 26 ToCss, 27 ToResolvedValue, 28 ToShmem, 29 )] 30 #[repr(u8)] 31 #[allow(missing_docs)] 32 pub enum VerticalAlignKeyword { 33 Baseline, 34 Sub, 35 Super, 36 Top, 37 TextTop, 38 Middle, 39 Bottom, 40 TextBottom, 41 #[cfg(feature = "gecko")] 42 MozMiddleWithBaseline, 43 } 44 45 /// A generic value for the `vertical-align` property. 46 #[derive( 47 Animate, 48 Clone, 49 ComputeSquaredDistance, 50 Copy, 51 Debug, 52 MallocSizeOf, 53 PartialEq, 54 SpecifiedValueInfo, 55 ToAnimatedValue, 56 ToComputedValue, 57 ToCss, 58 ToResolvedValue, 59 ToShmem, 60 ToTyped, 61 )] 62 #[repr(C, u8)] 63 pub enum GenericVerticalAlign<LengthPercentage> { 64 /// One of the vertical-align keywords. 65 Keyword(VerticalAlignKeyword), 66 /// `<length-percentage>` 67 Length(LengthPercentage), 68 } 69 70 pub use self::GenericVerticalAlign as VerticalAlign; 71 72 impl<L> VerticalAlign<L> { 73 /// Returns `baseline`. 74 #[inline] 75 pub fn baseline() -> Self { 76 VerticalAlign::Keyword(VerticalAlignKeyword::Baseline) 77 } 78 } 79 80 impl<L> ToAnimatedZero for VerticalAlign<L> { 81 fn to_animated_zero(&self) -> Result<Self, ()> { 82 Err(()) 83 } 84 } 85 86 /// https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override 87 #[derive( 88 Animate, 89 Clone, 90 ComputeSquaredDistance, 91 Debug, 92 MallocSizeOf, 93 PartialEq, 94 SpecifiedValueInfo, 95 ToComputedValue, 96 ToAnimatedValue, 97 ToAnimatedZero, 98 ToResolvedValue, 99 ToShmem, 100 ToTyped, 101 )] 102 #[value_info(other_values = "auto")] 103 #[repr(C, u8)] 104 pub enum GenericContainIntrinsicSize<L> { 105 /// The keyword `none`. 106 None, 107 /// The keywords 'auto none', 108 AutoNone, 109 /// A non-negative length. 110 Length(L), 111 /// "auto <Length>" 112 AutoLength(L), 113 } 114 115 pub use self::GenericContainIntrinsicSize as ContainIntrinsicSize; 116 117 impl<L: ToCss> ToCss for ContainIntrinsicSize<L> { 118 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result 119 where 120 W: Write, 121 { 122 match *self { 123 Self::None => dest.write_str("none"), 124 Self::AutoNone => dest.write_str("auto none"), 125 Self::Length(ref l) => l.to_css(dest), 126 Self::AutoLength(ref l) => { 127 dest.write_str("auto ")?; 128 l.to_css(dest) 129 }, 130 } 131 } 132 } 133 134 /// Note that we only implement -webkit-line-clamp as a single, longhand 135 /// property for now, but the spec defines line-clamp as a shorthand for 136 /// separate max-lines, block-ellipsis, and continue properties. 137 /// 138 /// https://drafts.csswg.org/css-overflow-3/#line-clamp 139 #[derive( 140 Clone, 141 ComputeSquaredDistance, 142 Copy, 143 Debug, 144 MallocSizeOf, 145 PartialEq, 146 SpecifiedValueInfo, 147 ToComputedValue, 148 ToAnimatedValue, 149 ToAnimatedZero, 150 ToResolvedValue, 151 ToShmem, 152 ToTyped, 153 )] 154 #[repr(transparent)] 155 #[value_info(other_values = "none")] 156 pub struct GenericLineClamp<I>(pub I); 157 158 pub use self::GenericLineClamp as LineClamp; 159 160 impl<I: Zero> LineClamp<I> { 161 /// Returns the `none` value. 162 pub fn none() -> Self { 163 Self(crate::Zero::zero()) 164 } 165 166 /// Returns whether we're the `none` value. 167 pub fn is_none(&self) -> bool { 168 self.0.is_zero() 169 } 170 } 171 172 impl<I: Zero + ToCss> ToCss for LineClamp<I> { 173 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result 174 where 175 W: Write, 176 { 177 if self.is_none() { 178 return dest.write_str("none"); 179 } 180 self.0.to_css(dest) 181 } 182 } 183 184 /// A generic value for the `perspective` property. 185 #[derive( 186 Animate, 187 Clone, 188 ComputeSquaredDistance, 189 Copy, 190 Debug, 191 MallocSizeOf, 192 Parse, 193 PartialEq, 194 SpecifiedValueInfo, 195 ToAnimatedValue, 196 ToAnimatedZero, 197 ToComputedValue, 198 ToCss, 199 ToResolvedValue, 200 ToShmem, 201 ToTyped, 202 )] 203 #[repr(C, u8)] 204 #[typed_value(derive_fields)] 205 pub enum GenericPerspective<NonNegativeLength> { 206 /// A non-negative length. 207 Length(NonNegativeLength), 208 /// The keyword `none`. 209 None, 210 } 211 212 pub use self::GenericPerspective as Perspective; 213 214 impl<L> Perspective<L> { 215 /// Returns `none`. 216 #[inline] 217 pub fn none() -> Self { 218 Perspective::None 219 } 220 } 221 222 #[derive( 223 Clone, 224 Copy, 225 Debug, 226 MallocSizeOf, 227 Parse, 228 PartialEq, 229 SpecifiedValueInfo, 230 ToComputedValue, 231 ToCss, 232 ToResolvedValue, 233 ToShmem, 234 ToTyped, 235 )] 236 #[repr(u8)] 237 #[allow(missing_docs)] 238 pub enum PositionProperty { 239 Static = 0, 240 Relative, 241 Absolute, 242 Fixed, 243 Sticky, 244 } 245 246 impl PositionProperty { 247 /// Is the box absolutely positioned? 248 pub fn is_absolutely_positioned(self) -> bool { 249 matches!(self, Self::Absolute | Self::Fixed) 250 } 251 } 252 253 /// https://drafts.csswg.org/css-overflow-4/#overflow-clip-margin's <visual-box>. Note that the 254 /// spec has special behavior for the omitted keyword, but that's rather odd, see: 255 /// https://github.com/w3c/csswg-drafts/issues/13185 256 #[allow(missing_docs)] 257 #[derive( 258 Clone, 259 ComputeSquaredDistance, 260 Copy, 261 Debug, 262 Eq, 263 MallocSizeOf, 264 PartialEq, 265 Parse, 266 SpecifiedValueInfo, 267 ToAnimatedValue, 268 ToComputedValue, 269 ToCss, 270 ToResolvedValue, 271 ToShmem, 272 ToTyped, 273 )] 274 #[repr(u8)] 275 pub enum OverflowClipMarginBox { 276 ContentBox, 277 PaddingBox, 278 BorderBox, 279 } 280 281 /// https://drafts.csswg.org/css-overflow-4/#overflow-clip-margin 282 #[derive( 283 Animate, 284 Clone, 285 ComputeSquaredDistance, 286 Copy, 287 Debug, 288 Eq, 289 MallocSizeOf, 290 PartialEq, 291 SpecifiedValueInfo, 292 ToAnimatedValue, 293 ToComputedValue, 294 ToAnimatedZero, 295 ToResolvedValue, 296 ToShmem, 297 ToTyped, 298 )] 299 #[repr(C)] 300 pub struct GenericOverflowClipMargin<L> { 301 /// The offset of the clip. 302 pub offset: L, 303 /// The box that we're clipping to. 304 #[animation(constant)] 305 pub visual_box: OverflowClipMarginBox, 306 } 307 308 pub use self::GenericOverflowClipMargin as OverflowClipMargin; 309 310 impl<L: Zero> GenericOverflowClipMargin<L> { 311 /// Returns the `none` value. 312 pub fn zero() -> Self { 313 Self { 314 offset: Zero::zero(), 315 visual_box: OverflowClipMarginBox::PaddingBox, 316 } 317 } 318 } 319 320 impl<L: Zero + ToCss> ToCss for OverflowClipMargin<L> { 321 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result 322 where 323 W: Write, 324 { 325 if self.visual_box == OverflowClipMarginBox::PaddingBox { 326 return self.offset.to_css(dest); 327 } 328 self.visual_box.to_css(dest)?; 329 if !self.offset.is_zero() { 330 dest.write_char(' ')?; 331 self.offset.to_css(dest)?; 332 } 333 Ok(()) 334 } 335 }