box.mako.rs (9924B)
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 <%namespace name="helpers" file="/helpers.mako.rs" /> 6 7 ${helpers.two_properties_shorthand( 8 "overflow", 9 "overflow-x", 10 "overflow-y", 11 engines="gecko servo", 12 spec="https://drafts.csswg.org/css-overflow/#propdef-overflow", 13 )} 14 15 ${helpers.two_properties_shorthand( 16 "overscroll-behavior", 17 "overscroll-behavior-x", 18 "overscroll-behavior-y", 19 engines="gecko", 20 spec="https://wicg.github.io/overscroll-behavior/#overscroll-behavior-properties", 21 )} 22 23 <%helpers:shorthand 24 engines="gecko" 25 name="container" 26 sub_properties="container-name container-type" 27 spec="https://drafts.csswg.org/css-contain-3/#container-shorthand" 28 > 29 use crate::values::specified::box_::{ContainerName, ContainerType}; 30 pub fn parse_value<'i>( 31 context: &ParserContext, 32 input: &mut Parser<'i, '_>, 33 ) -> Result<Longhands, ParseError<'i>> { 34 use crate::parser::Parse; 35 // See https://github.com/w3c/csswg-drafts/issues/7180 for why we don't 36 // match the spec. 37 let container_name = ContainerName::parse(context, input)?; 38 let container_type = if input.try_parse(|input| input.expect_delim('/')).is_ok() { 39 ContainerType::parse(context, input)? 40 } else { 41 ContainerType::NORMAL 42 }; 43 Ok(expanded! { 44 container_name: container_name, 45 container_type: container_type, 46 }) 47 } 48 49 impl<'a> ToCss for LonghandsToSerialize<'a> { 50 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 51 self.container_name.to_css(dest)?; 52 if !self.container_type.is_normal() { 53 dest.write_str(" / ")?; 54 self.container_type.to_css(dest)?; 55 } 56 Ok(()) 57 } 58 } 59 </%helpers:shorthand> 60 61 <%helpers:shorthand 62 engines="gecko" 63 name="page-break-before" 64 flags="IS_LEGACY_SHORTHAND" 65 sub_properties="break-before" 66 spec="https://drafts.csswg.org/css-break-3/#page-break-properties" 67 > 68 pub fn parse_value<'i>( 69 context: &ParserContext, 70 input: &mut Parser<'i, '_>, 71 ) -> Result<Longhands, ParseError<'i>> { 72 use crate::values::specified::box_::BreakBetween; 73 Ok(expanded! { 74 break_before: BreakBetween::parse_legacy(context, input)?, 75 }) 76 } 77 78 impl<'a> ToCss for LonghandsToSerialize<'a> { 79 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 80 self.break_before.to_css_legacy(dest) 81 } 82 } 83 </%helpers:shorthand> 84 85 <%helpers:shorthand 86 engines="gecko" 87 name="page-break-after" 88 flags="IS_LEGACY_SHORTHAND" 89 sub_properties="break-after" 90 spec="https://drafts.csswg.org/css-break-3/#page-break-properties" 91 > 92 pub fn parse_value<'i>( 93 context: &ParserContext, 94 input: &mut Parser<'i, '_>, 95 ) -> Result<Longhands, ParseError<'i>> { 96 use crate::values::specified::box_::BreakBetween; 97 Ok(expanded! { 98 break_after: BreakBetween::parse_legacy(context, input)?, 99 }) 100 } 101 102 impl<'a> ToCss for LonghandsToSerialize<'a> { 103 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 104 self.break_after.to_css_legacy(dest) 105 } 106 } 107 </%helpers:shorthand> 108 109 <%helpers:shorthand 110 engines="gecko" 111 name="page-break-inside" 112 flags="IS_LEGACY_SHORTHAND" 113 sub_properties="break-inside" 114 spec="https://drafts.csswg.org/css-break-3/#page-break-properties" 115 > 116 pub fn parse_value<'i>( 117 context: &ParserContext, 118 input: &mut Parser<'i, '_>, 119 ) -> Result<Longhands, ParseError<'i>> { 120 use crate::values::specified::box_::BreakWithin; 121 Ok(expanded! { 122 break_inside: BreakWithin::parse_legacy(context, input)?, 123 }) 124 } 125 126 impl<'a> ToCss for LonghandsToSerialize<'a> { 127 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 128 self.break_inside.to_css_legacy(dest) 129 } 130 } 131 </%helpers:shorthand> 132 133 <%helpers:shorthand name="offset" 134 engines="gecko" 135 sub_properties="offset-path offset-distance offset-rotate offset-anchor 136 offset-position" 137 spec="https://drafts.fxtf.org/motion-1/#offset-shorthand"> 138 use crate::parser::Parse; 139 use crate::values::specified::motion::{OffsetPath, OffsetPosition, OffsetRotate}; 140 use crate::values::specified::{LengthPercentage, PositionOrAuto}; 141 use crate::Zero; 142 143 pub fn parse_value<'i, 't>( 144 context: &ParserContext, 145 input: &mut Parser<'i, 't>, 146 ) -> Result<Longhands, ParseError<'i>> { 147 let offset_position = input.try_parse(|i| OffsetPosition::parse(context, i)).ok(); 148 let offset_path = input.try_parse(|i| OffsetPath::parse(context, i)).ok(); 149 150 // Must have one of [offset-position, offset-path]. 151 // FIXME: The syntax is out-of-date after the update of the spec. 152 // https://github.com/w3c/fxtf-drafts/issues/515 153 if offset_position.is_none() && offset_path.is_none() { 154 return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); 155 } 156 157 let mut offset_distance = None; 158 let mut offset_rotate = None; 159 // offset-distance and offset-rotate are grouped with offset-path. 160 if offset_path.is_some() { 161 loop { 162 if offset_distance.is_none() { 163 if let Ok(value) = input.try_parse(|i| LengthPercentage::parse(context, i)) { 164 offset_distance = Some(value); 165 } 166 } 167 168 if offset_rotate.is_none() { 169 if let Ok(value) = input.try_parse(|i| OffsetRotate::parse(context, i)) { 170 offset_rotate = Some(value); 171 continue; 172 } 173 } 174 break; 175 } 176 } 177 178 let offset_anchor = input.try_parse(|i| { 179 i.expect_delim('/')?; 180 PositionOrAuto::parse(context, i) 181 }).ok(); 182 183 Ok(expanded! { 184 offset_position: offset_position.unwrap_or(OffsetPosition::normal()), 185 offset_path: offset_path.unwrap_or(OffsetPath::none()), 186 offset_distance: offset_distance.unwrap_or(LengthPercentage::zero()), 187 offset_rotate: offset_rotate.unwrap_or(OffsetRotate::auto()), 188 offset_anchor: offset_anchor.unwrap_or(PositionOrAuto::auto()), 189 }) 190 } 191 192 impl<'a> ToCss for LonghandsToSerialize<'a> { 193 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 194 // The basic concept is: we must serialize offset-position or offset-path group. 195 // offset-path group means "offset-path offset-distance offset-rotate". 196 let must_serialize_path = *self.offset_path != OffsetPath::None 197 || (!self.offset_distance.is_zero() || !self.offset_rotate.is_auto()); 198 let position_is_default = matches!(self.offset_position, OffsetPosition::Normal); 199 if !position_is_default || !must_serialize_path { 200 self.offset_position.to_css(dest)?; 201 } 202 203 if must_serialize_path { 204 if !position_is_default { 205 dest.write_char(' ')?; 206 } 207 self.offset_path.to_css(dest)?; 208 } 209 210 if !self.offset_distance.is_zero() { 211 dest.write_char(' ')?; 212 self.offset_distance.to_css(dest)?; 213 } 214 215 if !self.offset_rotate.is_auto() { 216 dest.write_char(' ')?; 217 self.offset_rotate.to_css(dest)?; 218 } 219 220 if *self.offset_anchor != PositionOrAuto::auto() { 221 dest.write_str(" / ")?; 222 self.offset_anchor.to_css(dest)?; 223 } 224 Ok(()) 225 } 226 } 227 </%helpers:shorthand> 228 229 <%helpers:shorthand name="-webkit-perspective" 230 engines="gecko servo" 231 sub_properties="perspective" 232 derive_serialize="True" 233 flags="IS_LEGACY_SHORTHAND" 234 spec="https://github.com/whatwg/compat/issues/100"> 235 pub fn parse_value<'i, 't>( 236 context: &ParserContext, 237 input: &mut Parser<'i, 't>, 238 ) -> Result<Longhands, ParseError<'i>> { 239 use crate::values::specified::Length; 240 use crate::values::generics::NonNegative; 241 use crate::values::specified::AllowQuirks; 242 use crate::values::specified::Perspective; 243 use crate::properties::longhands::perspective; 244 245 if let Ok(l) = input.try_parse(|input| Length::parse_non_negative_quirky(context, input, AllowQuirks::Always)) { 246 Ok(expanded! { 247 perspective: Perspective::Length(NonNegative(l)), 248 }) 249 } else { 250 Ok(expanded! { 251 perspective: perspective::parse(context, input)? 252 }) 253 } 254 } 255 </%helpers:shorthand> 256 257 <%helpers:shorthand name="-webkit-transform" 258 engines="gecko servo" 259 sub_properties="transform" 260 derive_serialize="True" 261 flags="IS_LEGACY_SHORTHAND" 262 spec="https://github.com/whatwg/compat/issues/100"> 263 pub fn parse_value<'i, 't>( 264 context: &ParserContext, 265 input: &mut Parser<'i, 't>, 266 ) -> Result<Longhands, ParseError<'i>> { 267 use crate::values::specified::Transform; 268 Ok(expanded! { 269 transform: Transform::parse_legacy(context, input)?, 270 }) 271 } 272 </%helpers:shorthand>