Auto merge of #11851 - Manishearth:stylo-autoarray, r=emilio

Add support for gecko-only array values; use for stylo

Doesn't yet work, because I can't grow nsTArrays from Rust. If anyone knows how to add bindings for that, let me know!

Thoughts on the design so far? Once this PR lands, all of the array-accepting background- properties can just use gecko_autoarray_longhand and some iterators in the geckolib implementation without changing much other code to work with arrays.

cc @emilio @bholley

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/11851)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-07-14 02:32:49 -07:00 committed by GitHub
commit ed985f75ec
11 changed files with 413 additions and 242 deletions

View file

@ -33,6 +33,85 @@
</%call>
</%def>
// FIXME (Manishearth): Add computed_value_as_specified argument
// and handle the empty case correctly
<%doc>
To be used in cases where we have a grammar like
"<thing> [ , <thing> ]*", but only support a single value
in servo
</%doc>
<%def name="gecko_autoarray_longhand(name, **kwargs)">
<%call expr="longhand(name, **kwargs)">
% if product == "gecko":
use cssparser::ToCss;
use std::fmt;
pub mod single_value {
use cssparser::Parser;
use parser::{ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
use values::computed::{TContext, ToComputedValue};
use values::{computed, specified};
${caller.body()}
}
pub mod computed_value {
use super::single_value;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<single_value::computed_value::T>);
}
impl ToCss for computed_value::T {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if !self.0.is_empty() {
try!(self.0[0].to_css(dest));
}
for i in self.0.iter().skip(1) {
try!(dest.write_str(", "));
try!(i.to_css(dest));
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue(pub Vec<single_value::SpecifiedValue>);
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if !self.0.is_empty() {
try!(self.0[0].to_css(dest))
}
for i in self.0.iter().skip(1) {
try!(dest.write_str(", "));
try!(i.to_css(dest));
}
Ok(())
}
}
pub fn get_initial_value() -> computed_value::T {
computed_value::T(vec![single_value::get_initial_value()])
}
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
input.parse_comma_separated(|parser| {
single_value::parse(context, parser)
}).map(|ok| SpecifiedValue(ok))
}
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect())
}
}
% else:
${caller.body()}
% endif
</%call>
</%def>
<%def name="raw_longhand(*args, **kwargs)">
<%
property = data.declare_longhand(*args, **kwargs)

View file

@ -10,7 +10,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
"::cssparser::Color::RGBA(::cssparser::RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */",
animatable=True)}
<%helpers:longhand name="background-image" animatable="False">
<%helpers:gecko_autoarray_longhand name="background-image" animatable="False">
use cssparser::ToCss;
use std::fmt;
use values::specified::Image;
@ -70,7 +70,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
}
}
}
</%helpers:longhand>
</%helpers:gecko_autoarray_longhand>
<%helpers:longhand name="background-position" animatable="True">
use cssparser::ToCss;