From b2b3f99427b8288761a70a85da77e97de95fcf44 Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Wed, 12 Apr 2017 21:16:49 +0530 Subject: [PATCH] Make BorderRadius generic --- .../style/properties/shorthand/border.mako.rs | 3 +- .../properties/shorthand/outline.mako.rs | 2 +- .../style/values/computed/basic_shape.rs | 23 +---- .../style/values/generics/basic_shape.rs | 80 +++++++++++++++++ components/style/values/generics/mod.rs | 4 + .../style/values/specified/basic_shape.rs | 87 ++----------------- 6 files changed, 100 insertions(+), 99 deletions(-) create mode 100644 components/style/values/generics/basic_shape.rs diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs index 35afe623205..00fc89b0cec 100644 --- a/components/style/properties/shorthand/border.mako.rs +++ b/components/style/properties/shorthand/border.mako.rs @@ -203,7 +203,8 @@ pub fn parse_border(context: &ParserContext, input: &mut Parser) 'border-%s-radius' % (corner) for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left'] )}" extra_prefixes="webkit" spec="https://drafts.csswg.org/css-backgrounds/#border-radius"> - use values::specified::basic_shape::{BorderRadius, serialize_radius_values}; + use values::generics::serialize_radius_values; + use values::specified::basic_shape::BorderRadius; use parser::Parse; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { diff --git a/components/style/properties/shorthand/outline.mako.rs b/components/style/properties/shorthand/outline.mako.rs index 30c585f65b5..2a1e7e54486 100644 --- a/components/style/properties/shorthand/outline.mako.rs +++ b/components/style/properties/shorthand/outline.mako.rs @@ -68,7 +68,7 @@ for corner in ['topleft', 'topright', 'bottomright', 'bottomleft'] )}" products="gecko" spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-outline-radius)"> use properties::shorthands; - use values::specified::basic_shape::serialize_radius_values; + use values::generics::serialize_radius_values; pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result { // Re-use border-radius parsing. diff --git a/components/style/values/computed/basic_shape.rs b/components/style/values/computed/basic_shape.rs index 2ae1675bb3c..33075b0e296 100644 --- a/components/style/values/computed/basic_shape.rs +++ b/components/style/values/computed/basic_shape.rs @@ -9,8 +9,9 @@ use std::fmt; use style_traits::ToCss; -use values::computed::{BorderRadiusSize, LengthOrPercentage}; +use values::computed::LengthOrPercentage; use values::computed::position::Position; +use values::generics::basic_shape::BorderRadius as GenericBorderRadius; use values::specified::url::SpecifiedUrl; pub use values::specified::basic_shape::{self, FillRule, GeometryBox, ShapeBox}; @@ -196,21 +197,5 @@ impl ToCss for ShapeRadius { } } -/// https://drafts.csswg.org/css-backgrounds-3/#border-radius -#[derive(Clone, PartialEq, Copy, Debug)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[allow(missing_docs)] -pub struct BorderRadius { - pub top_left: BorderRadiusSize, - pub top_right: BorderRadiusSize, - pub bottom_right: BorderRadiusSize, - pub bottom_left: BorderRadiusSize, -} - -impl ToCss for BorderRadius { - #[inline] - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - basic_shape::serialize_radius_values(dest, &self.top_left.0, &self.top_right.0, - &self.bottom_right.0, &self.bottom_left.0) - } -} +/// The computed value of `BorderRadius` +pub type BorderRadius = GenericBorderRadius; diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs new file mode 100644 index 00000000000..d3f2d5b5b4f --- /dev/null +++ b/components/style/values/generics/basic_shape.rs @@ -0,0 +1,80 @@ +/* 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/. */ + +//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape) +//! types that are generic over their `ToCss` implementations. + +use euclid::size::Size2D; +use properties::shorthands::serialize_four_sides; +use std::fmt; +use style_traits::ToCss; +use values::computed::{Context, ToComputedValue}; +use values::generics::BorderRadiusSize; + +/// A generic type used for `border-radius`, `outline-radius` and `inset()` values. +/// +/// https://drafts.csswg.org/css-backgrounds-3/#border-radius +#[derive(Clone, PartialEq, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub struct BorderRadius { + /// The top left radius. + pub top_left: BorderRadiusSize, + /// The top right radius. + pub top_right: BorderRadiusSize, + /// The bottom right radius. + pub bottom_right: BorderRadiusSize, + /// The bottom left radius. + pub bottom_left: BorderRadiusSize, +} + +/// Serialization helper for types of longhands like `border-radius` and `outline-radius` +pub fn serialize_radius_values(dest: &mut W, top_left: &Size2D, + top_right: &Size2D, bottom_right: &Size2D, + bottom_left: &Size2D) -> fmt::Result + where L: ToCss + PartialEq, W: fmt::Write +{ + if top_left.width == top_left.height && top_right.width == top_right.height && + bottom_right.width == bottom_right.height && bottom_left.width == bottom_left.height { + serialize_four_sides(dest, &top_left.width, &top_right.width, + &bottom_right.width, &bottom_left.width) + } else { + serialize_four_sides(dest, &top_left.width, &top_right.width, + &bottom_right.width, &bottom_left.width)?; + dest.write_str(" / ")?; + serialize_four_sides(dest, &top_left.height, &top_right.height, + &bottom_right.height, &bottom_left.height) + } +} + +impl ToCss for BorderRadius { + #[inline] + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + serialize_radius_values(dest, &self.top_left.0, &self.top_right.0, + &self.bottom_right.0, &self.bottom_left.0) + } +} + +impl ToComputedValue for BorderRadius { + type ComputedValue = BorderRadius; + + #[inline] + fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { + BorderRadius { + top_left: self.top_left.to_computed_value(cx), + top_right: self.top_right.to_computed_value(cx), + bottom_right: self.bottom_right.to_computed_value(cx), + bottom_left: self.bottom_left.to_computed_value(cx), + } + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + BorderRadius { + top_left: ToComputedValue::from_computed_value(&computed.top_left), + top_right: ToComputedValue::from_computed_value(&computed.top_right), + bottom_right: ToComputedValue::from_computed_value(&computed.bottom_right), + bottom_left: ToComputedValue::from_computed_value(&computed.bottom_left), + } + } +} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 899d7241aac..75ca9ccf8ab 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -11,6 +11,10 @@ use style_traits::ToCss; use super::HasViewportPercentage; use super::computed::{Context, ToComputedValue}; +pub use self::basic_shape::serialize_radius_values; + +pub mod basic_shape; + #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A type for representing CSS `widthh` and `height` values. diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index 311049043e0..2f66c79af31 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -8,16 +8,17 @@ //! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape use cssparser::Parser; -use euclid::size::Size2D; use parser::{Parse, ParserContext}; -use properties::shorthands::{parse_four_sides, serialize_four_sides}; +use properties::shorthands::parse_four_sides; use std::ascii::AsciiExt; use std::fmt; use style_traits::ToCss; use values::HasViewportPercentage; use values::computed::{ComputedValueAsSpecified, Context, ToComputedValue}; use values::computed::basic_shape as computed_basic_shape; -use values::specified::{BorderRadiusSize, LengthOrPercentage, Percentage}; +use values::generics::BorderRadiusSize; +use values::generics::basic_shape::BorderRadius as GenericBorderRadius; +use values::specified::{LengthOrPercentage, Percentage}; use values::specified::position::{Keyword, Position}; use values::specified::url::SpecifiedUrl; @@ -682,66 +683,21 @@ impl ToComputedValue for ShapeRadius { } } -/// https://drafts.csswg.org/css-backgrounds-3/#border-radius -#[derive(Clone, PartialEq, Debug)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[allow(missing_docs)] -pub struct BorderRadius { - pub top_left: BorderRadiusSize, - pub top_right: BorderRadiusSize, - pub bottom_right: BorderRadiusSize, - pub bottom_left: BorderRadiusSize, -} - -/// Serialization helper for types of longhands like `border-radius` and `outline-radius` -pub fn serialize_radius_values(dest: &mut W, top_left: &Size2D, - top_right: &Size2D, bottom_right: &Size2D, - bottom_left: &Size2D) -> fmt::Result - where L: ToCss + PartialEq, W: fmt::Write -{ - if top_left.width == top_left.height && - top_right.width == top_right.height && - bottom_right.width == bottom_right.height && - bottom_left.width == bottom_left.height { - serialize_four_sides(dest, - &top_left.width, - &top_right.width, - &bottom_right.width, - &bottom_left.width) - } else { - serialize_four_sides(dest, - &top_left.width, - &top_right.width, - &bottom_right.width, - &bottom_left.width)?; - dest.write_str(" / ")?; - serialize_four_sides(dest, - &top_left.height, - &top_right.height, - &bottom_right.height, - &bottom_left.height) - } -} - -impl ToCss for BorderRadius { - #[inline] - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - serialize_radius_values(dest, &self.top_left.0, &self.top_right.0, - &self.bottom_right.0, &self.bottom_left.0) - } -} +/// The specified value of `BorderRadius` +pub type BorderRadius = GenericBorderRadius; impl Parse for BorderRadius { fn parse(context: &ParserContext, input: &mut Parser) -> Result { - let mut widths = try!(parse_one_set_of_border_values(context, input)); + let mut widths = parse_one_set_of_border_values(context, input)?; let mut heights = if input.try(|input| input.expect_delim('/')).is_ok() { - try!(parse_one_set_of_border_values(context, input)) + parse_one_set_of_border_values(context, input)? } else { [widths[0].clone(), widths[1].clone(), widths[2].clone(), widths[3].clone()] }; + Ok(BorderRadius { top_left: BorderRadiusSize::new(widths[0].take(), heights[0].take()), top_right: BorderRadiusSize::new(widths[1].take(), heights[1].take()), @@ -773,31 +729,6 @@ fn parse_one_set_of_border_values(context: &ParserContext, mut input: &mut Parse } } - -impl ToComputedValue for BorderRadius { - type ComputedValue = computed_basic_shape::BorderRadius; - - #[inline] - fn to_computed_value(&self, cx: &Context) -> Self::ComputedValue { - computed_basic_shape::BorderRadius { - top_left: self.top_left.to_computed_value(cx), - top_right: self.top_right.to_computed_value(cx), - bottom_right: self.bottom_right.to_computed_value(cx), - bottom_left: self.bottom_left.to_computed_value(cx), - } - } - - #[inline] - fn from_computed_value(computed: &Self::ComputedValue) -> Self { - BorderRadius { - top_left: ToComputedValue::from_computed_value(&computed.top_left), - top_right: ToComputedValue::from_computed_value(&computed.top_right), - bottom_right: ToComputedValue::from_computed_value(&computed.bottom_right), - bottom_left: ToComputedValue::from_computed_value(&computed.bottom_left), - } - } -} - // https://drafts.csswg.org/css-shapes/#typedef-fill-rule // NOTE: Basic shapes spec says that these are the only two values, however // https://www.w3.org/TR/SVG/painting.html#FillRuleProperty