inherited_text.mako.rs (9481B)
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:shorthand 8 name="text-emphasis" 9 engines="gecko" 10 sub_properties="text-emphasis-style text-emphasis-color" 11 derive_serialize="True" 12 spec="https://drafts.csswg.org/css-text-decor-3/#text-emphasis-property" 13 > 14 use crate::properties::longhands::{text_emphasis_color, text_emphasis_style}; 15 16 pub fn parse_value<'i, 't>( 17 context: &ParserContext, 18 input: &mut Parser<'i, 't>, 19 ) -> Result<Longhands, ParseError<'i>> { 20 let mut color = None; 21 let mut style = None; 22 23 loop { 24 if color.is_none() { 25 if let Ok(value) = input.try_parse(|input| text_emphasis_color::parse(context, input)) { 26 color = Some(value); 27 continue 28 } 29 } 30 if style.is_none() { 31 if let Ok(value) = input.try_parse(|input| text_emphasis_style::parse(context, input)) { 32 style = Some(value); 33 continue 34 } 35 } 36 break 37 } 38 if color.is_some() || style.is_some() { 39 Ok(expanded! { 40 text_emphasis_color: unwrap_or_initial!(text_emphasis_color, color), 41 text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style), 42 }) 43 } else { 44 Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) 45 } 46 } 47 </%helpers:shorthand> 48 49 <%helpers:shorthand 50 name="text-wrap" 51 engines="gecko" 52 sub_properties="text-wrap-mode text-wrap-style" 53 spec="https://www.w3.org/TR/css-text-4/#text-wrap" 54 > 55 use crate::properties::longhands::{text_wrap_mode, text_wrap_style}; 56 57 pub fn parse_value<'i, 't>( 58 context: &ParserContext, 59 input: &mut Parser<'i, 't>, 60 ) -> Result<Longhands, ParseError<'i>> { 61 let mut mode = None; 62 let mut style = None; 63 64 loop { 65 if mode.is_none() { 66 if let Ok(value) = input.try_parse(|input| text_wrap_mode::parse(context, input)) { 67 mode = Some(value); 68 continue 69 } 70 } 71 if style.is_none() { 72 if let Ok(value) = input.try_parse(|input| text_wrap_style::parse(context, input)) { 73 style = Some(value); 74 continue 75 } 76 } 77 break 78 } 79 if mode.is_some() || style.is_some() { 80 Ok(expanded! { 81 text_wrap_mode: unwrap_or_initial!(text_wrap_mode, mode), 82 text_wrap_style: unwrap_or_initial!(text_wrap_style, style), 83 }) 84 } else { 85 Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) 86 } 87 } 88 89 impl<'a> ToCss for LonghandsToSerialize<'a> { 90 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 91 use text_wrap_mode::computed_value::T as Mode; 92 use text_wrap_style::computed_value::T as Style; 93 94 if matches!(self.text_wrap_style, &Style::Auto) { 95 return self.text_wrap_mode.to_css(dest); 96 } 97 98 if *self.text_wrap_mode != Mode::Wrap { 99 self.text_wrap_mode.to_css(dest)?; 100 dest.write_char(' ')?; 101 } 102 103 self.text_wrap_style.to_css(dest) 104 } 105 } 106 </%helpers:shorthand> 107 108 <%helpers:shorthand 109 name="white-space" 110 engines="gecko servo" 111 sub_properties="text-wrap-mode white-space-collapse" 112 derive_value_info="False" 113 spec="https://www.w3.org/TR/css-text-4/#white-space-property" 114 > 115 use crate::properties::longhands::{text_wrap_mode, white_space_collapse}; 116 117 pub fn parse_value<'i, 't>( 118 context: &ParserContext, 119 input: &mut Parser<'i, 't>, 120 ) -> Result<Longhands, ParseError<'i>> { 121 use white_space_collapse::computed_value::T as Collapse; 122 use text_wrap_mode::computed_value::T as Wrap; 123 124 fn parse_special_shorthands<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Longhands, ParseError<'i>> { 125 let (mode, collapse) = try_match_ident_ignore_ascii_case! { input, 126 "normal" => (Wrap::Wrap, Collapse::Collapse), 127 "pre" => (Wrap::Nowrap, Collapse::Preserve), 128 "pre-wrap" => (Wrap::Wrap, Collapse::Preserve), 129 "pre-line" => (Wrap::Wrap, Collapse::PreserveBreaks), 130 }; 131 Ok(expanded! { 132 text_wrap_mode: mode, 133 white_space_collapse: collapse, 134 }) 135 } 136 137 if let Ok(result) = input.try_parse(parse_special_shorthands) { 138 return Ok(result); 139 } 140 141 let mut wrap = None; 142 let mut collapse = None; 143 144 loop { 145 if wrap.is_none() { 146 if let Ok(value) = input.try_parse(|input| text_wrap_mode::parse(context, input)) { 147 wrap = Some(value); 148 continue 149 } 150 } 151 if collapse.is_none() { 152 if let Ok(value) = input.try_parse(|input| white_space_collapse::parse(context, input)) { 153 collapse = Some(value); 154 continue 155 } 156 } 157 break 158 } 159 160 if wrap.is_some() || collapse.is_some() { 161 Ok(expanded! { 162 text_wrap_mode: unwrap_or_initial!(text_wrap_mode, wrap), 163 white_space_collapse: unwrap_or_initial!(white_space_collapse, collapse), 164 }) 165 } else { 166 Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) 167 } 168 } 169 170 impl<'a> ToCss for LonghandsToSerialize<'a> { 171 fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { 172 use white_space_collapse::computed_value::T as Collapse; 173 use text_wrap_mode::computed_value::T as Wrap; 174 175 match *self.text_wrap_mode { 176 Wrap::Wrap => { 177 match *self.white_space_collapse { 178 Collapse::Collapse => return dest.write_str("normal"), 179 Collapse::Preserve => return dest.write_str("pre-wrap"), 180 Collapse::PreserveBreaks => return dest.write_str("pre-line"), 181 _ => (), 182 } 183 }, 184 Wrap::Nowrap => { 185 if let Collapse::Preserve = *self.white_space_collapse { 186 return dest.write_str("pre"); 187 } 188 }, 189 } 190 191 let mut has_value = false; 192 if *self.white_space_collapse != Collapse::Collapse { 193 self.white_space_collapse.to_css(dest)?; 194 has_value = true; 195 } 196 197 if *self.text_wrap_mode != Wrap::Wrap { 198 if has_value { 199 dest.write_char(' ')?; 200 } 201 self.text_wrap_mode.to_css(dest)?; 202 } 203 204 Ok(()) 205 } 206 } 207 208 impl SpecifiedValueInfo for Longhands { 209 fn collect_completion_keywords(f: KeywordsCollectFn) { 210 // Collect keywords from our longhands. 211 text_wrap_mode::SpecifiedValue::collect_completion_keywords(f); 212 white_space_collapse::SpecifiedValue::collect_completion_keywords(f); 213 214 // Add the special values supported only by the shorthand 215 // (see parse_special_shorthands() above). 216 f(&["normal", "pre", "pre-wrap", "pre-line"]) 217 } 218 } 219 </%helpers:shorthand> 220 221 // CSS Compatibility 222 // https://compat.spec.whatwg.org/ 223 <%helpers:shorthand name="-webkit-text-stroke" 224 engines="gecko" 225 sub_properties="-webkit-text-stroke-width 226 -webkit-text-stroke-color" 227 derive_serialize="True" 228 spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke"> 229 use crate::properties::longhands::{_webkit_text_stroke_color, _webkit_text_stroke_width}; 230 231 pub fn parse_value<'i, 't>( 232 context: &ParserContext, 233 input: &mut Parser<'i, 't>, 234 ) -> Result<Longhands, ParseError<'i>> { 235 let mut color = None; 236 let mut width = None; 237 loop { 238 if color.is_none() { 239 if let Ok(value) = input.try_parse(|input| _webkit_text_stroke_color::parse(context, input)) { 240 color = Some(value); 241 continue 242 } 243 } 244 245 if width.is_none() { 246 if let Ok(value) = input.try_parse(|input| _webkit_text_stroke_width::parse(context, input)) { 247 width = Some(value); 248 continue 249 } 250 } 251 break 252 } 253 254 if color.is_some() || width.is_some() { 255 Ok(expanded! { 256 _webkit_text_stroke_color: unwrap_or_initial!(_webkit_text_stroke_color, color), 257 _webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width), 258 }) 259 } else { 260 Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) 261 } 262 } 263 </%helpers:shorthand>