diff options
-rw-r--r-- | components/style/properties/gecko.mako.rs | 3 | ||||
-rw-r--r-- | components/style/properties/longhand/border.mako.rs | 110 | ||||
-rw-r--r-- | components/style/values/computed/length.rs | 8 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/computed/rect.rs | 11 | ||||
-rw-r--r-- | components/style/values/generics/mod.rs | 1 | ||||
-rw-r--r-- | components/style/values/generics/rect.rs | 110 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 6 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/specified/rect.rs | 21 |
10 files changed, 169 insertions, 105 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index fa7d5c67271..d2416781330 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -959,8 +959,7 @@ fn static_assert() { pub fn set_border_image_outset(&mut self, v: longhands::border_image_outset::computed_value::T) { % for side in SIDES: - v.${side.index}.to_gecko_style_coord(&mut self.gecko.mBorderImageOutset - .data_at_mut(${side.index})); + v.${side.ident}.to_gecko_style_coord(&mut self.gecko.mBorderImageOutset.data_at_mut(${side.index})); % endfor } diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 8c775b682c0..82169a9a943 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -200,109 +200,13 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", has_uncacheable_values=False, boxed="True")} -<%helpers:longhand name="border-image-outset" animation_value_type="none" - spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset"> - use std::fmt; - use style_traits::ToCss; - use values::specified::{LengthOrNumber, Number}; - - pub mod computed_value { - use values::computed::LengthOrNumber; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T(pub LengthOrNumber, pub LengthOrNumber, - pub LengthOrNumber, pub LengthOrNumber); - } - - #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue(pub Vec<LengthOrNumber>); - - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - try!(self.0.to_css(dest)); - try!(dest.write_str(" ")); - try!(self.1.to_css(dest)); - try!(dest.write_str(" ")); - try!(self.2.to_css(dest)); - try!(dest.write_str(" ")); - self.3.to_css(dest) - } - } - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - try!(self.0[0].to_css(dest)); - for value in self.0.iter().skip(1) { - try!(dest.write_str(" ")); - try!(value.to_css(dest)); - } - Ok(()) - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(Either::Second(0.0), Either::Second(0.0), - Either::Second(0.0), Either::Second(0.0)) - } - - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue(vec![Either::Second(Number::new(0.0))]) - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - let length = self.0.len(); - match length { - 4 => computed_value::T(self.0[0].to_computed_value(context), - self.0[1].to_computed_value(context), - self.0[2].to_computed_value(context), - self.0[3].to_computed_value(context)), - 3 => computed_value::T(self.0[0].to_computed_value(context), - self.0[1].to_computed_value(context), - self.0[2].to_computed_value(context), - self.0[1].to_computed_value(context)), - 2 => computed_value::T(self.0[0].to_computed_value(context), - self.0[1].to_computed_value(context), - self.0[0].to_computed_value(context), - self.0[1].to_computed_value(context)), - 1 => computed_value::T(self.0[0].to_computed_value(context), - self.0[0].to_computed_value(context), - self.0[0].to_computed_value(context), - self.0[0].to_computed_value(context)), - _ => unreachable!(), - } - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue(vec![ToComputedValue::from_computed_value(&computed.0), - ToComputedValue::from_computed_value(&computed.1), - ToComputedValue::from_computed_value(&computed.2), - ToComputedValue::from_computed_value(&computed.3)]) - } - } - - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { - let mut values = vec![]; - for _ in 0..4 { - let value = input.try(|input| LengthOrNumber::parse_non_negative(context, input)); - match value { - Ok(val) => values.push(val), - Err(_) => break, - } - } - - if values.len() > 0 { - Ok(SpecifiedValue(values)) - } else { - Err(()) - } - } -</%helpers:longhand> +${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", + parse_method="parse_non_negative", + initial_value="computed::LengthOrNumber::zero().into()", + initial_specified_value="specified::LengthOrNumber::zero().into()", + spec="https://drafts.csswg.org/css-backgrounds/#border-image-outset", + animation_value_type="none", + boxed=True)} <%helpers:longhand name="border-image-repeat" animation_value_type="none" spec="https://drafts.csswg.org/css-backgrounds/#border-image-repeat"> diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index e2dac197652..1ed038941a7 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -603,6 +603,14 @@ pub type LengthOrAuto = Either<Length, Auto>; /// Either a computed `<length>` or a `<number>` value. pub type LengthOrNumber = Either<Length, Number>; +impl LengthOrNumber { + /// Returns `0`. + #[inline] + pub fn zero() -> Self { + Either::Second(0.) + } +} + /// Either a computed `<length>` or the `normal` keyword. pub type LengthOrNormal = Either<Length, Normal>; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 7251b315796..97d3ca76114 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -25,6 +25,7 @@ use super::specified; pub use app_units::Au; pub use cssparser::Color as CSSColor; pub use self::image::{Gradient, GradientItem, ImageLayer, LineDirection, Image, ImageRect}; +pub use self::rect::LengthOrNumberRect; pub use super::{Auto, Either, None_}; #[cfg(feature = "gecko")] pub use super::specified::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; @@ -40,6 +41,7 @@ pub mod basic_shape; pub mod image; pub mod length; pub mod position; +pub mod rect; /// A `Context` is all the data a specified value could ever need to compute /// itself and be transformed to a computed value. diff --git a/components/style/values/computed/rect.rs b/components/style/values/computed/rect.rs new file mode 100644 index 00000000000..46fcdc65583 --- /dev/null +++ b/components/style/values/computed/rect.rs @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Computed types for CSS borders. + +use values::computed::length::LengthOrNumber; +use values::generics::rect::Rect; + +/// A specified rectangle made of four `<length-or-number>` values. +pub type LengthOrNumberRect = Rect<LengthOrNumber>; diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 65fca55feb6..de5e043c52e 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -19,6 +19,7 @@ pub mod basic_shape; pub mod grid; pub mod image; pub mod position; +pub mod rect; #[derive(Clone, Debug, PartialEq, ToComputedValue)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/values/generics/rect.rs b/components/style/values/generics/rect.rs new file mode 100644 index 00000000000..767ce2223e4 --- /dev/null +++ b/components/style/values/generics/rect.rs @@ -0,0 +1,110 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Generic types for CSS values that are composed of four sides. + +use cssparser::Parser; +use parser::{Parse, ParserContext}; +use std::fmt; +use style_traits::ToCss; + +/// A CSS value made of four sides: top, right, bottom, and left. +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct Rect<T> { + /// Top + pub top: T, + /// Right. + pub right: T, + /// Bottom. + pub bottom: T, + /// Left. + pub left: T, +} + +impl<T> Rect<T> { + /// Returns a new `Rect<T>` value. + pub fn new(top: T, right: T, bottom: T, left: T) -> Self { + Rect { + top: top, + right: right, + bottom: bottom, + left: left, + } + } +} + +impl<T> Rect<T> + where T: Clone +{ + /// Parses a new `Rect<T>` value with the given parse function. + pub fn parse_with<Parse>( + context: &ParserContext, + input: &mut Parser, + parse: Parse) + -> Result<Self, ()> + where Parse: Fn(&ParserContext, &mut Parser) -> Result<T, ()> + { + let top = parse(context, input)?; + let right = if let Ok(right) = input.try(|i| parse(context, i)) { right } else { + // <top> + return Ok(Self::new(top.clone(), top.clone(), top.clone(), top)); + }; + let bottom = if let Ok(bottom) = input.try(|i| parse(context, i)) { bottom } else { + // <top> <right> + return Ok(Self::new(top.clone(), right.clone(), top, right)); + }; + let left = if let Ok(left) = input.try(|i| parse(context, i)) { left } else { + // <top> <right> <bottom> + return Ok(Self::new(top, right.clone(), bottom, right)); + }; + // <top> <right> <bottom> <left> + Ok(Self::new(top, right, bottom, left)) + } +} + +impl<T> From<T> for Rect<T> + where T: Clone +{ + #[inline] + fn from(value: T) -> Self { + Self::new(value.clone(), value.clone(), value.clone(), value) + } +} + +impl<T> Parse for Rect<T> + where T: Clone + Parse +{ + #[inline] + fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + Self::parse_with(context, input, T::parse) + } +} + +impl<T> ToCss for Rect<T> + where T: PartialEq + ToCss +{ + fn to_css<W>(&self, dest: &mut W) -> fmt::Result + where W: fmt::Write, + { + self.top.to_css(dest)?; + let same_vertical = self.top == self.bottom; + let same_horizontal = self.right == self.left; + if same_vertical && same_horizontal && self.top == self.right { + return Ok(()); + } + dest.write_str(" ")?; + self.right.to_css(dest)?; + if same_vertical && same_horizontal { + return Ok(()); + } + dest.write_str(" ")?; + self.bottom.to_css(dest)?; + if same_horizontal { + return Ok(()); + } + dest.write_str(" ")?; + self.left.to_css(dest) + } +} diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index e37aad81f0e..ef4083544ae 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -1180,6 +1180,12 @@ impl LengthOrNumber { Length::parse_non_negative(context, input).map(Either::First) } + + /// Returns `0`. + #[inline] + pub fn zero() -> Self { + Either::Second(Number::new(0.)) + } } /// A value suitable for a `min-width` or `min-height` property. diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 8d75e0c4a07..87a46823d5f 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -30,6 +30,7 @@ use values::specified::calc::CalcNode; #[cfg(feature = "gecko")] pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; +pub use self::rect::LengthOrNumberRect; pub use self::color::Color; pub use super::generics::grid::GridLine; pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; @@ -50,6 +51,7 @@ pub mod grid; pub mod image; pub mod length; pub mod position; +pub mod rect; /// Common handling for the specified value CSS url() values. pub mod url { diff --git a/components/style/values/specified/rect.rs b/components/style/values/specified/rect.rs new file mode 100644 index 00000000000..11c03e57f7b --- /dev/null +++ b/components/style/values/specified/rect.rs @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Computed types for CSS borders. + +use cssparser::Parser; +use parser::ParserContext; +use values::generics::rect::Rect; +use values::specified::length::LengthOrNumber; + +/// A specified rectangle made of four `<length-or-number>` values. +pub type LengthOrNumberRect = Rect<LengthOrNumber>; + +impl LengthOrNumberRect { + /// Parses a `LengthOrNumberRect`, rejecting negative values. + #[inline] + pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { + Rect::parse_with(context, input, LengthOrNumber::parse_non_negative) + } +} |