var() functions in shorthands: use a single code path with IDs

… rather than generating similar code for each shorthand.
This commit is contained in:
Simon Sapin 2017-07-12 22:44:47 +02:00
parent 8a8614eccd
commit 252e52e24e
2 changed files with 41 additions and 44 deletions

View file

@ -760,13 +760,12 @@
pub mod ${shorthand.ident} { pub mod ${shorthand.ident} {
use cssparser::Parser; use cssparser::Parser;
use parser::ParserContext; use parser::ParserContext;
use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed}; use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands};
use properties::{ShorthandId, LonghandId, UnparsedValue, longhands};
#[allow(unused_imports)] #[allow(unused_imports)]
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
#[allow(unused_imports)] #[allow(unused_imports)]
use std::fmt; use std::fmt;
use stylearc::Arc; #[allow(unused_imports)]
use style_traits::{ParseError, StyleParseError}; use style_traits::{ParseError, StyleParseError};
#[allow(unused_imports)] #[allow(unused_imports)]
use style_traits::ToCss; use style_traits::ToCss;
@ -845,41 +844,15 @@
/// Parse the given shorthand and fill the result into the /// Parse the given shorthand and fill the result into the
/// `declarations` vector. /// `declarations` vector.
pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration, pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration,
context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { context: &ParserContext, input: &mut Parser<'i, 't>)
input.look_for_var_functions(); -> Result<(), ParseError<'i>> {
let start = input.position(); parse_value(context, input).map(|longhands| {
let value = input.parse_entirely(|input| parse_value(context, input));
if value.is_err() {
while let Ok(_) = input.next() {} // Look for var() after the error.
}
let var = input.seen_var_functions();
if let Ok(value) = value {
% for sub_property in shorthand.sub_properties: % for sub_property in shorthand.sub_properties:
declarations.push(PropertyDeclaration::${sub_property.camel_case}( declarations.push(PropertyDeclaration::${sub_property.camel_case}(
value.${sub_property.ident} longhands.${sub_property.ident}
)); ));
% endfor % endfor
Ok(()) })
} else if var {
input.reset(start);
let (first_token_type, css) =
::custom_properties::parse_non_custom_with_var(input)?;
let unparsed = Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
url_data: context.url_data.clone(),
from_shorthand: Some(ShorthandId::${shorthand.camel_case}),
});
% for sub_property in shorthand.sub_properties:
declarations.push(PropertyDeclaration::WithVariables(
LonghandId::${sub_property.camel_case},
unparsed.clone()
));
% endfor
Ok(())
} else {
Err(StyleParseError::UnspecifiedError.into())
}
} }
${caller.body()} ${caller.body()}

View file

@ -1522,7 +1522,7 @@ impl PropertyDeclaration {
} }
PropertyId::Longhand(id) => { PropertyId::Longhand(id) => {
if let Ok(keyword) = input.try(|i| CSSWideKeyword::parse(context, i)) { if let Ok(keyword) = input.try(|i| CSSWideKeyword::parse(context, i)) {
declarations.push(PropertyDeclaration::CSSWideKeyword(id, keyword)) declarations.push(PropertyDeclaration::CSSWideKeyword(id, keyword));
Ok(()) Ok(())
} else { } else {
match id { match id {
@ -1559,16 +1559,40 @@ impl PropertyDeclaration {
} }
Ok(()) Ok(())
} else { } else {
match id { input.look_for_var_functions();
% for shorthand in data.shorthands: let start = input.position();
ShorthandId::${shorthand.camel_case} => { input.parse_entirely(|input| {
shorthands::${shorthand.ident}::parse_into(declarations, context, input) match id {
.map_err(|_| PropertyDeclarationParseError::InvalidValue( % for shorthand in data.shorthands:
"${shorthand.ident}".into() ShorthandId::${shorthand.camel_case} => {
)) shorthands::${shorthand.ident}::parse_into(declarations, context, input)
}
% endfor
}
}).or_else(|_| {
while let Ok(_) = input.next() {} // Look for var() after the error.
if input.seen_var_functions() {
input.reset(start);
let (first_token_type, css) =
::custom_properties::parse_non_custom_with_var(input).map_err(|_| {
PropertyDeclarationParseError::InvalidValue(id.name().into())
})?;
let unparsed = Arc::new(UnparsedValue {
css: css.into_owned(),
first_token_type: first_token_type,
url_data: context.url_data.clone(),
from_shorthand: Some(id),
});
for &longhand in id.longhands() {
declarations.push(
PropertyDeclaration::WithVariables(longhand, unparsed.clone())
)
} }
% endfor Ok(())
} } else {
Err(PropertyDeclarationParseError::InvalidValue(id.name().into()))
}
})
} }
} }
} }