From 2b83d844da5c07bc5068309bc5dcacbfc96c50d0 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 27 Jan 2017 17:54:15 +0100 Subject: [PATCH] Use the Parse trait for `@font-face` parsing. --- components/style/font_face.rs | 63 +++++++------ .../style/properties/longhand/font.mako.rs | 94 ++++++++++--------- .../style/properties/shorthand/font.mako.rs | 4 +- 3 files changed, 88 insertions(+), 73 deletions(-) diff --git a/components/style/font_face.rs b/components/style/font_face.rs index a25c1948bd3..0386ec16abf 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -11,7 +11,6 @@ use computed_values::font_family::FontFamily; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use parser::{ParserContext, log_css_error, Parse}; -use properties::longhands::font_family::parse_one_family; use std::fmt; use std::iter; use style_traits::ToCss; @@ -181,40 +180,44 @@ impl<'a, 'b> DeclarationParser for FontFaceRuleParser<'a, 'b> { fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> { match_ignore_ascii_case! { name, - "font-family" => { - self.rule.family = parse_one_family(input)?; - }, - "src" => { - self.rule.sources = input.parse_comma_separated(|input| { - parse_one_src(self.context, input) - })?; - }, + "font-family" => self.rule.family = Parse::parse(self.context, input)?, + "src" => self.rule.sources = Parse::parse(self.context, input)?, _ => return Err(()) } Ok(()) } } -fn parse_one_src(context: &ParserContext, input: &mut Parser) -> Result { - if input.try(|input| input.expect_function_matching("local")).is_ok() { - return Ok(Source::Local(try!(input.parse_nested_block(parse_one_family)))) +impl Parse for Vec { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.parse_comma_separated(|input| Source::parse(context, input)) + } +} + +impl Parse for Source { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if input.try(|input| input.expect_function_matching("local")).is_ok() { + return input.parse_nested_block(|input| { + FontFamily::parse(context, input) + }).map(Source::Local) + } + + let url = SpecifiedUrl::parse(context, input)?; + + // Parsing optional format() + let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() { + input.parse_nested_block(|input| { + input.parse_comma_separated(|input| { + Ok(input.expect_string()?.into_owned()) + }) + })? + } else { + vec![] + }; + + Ok(Source::Url(UrlSource { + url: url, + format_hints: format_hints, + })) } - - let url = try!(SpecifiedUrl::parse(context, input)); - - // Parsing optional format() - let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() { - try!(input.parse_nested_block(|input| { - input.parse_comma_separated(|input| { - Ok((try!(input.expect_string())).into_owned()) - }) - })) - } else { - vec![] - }; - - Ok(Source::Url(UrlSource { - url: url, - format_hints: format_hints, - })) } diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index b25d40fefea..a110f389bbc 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -107,56 +107,66 @@ pub fn get_initial_value() -> computed_value::T { computed_value::T(vec![FontFamily::Generic(atom!("serif"))]) } + /// # /// = | [ + ] /// TODO: - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - input.parse_comma_separated(parse_one_family).map(SpecifiedValue) + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { + Vec::::parse(context, input).map(SpecifiedValue) } - pub fn parse_one_family(input: &mut Parser) -> Result { - if let Ok(value) = input.try(|input| input.expect_string()) { - return Ok(FontFamily::FamilyName(Atom::from(&*value))) - } - let first_ident = try!(input.expect_ident()); - // FIXME(bholley): The fast thing to do here would be to look up the - // string (as lowercase) in the static atoms table. We don't have an - // API to do that yet though, so we do the simple thing for now. - let mut css_wide_keyword = false; - match_ignore_ascii_case! { first_ident, - "serif" => return Ok(FontFamily::Generic(atom!("serif"))), - "sans-serif" => return Ok(FontFamily::Generic(atom!("sans-serif"))), - "cursive" => return Ok(FontFamily::Generic(atom!("cursive"))), - "fantasy" => return Ok(FontFamily::Generic(atom!("fantasy"))), - "monospace" => return Ok(FontFamily::Generic(atom!("monospace"))), + impl Parse for Vec { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + input.parse_comma_separated(|input| FontFamily::parse(context, input)) + } + } - // https://drafts.csswg.org/css-fonts/#propdef-font-family - // "Font family names that happen to be the same as a keyword value - // (‘inherit’, ‘serif’, ‘sans-serif’, ‘monospace’, ‘fantasy’, and ‘cursive’) - // must be quoted to prevent confusion with the keywords with the same names. - // The keywords ‘initial’ and ‘default’ are reserved for future use - // and must also be quoted when used as font names. - // UAs must not consider these keywords as matching the type." - "inherit" => css_wide_keyword = true, - "initial" => css_wide_keyword = true, - "unset" => css_wide_keyword = true, - "default" => css_wide_keyword = true, - _ => {} - } + impl Parse for FontFamily { + fn parse(_context: &ParserContext, input: &mut Parser) -> Result { + if let Ok(value) = input.try(|input| input.expect_string()) { + return Ok(FontFamily::FamilyName(Atom::from(&*value))) + } + let first_ident = try!(input.expect_ident()); - let mut value = first_ident.into_owned(); - // These keywords are not allowed by themselves. - // The only way this value can be valid with with another keyword. - if css_wide_keyword { - let ident = input.expect_ident()?; - value.push_str(" "); - value.push_str(&ident); + // FIXME(bholley): The fast thing to do here would be to look up the + // string (as lowercase) in the static atoms table. We don't have an + // API to do that yet though, so we do the simple thing for now. + let mut css_wide_keyword = false; + match_ignore_ascii_case! { first_ident, + "serif" => return Ok(FontFamily::Generic(atom!("serif"))), + "sans-serif" => return Ok(FontFamily::Generic(atom!("sans-serif"))), + "cursive" => return Ok(FontFamily::Generic(atom!("cursive"))), + "fantasy" => return Ok(FontFamily::Generic(atom!("fantasy"))), + "monospace" => return Ok(FontFamily::Generic(atom!("monospace"))), + + // https://drafts.csswg.org/css-fonts/#propdef-font-family + // "Font family names that happen to be the same as a keyword value + // (‘inherit’, ‘serif’, ‘sans-serif’, ‘monospace’, ‘fantasy’, and ‘cursive’) + // must be quoted to prevent confusion with the keywords with the same names. + // The keywords ‘initial’ and ‘default’ are reserved for future use + // and must also be quoted when used as font names. + // UAs must not consider these keywords as matching the type." + "inherit" => css_wide_keyword = true, + "initial" => css_wide_keyword = true, + "unset" => css_wide_keyword = true, + "default" => css_wide_keyword = true, + _ => {} + } + + let mut value = first_ident.into_owned(); + // These keywords are not allowed by themselves. + // The only way this value can be valid with with another keyword. + if css_wide_keyword { + let ident = input.expect_ident()?; + value.push_str(" "); + value.push_str(&ident); + } + while let Ok(ident) = input.try(|input| input.expect_ident()) { + value.push_str(" "); + value.push_str(&ident); + } + Ok(FontFamily::FamilyName(Atom::from(value))) } - while let Ok(ident) = input.try(|input| input.expect_ident()) { - value.push_str(" "); - value.push_str(&ident); - } - Ok(FontFamily::FamilyName(Atom::from(value))) } diff --git a/components/style/properties/shorthand/font.mako.rs b/components/style/properties/shorthand/font.mako.rs index f058c56a777..7d151e84956 100644 --- a/components/style/properties/shorthand/font.mako.rs +++ b/components/style/properties/shorthand/font.mako.rs @@ -7,8 +7,10 @@ <%helpers:shorthand name="font" sub_properties="font-style font-variant font-weight font-stretch font-size line-height font-family" spec="https://drafts.csswg.org/css-fonts-3/#propdef-font"> + use parser::Parse; use properties::longhands::{font_style, font_variant, font_weight, font_stretch}; use properties::longhands::{font_size, line_height, font_family}; + use properties::longhands::font_family::computed_value::FontFamily; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { let mut nb_normals = 0; @@ -64,7 +66,7 @@ } else { None }; - let family = try!(input.parse_comma_separated(font_family::parse_one_family)); + let family = Vec::::parse(context, input)?; Ok(Longhands { font_style: style, font_variant: variant,