mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Fix parsing of -webkit-linear-gradient()
No code can actually be shared between WebKit and modern gradients. :(
This commit is contained in:
parent
2ac57a7d8f
commit
0854df922d
1 changed files with 54 additions and 50 deletions
|
@ -147,23 +147,12 @@ impl ToCss for Gradient {
|
||||||
impl Gradient {
|
impl Gradient {
|
||||||
/// Parses a gradient from the given arguments.
|
/// Parses a gradient from the given arguments.
|
||||||
pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result<Gradient, ()> {
|
pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result<Gradient, ()> {
|
||||||
let parse_linear_gradient = |input: &mut Parser, mode| {
|
fn parse<F>(context: &ParserContext, input: &mut Parser, parse_kind: F)
|
||||||
|
-> Result<(GradientKind, Vec<ColorStop>), ()>
|
||||||
|
where F: FnOnce(&ParserContext, &mut Parser) -> Result<GradientKind, ()>
|
||||||
|
{
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let kind = try!(GradientKind::parse_linear(context, input, mode));
|
let kind = try!(parse_kind(context, input));
|
||||||
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
|
||||||
Ok((kind, stops))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let parse_modern_radial_gradient = |input: &mut Parser| {
|
|
||||||
input.parse_nested_block(|input| {
|
|
||||||
let kind = try!(GradientKind::parse_modern_radial(context, input));
|
|
||||||
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
|
||||||
Ok((kind, stops))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let parse_webkit_radial_gradient = |input: &mut Parser| {
|
|
||||||
input.parse_nested_block(|input| {
|
|
||||||
let kind = try!(GradientKind::parse_webkit_radial(context, input));
|
|
||||||
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
||||||
Ok((kind, stops))
|
Ok((kind, stops))
|
||||||
})
|
})
|
||||||
|
@ -172,36 +161,36 @@ impl Gradient {
|
||||||
let mut compat_mode = CompatMode::Modern;
|
let mut compat_mode = CompatMode::Modern;
|
||||||
let (gradient_kind, stops) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
let (gradient_kind, stops) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
||||||
"linear-gradient" => {
|
"linear-gradient" => {
|
||||||
try!(parse_linear_gradient(input, compat_mode))
|
try!(parse(context, input, GradientKind::parse_modern_linear))
|
||||||
},
|
},
|
||||||
"-webkit-linear-gradient" => {
|
"-webkit-linear-gradient" => {
|
||||||
compat_mode = CompatMode::WebKit;
|
compat_mode = CompatMode::WebKit;
|
||||||
try!(parse_linear_gradient(input, compat_mode))
|
try!(parse(context, input, GradientKind::parse_webkit_linear))
|
||||||
},
|
},
|
||||||
"repeating-linear-gradient" => {
|
"repeating-linear-gradient" => {
|
||||||
repeating = true;
|
repeating = true;
|
||||||
try!(parse_linear_gradient(input, compat_mode))
|
try!(parse(context, input, GradientKind::parse_modern_linear))
|
||||||
},
|
},
|
||||||
"-webkit-repeating-linear-gradient" => {
|
"-webkit-repeating-linear-gradient" => {
|
||||||
repeating = true;
|
repeating = true;
|
||||||
compat_mode = CompatMode::WebKit;
|
compat_mode = CompatMode::WebKit;
|
||||||
try!(parse_linear_gradient(input, compat_mode))
|
try!(parse(context, input, GradientKind::parse_webkit_linear))
|
||||||
},
|
},
|
||||||
"radial-gradient" => {
|
"radial-gradient" => {
|
||||||
try!(parse_modern_radial_gradient(input))
|
try!(parse(context, input, GradientKind::parse_modern_radial))
|
||||||
},
|
},
|
||||||
"-webkit-radial-gradient" => {
|
"-webkit-radial-gradient" => {
|
||||||
compat_mode = CompatMode::WebKit;
|
compat_mode = CompatMode::WebKit;
|
||||||
try!(parse_webkit_radial_gradient(input))
|
try!(parse(context, input, GradientKind::parse_webkit_radial))
|
||||||
},
|
},
|
||||||
"repeating-radial-gradient" => {
|
"repeating-radial-gradient" => {
|
||||||
repeating = true;
|
repeating = true;
|
||||||
try!(parse_modern_radial_gradient(input))
|
try!(parse(context, input, GradientKind::parse_modern_radial))
|
||||||
},
|
},
|
||||||
"-webkit-repeating-radial-gradient" => {
|
"-webkit-repeating-radial-gradient" => {
|
||||||
repeating = true;
|
repeating = true;
|
||||||
compat_mode = CompatMode::WebKit;
|
compat_mode = CompatMode::WebKit;
|
||||||
try!(parse_webkit_radial_gradient(input))
|
try!(parse(context, input, GradientKind::parse_webkit_radial))
|
||||||
},
|
},
|
||||||
_ => { return Err(()); }
|
_ => { return Err(()); }
|
||||||
};
|
};
|
||||||
|
@ -248,9 +237,46 @@ pub enum CompatMode {
|
||||||
|
|
||||||
impl GradientKind {
|
impl GradientKind {
|
||||||
/// Parses a linear gradient kind from the given arguments.
|
/// Parses a linear gradient kind from the given arguments.
|
||||||
fn parse_linear(context: &ParserContext, input: &mut Parser, mode: CompatMode) -> Result<GradientKind, ()> {
|
fn parse_modern_linear(context: &ParserContext, input: &mut Parser) -> Result<GradientKind, ()> {
|
||||||
let angle_or_corner = try!(AngleOrCorner::parse(context, input, mode));
|
let direction = if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
||||||
Ok(GradientKind::Linear(angle_or_corner))
|
try!(input.expect_comma());
|
||||||
|
AngleOrCorner::Angle(angle)
|
||||||
|
} else {
|
||||||
|
if input.try(|i| i.expect_ident_matching("to")).is_ok() {
|
||||||
|
let (horizontal, vertical) =
|
||||||
|
if let Ok(value) = input.try(HorizontalDirection::parse) {
|
||||||
|
(Some(value), input.try(VerticalDirection::parse).ok())
|
||||||
|
} else {
|
||||||
|
let value = try!(VerticalDirection::parse(input));
|
||||||
|
(input.try(HorizontalDirection::parse).ok(), Some(value))
|
||||||
|
};
|
||||||
|
try!(input.expect_comma());
|
||||||
|
AngleOrCorner::Corner(horizontal, vertical)
|
||||||
|
} else {
|
||||||
|
AngleOrCorner::None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(GradientKind::Linear(direction))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_webkit_linear(context: &ParserContext, input: &mut Parser) -> Result<GradientKind, ()> {
|
||||||
|
let direction = if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
||||||
|
AngleOrCorner::Angle(angle)
|
||||||
|
} else {
|
||||||
|
if let Ok(value) = input.try(HorizontalDirection::parse) {
|
||||||
|
AngleOrCorner::Corner(Some(value), input.try(VerticalDirection::parse).ok())
|
||||||
|
} else {
|
||||||
|
if let Ok(value) = input.try(VerticalDirection::parse) {
|
||||||
|
AngleOrCorner::Corner(input.try(HorizontalDirection::parse).ok(), Some(value))
|
||||||
|
} else {
|
||||||
|
AngleOrCorner::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if direction != AngleOrCorner::None {
|
||||||
|
try!(input.expect_comma());
|
||||||
|
}
|
||||||
|
Ok(GradientKind::Linear(direction))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a modern radial gradient from the given arguments.
|
/// Parses a modern radial gradient from the given arguments.
|
||||||
|
@ -345,7 +371,7 @@ impl GradientKind {
|
||||||
} else {
|
} else {
|
||||||
// If there is no shape keyword, it should set to default.
|
// If there is no shape keyword, it should set to default.
|
||||||
needs_comma = false;
|
needs_comma = false;
|
||||||
EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::FarthestCorner))
|
EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(SizeKeyword::Cover))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -463,28 +489,6 @@ impl AngleOrCorner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AngleOrCorner {
|
|
||||||
fn parse(context: &ParserContext, input: &mut Parser, mode: CompatMode) -> Result<Self, ()> {
|
|
||||||
if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
|
||||||
try!(input.expect_comma());
|
|
||||||
return Ok(AngleOrCorner::Angle(angle))
|
|
||||||
}
|
|
||||||
if mode == CompatMode::WebKit || input.try(|input| input.expect_ident_matching("to")).is_ok() {
|
|
||||||
let (horizontal, vertical) =
|
|
||||||
if let Ok(value) = input.try(HorizontalDirection::parse) {
|
|
||||||
(Some(value), input.try(VerticalDirection::parse).ok())
|
|
||||||
} else {
|
|
||||||
let value = try!(VerticalDirection::parse(input));
|
|
||||||
(input.try(HorizontalDirection::parse).ok(), Some(value))
|
|
||||||
};
|
|
||||||
try!(input.expect_comma());
|
|
||||||
Ok(AngleOrCorner::Corner(horizontal, vertical))
|
|
||||||
} else {
|
|
||||||
Ok(AngleOrCorner::None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Specified values for one color stop in a linear gradient.
|
/// Specified values for one color stop in a linear gradient.
|
||||||
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue