style: Deduplicate Angle parsing code.

This commit is contained in:
Emilio Cobos Álvarez 2017-12-02 15:30:20 +01:00
parent 55439e6222
commit 3631b1e197
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
3 changed files with 41 additions and 26 deletions

View file

@ -102,23 +102,25 @@ impl AsRef<ComputedAngle> for Angle {
}
}
/// Whether to allow parsing an unitless zero as a valid angle.
///
/// This should always be `No`, except for exceptions like:
///
/// https://github.com/w3c/fxtf-drafts/issues/228
///
/// See also: https://github.com/w3c/csswg-drafts/issues/1162.
enum AllowUnitlessZeroAngle {
Yes,
No,
}
impl Parse for Angle {
/// Parses an angle according to CSS-VALUES § 6.1.
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token {
Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false)
}
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
}
_ => Err(())
}.map_err(|()| input.new_unexpected_token_error(token.clone()))
Self::parse_internal(context, input, AllowUnitlessZeroAngle::No)
}
}
@ -127,9 +129,8 @@ impl Angle {
pub fn parse_dimension(
value: CSSFloat,
unit: &str,
from_calc: bool)
-> Result<Angle, ()>
{
from_calc: bool,
) -> Result<Angle, ()> {
let angle = match_ignore_ascii_case! { unit,
"deg" => Angle::from_degrees(value, from_calc),
"grad" => Angle::from_gradians(value, from_calc),
@ -140,23 +141,33 @@ impl Angle {
Ok(angle)
}
/// Parse an angle, including unitless 0 degree.
/// Parse an `<angle>` allowing unitless zero to represent a zero angle.
///
/// Note that numbers without any AngleUnit, including unitless 0 angle,
/// should be invalid. However, some properties still accept unitless 0
/// angle and stores it as '0deg'.
///
/// We can remove this and get back to the unified version Angle::parse once
/// https://github.com/w3c/csswg-drafts/issues/1162 is resolved.
pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> {
/// See the comment in `AllowUnitlessZeroAngle` for why.
pub fn parse_with_unitless<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_internal(context, input, AllowUnitlessZeroAngle::Yes)
}
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
allow_unitless_zero: AllowUnitlessZeroAngle,
) -> Result<Self, ParseError<'i>> {
// FIXME: remove clone() when lifetimes are non-lexical
let token = input.next()?.clone();
match token {
Token::Dimension { value, ref unit, .. } => {
Angle::parse_dimension(value, unit, /* from_calc = */ false)
}
Token::Number { value, .. } if value == 0. => Ok(Angle::zero()),
Token::Number { value, .. } if value == 0. => {
match allow_unitless_zero {
AllowUnitlessZeroAngle::Yes => Ok(Angle::zero()),
AllowUnitlessZeroAngle::No => Err(()),
}
},
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
}

View file

@ -714,6 +714,8 @@ impl LineDirection {
let mut _angle = if *compat_mode == CompatMode::Moz {
input.try(|i| Angle::parse(context, i)).ok()
} else {
// Gradients allow unitless zero angles as an exception, see:
// https://github.com/w3c/csswg-drafts/issues/1162
if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
return Ok(LineDirection::Angle(angle));
}

View file

@ -29,16 +29,18 @@ pub type TransformOperation = GenericTransformOperation<
LengthOrPercentage,
LengthOrPercentageOrNumber,
>;
/// A specified CSS `transform`
pub type Transform = GenericTransform<TransformOperation>;
/// The specified value of a CSS `<transform-origin>`
pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComponent<Y>, Length>;
impl Transform {
/// Internal parse function for deciding if we wish to accept prefixed values or not
// Allow unitless zero angle for rotate() and skew() to align with gecko
///
/// `transform` allows unitless zero angles as an exception, see:
/// https://github.com/w3c/csswg-drafts/issues/1162
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,