From 50c25f32210d81808e2b9789d0bb8148ca37a018 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 18 Apr 2017 10:31:14 +0200 Subject: [PATCH] Extract the shape parsing code from GradientKind::parse_radial --- components/style/values/specified/image.rs | 81 +++++++++++----------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 50129350c63..eaa2d58d93c 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -235,49 +235,17 @@ impl GradientKind { pub fn parse_radial(context: &ParserContext, input: &mut Parser) -> Result { let mut needs_comma = true; - // Ending shape and position can be in various order. Checks all probabilities. let (shape, position) = if let Ok(position) = input.try(|i| parse_position(context, i)) { - // Handle just + // Handle just "at" (EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)), position) - } else if let Ok((first, second)) = input.try(|i| parse_two_length(context, i)) { - // Handle ? ? - let _ = input.try(|input| input.expect_ident_matching("ellipse")); - (EndingShape::Ellipse(LengthOrPercentageOrKeyword::LengthOrPercentage(first, second)), - input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) - } else if let Ok(length) = input.try(|i| Length::parse(context, i)) { - // Handle ? ? - let _ = input.try(|input| input.expect_ident_matching("circle")); - (EndingShape::Circle(LengthOrKeyword::Length(length)), - input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) - } else if let Ok(keyword) = input.try(SizeKeyword::parse) { - // Handle ? ? - let shape = if input.try(|input| input.expect_ident_matching("circle")).is_ok() { - EndingShape::Circle(LengthOrKeyword::Keyword(keyword)) - } else { - let _ = input.try(|input| input.expect_ident_matching("ellipse")); - EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(keyword)) - }; + } else if let Ok(shape) = input.try(|i| parse_shape(context, i)) { + // Handle ["at" ]? (shape, input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) } else { - // Handle ? ? - if input.try(|input| input.expect_ident_matching("ellipse")).is_ok() { - // Handle ? ? - let length = input.try(|i| LengthOrPercentageOrKeyword::parse(context, i)) - .unwrap_or(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)); - (EndingShape::Ellipse(length), - input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) - } else if input.try(|input| input.expect_ident_matching("circle")).is_ok() { - // Handle ? ? - let length = input.try(|i| LengthOrKeyword::parse(context, i)) - .unwrap_or(LengthOrKeyword::Keyword(SizeKeyword::FarthestCorner)); - (EndingShape::Circle(length), input.try(|i| parse_position(context, i)) - .unwrap_or(Position::center())) - } else { - // If there is no shape keyword, it should set to default. - needs_comma = false; - (EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)), - input.try(|i| parse_position(context, i)).unwrap_or(Position::center())) - } + // If there is no shape keyword, it should set to default. + needs_comma = false; + (EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)), + Position::center()) }; if needs_comma { @@ -358,6 +326,41 @@ fn parse_position(context: &ParserContext, input: &mut Parser) -> Result Result { + if let Ok((first, second)) = input.try(|i| parse_two_length(context, i)) { + // Handle ? + let _ = input.try(|input| input.expect_ident_matching("ellipse")); + Ok(EndingShape::Ellipse(LengthOrPercentageOrKeyword::LengthOrPercentage(first, second))) + } else if let Ok(length) = input.try(|i| Length::parse(context, i)) { + // Handle ? + let _ = input.try(|input| input.expect_ident_matching("circle")); + Ok(EndingShape::Circle(LengthOrKeyword::Length(length))) + } else if let Ok(keyword) = input.try(SizeKeyword::parse) { + // Handle ? + if input.try(|input| input.expect_ident_matching("circle")).is_ok() { + Ok(EndingShape::Circle(LengthOrKeyword::Keyword(keyword))) + } else { + let _ = input.try(|input| input.expect_ident_matching("ellipse")); + Ok(EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(keyword))) + } + } else { + // https://github.com/rust-lang/rust/issues/41272 + if input.try(|input| input.expect_ident_matching("ellipse")).is_ok() { + // Handle ? + let length = input.try(|i| LengthOrPercentageOrKeyword::parse(context, i)) + .unwrap_or(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner)); + Ok(EndingShape::Ellipse(length)) + } else if input.try(|input| input.expect_ident_matching("circle")).is_ok() { + // Handle ? + let length = input.try(|i| LengthOrKeyword::parse(context, i)) + .unwrap_or(LengthOrKeyword::Keyword(SizeKeyword::FarthestCorner)); + Ok(EndingShape::Circle(length)) + } else { + Err(()) + } + } +} + /// Specified values for an angle or a corner in a linear gradient. #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]