From c03f5f19ab3dd6cb5dd6b18887ea4a970a859035 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 27 Jun 2017 11:06:24 +0200 Subject: [PATCH] Introduce CommaWithSpace This allows us to support stroke-dasharray the same way as comma-separated values. --- components/style/parser.rs | 16 ---------- components/style/properties/helpers.mako.rs | 9 +++--- components/style_traits/lib.rs | 2 +- components/style_traits/values.rs | 35 ++++++++++++++++++++- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/components/style/parser.rs b/components/style/parser.rs index d1121533170..5df3fb25ec6 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -172,22 +172,6 @@ where } } -/// Parse a non-empty space-separated or comma-separated list of objects parsed by parse_one -pub fn parse_space_or_comma_separated<'i, 't, F, T>(input: &mut Parser<'i, 't>, mut parse_one: F) - -> Result, ParseError<'i>> - where F: for<'ii, 'tt> FnMut(&mut Parser<'ii, 'tt>) -> Result> { - let first = parse_one(input)?; - let mut vec = vec![first]; - loop { - let _ = input.try(|i| i.expect_comma()); - if let Ok(val) = input.try(|i| parse_one(i)) { - vec.push(val) - } else { - break - } - } - Ok(vec) -} impl Parse for UnicodeRange { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 8c6701497e4..6ec124c4b1e 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -217,13 +217,12 @@ pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + use style_traits::Separator; #[allow(unused_imports)] - use parser::parse_space_or_comma_separated; + use style_traits::{Comma, CommaWithSpace}; <% - parse_func = "Parser::parse_comma_separated" - if space_separated_allowed: - parse_func = "parse_space_or_comma_separated" + separator = "CommaWithSpace" if space_separated_allowed else "Comma" %> % if allow_empty: @@ -232,7 +231,7 @@ } % endif - ${parse_func}(input, |parser| { + ${separator}::parse(input, |parser| { single_value::parse(context, parser) }).map(SpecifiedValue) } diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index feebf80bfdc..7cb28e7f7c7 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -71,7 +71,7 @@ pub mod values; #[macro_use] pub mod viewport; -pub use values::{Comma, OneOrMoreSeparated, Separator, Space, ToCss}; +pub use values::{Comma, CommaWithSpace, OneOrMoreSeparated, Separator, Space, ToCss}; pub use viewport::HasViewportPercentage; /// The error type for all CSS parsing routines. diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index 5ae48def781..6024eae4054 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -5,7 +5,7 @@ //! Helper types and traits for the handling of CSS values. use app_units::Au; -use cssparser::{ParseError, Parser, UnicodeRange, serialize_string}; +use cssparser::{BasicParseError, ParseError, Parser, Token, UnicodeRange, serialize_string}; use std::fmt::{self, Write}; /// Serialises a value according to its CSS representation. @@ -191,6 +191,12 @@ pub struct Comma; /// separated by spaces. pub struct Space; +/// Type used as the associated type in the `OneOrMoreSeparated` trait on a +/// type to indicate that a serialized list of elements of this type is +/// separated by commas, but spaces without commas are also allowed when +/// parsing. +pub struct CommaWithSpace; + /// A trait satisfied by the types corresponding to separators. pub trait Separator { /// The separator string that the satisfying separator type corresponds to. @@ -248,6 +254,33 @@ impl Separator for Space { } } +impl Separator for CommaWithSpace { + fn separator() -> &'static str { + ", " + } + + fn parse<'i, 't, F, T, E>( + input: &mut Parser<'i, 't>, + mut parse_one: F, + ) -> Result, ParseError<'i, E>> + where + F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result> + { + let mut results = vec![parse_one(input)?]; + loop { + let comma = input.try(|i| i.expect_comma()).is_ok(); + if let Ok(item) = input.try(&mut parse_one) { + results.push(item); + } else if comma { + return Err(BasicParseError::UnexpectedToken(Token::Comma).into()); + } else { + break; + } + } + Ok(results) + } +} + /// Marker trait on T to automatically implement ToCss for Vec when T's are /// separated by some delimiter `delim`. pub trait OneOrMoreSeparated {