mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #12458 - Manishearth:style-gecko-only, r=emilio
Cleanups in autoarray helper Addresses @emilio's comments from #11851 - Replace gecko_autoarray_longhand with vector_longhand, make it configurable - Allow for empty vectors, use empty vector longhand in box-shadow <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12458) <!-- Reviewable:end -->
This commit is contained in:
commit
a8a6d83d07
4 changed files with 68 additions and 94 deletions
|
@ -37,12 +37,18 @@
|
|||
// 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
|
||||
"<thing> [ , <thing> ]*". `gecko_only` should be set
|
||||
to True for cases where Servo takes a single value
|
||||
and Stylo supports vector values.
|
||||
|
||||
Setting allow_empty to False allows for cases where the vector
|
||||
is empty. The grammar for these is usually "none | <thing> [ , <thing> ]*".
|
||||
We assume that the default/initial value is an empty vector for these.
|
||||
`initial_value` need not be defined for these.
|
||||
</%doc>
|
||||
<%def name="gecko_autoarray_longhand(name, **kwargs)">
|
||||
<%def name="vector_longhand(name, gecko_only=False, allow_empty=False, **kwargs)">
|
||||
<%call expr="longhand(name, **kwargs)">
|
||||
% if product == "gecko":
|
||||
% if product == "gecko" or not gecko_only:
|
||||
use cssparser::ToCss;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -63,10 +69,17 @@
|
|||
|
||||
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));
|
||||
let mut iter = self.0.iter();
|
||||
if let Some(val) = iter.next() {
|
||||
try!(val.to_css(dest));
|
||||
} else {
|
||||
% if allow_empty:
|
||||
try!(dest.write_str("none"));
|
||||
% else:
|
||||
error!("Found empty value for property ${name}");
|
||||
% endif
|
||||
}
|
||||
for i in self.0.iter().skip(1) {
|
||||
for i in iter {
|
||||
try!(dest.write_str(", "));
|
||||
try!(i.to_css(dest));
|
||||
}
|
||||
|
@ -80,10 +93,17 @@
|
|||
|
||||
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))
|
||||
let mut iter = self.0.iter();
|
||||
if let Some(val) = iter.next() {
|
||||
try!(val.to_css(dest));
|
||||
} else {
|
||||
% if allow_empty:
|
||||
try!(dest.write_str("none"));
|
||||
% else:
|
||||
error!("Found empty value for property ${name}");
|
||||
% endif
|
||||
}
|
||||
for i in self.0.iter().skip(1) {
|
||||
for i in iter {
|
||||
try!(dest.write_str(", "));
|
||||
try!(i.to_css(dest));
|
||||
}
|
||||
|
@ -91,12 +111,26 @@
|
|||
}
|
||||
}
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T(vec![single_value::get_initial_value()])
|
||||
% if allow_empty:
|
||||
computed_value::T(vec![])
|
||||
% else:
|
||||
computed_value::T(vec![single_value::get_initial_value()])
|
||||
% endif
|
||||
}
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
input.parse_comma_separated(|parser| {
|
||||
single_value::parse(context, parser)
|
||||
}).map(|ok| SpecifiedValue(ok))
|
||||
% if allow_empty:
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
Ok(SpecifiedValue(Vec::new()))
|
||||
} else {
|
||||
input.parse_comma_separated(|parser| {
|
||||
single_value::parse(context, parser)
|
||||
}).map(SpecifiedValue)
|
||||
}
|
||||
% else:
|
||||
input.parse_comma_separated(|parser| {
|
||||
single_value::parse(context, parser)
|
||||
}).map(SpecifiedValue)
|
||||
% endif
|
||||
}
|
||||
impl ToComputedValue for SpecifiedValue {
|
||||
type ComputedValue = computed_value::T;
|
||||
|
|
|
@ -16,7 +16,7 @@ use properties::longhands::line_height::computed_value::T as LineHeight;
|
|||
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
|
||||
use properties::longhands::text_shadow::computed_value::TextShadow;
|
||||
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
|
||||
use properties::longhands::box_shadow::computed_value::BoxShadow;
|
||||
use properties::longhands::box_shadow::single_value::computed_value::T as BoxShadow;
|
||||
use properties::longhands::transform::computed_value::ComputedMatrix;
|
||||
use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
|
||||
use properties::longhands::transform::computed_value::T as TransformList;
|
||||
|
|
|
@ -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:gecko_autoarray_longhand name="background-image" animatable="False">
|
||||
<%helpers:vector_longhand gecko_only="True" 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:gecko_autoarray_longhand>
|
||||
</%helpers:vector_longhand>
|
||||
|
||||
<%helpers:longhand name="background-position" animatable="True">
|
||||
use cssparser::ToCss;
|
||||
|
|
|
@ -12,18 +12,14 @@ ${helpers.predefined_type("opacity",
|
|||
"1.0",
|
||||
animatable=True)}
|
||||
|
||||
<%helpers:longhand name="box-shadow" animatable="True">
|
||||
<%helpers:vector_longhand name="box-shadow" allow_empty="True" animatable="True">
|
||||
use cssparser::{self, ToCss};
|
||||
use std::fmt;
|
||||
use values::LocalToCss;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct SpecifiedValue(Vec<SpecifiedBoxShadow>);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct SpecifiedBoxShadow {
|
||||
pub struct SpecifiedValue {
|
||||
pub offset_x: specified::Length,
|
||||
pub offset_y: specified::Length,
|
||||
pub blur_radius: specified::Length,
|
||||
|
@ -33,23 +29,6 @@ ${helpers.predefined_type("opacity",
|
|||
}
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
let mut iter = self.0.iter();
|
||||
if let Some(shadow) = iter.next() {
|
||||
try!(shadow.to_css(dest));
|
||||
} else {
|
||||
try!(dest.write_str("none"));
|
||||
return Ok(())
|
||||
}
|
||||
for shadow in iter {
|
||||
try!(dest.write_str(", "));
|
||||
try!(shadow.to_css(dest));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for SpecifiedBoxShadow {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
if self.inset {
|
||||
try!(dest.write_str("inset "));
|
||||
|
@ -75,13 +54,9 @@ ${helpers.predefined_type("opacity",
|
|||
use std::fmt;
|
||||
use values::computed;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct T(pub Vec<BoxShadow>);
|
||||
|
||||
#[derive(Clone, PartialEq, Copy, Debug)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub struct BoxShadow {
|
||||
pub struct T {
|
||||
pub offset_x: Au,
|
||||
pub offset_y: Au,
|
||||
pub blur_radius: Au,
|
||||
|
@ -92,23 +67,6 @@ ${helpers.predefined_type("opacity",
|
|||
}
|
||||
|
||||
impl ToCss for computed_value::T {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
let mut iter = self.0.iter();
|
||||
if let Some(shadow) = iter.next() {
|
||||
try!(shadow.to_css(dest));
|
||||
} else {
|
||||
try!(dest.write_str("none"));
|
||||
return Ok(())
|
||||
}
|
||||
for shadow in iter {
|
||||
try!(dest.write_str(", "));
|
||||
try!(shadow.to_css(dest));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for computed_value::BoxShadow {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
if self.inset {
|
||||
try!(dest.write_str("inset "));
|
||||
|
@ -126,44 +84,26 @@ ${helpers.predefined_type("opacity",
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T(Vec::new())
|
||||
}
|
||||
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||
Ok(SpecifiedValue(Vec::new()))
|
||||
} else {
|
||||
input.parse_comma_separated(parse_one_box_shadow).map(SpecifiedValue)
|
||||
}
|
||||
}
|
||||
|
||||
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(|value| compute_one_box_shadow(value, context)).collect())
|
||||
computed_value::T {
|
||||
offset_x: self.offset_x.to_computed_value(context),
|
||||
offset_y: self.offset_y.to_computed_value(context),
|
||||
blur_radius: self.blur_radius.to_computed_value(context),
|
||||
spread_radius: self.spread_radius.to_computed_value(context),
|
||||
color: self.color
|
||||
.as_ref()
|
||||
.map(|color| color.parsed)
|
||||
.unwrap_or(cssparser::Color::CurrentColor),
|
||||
inset: self.inset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_one_box_shadow<Cx: TContext>(value: &SpecifiedBoxShadow, context: &Cx)
|
||||
-> computed_value::BoxShadow {
|
||||
computed_value::BoxShadow {
|
||||
offset_x: value.offset_x.to_computed_value(context),
|
||||
offset_y: value.offset_y.to_computed_value(context),
|
||||
blur_radius: value.blur_radius.to_computed_value(context),
|
||||
spread_radius: value.spread_radius.to_computed_value(context),
|
||||
color: value.color
|
||||
.as_ref()
|
||||
.map(|color| color.parsed)
|
||||
.unwrap_or(cssparser::Color::CurrentColor),
|
||||
inset: value.inset,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_one_box_shadow(input: &mut Parser) -> Result<SpecifiedBoxShadow, ()> {
|
||||
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
use app_units::Au;
|
||||
let mut lengths = [specified::Length::Absolute(Au(0)); 4];
|
||||
let mut lengths_parsed = false;
|
||||
|
@ -213,7 +153,7 @@ ${helpers.predefined_type("opacity",
|
|||
return Err(())
|
||||
}
|
||||
|
||||
Ok(SpecifiedBoxShadow {
|
||||
Ok(SpecifiedValue {
|
||||
offset_x: lengths[0],
|
||||
offset_y: lengths[1],
|
||||
blur_radius: lengths[2],
|
||||
|
@ -222,7 +162,7 @@ ${helpers.predefined_type("opacity",
|
|||
inset: inset,
|
||||
})
|
||||
}
|
||||
</%helpers:longhand>
|
||||
</%helpers:vector_longhand>
|
||||
|
||||
// FIXME: This prop should be animatable
|
||||
<%helpers:longhand name="clip" animatable="False">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue