diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 780ca9e96074..52d8761469e1 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -64,7 +64,6 @@ use style::computed_values::position::T as StylePosition; use style::computed_values::visibility::T as Visibility; use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::properties::ComputedValues; -use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword; use style::properties::style_structs; use style::servo::restyle_damage::ServoRestyleDamage; use style::values::{Either, RGBA}; @@ -73,6 +72,7 @@ use style::values::computed::effects::SimpleShadow; use style::values::generics::background::BackgroundSize; use style::values::generics::effects::Filter; use style::values::generics::image::{GradientKind, Image, PaintWorklet}; +use style::values::specified::border::RepeatKeyword; use style_traits::CSSPixel; use style_traits::ToCss; use style_traits::cursor::Cursor; diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index e74c2f6fd1fd..824ed7836e23 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1783,7 +1783,7 @@ fn static_assert() { %> pub fn set_border_image_repeat(&mut self, v: longhands::border_image_repeat::computed_value::T) { - use properties::longhands::border_image_repeat::computed_value::RepeatKeyword; + use values::specified::border::RepeatKeyword; use gecko_bindings::structs::StyleBorderImageRepeat; % for i, side in enumerate(["H", "V"]): @@ -1805,7 +1805,7 @@ fn static_assert() { } pub fn clone_border_image_repeat(&self) -> longhands::border_image_repeat::computed_value::T { - use properties::longhands::border_image_repeat::computed_value::RepeatKeyword; + use values::specified::border::RepeatKeyword; use gecko_bindings::structs::StyleBorderImageRepeat; % for side in ["H", "V"]: diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 11fdf30b9831..a8cc6307a602 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -221,57 +221,15 @@ ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", flags="APPLIES_TO_FIRST_LETTER", boxed=True)} -<%helpers:longhand name="border-image-repeat" animation_value_type="discrete" - flags="APPLIES_TO_FIRST_LETTER" - spec="https://drafts.csswg.org/css-backgrounds/#border-image-repeat"> - pub mod computed_value { - pub use super::RepeatKeyword; - - #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] - pub struct T(pub RepeatKeyword, pub RepeatKeyword); - } - - #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] - pub struct SpecifiedValue(pub RepeatKeyword, - pub Option); - - define_css_keyword_enum!(RepeatKeyword: - "stretch" => Stretch, - "repeat" => Repeat, - "round" => Round, - "space" => Space); - - #[inline] - pub fn get_initial_value() -> computed_value::T { - 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; - - #[inline] - fn to_computed_value(&self, _context: &Context) -> computed_value::T { - computed_value::T(self.0, self.1.unwrap_or(self.0)) - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue(computed.0, Some(computed.1)) - } - } - - pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { - let first = RepeatKeyword::parse(input)?; - let second = input.try(RepeatKeyword::parse).ok(); - - Ok(SpecifiedValue(first, second)) - } - +${helpers.predefined_type( + "border-image-repeat", + "BorderImageRepeat", + "computed::BorderImageRepeat::repeat()", + initial_specified_value="specified::BorderImageRepeat::repeat()", + animation_value_type="discrete", + spec="https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat", + flags="APPLIES_TO_FIRST_LETTER", +)} ${helpers.predefined_type("border-image-width", "BorderImageWidth", initial_value="computed::BorderImageWidth::all(computed::BorderImageSideWidth::one())", diff --git a/components/style/values/computed/border.rs b/components/style/values/computed/border.rs index d8f24a2266b1..b3bef732f07e 100644 --- a/components/style/values/computed/border.rs +++ b/components/style/values/computed/border.rs @@ -5,8 +5,10 @@ //! Computed types for CSS values related to borders. use app_units::Au; +use std::fmt; +use style_traits::ToCss; use values::animated::ToAnimatedZero; -use values::computed::{Number, NumberOrPercentage}; +use values::computed::{Context, Number, NumberOrPercentage, ToComputedValue}; use values::computed::length::{LengthOrPercentage, NonNegativeLength}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; @@ -15,6 +17,7 @@ use values::generics::border::BorderRadius as GenericBorderRadius; use values::generics::border::BorderSpacing as GenericBorderSpacing; use values::generics::rect::Rect; use values::generics::size::Size; +use values::specified::border::{BorderImageRepeat as SpecifiedBorderImageRepeat, RepeatKeyword}; /// A computed value for the `border-image-width` property. pub type BorderImageWidth = Rect; @@ -81,3 +84,46 @@ impl ToAnimatedZero for BorderCornerRadius { Err(()) } } + +/// The computed value of the `border-image-repeat` property: +/// +/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat +#[derive(Clone, Debug, MallocSizeOf, PartialEq)] +pub struct BorderImageRepeat(pub RepeatKeyword, pub RepeatKeyword); + +impl BorderImageRepeat { + /// Returns the `repeat repeat` value. + pub fn repeat() -> Self { + BorderImageRepeat(RepeatKeyword::Repeat, RepeatKeyword::Repeat) + } +} + +impl ToCss for BorderImageRepeat { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let BorderImageRepeat(horizontal, vertical) = *self; + horizontal.to_css(dest)?; + if horizontal != vertical { + dest.write_str(" ")?; + vertical.to_css(dest)?; + } + Ok(()) + } +} + +impl ToComputedValue for SpecifiedBorderImageRepeat { + type ComputedValue = BorderImageRepeat; + + #[inline] + fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { + match *self { + SpecifiedBorderImageRepeat(horizontal, vertical) => { + BorderImageRepeat(horizontal, vertical.unwrap_or(horizontal)) + } + } + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + SpecifiedBorderImageRepeat(computed.0, Some(computed.1)) + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index a127b8e58b06..dc2aeecfdec8 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -34,7 +34,7 @@ pub use properties::animated_properties::TransitionProperty; pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; pub use self::angle::Angle; pub use self::background::{BackgroundSize, BackgroundRepeat}; -pub use self::border::{BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; +pub use self::border::{BorderImageRepeat, BorderImageSlice, BorderImageWidth, BorderImageSideWidth}; pub use self::border::{BorderRadius, BorderCornerRadius, BorderSpacing}; pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates}; pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian}; diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs index deb4e827b583..a35abc594822 100644 --- a/components/style/values/specified/border.rs +++ b/components/style/values/specified/border.rs @@ -6,6 +6,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; +use selectors::parser::SelectorParseErrorKind; use style_traits::ParseError; use values::computed::{self, Context, ToComputedValue}; use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; @@ -171,3 +172,44 @@ impl Parse for BorderSpacing { }).map(GenericBorderSpacing) } } + +define_css_keyword_enum! { RepeatKeyword: + "stretch" => Stretch, + "repeat" => Repeat, + "round" => Round, + "space" => Space +} + +/// The specified value for the `border-image-repeat` property. +/// +/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] +pub struct BorderImageRepeat(pub RepeatKeyword, pub Option); + +impl BorderImageRepeat { + /// Returns the `repeat` value. + #[inline] + pub fn repeat() -> Self { + BorderImageRepeat(RepeatKeyword::Repeat, None) + } +} + +impl Parse for BorderImageRepeat { + fn parse<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let ident = input.expect_ident_cloned()?; + let horizontal = match RepeatKeyword::from_ident(&ident) { + Ok(h) => h, + Err(()) => { + return Err(input.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + )); + } + }; + + let vertical = input.try(RepeatKeyword::parse).ok(); + Ok(BorderImageRepeat(horizontal, vertical)) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index e2b166079578..0ef49b6e4bac 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -29,7 +29,7 @@ pub use self::angle::Angle; pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, JustifyItems}; pub use self::background::{BackgroundRepeat, BackgroundSize}; pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; -pub use self::border::{BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing}; +pub use self::border::{BorderImageRepeat, BorderImageSideWidth, BorderRadius, BorderSideWidth, BorderSpacing}; pub use self::font::{FontSize, FontSizeAdjust, FontSynthesis, FontWeight, FontVariantAlternates}; pub use self::font::{FontFamily, FontLanguageOverride, FontVariantSettings, FontVariantEastAsian}; pub use self::font::{FontVariantLigatures, FontVariantNumeric, FontFeatureSettings};