Make LonghandsToSerialize store reference to specified value

This significantly simplify the code.
This commit is contained in:
Xidorn Quan 2017-03-01 16:56:22 +11:00
parent 2cc6593fa1
commit f327b2fc73
15 changed files with 166 additions and 563 deletions

View file

@ -70,7 +70,7 @@
pub mod single_value {
use cssparser::Parser;
use parser::{Parse, ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
use properties::{DeclaredValue, ShorthandId};
use values::computed::{Context, ToComputedValue};
use values::{computed, specified};
use values::{Auto, Either, None_, Normal};
@ -210,14 +210,14 @@
% if not property.derived_from:
use cssparser::Parser;
use parser::{Parse, ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, UnparsedValue, ShorthandId};
use properties::{DeclaredValue, UnparsedValue, ShorthandId};
% endif
use values::{Auto, Either, None_, Normal};
use cascade_info::CascadeInfo;
use error_reporting::ParseErrorReporter;
use properties::longhands;
use properties::LonghandIdSet;
use properties::{ComputedValues, PropertyDeclaration};
use properties::{CSSWideKeyword, ComputedValues, PropertyDeclaration};
use properties::style_structs;
use std::boxed::Box as StdBox;
use std::collections::HashMap;
@ -483,12 +483,11 @@
#[allow(unused_imports)]
use cssparser::Parser;
use parser::ParserContext;
use properties::{CSSWideKeyword, DeclaredValue, PropertyDeclaration};
use properties::{DeclaredValue, PropertyDeclaration};
use properties::{ShorthandId, UnparsedValue, longhands};
use properties::declaration_block::Importance;
use std::fmt;
use style_traits::ToCss;
use super::{SerializeFlags, ALL_INHERIT, ALL_INITIAL, ALL_UNSET};
pub struct Longhands {
% for sub_property in shorthand.sub_properties:
@ -502,10 +501,10 @@
% for sub_property in shorthand.sub_properties:
% if sub_property.boxed:
pub ${sub_property.ident}:
&'a DeclaredValue<Box<longhands::${sub_property.ident}::SpecifiedValue>>,
&'a Box<longhands::${sub_property.ident}::SpecifiedValue>,
% else:
pub ${sub_property.ident}:
&'a DeclaredValue<longhands::${sub_property.ident}::SpecifiedValue>,
&'a longhands::${sub_property.ident}::SpecifiedValue,
% endif
% endfor
}
@ -525,7 +524,7 @@
for longhand in iter {
match *longhand {
% for sub_property in shorthand.sub_properties:
PropertyDeclaration::${sub_property.camel_case}(ref value) => {
PropertyDeclaration::${sub_property.camel_case}(DeclaredValue::Value(ref value)) => {
${sub_property.ident} = Some(value)
},
% endfor
@ -559,34 +558,7 @@
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
{
let mut all_flags = SerializeFlags::all();
let mut with_variables = false;
% for sub_property in shorthand.sub_properties:
match *self.${sub_property.ident} {
DeclaredValue::CSSWideKeyword(keyword) => match keyword {
CSSWideKeyword::Initial => all_flags &= ALL_INITIAL,
CSSWideKeyword::Inherit => all_flags &= ALL_INHERIT,
CSSWideKeyword::Unset => all_flags &= ALL_UNSET,
},
DeclaredValue::WithVariables(_) => with_variables = true,
DeclaredValue::Value(..) => {
all_flags = SerializeFlags::empty();
}
}
% endfor
if with_variables {
// We don't serialize shorthands with variables
dest.write_str("")
} else if all_flags == ALL_INHERIT {
dest.write_str("inherit")
} else if all_flags == ALL_INITIAL {
dest.write_str("initial")
} else if all_flags == ALL_UNSET {
dest.write_str("unset")
} else {
self.to_css_declared(dest)
}
self.to_css_declared(dest)
}
}

View file

@ -102,14 +102,6 @@ pub mod shorthands {
use parser::{Parse, ParserContext};
use values::specified;
bitflags! {
flags SerializeFlags: u8 {
const ALL_INHERIT = 0b001,
const ALL_INITIAL = 0b010,
const ALL_UNSET = 0b100,
}
}
/// Parses a property for four different sides per CSS syntax.
///
/// * Zero or more than four values is invalid.

View file

@ -129,61 +129,34 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// mako doesn't like ampersands following `<`
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
let len = extract_value(self.background_image).map(|i| i.0.len()).unwrap_or(0);
let len = self.background_image.0.len();
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
return Ok(());
}
// If a value list length is differs then we don't do a shorthand serialization.
// The exceptions to this is color which appears once only and is serialized
// with the last item.
% for name in "image position_x position_y size repeat origin clip attachment".split():
if len != extract_value(self.background_${name}).map(|i| i.0.len()).unwrap_or(0) {
return dest.write_str("")
if len != self.background_${name}.0.len() {
return Ok(());
}
% endfor
let mut first = true;
for i in 0..len {
% for name in "image position_x position_y repeat size attachment origin clip".split():
let ${name} = if let DeclaredValue::Value(ref arr) = *self.background_${name} {
&arr.0[i]
} else {
unreachable!()
};
let ${name} = &self.background_${name}.0[i];
% endfor
let color = if i == len - 1 {
Some(self.background_color)
} else {
None
};
if first {
first = false;
} else {
if i != 0 {
try!(write!(dest, ", "));
}
match color {
Some(&DeclaredValue::Value(ref color)) => {
try!(color.to_css(dest));
try!(write!(dest, " "));
},
Some(_) => {
try!(write!(dest, "transparent "));
}
// Not yet the last one
None => ()
};
if i == len - 1 {
try!(self.background_color.to_css(dest));
try!(write!(dest, " "));
}
% for name in "image repeat attachment position_x position_y".split():
try!(${name}.to_css(dest));
@ -253,47 +226,15 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// mako doesn't like ampersands following `<`
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
let len = self.background_position_x.0.len();
if len == 0 || len != self.background_position_y.0.len() {
return Ok(());
}
use std::cmp;
let mut len = 0;
% for name in "x y".split():
len = cmp::max(len, extract_value(self.background_position_${name})
.map(|i| i.0.len())
.unwrap_or(0));
% endfor
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
}
for i in 0..len {
% for name in "x y".split():
let position_${name} = if let DeclaredValue::Value(ref arr) =
*self.background_position_${name} {
arr.0.get(i % arr.0.len())
} else {
None
};
% endfor
try!(position_x.unwrap_or(&background_position_x::single_value
::get_initial_position_value())
.to_css(dest));
try!(write!(dest, " "));
try!(position_y.unwrap_or(&background_position_y::single_value
::get_initial_position_value())
.to_css(dest));
self.background_position_x.0[i].to_css(dest)?;
dest.write_str(" ")?;
self.background_position_y.0[i].to_css(dest)?;
}
Ok(())
}
}

View file

@ -291,53 +291,15 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser)
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
% for name in "outset repeat slice source width".split():
let ${name} = if let DeclaredValue::Value(ref value) = *self.border_image_${name} {
Some(value)
} else {
None
};
% endfor
if let Some(source) = source {
try!(source.to_css(dest));
} else {
try!(write!(dest, "none"));
}
try!(write!(dest, " "));
if let Some(slice) = slice {
try!(slice.to_css(dest));
} else {
try!(write!(dest, "100%"));
}
try!(write!(dest, " / "));
if let Some(width) = width {
try!(width.to_css(dest));
} else {
try!(write!(dest, "1"));
}
try!(write!(dest, " / "));
if let Some(outset) = outset {
try!(outset.to_css(dest));
} else {
try!(write!(dest, "0"));
}
try!(write!(dest, " "));
if let Some(repeat) = repeat {
try!(repeat.to_css(dest));
} else {
try!(write!(dest, "stretch"));
}
Ok(())
self.border_image_source.to_css(dest)?;
dest.write_str(" ")?;
self.border_image_slice.to_css(dest)?;
dest.write_str(" / ")?;
self.border_image_width.to_css(dest)?;
dest.write_str(" / ")?;
self.border_image_outset.to_css(dest)?;
dest.write_str(" ")?;
self.border_image_repeat.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -18,20 +18,11 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let x_and_y_equal = match (self.overflow_x, self.overflow_y) {
(&DeclaredValue::Value(ref x_value), &DeclaredValue::Value(ref y_container)) => {
*x_value == y_container.0
},
(&DeclaredValue::WithVariables(_), &DeclaredValue::WithVariables(_)) => true,
(&DeclaredValue::CSSWideKeyword(x_keyword),
&DeclaredValue::CSSWideKeyword(y_keyword)) => x_keyword == y_keyword,
_ => false
};
if x_and_y_equal {
try!(self.overflow_x.to_css(dest));
if *self.overflow_x == self.overflow_y.0 {
self.overflow_x.to_css(dest)
} else {
Ok(())
}
Ok(())
}
}
</%helpers:shorthand>
@ -126,48 +117,28 @@ macro_rules! try_parse_one {
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
let len = extract_value(self.transition_property).map(|i| i.0.len()).unwrap_or(0);
let len = self.transition_property.0.len();
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
return Ok(());
}
// If any value list length is differs then we don't do a shorthand serialization
// either.
% for name in "property duration delay timing_function".split():
if len != extract_value(self.transition_${name}).map(|i| i.0.len()).unwrap_or(0) {
return dest.write_str("")
if len != self.transition_${name}.0.len() {
return Ok(());
}
% endfor
let mut first = true;
for i in 0..len {
% for name in "property duration delay timing_function".split():
let ${name} = if let DeclaredValue::Value(ref arr) = *self.transition_${name} {
&arr.0[i]
} else {
unreachable!()
};
% endfor
if first {
first = false;
} else {
try!(write!(dest, ", "));
if i != 0 {
write!(dest, ", ")?;
}
try!(property.to_css(dest));
self.transition_property.0[i].to_css(dest)?;
% for name in "duration timing_function delay".split():
try!(write!(dest, " "));
try!(${name}.to_css(dest));
dest.write_str(" ")?;
self.transition_${name}.0[i].to_css(dest)?;
% endfor
}
Ok(())
@ -288,49 +259,35 @@ macro_rules! try_parse_one {
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
let len = extract_value(self.animation_name).map(|i| i.0.len()).unwrap_or(0);
let len = self.animation_name.0.len();
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
return Ok(());
}
<%
subproperties = "duration timing_function delay direction \
fill_mode iteration_count play_state".split()
%>
// If any value list length is differs then we don't do a shorthand serialization
// either.
% for name in "duration timing_function delay direction fill_mode iteration_count play_state".split():
if len != extract_value(self.animation_${name}).map(|i| i.0.len()).unwrap_or(0) {
return dest.write_str("")
% for name in subproperties:
if len != self.animation_${name}.0.len() {
return Ok(())
}
% endfor
let mut first = true;
for i in 0..len {
% for name in "duration timing_function delay direction fill_mode iteration_count play_state name".split():
let ${name} = if let DeclaredValue::Value(ref arr) = *self.animation_${name} {
&arr.0[i]
} else {
unreachable!()
};
% endfor
if first {
first = false;
} else {
if i != 0 {
try!(write!(dest, ", "));
}
% for name in "duration timing_function delay direction fill_mode iteration_count play_state".split():
try!(${name}.to_css(dest));
try!(write!(dest, " "));
% endfor
try!(name.to_css(dest));
% for name in subproperties:
self.animation_${name}.0[i].to_css(dest)?;
dest.write_str(" ")?;
% endfor
self.animation_name.0[i].to_css(dest)?;
}
Ok(())
}
@ -354,16 +311,7 @@ macro_rules! try_parse_one {
// Serializes into the single keyword value if both scroll-snap-type and scroll-snap-type-y are same.
// Otherwise into an empty string. This is done to match Gecko's behaviour.
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let x_and_y_equal = match (self.scroll_snap_type_x, self.scroll_snap_type_y) {
(&DeclaredValue::Value(ref x_value), &DeclaredValue::Value(ref y_value)) => {
*x_value == *y_value
},
(&DeclaredValue::CSSWideKeyword(x_keyword),
&DeclaredValue::CSSWideKeyword(y_keyword)) => x_keyword == y_keyword,
(x, y) => { *x == *y },
};
if x_and_y_equal {
if self.scroll_snap_type_x == self.scroll_snap_type_y {
self.scroll_snap_type_x.to_css(dest)
} else {
Ok(())

View file

@ -98,28 +98,11 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let mut need_space = false;
if let DeclaredValue::Value(ref width) = *self.column_rule_width {
try!(width.to_css(dest));
need_space = true;
}
if let DeclaredValue::Value(ref style) = *self.column_rule_style {
if need_space {
try!(write!(dest, " "));
}
try!(style.to_css(dest));
need_space = true;
}
if let DeclaredValue::Value(ref color) = *self.column_rule_color {
if need_space {
try!(write!(dest, " "));
}
try!(color.to_css(dest));
}
Ok(())
self.column_rule_width.to_css(dest)?;
dest.write_str(" ")?;
self.column_rule_style.to_css(dest)?;
dest.write_str(" ")?;
self.column_rule_color.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -97,39 +97,25 @@
// This may be a bit off, unsure, possibly needs changes
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if let DeclaredValue::Value(ref style) = *self.font_style {
try!(style.to_css(dest));
try!(write!(dest, " "));
}
self.font_style.to_css(dest)?;
dest.write_str(" ")?;
self.font_variant.to_css(dest)?;
dest.write_str(" ")?;
self.font_weight.to_css(dest)?;
dest.write_str(" ")?;
self.font_stretch.to_css(dest)?;
dest.write_str(" ")?;
if let DeclaredValue::Value(ref variant) = *self.font_variant {
try!(variant.to_css(dest));
try!(write!(dest, " "));
}
if let DeclaredValue::Value(ref weight) = *self.font_weight {
try!(weight.to_css(dest));
try!(write!(dest, " "));
}
if let DeclaredValue::Value(ref stretch) = *self.font_stretch {
try!(stretch.to_css(dest));
try!(write!(dest, " "));
}
try!(self.font_size.to_css(dest));
if let DeclaredValue::Value(ref height) = *self.line_height {
match *height {
line_height::SpecifiedValue::Normal => {},
_ => {
try!(write!(dest, "/"));
try!(height.to_css(dest));
}
self.font_size.to_css(dest)?;
match *self.line_height {
line_height::SpecifiedValue::Normal => {},
_ => {
dest.write_str("/")?;
self.line_height.to_css(dest)?;
}
}
try!(write!(dest, " "));
dest.write_str(" ")?;
self.font_family.to_css(dest)
}
}

View file

@ -22,16 +22,11 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
if let DeclaredValue::Value(ref start) = *self.marker_start {
if let DeclaredValue::Value(ref mid) = *self.marker_mid {
if let DeclaredValue::Value(ref end) = *self.marker_end {
if start == mid && mid == end {
start.to_css(dest)?;
}
}
}
if self.marker_start == self.marker_mid && self.marker_mid == self.marker_end {
self.marker_start.to_css(dest)
} else {
Ok(())
}
Ok(())
}
}
</%helpers:shorthand>

View file

@ -40,19 +40,9 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let mut style_present = false;
if let DeclaredValue::Value(ref value) = *self.text_emphasis_style {
style_present = true;
try!(value.to_css(dest));
}
if let DeclaredValue::Value(ref color) = *self.text_emphasis_color {
if style_present {
try!(write!(dest, " "));
}
try!(color.to_css(dest));
}
Ok(())
self.text_emphasis_style.to_css(dest)?;
dest.write_str(" ")?;
self.text_emphasis_color.to_css(dest)
}
}
</%helpers:shorthand>
@ -98,20 +88,9 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let mut style_present = false;
if let DeclaredValue::Value(ref width) = *self._webkit_text_stroke_width {
style_present = true;
try!(width.to_css(dest));
}
if let DeclaredValue::Value(ref color) = *self._webkit_text_stroke_color {
if style_present {
try!(write!(dest, " "));
}
try!(color.to_css(dest));
}
Ok(())
self._webkit_text_stroke_width.to_css(dest)?;
dest.write_str(" ")?;
self._webkit_text_stroke_color.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -98,27 +98,11 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self.list_style_position {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
try!(write!(dest, "outside")),
_ => try!(self.list_style_position.to_css(dest))
}
try!(write!(dest, " "));
match *self.list_style_image {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
try!(write!(dest, "none")),
_ => try!(self.list_style_image.to_css(dest))
};
try!(write!(dest, " "));
match *self.list_style_type {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
write!(dest, "disc"),
_ => self.list_style_type.to_css(dest)
}
self.list_style_position.to_css(dest)?;
dest.write_str(" ")?;
self.list_style_image.to_css(dest)?;
dest.write_str(" ")?;
self.list_style_type.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -122,111 +122,60 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// mako doesn't like ampersands following `<`
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
use std::cmp;
let mut len = 0;
% for name in "image mode position_x position_y size repeat origin clip composite".split():
len = cmp::max(len, extract_value(self.mask_${name}).map(|i| i.0.len())
.unwrap_or(0));
% endfor
use properties::longhands::mask_origin::single_value::computed_value::T as Origin;
use properties::longhands::mask_clip::single_value::computed_value::T as Clip;
// There should be at least one declared value
let len = self.mask_image.0.len();
if len == 0 {
return dest.write_str("")
return Ok(());
}
% for name in "mode position_x position_y size repeat origin clip composite".split():
if self.mask_${name}.0.len() != len {
return Ok(());
}
% endfor
for i in 0..len {
if i > 0 {
try!(dest.write_str(", "));
dest.write_str(", ")?;
}
% for name in "image mode position_x position_y size repeat origin clip composite".split():
let ${name} = if let DeclaredValue::Value(ref arr) = *self.mask_${name} {
arr.0.get(i % arr.0.len())
} else {
None
};
let ${name} = &self.mask_${name}.0[i];
% endfor
if let Some(image) = image {
try!(image.to_css(dest));
} else {
try!(write!(dest, "none"));
}
try!(write!(dest, " "));
if let Some(mode) = mode {
try!(mode.to_css(dest));
} else {
try!(write!(dest, "match-source"));
}
try!(write!(dest, " "));
try!(position_x.unwrap_or(&mask_position_x::single_value
::get_initial_position_value())
.to_css(dest));
try!(write!(dest, " "));
try!(position_y.unwrap_or(&mask_position_y::single_value
::get_initial_position_value())
.to_css(dest));
if let Some(size) = size {
try!(write!(dest, " / "));
try!(size.to_css(dest));
}
try!(write!(dest, " "));
if let Some(repeat) = repeat {
try!(repeat.to_css(dest));
} else {
try!(write!(dest, "repeat"));
}
image.to_css(dest)?;
dest.write_str(" ")?;
mode.to_css(dest)?;
dest.write_str(" ")?;
position_x.to_css(dest)?;
dest.write_str(" ")?;
position_y.to_css(dest)?;
dest.write_str(" / ")?;
size.to_css(dest)?;
dest.write_str(" ")?;
repeat.to_css(dest)?;
dest.write_str(" ")?;
match (origin, clip) {
(Some(origin), Some(clip)) => {
use properties::longhands::mask_origin::single_value::computed_value::T as Origin;
use properties::longhands::mask_clip::single_value::computed_value::T as Clip;
try!(write!(dest, " "));
match (origin, clip) {
(&Origin::padding_box, &Clip::padding_box) => {
try!(origin.to_css(dest));
},
(&Origin::border_box, &Clip::border_box) => {
try!(origin.to_css(dest));
},
(&Origin::content_box, &Clip::content_box) => {
try!(origin.to_css(dest));
},
_ => {
try!(origin.to_css(dest));
try!(write!(dest, " "));
try!(clip.to_css(dest));
}
}
(&Origin::padding_box, &Clip::padding_box) => {
try!(origin.to_css(dest));
},
_ => {}
};
try!(write!(dest, " "));
if let Some(composite) = composite {
try!(composite.to_css(dest));
} else {
try!(write!(dest, "add"));
(&Origin::border_box, &Clip::border_box) => {
try!(origin.to_css(dest));
},
(&Origin::content_box, &Clip::content_box) => {
try!(origin.to_css(dest));
},
_ => {
try!(origin.to_css(dest));
try!(write!(dest, " "));
try!(clip.to_css(dest));
}
}
dest.write_str(" ")?;
composite.to_css(dest)?;
}
Ok(())
@ -270,45 +219,14 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// mako doesn't like ampersands following `<`
fn extract_value<T>(x: &DeclaredValue<T>) -> Option< &T> {
match *x {
DeclaredValue::Value(ref val) => Some(val),
_ => None,
}
}
use std::cmp;
let mut len = 0;
% for name in "x y".split():
len = cmp::max(len, extract_value(self.mask_position_${name})
.map(|i| i.0.len())
.unwrap_or(0));
% endfor
// There should be at least one declared value
if len == 0 {
return dest.write_str("")
let len = self.mask_position_x.0.len();
if len == 0 || self.mask_position_y.0.len() != len {
return Ok(());
}
for i in 0..len {
% for name in "x y".split():
let position_${name} = if let DeclaredValue::Value(ref arr) =
*self.mask_position_${name} {
arr.0.get(i % arr.0.len())
} else {
None
};
% endfor
try!(position_x.unwrap_or(&mask_position_x::single_value
::get_initial_position_value())
.to_css(dest));
try!(write!(dest, " "));
try!(position_y.unwrap_or(&mask_position_y::single_value
::get_initial_position_value())
.to_css(dest));
self.mask_position_x.0[i].to_css(dest)?;
self.mask_position_y.0[i].to_css(dest)?;
}
Ok(())

View file

@ -55,20 +55,9 @@
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.outline_width.to_css(dest));
try!(write!(dest, " "));
match *self.outline_style {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
try!(write!(dest, "none")),
_ => try!(self.outline_style.to_css(dest))
};
match *self.outline_color {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) => Ok(()),
_ => {
try!(write!(dest, " "));
self.outline_color.to_css(dest)
}
}
try!(self.outline_style.to_css(dest));
try!(write!(dest, " "));
self.outline_color.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -39,19 +39,9 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self.flex_direction {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
try!(write!(dest, "row")),
_ => try!(self.flex_direction.to_css(dest))
};
try!(write!(dest, " "));
match *self.flex_wrap {
DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial) =>
write!(dest, "nowrap"),
_ => self.flex_wrap.to_css(dest)
}
self.flex_direction.to_css(dest)?;
dest.write_str(" ")?;
self.flex_wrap.to_css(dest)
}
}
</%helpers:shorthand>

View file

@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::Color;
use properties::DeclaredValue;
use style_traits::ToCss;
use values::specified::{BorderStyle, CSSColor};
use std::fmt;
@ -60,35 +59,16 @@ pub fn serialize_four_sides<W, I>(dest: &mut W,
}
fn serialize_directional_border<W, I,>(dest: &mut W,
width: &DeclaredValue<I>,
style: &DeclaredValue<BorderStyle>,
color: &DeclaredValue<CSSColor>)
-> fmt::Result where W: fmt::Write, I: ToCss {
match *width {
DeclaredValue::Value(ref width) => {
try!(width.to_css(dest));
},
_ => {
try!(write!(dest, "medium"));
}
};
try!(write!(dest, " "));
match *style {
DeclaredValue::Value(ref style) => {
try!(style.to_css(dest));
},
_ => {
try!(write!(dest, "none"));
}
};
match *color {
DeclaredValue::Value(ref color) if color.parsed != Color::CurrentColor => {
try!(write!(dest, " "));
color.to_css(dest)
},
_ => Ok(())
width: &I,
style: &BorderStyle,
color: &CSSColor)
-> fmt::Result where W: fmt::Write, I: ToCss {
width.to_css(dest)?;
dest.write_str(" ")?;
style.to_css(dest)?;
if color.parsed != Color::CurrentColor {
dest.write_str(" ")?;
color.to_css(dest)?;
}
Ok(())
}

View file

@ -48,29 +48,13 @@
impl<'a> LonghandsToSerialize<'a> {
fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self.text_decoration_line {
DeclaredValue::Value(ref line) => {
try!(line.to_css(dest));
},
_ => {
try!(write!(dest, "none"));
}
};
if let DeclaredValue::Value(ref style) = *self.text_decoration_style {
if *style != text_decoration_style::computed_value::T::solid {
try!(write!(dest, " "));
try!(style.to_css(dest));
}
self.text_decoration_line.to_css(dest)?;
dest.write_str(" ")?;
self.text_decoration_style.to_css(dest)?;
if self.text_decoration_color.parsed != CSSParserColor::CurrentColor {
dest.write_str(" ")?;
self.text_decoration_color.to_css(dest)?;
}
if let DeclaredValue::Value(ref color) = *self.text_decoration_color {
if color.parsed != CSSParserColor::CurrentColor {
try!(write!(dest, " "));
try!(color.to_css(dest));
}
}
Ok(())
}
}