mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
style: Deduplicate Angle parsing code.
This commit is contained in:
parent
55439e6222
commit
3631b1e197
3 changed files with 41 additions and 26 deletions
|
@ -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 {
|
impl Parse for Angle {
|
||||||
/// Parses an angle according to CSS-VALUES § 6.1.
|
/// Parses an angle according to CSS-VALUES § 6.1.
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
// FIXME: remove clone() when lifetimes are non-lexical
|
Self::parse_internal(context, input, AllowUnitlessZeroAngle::No)
|
||||||
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()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +129,8 @@ impl Angle {
|
||||||
pub fn parse_dimension(
|
pub fn parse_dimension(
|
||||||
value: CSSFloat,
|
value: CSSFloat,
|
||||||
unit: &str,
|
unit: &str,
|
||||||
from_calc: bool)
|
from_calc: bool,
|
||||||
-> Result<Angle, ()>
|
) -> Result<Angle, ()> {
|
||||||
{
|
|
||||||
let angle = match_ignore_ascii_case! { unit,
|
let angle = match_ignore_ascii_case! { unit,
|
||||||
"deg" => Angle::from_degrees(value, from_calc),
|
"deg" => Angle::from_degrees(value, from_calc),
|
||||||
"grad" => Angle::from_gradians(value, from_calc),
|
"grad" => Angle::from_gradians(value, from_calc),
|
||||||
|
@ -140,23 +141,33 @@ impl Angle {
|
||||||
Ok(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,
|
/// See the comment in `AllowUnitlessZeroAngle` for why.
|
||||||
/// should be invalid. However, some properties still accept unitless 0
|
pub fn parse_with_unitless<'i, 't>(
|
||||||
/// angle and stores it as '0deg'.
|
context: &ParserContext,
|
||||||
///
|
input: &mut Parser<'i, 't>,
|
||||||
/// We can remove this and get back to the unified version Angle::parse once
|
) -> Result<Self, ParseError<'i>> {
|
||||||
/// https://github.com/w3c/csswg-drafts/issues/1162 is resolved.
|
Self::parse_internal(context, input, AllowUnitlessZeroAngle::Yes)
|
||||||
pub fn parse_with_unitless<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
}
|
||||||
-> Result<Self, ParseError<'i>> {
|
|
||||||
|
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
|
// FIXME: remove clone() when lifetimes are non-lexical
|
||||||
let token = input.next()?.clone();
|
let token = input.next()?.clone();
|
||||||
match token {
|
match token {
|
||||||
Token::Dimension { value, ref unit, .. } => {
|
Token::Dimension { value, ref unit, .. } => {
|
||||||
Angle::parse_dimension(value, unit, /* from_calc = */ false)
|
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") => {
|
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
|
||||||
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
|
return input.parse_nested_block(|i| CalcNode::parse_angle(context, i))
|
||||||
}
|
}
|
||||||
|
|
|
@ -714,6 +714,8 @@ impl LineDirection {
|
||||||
let mut _angle = if *compat_mode == CompatMode::Moz {
|
let mut _angle = if *compat_mode == CompatMode::Moz {
|
||||||
input.try(|i| Angle::parse(context, i)).ok()
|
input.try(|i| Angle::parse(context, i)).ok()
|
||||||
} else {
|
} 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)) {
|
if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
||||||
return Ok(LineDirection::Angle(angle));
|
return Ok(LineDirection::Angle(angle));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,18 @@ pub type TransformOperation = GenericTransformOperation<
|
||||||
LengthOrPercentage,
|
LengthOrPercentage,
|
||||||
LengthOrPercentageOrNumber,
|
LengthOrPercentageOrNumber,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/// A specified CSS `transform`
|
/// A specified CSS `transform`
|
||||||
pub type Transform = GenericTransform<TransformOperation>;
|
pub type Transform = GenericTransform<TransformOperation>;
|
||||||
|
|
||||||
/// The specified value of a CSS `<transform-origin>`
|
/// The specified value of a CSS `<transform-origin>`
|
||||||
pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComponent<Y>, Length>;
|
pub type TransformOrigin = GenericTransformOrigin<OriginComponent<X>, OriginComponent<Y>, Length>;
|
||||||
|
|
||||||
|
|
||||||
impl Transform {
|
impl Transform {
|
||||||
/// Internal parse function for deciding if we wish to accept prefixed values or not
|
/// 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>(
|
fn parse_internal<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue