Introduce CommaWithSpace

This allows us to support stroke-dasharray the same way as comma-separated
values.
This commit is contained in:
Anthony Ramine 2017-06-27 11:06:24 +02:00
parent 17875b8a81
commit c03f5f19ab
4 changed files with 39 additions and 23 deletions

View file

@ -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<Vec<T>, ParseError<'i>>
where F: for<'ii, 'tt> FnMut(&mut Parser<'ii, 'tt>) -> Result<T, ParseError<'ii>> {
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<Self, ParseError<'i>> {

View file

@ -217,13 +217,12 @@
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<SpecifiedValue, ParseError<'i>> {
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)
}

View file

@ -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.

View file

@ -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<Vec<T>, ParseError<'i, E>>
where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>
{
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<T> when T's are
/// separated by some delimiter `delim`.
pub trait OneOrMoreSeparated {