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 //! Computed types for box properties. 6 7 use crate::values::computed::length::{LengthPercentage, NonNegativeLength}; 8 use crate::values::computed::{Context, Number, ToComputedValue}; 9 use crate::values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; 10 use crate::values::generics::box_::Perspective as GenericPerspective; 11 use crate::values::generics::box_::VerticalAlign as GenericVerticalAlign; 12 use crate::values::specified::box_ as specified; 13 14 pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween, BreakWithin}; 15 pub use crate::values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat}; 16 pub use crate::values::specified::box_::{Contain, Display, Overflow}; 17 pub use crate::values::specified::box_::{OverflowAnchor, OverflowClipBox, OverscrollBehavior}; 18 pub use crate::values::specified::box_::{ 19 ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType, 20 }; 21 pub use crate::values::specified::box_::{TouchAction, TransitionProperty, WillChange}; 22 23 /// A computed value for the `vertical-align` property. 24 pub type VerticalAlign = GenericVerticalAlign<LengthPercentage>; 25 26 /// A computed value for the `animation-iteration-count` property. 27 pub type AnimationIterationCount = GenericAnimationIterationCount<Number>; 28 29 impl AnimationIterationCount { 30 /// Returns the value `1.0`. 31 #[inline] one() -> Self32 pub fn one() -> Self { 33 GenericAnimationIterationCount::Number(1.0) 34 } 35 } 36 37 /// A computed value for the `perspective` property. 38 pub type Perspective = GenericPerspective<NonNegativeLength>; 39 40 #[allow(missing_docs)] 41 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] 42 #[derive( 43 Clone, 44 Copy, 45 Debug, 46 Eq, 47 FromPrimitive, 48 Hash, 49 MallocSizeOf, 50 Parse, 51 PartialEq, 52 SpecifiedValueInfo, 53 ToCss, 54 ToResolvedValue, 55 )] 56 #[repr(u8)] 57 /// A computed value for the `float` property. 58 pub enum Float { 59 Left, 60 Right, 61 None, 62 } 63 64 impl Float { 65 /// Returns true if `self` is not `None`. is_floating(self) -> bool66 pub fn is_floating(self) -> bool { 67 self != Self::None 68 } 69 } 70 71 impl ToComputedValue for SpecifiedFloat { 72 type ComputedValue = Float; 73 74 #[inline] to_computed_value(&self, context: &Context) -> Self::ComputedValue75 fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { 76 let ltr = context.style().writing_mode.is_bidi_ltr(); 77 // https://drafts.csswg.org/css-logical-props/#float-clear 78 match *self { 79 SpecifiedFloat::InlineStart => { 80 context 81 .rule_cache_conditions 82 .borrow_mut() 83 .set_writing_mode_dependency(context.builder.writing_mode); 84 if ltr { 85 Float::Left 86 } else { 87 Float::Right 88 } 89 }, 90 SpecifiedFloat::InlineEnd => { 91 context 92 .rule_cache_conditions 93 .borrow_mut() 94 .set_writing_mode_dependency(context.builder.writing_mode); 95 if ltr { 96 Float::Right 97 } else { 98 Float::Left 99 } 100 }, 101 SpecifiedFloat::Left => Float::Left, 102 SpecifiedFloat::Right => Float::Right, 103 SpecifiedFloat::None => Float::None, 104 } 105 } 106 107 #[inline] from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat108 fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat { 109 match *computed { 110 Float::Left => SpecifiedFloat::Left, 111 Float::Right => SpecifiedFloat::Right, 112 Float::None => SpecifiedFloat::None, 113 } 114 } 115 } 116 117 #[allow(missing_docs)] 118 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] 119 #[derive( 120 Clone, 121 Copy, 122 Debug, 123 Eq, 124 FromPrimitive, 125 Hash, 126 MallocSizeOf, 127 Parse, 128 PartialEq, 129 SpecifiedValueInfo, 130 ToCss, 131 ToResolvedValue, 132 )] 133 /// A computed value for the `clear` property. 134 pub enum Clear { 135 None, 136 Left, 137 Right, 138 Both, 139 } 140 141 impl ToComputedValue for SpecifiedClear { 142 type ComputedValue = Clear; 143 144 #[inline] to_computed_value(&self, context: &Context) -> Self::ComputedValue145 fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { 146 let ltr = context.style().writing_mode.is_bidi_ltr(); 147 // https://drafts.csswg.org/css-logical-props/#float-clear 148 match *self { 149 SpecifiedClear::InlineStart => { 150 context 151 .rule_cache_conditions 152 .borrow_mut() 153 .set_writing_mode_dependency(context.builder.writing_mode); 154 if ltr { 155 Clear::Left 156 } else { 157 Clear::Right 158 } 159 }, 160 SpecifiedClear::InlineEnd => { 161 context 162 .rule_cache_conditions 163 .borrow_mut() 164 .set_writing_mode_dependency(context.builder.writing_mode); 165 if ltr { 166 Clear::Right 167 } else { 168 Clear::Left 169 } 170 }, 171 SpecifiedClear::None => Clear::None, 172 SpecifiedClear::Left => Clear::Left, 173 SpecifiedClear::Right => Clear::Right, 174 SpecifiedClear::Both => Clear::Both, 175 } 176 } 177 178 #[inline] from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear179 fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear { 180 match *computed { 181 Clear::None => SpecifiedClear::None, 182 Clear::Left => SpecifiedClear::Left, 183 Clear::Right => SpecifiedClear::Right, 184 Clear::Both => SpecifiedClear::Both, 185 } 186 } 187 } 188 189 /// A computed value for the `resize` property. 190 #[allow(missing_docs)] 191 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] 192 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue)] 193 #[repr(u8)] 194 pub enum Resize { 195 None, 196 Both, 197 Horizontal, 198 Vertical, 199 } 200 201 impl ToComputedValue for specified::Resize { 202 type ComputedValue = Resize; 203 204 #[inline] to_computed_value(&self, context: &Context) -> Resize205 fn to_computed_value(&self, context: &Context) -> Resize { 206 let is_vertical = context.style().writing_mode.is_vertical(); 207 match self { 208 specified::Resize::Inline => { 209 context 210 .rule_cache_conditions 211 .borrow_mut() 212 .set_writing_mode_dependency(context.builder.writing_mode); 213 if is_vertical { 214 Resize::Vertical 215 } else { 216 Resize::Horizontal 217 } 218 }, 219 specified::Resize::Block => { 220 context 221 .rule_cache_conditions 222 .borrow_mut() 223 .set_writing_mode_dependency(context.builder.writing_mode); 224 if is_vertical { 225 Resize::Horizontal 226 } else { 227 Resize::Vertical 228 } 229 }, 230 specified::Resize::None => Resize::None, 231 specified::Resize::Both => Resize::Both, 232 specified::Resize::Horizontal => Resize::Horizontal, 233 specified::Resize::Vertical => Resize::Vertical, 234 } 235 } 236 237 #[inline] from_computed_value(computed: &Resize) -> specified::Resize238 fn from_computed_value(computed: &Resize) -> specified::Resize { 239 match computed { 240 Resize::None => specified::Resize::None, 241 Resize::Both => specified::Resize::Both, 242 Resize::Horizontal => specified::Resize::Horizontal, 243 Resize::Vertical => specified::Resize::Vertical, 244 } 245 } 246 } 247