mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Parse interpolation hints (fixes #15166)
This commit is contained in:
parent
8824a68063
commit
ae82cdab34
6 changed files with 152 additions and 57 deletions
|
@ -92,8 +92,8 @@ impl Image {
|
|||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct Gradient {
|
||||
/// The color stops.
|
||||
pub stops: Vec<ColorStop>,
|
||||
/// The color stops and interpolation hints.
|
||||
pub items: Vec<GradientItem>,
|
||||
/// True if this is a repeating gradient.
|
||||
pub repeating: bool,
|
||||
/// Gradients can be linear or radial.
|
||||
|
@ -132,13 +132,13 @@ impl ToCss for Gradient {
|
|||
}
|
||||
},
|
||||
}
|
||||
for stop in &self.stops {
|
||||
for item in &self.items {
|
||||
if !skipcomma {
|
||||
try!(dest.write_str(", "));
|
||||
} else {
|
||||
skipcomma = false;
|
||||
}
|
||||
try!(stop.to_css(dest));
|
||||
try!(item.to_css(dest));
|
||||
}
|
||||
dest.write_str(")")
|
||||
}
|
||||
|
@ -148,18 +148,18 @@ impl Gradient {
|
|||
/// Parses a gradient from the given arguments.
|
||||
pub fn parse_function(context: &ParserContext, input: &mut Parser) -> Result<Gradient, ()> {
|
||||
fn parse<F>(context: &ParserContext, input: &mut Parser, parse_kind: F)
|
||||
-> Result<(GradientKind, Vec<ColorStop>), ()>
|
||||
-> Result<(GradientKind, Vec<GradientItem>), ()>
|
||||
where F: FnOnce(&ParserContext, &mut Parser) -> Result<GradientKind, ()>
|
||||
{
|
||||
input.parse_nested_block(|input| {
|
||||
let kind = try!(parse_kind(context, input));
|
||||
let stops = try!(input.parse_comma_separated(|i| ColorStop::parse(context, i)));
|
||||
Ok((kind, stops))
|
||||
let items = try!(Gradient::parse_items(context, input));
|
||||
Ok((kind, items))
|
||||
})
|
||||
};
|
||||
let mut repeating = false;
|
||||
let mut compat_mode = CompatMode::Modern;
|
||||
let (gradient_kind, stops) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
||||
let (gradient_kind, items) = match_ignore_ascii_case! { &try!(input.expect_function()),
|
||||
"linear-gradient" => {
|
||||
try!(parse(context, input, GradientKind::parse_modern_linear))
|
||||
},
|
||||
|
@ -195,18 +195,31 @@ impl Gradient {
|
|||
_ => { return Err(()); }
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
||||
if stops.len() < 2 {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
Ok(Gradient {
|
||||
stops: stops,
|
||||
items: items,
|
||||
repeating: repeating,
|
||||
gradient_kind: gradient_kind,
|
||||
compat_mode: compat_mode,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_items(context: &ParserContext, input: &mut Parser) -> Result<Vec<GradientItem>, ()> {
|
||||
let mut seen_stop = false;
|
||||
let items = try!(input.parse_comma_separated(|input| {
|
||||
if seen_stop {
|
||||
if let Ok(hint) = input.try(|i| LengthOrPercentage::parse(context, i)) {
|
||||
seen_stop = false;
|
||||
return Ok(GradientItem::InterpolationHint(hint));
|
||||
}
|
||||
}
|
||||
seen_stop = true;
|
||||
ColorStop::parse(context, input).map(GradientItem::ColorStop)
|
||||
}));
|
||||
if !seen_stop || items.len() < 2 {
|
||||
return Err(());
|
||||
}
|
||||
Ok(items)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specified values for CSS linear or radial gradients.
|
||||
|
@ -489,7 +502,27 @@ impl AngleOrCorner {
|
|||
}
|
||||
}
|
||||
|
||||
/// Specified values for one color stop in a linear gradient.
|
||||
/// Specified values for color stops and interpolation hints.
|
||||
/// https://drafts.csswg.org/css-images-4/#color-stop-syntax
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum GradientItem {
|
||||
/// A color stop.
|
||||
ColorStop(ColorStop),
|
||||
/// An interpolation hint.
|
||||
InterpolationHint(LengthOrPercentage),
|
||||
}
|
||||
|
||||
impl ToCss for GradientItem {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match *self {
|
||||
GradientItem::ColorStop(ref stop) => stop.to_css(dest),
|
||||
GradientItem::InterpolationHint(ref hint) => hint.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Specified values for one color stop in a gradient.
|
||||
/// https://drafts.csswg.org/css-images/#typedef-color-stop-list
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue