From 3c3e7f63eeb683d55f5ec6e3a415c70db46e9c96 Mon Sep 17 00:00:00 2001 From: cku Date: Wed, 3 May 2017 13:23:35 +0800 Subject: [PATCH 1/2] Stylo: Implement {specified|computed}::LayerImage. --- components/style/properties/gecko.mako.rs | 19 +--- components/style/properties/helpers.mako.rs | 2 +- .../properties/longhand/background.mako.rs | 83 ++------------ .../style/properties/longhand/border.mako.rs | 83 ++------------ .../style/properties/longhand/svg.mako.rs | 105 ++---------------- components/style/values/computed/image.rs | 14 +++ components/style/values/computed/mod.rs | 2 +- components/style/values/specified/image.rs | 49 ++++++++ components/style/values/specified/mod.rs | 2 +- 9 files changed, 96 insertions(+), 263 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index e6aab102506..6fc0a5e7172 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -921,13 +921,13 @@ fn static_assert() { need_clone=True) %> % endfor - pub fn set_border_image_source(&mut self, v: longhands::border_image_source::computed_value::T) { + pub fn set_border_image_source(&mut self, image: longhands::border_image_source::computed_value::T) { unsafe { // Prevent leaking of the last elements we did set Gecko_SetNullImageValue(&mut self.gecko.mBorderImageSource); } - if let Some(image) = v.0 { + if let Some(image) = image.0 { self.gecko.mBorderImageSource.set(image, &mut false) } } @@ -2756,18 +2756,9 @@ fn static_assert() { for (image, geckoimage) in images.0.into_iter().zip(self.gecko.${image_layers_field} .mLayers.iter_mut()) { - % if shorthand == "background": - if let Some(image) = image.0 { - geckoimage.mImage.set(image, cacheable) - } - % else: - use properties::longhands::mask_image::single_value::computed_value::T; - match image { - T::Image(image) => geckoimage.mImage.set(image, cacheable), - _ => () - } - % endif - + if let Some(image) = image.0 { + geckoimage.mImage.set(image, cacheable) + } } } diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 3c3bb537320..b69057f916c 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -309,7 +309,7 @@ computed, inherited_style.get_font()); % else: - % if property.has_uncacheable_values: + % if property.has_uncacheable_values == "True": context.mutate_style().mutate_${data.current_style_struct.name_lower}() .set_${property.ident}(computed, cacheable ${maybe_wm}); % else: diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 726003f9571..3689ea61c02 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -12,82 +12,13 @@ ${helpers.predefined_type("background-color", "CSSColor", spec="https://drafts.csswg.org/css-backgrounds/#background-color", animation_value_type="IntermediateColor", complex_color=True)} -<%helpers:vector_longhand name="background-image" animation_value_type="none" - spec="https://drafts.csswg.org/css-backgrounds/#the-background-image" - has_uncacheable_values="${product == 'gecko'}"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; - use values::specified::Image; - - pub mod computed_value { - use values::computed; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T(pub Option); - } - - impl ToCss for computed_value::T { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.0 { - None => dest.write_str("none"), - Some(ref image) => image.to_css(dest), - } - } - } - - no_viewport_percentage!(SpecifiedValue); - - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue(pub Option); - - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - SpecifiedValue(Some(ref image)) => image.to_css(dest), - SpecifiedValue(None) => dest.write_str("none"), - } - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(None) - } - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue(None) - } - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - Ok(SpecifiedValue(None)) - } else { - Ok(SpecifiedValue(Some(try!(Image::parse(context, input))))) - } - } - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match *self { - SpecifiedValue(None) => computed_value::T(None), - SpecifiedValue(Some(ref image)) => - computed_value::T(Some(image.to_computed_value(context))), - } - } - - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - match *computed { - computed_value::T(None) => SpecifiedValue(None), - computed_value::T(Some(ref image)) => - SpecifiedValue(Some(ToComputedValue::from_computed_value(image))), - } - } - } - +${helpers.predefined_type("background-image", "LayerImage", + initial_value="computed_value::T(None)", + initial_specified_value="SpecifiedValue(None)", + spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", + vector="True", + animation_value_type="none", + has_uncacheable_values="True" if product == "gecko" else "False")} <%helpers:predefined_type name="background-position-x" type="position::HorizontalPosition" initial_value="computed::position::HorizontalPosition::zero()" diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index b43363edf48..6f07db69038 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -190,81 +190,14 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box", spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-float-edge)", animation_value_type="none")} -<%helpers:longhand name="border-image-source" animation_value_type="none" boxed="True" - spec="https://drafts.csswg.org/css-backgrounds/#border-image-source"> - use std::fmt; - use style_traits::ToCss; - use values::HasViewportPercentage; - use values::specified::Image; - - no_viewport_percentage!(SpecifiedValue); - - pub mod computed_value { - use values::computed; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct T(pub Option); - } - - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue(pub Option); - - impl ToCss for computed_value::T { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.0 { - Some(ref image) => image.to_css(dest), - None => dest.write_str("none"), - } - } - } - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self.0 { - Some(ref image) => image.to_css(dest), - None => dest.write_str("none"), - } - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T(None) - } - - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue(None) - } - - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match self.0 { - Some(ref image) => computed_value::T(Some(image.to_computed_value(context))), - None => computed_value::T(None), - } - } - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - match computed.0 { - Some(ref image) => - SpecifiedValue(Some(ToComputedValue::from_computed_value(image))), - None => SpecifiedValue(None), - } - } - } - - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(SpecifiedValue(None)); - } - - Ok(SpecifiedValue(Some(try!(Image::parse(context, input))))) - } - +${helpers.predefined_type("border-image-source", "LayerImage", + initial_value="computed_value::T(None)", + initial_specified_value="SpecifiedValue(None)", + spec="https://drafts.csswg.org/css-backgrounds/#the-background-image", + vector=False, + animation_value_type="none", + 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"> diff --git a/components/style/properties/longhand/svg.mako.rs b/components/style/properties/longhand/svg.mako.rs index 45cb125bf33..500c8cc1460 100644 --- a/components/style/properties/longhand/svg.mako.rs +++ b/components/style/properties/longhand/svg.mako.rs @@ -190,98 +190,13 @@ ${helpers.single_keyword("mask-composite", extra_prefixes="webkit", animation_value_type="none", spec="https://drafts.fxtf.org/css-masking/#propdef-mask-composite")} - -<%helpers:vector_longhand name="mask-image" products="gecko" animation_value_type="none" extra_prefixes="webkit" - has_uncacheable_values="${product == 'gecko'}" - flags="CREATES_STACKING_CONTEXT", - spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image"> - use std::fmt; - use style_traits::ToCss; - use stylearc::Arc; - use values::specified::Image; - use values::specified::url::SpecifiedUrl; - use values::HasViewportPercentage; - - pub mod computed_value { - use std::fmt; - use style_traits::ToCss; - use values::computed; - use values::specified::url::SpecifiedUrl; - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum T { - Image(computed::Image), - None - } - - impl ToCss for T { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - T::None => dest.write_str("none"), - T::Image(ref image) => image.to_css(dest), - } - } - } - } - - no_viewport_percentage!(SpecifiedValue); - - #[derive(Debug, Clone, PartialEq)] - #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub enum SpecifiedValue { - Image(Image), - None - } - - impl ToCss for SpecifiedValue { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - SpecifiedValue::Image(ref image) => image.to_css(dest), - SpecifiedValue::None => dest.write_str("none"), - } - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - computed_value::T::None - } - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::None - } - pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - Ok(SpecifiedValue::None) - } else { - let image = try!(Image::parse(context, input)); - match image { - Image::Url(url_value) => { - Ok(SpecifiedValue::Image(Image::Url(url_value))) - } - image => Ok(SpecifiedValue::Image(image)) - } - } - } - impl ToComputedValue for SpecifiedValue { - type ComputedValue = computed_value::T; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed_value::T { - match *self { - SpecifiedValue::None => computed_value::T::None, - SpecifiedValue::Image(ref image) => - computed_value::T::Image(image.to_computed_value(context)), - } - } - - #[inline] - fn from_computed_value(computed: &computed_value::T) -> Self { - match *computed { - computed_value::T::None => SpecifiedValue::None, - computed_value::T::Image(ref image) => - SpecifiedValue::Image(ToComputedValue::from_computed_value(image)), - } - } - } - +${helpers.predefined_type("mask-image", "LayerImage", + initial_value="computed_value::T(None)", + initial_specified_value="SpecifiedValue(None)", + spec="https://drafts.fxtf.org/css-masking/#propdef-mask-image", + vector=True, + products="gecko", + extra_prefixes="webkit", + animation_value_type="none", + flags="CREATES_STACKING_CONTEXT", + has_uncacheable_values="True" if product == "gecko" else "False")} diff --git a/components/style/values/computed/image.rs b/components/style/values/computed/image.rs index 607cc8f2025..01a6106f3d3 100644 --- a/components/style/values/computed/image.rs +++ b/components/style/values/computed/image.rs @@ -677,3 +677,17 @@ impl AngleOrCorner { } } } + +/// Computed values for none | | . +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct LayerImage(pub Option); + +impl ToCss for LayerImage { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match self.0 { + None => dest.write_str("none"), + Some(ref image) => image.to_css(dest), + } + } +} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 6d1cbe2f616..19cc22edf27 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -22,7 +22,7 @@ use super::specified::grid::{TrackBreadth as GenericTrackBreadth, TrackSize as G pub use app_units::Au; pub use cssparser::Color as CSSColor; -pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientItem}; +pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientItem, LayerImage}; pub use self::image::{GradientKind, Image, ImageRect, LengthOrKeyword, LengthOrPercentageOrKeyword}; pub use super::{Auto, Either, None_}; #[cfg(feature = "gecko")] diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 5ca137864c7..f914b2488ca 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -666,3 +666,52 @@ impl SizeKeyword { } } } + +/// Specified values for none | | . +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct LayerImage(pub Option); +use values::HasViewportPercentage; +no_viewport_percentage!(LayerImage); + +impl ToCss for LayerImage { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + LayerImage(Some(ref image)) => image.to_css(dest), + LayerImage(None) => dest.write_str("none"), + } + } +} + +use super::computed::{ToComputedValue, Context}; +impl ToComputedValue for LayerImage { + type ComputedValue = super::computed::LayerImage; + + #[inline] + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + match *self { + LayerImage(None) => super::computed::LayerImage(None), + LayerImage(Some(ref image)) => + super::computed::LayerImage(Some(image.to_computed_value(context))), + } + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + match *computed { + super::computed::LayerImage(None) => LayerImage(None), + super::computed::LayerImage(Some(ref image)) => + LayerImage(Some(ToComputedValue::from_computed_value(image))), + } + } +} + +impl Parse for LayerImage { + fn parse(context: &ParserContext, input: &mut Parser) -> Result { + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + Ok(LayerImage(None)) + } else { + Ok(LayerImage(Some(try!(Image::parse(context, input))))) + } + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 100ea98aa9b..45cebecd22b 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -29,7 +29,7 @@ pub use self::align::{AlignItems, AlignJustifyContent, AlignJustifySelf, Justify pub use self::color::Color; pub use self::grid::{GridLine, TrackKeyword}; pub use self::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; -pub use self::image::{GradientItem, GradientKind, HorizontalDirection, Image, ImageRect}; +pub use self::image::{GradientItem, GradientKind, HorizontalDirection, Image, ImageRect, LayerImage}; pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword, SizeKeyword, VerticalDirection}; pub use self::length::AbsoluteLength; pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage}; From 748359f4c4e59a897fad0c62a4bfc519e56b2468 Mon Sep 17 00:00:00 2001 From: cku Date: Wed, 3 May 2017 19:56:46 +0800 Subject: [PATCH 2/2] Stylo: Update test cases in serialize.rs for mask-image and background-image. --- tests/unit/style/properties/serialization.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 2446e15e121..5f2ecdaf7ca 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -827,8 +827,8 @@ mod shorthand_serialization { let mut properties = Vec::new(); let image = single_vec_value_typedef!(image, - image::single_value::SpecifiedValue::Image( - Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png")))); + image::single_value::SpecifiedValue( + Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))))); let mode = single_vec_keyword_value!(mode, luminance); @@ -882,8 +882,8 @@ mod shorthand_serialization { let mut properties = Vec::new(); let image = single_vec_value_typedef!(image, - image::single_value::SpecifiedValue::Image( - Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png")))); + image::single_value::SpecifiedValue( + Some(Image::Url(SpecifiedUrl::new_for_testing("http://servo/test.png"))))); let mode = single_vec_keyword_value!(mode, luminance);