diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 3d10db6c7da..980d3de11ff 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -1197,7 +1197,7 @@ pub fn append_declaration_value<'a, 'b: 'a>( AppendableValue::Css(css) => dest.write_str(css), AppendableValue::Declaration(decl) => decl.to_css(dest), AppendableValue::DeclarationsForShorthand(shorthand, decls) => { - shorthand.longhands_to_css(decls, &mut CssWriter::new(dest)) + shorthand.longhands_to_css(decls, dest) }, } } diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index ecd714cebfc..e46024feba1 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -845,10 +845,7 @@ impl<'a> LonghandsToSerialize<'a> { /// Tries to get a serializable set of longhands given a set of /// property declarations. - pub fn from_iter(iter: I) -> Result - where - I: Iterator, - { + pub fn from_iter(iter: impl Iterator) -> Result { // Define all of the expected variables that correspond to the shorthand % for sub_property in shorthand.sub_properties: let mut ${sub_property.ident} = @@ -856,8 +853,8 @@ % endfor // Attempt to assign the incoming declarations to the expected variables - for longhand in iter { - match *longhand { + for declaration in iter { + match *declaration { % for sub_property in shorthand.sub_properties: PropertyDeclaration::${sub_property.camel_case}(ref value) => { ${sub_property.ident} = Some(value) @@ -918,6 +915,14 @@ }) } + /// Try to serialize a given shorthand to a string. + pub fn to_css(declarations: &[&PropertyDeclaration], dest: &mut crate::str::CssStringWriter) -> fmt::Result { + match LonghandsToSerialize::from_iter(declarations.iter().cloned()) { + Ok(longhands) => longhands.to_css(&mut CssWriter::new(dest)), + Err(_) => Ok(()) + } + } + ${caller.body()} } % endif diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 474b3339170..7b69f23db9e 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1471,34 +1471,31 @@ impl ShorthandId { /// /// Returns an error if writing to the stream fails, or if the declarations /// do not map to a shorthand. - pub fn longhands_to_css( + pub fn longhands_to_css( &self, declarations: &[&PropertyDeclaration], - dest: &mut CssWriter, - ) -> fmt::Result - where - W: Write, - { - // TODO(emilio): Save codesize here by using a lookup table on - // ShorthandId instead. - let declarations = declarations.iter().cloned(); - match *self { - ShorthandId::All => { - // No need to try to serialize the declarations as the 'all' - // shorthand, since it only accepts CSS-wide keywords (and - // variable references), which will be handled in - // get_shorthand_appendable_value. - Ok(()) - } - % for property in data.shorthands_except_all(): - ShorthandId::${property.camel_case} => { - match shorthands::${property.ident}::LonghandsToSerialize::from_iter(declarations) { - Ok(longhands) => longhands.to_css(dest), - Err(_) => Ok(()) - } - }, - % endfor + dest: &mut CssStringWriter, + ) -> fmt::Result { + type LonghandsToCssFn = for<'a, 'b> fn(&'a [&'b PropertyDeclaration], &mut CssStringWriter) -> fmt::Result; + fn all_to_css(_: &[&PropertyDeclaration], _: &mut CssStringWriter) -> fmt::Result { + // No need to try to serialize the declarations as the 'all' + // shorthand, since it only accepts CSS-wide keywords (and variable + // references), which will be handled in + // get_shorthand_appendable_value. + Ok(()) } + + static LONGHANDS_TO_CSS: [LonghandsToCssFn; ${len(data.shorthands)}] = [ + % for shorthand in data.shorthands: + % if shorthand.ident == "all": + all_to_css, + % else: + shorthands::${shorthand.ident}::to_css, + % endif + % endfor + ]; + + LONGHANDS_TO_CSS[*self as usize](declarations, dest) } /// Finds and returns an appendable value for the given declarations. @@ -1591,23 +1588,20 @@ impl ShorthandId { input: &mut Parser<'i, 't>, ) -> Result<(), ParseError<'i>>; - fn unreachable<'i, 't>( + fn parse_all<'i, 't>( _: &mut SourcePropertyDeclaration, _: &ParserContext, - _: &mut Parser<'i, 't> + input: &mut Parser<'i, 't> ) -> Result<(), ParseError<'i>> { - unreachable!() + // 'all' accepts no value other than CSS-wide keywords + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } - // 'all' accepts no value other than CSS-wide keywords - if *self == ShorthandId::All { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } static PARSE_INTO: [ParseIntoFn; ${len(data.shorthands)}] = [ % for shorthand in data.shorthands: % if shorthand.ident == "all": - unreachable, + parse_all, % else: shorthands::${shorthand.ident}::parse_into, % endif