diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index b0b8d0701ad..390767a7699 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -107,6 +107,11 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", computed_value::T(None) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(None) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -141,7 +146,7 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; - use values::specified::LengthOrNumber; + use values::specified::{LengthOrNumber, Number}; impl HasViewportPercentage for SpecifiedValue { fn has_viewport_percentage(&self) -> bool { @@ -196,6 +201,11 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", computed::LengthOrNumber::Number(0.0)) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(vec![LengthOrNumber::Number(Number(0.0))]) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -301,6 +311,11 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", computed_value::T(RepeatKeyword::Stretch, RepeatKeyword::Stretch) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(RepeatKeyword::Stretch, None) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -449,6 +464,11 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", computed_value::SingleComputedValue::Number(1.0)) } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue(vec![SingleSpecifiedValue::Number(Number(1.0))]) + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -640,6 +660,14 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", } } + #[inline] + pub fn get_initial_specified_value() -> SpecifiedValue { + SpecifiedValue { + corners: vec![PercentageOrNumber::Percentage(Percentage(1.0))], + fill: false, + } + } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index ef04ab474f0..40318441827 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -180,3 +180,131 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) } } + +// https://drafts.csswg.org/css-backgrounds-3/#border-image +<%helpers:shorthand name="border-image" products="gecko" sub_properties="border-image-outset + border-image-repeat border-image-slice border-image-source border-image-width"> + use properties::longhands::{border_image_outset, border_image_repeat, border_image_slice}; + use properties::longhands::{border_image_source, border_image_width}; + + pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { + % for name in "outset repeat slice source width".split(): + let mut border_image_${name} = border_image_${name}::get_initial_specified_value(); + % endfor + + try!(input.try(|input| { + % for name in "outset repeat slice source width".split(): + let mut ${name} = None; + % endfor + loop { + if slice.is_none() { + if let Ok(value) = input.try(|input| border_image_slice::parse(context, input)) { + slice = Some(value); + // Parse border image width and outset, if applicable. + let maybe_width_outset: Result<_, ()> = input.try(|input| { + try!(input.expect_delim('/')); + + // Parse border image width, if applicable. + let w = input.try(|input| + border_image_width::parse(context, input)).ok(); + + // Parse border image outset if applicable. + let o = input.try(|input| { + try!(input.expect_delim('/')); + border_image_outset::parse(context, input) + }).ok(); + Ok((w, o)) + }); + if let Ok((w, o)) = maybe_width_outset { + width = w; + outset = o; + } + + continue + } + } + % for name in "source repeat".split(): + if ${name}.is_none() { + if let Ok(value) = input.try(|input| border_image_${name}::parse(context, input)) { + ${name} = Some(value); + continue + } + } + % endfor + break + } + let mut any = false; + % for name in "outset repeat slice source width".split(): + any = any || ${name}.is_some(); + % endfor + if any { + % for name in "outset repeat slice source width".split(): + if let Some(b_${name}) = ${name} { + border_image_${name} = b_${name}; + } + % endfor + Ok(()) + } else { + Err(()) + } + })); + + Ok(Longhands { + % for name in "outset repeat slice source width".split(): + border_image_${name}: Some(border_image_${name}), + % endfor + }) + } + + impl<'a> LonghandsToSerialize<'a> { + fn to_css_declared(&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(()) + } + } +