Make BorderRadius generic

This commit is contained in:
Ravi Shankar 2017-04-12 21:16:49 +05:30
parent 0249270f61
commit b2b3f99427
6 changed files with 100 additions and 99 deletions

View file

@ -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<Longhands, ()> {

View file

@ -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<Longhands, ()> {
// Re-use border-radius parsing.

View file

@ -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<W>(&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<LengthOrPercentage>;

View file

@ -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<L> {
/// The top left radius.
pub top_left: BorderRadiusSize<L>,
/// The top right radius.
pub top_right: BorderRadiusSize<L>,
/// The bottom right radius.
pub bottom_right: BorderRadiusSize<L>,
/// The bottom left radius.
pub bottom_left: BorderRadiusSize<L>,
}
/// Serialization helper for types of longhands like `border-radius` and `outline-radius`
pub fn serialize_radius_values<L, W>(dest: &mut W, top_left: &Size2D<L>,
top_right: &Size2D<L>, bottom_right: &Size2D<L>,
bottom_left: &Size2D<L>) -> 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<L: ToCss + PartialEq> ToCss for BorderRadius<L> {
#[inline]
fn to_css<W>(&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<L: ToComputedValue> ToComputedValue for BorderRadius<L> {
type ComputedValue = BorderRadius<L::ComputedValue>;
#[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),
}
}
}

View file

@ -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.

View file

@ -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<L, W>(dest: &mut W, top_left: &Size2D<L>,
top_right: &Size2D<L>, bottom_right: &Size2D<L>,
bottom_left: &Size2D<L>) -> 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<W>(&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<LengthOrPercentage>;
impl Parse for BorderRadius {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
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