mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
style: Use NonNegative more in the border code.
This ended up not being so small of a patch as I'd have thought, since it propagated a bit. But most of it is mechanical. Interesting part is NonNegativeNumberOrPercentage and the actual uses of the NonNegative stuff and during parsing. This looks like it'd fix a few correctness issues during interpolation for all the types except for BorderRadius and co (which handled it manually). I should write tests for those in a different patch. Differential Revision: https://phabricator.services.mozilla.com/D14673
This commit is contained in:
parent
19035590ce
commit
ca1ad003bd
14 changed files with 161 additions and 106 deletions
|
@ -5,6 +5,8 @@
|
||||||
//! This module contains conversion helpers between Servo and Gecko types
|
//! This module contains conversion helpers between Servo and Gecko types
|
||||||
//! Ideally, it would be in geckolib itself, but coherence
|
//! Ideally, it would be in geckolib itself, but coherence
|
||||||
//! forces us to keep the traits and implementations here
|
//! forces us to keep the traits and implementations here
|
||||||
|
//!
|
||||||
|
//! FIXME(emilio): This file should generally just die.
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
|
@ -22,6 +24,7 @@ use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
|
||||||
use crate::values::computed::{Integer, LengthOrPercentage};
|
use crate::values::computed::{Integer, LengthOrPercentage};
|
||||||
use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto};
|
use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto};
|
||||||
use crate::values::computed::{Percentage, TextAlign};
|
use crate::values::computed::{Percentage, TextAlign};
|
||||||
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::generics::box_::VerticalAlign;
|
use crate::values::generics::box_::VerticalAlign;
|
||||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
||||||
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
|
use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage};
|
||||||
|
@ -113,7 +116,6 @@ impl From<nsStyleCoord_CalcValue> for LengthOrPercentageOrAuto {
|
||||||
// disappear as we move more stuff to cbindgen.
|
// disappear as we move more stuff to cbindgen.
|
||||||
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
|
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
|
||||||
fn from(other: nsStyleCoord_CalcValue) -> Self {
|
fn from(other: nsStyleCoord_CalcValue) -> Self {
|
||||||
use crate::values::generics::NonNegative;
|
|
||||||
use style_traits::values::specified::AllowedNumericType;
|
use style_traits::values::specified::AllowedNumericType;
|
||||||
NonNegative(if other.mLength < 0 || other.mPercent < 0. {
|
NonNegative(if other.mLength < 0 || other.mPercent < 0. {
|
||||||
LengthOrPercentageOrAuto::Calc(CalcLengthOrPercentage::with_clamping_mode(
|
LengthOrPercentageOrAuto::Calc(CalcLengthOrPercentage::with_clamping_mode(
|
||||||
|
@ -675,6 +677,7 @@ pub mod basic_shape {
|
||||||
use crate::values::generics::basic_shape::{
|
use crate::values::generics::basic_shape::{
|
||||||
BasicShape as GenericBasicShape, InsetRect, Polygon,
|
BasicShape as GenericBasicShape, InsetRect, Polygon,
|
||||||
};
|
};
|
||||||
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord};
|
use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord};
|
||||||
use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource};
|
use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource};
|
||||||
use crate::values::generics::border::BorderRadius as GenericBorderRadius;
|
use crate::values::generics::border::BorderRadius as GenericBorderRadius;
|
||||||
|
@ -838,10 +841,10 @@ pub mod basic_shape {
|
||||||
fn from(other: &'a nsStyleCorners) -> Self {
|
fn from(other: &'a nsStyleCorners) -> Self {
|
||||||
let get_corner = |index| {
|
let get_corner = |index| {
|
||||||
BorderCornerRadius::new(
|
BorderCornerRadius::new(
|
||||||
LengthOrPercentage::from_gecko_style_coord(&other.data_at(index))
|
NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index))
|
||||||
.expect("<border-radius> should be a length, percentage, or calc value"),
|
.expect("<border-radius> should be a length, percentage, or calc value")),
|
||||||
LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1))
|
NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1))
|
||||||
.expect("<border-radius> should be a length, percentage, or calc value"),
|
.expect("<border-radius> should be a length, percentage, or calc value")),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1687,8 +1687,8 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T {
|
pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T {
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL;
|
use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL;
|
||||||
use crate::values::computed::{BorderImageSlice, NumberOrPercentage};
|
use crate::values::computed::{BorderImageSlice, NonNegativeNumberOrPercentage};
|
||||||
type NumberOrPercentageRect = crate::values::generics::rect::Rect<NumberOrPercentage>;
|
type NumberOrPercentageRect = crate::values::generics::rect::Rect<NonNegativeNumberOrPercentage>;
|
||||||
|
|
||||||
BorderImageSlice {
|
BorderImageSlice {
|
||||||
offsets:
|
offsets:
|
||||||
|
|
|
@ -153,14 +153,15 @@ ${helpers.predefined_type(
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"border-image-slice",
|
"border-image-slice",
|
||||||
"BorderImageSlice",
|
"BorderImageSlice",
|
||||||
initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()",
|
initial_value="computed::BorderImageSlice::hundred_percent()",
|
||||||
initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()",
|
initial_specified_value="specified::BorderImageSlice::hundred_percent()",
|
||||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
|
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
flags="APPLIES_TO_FIRST_LETTER",
|
flags="APPLIES_TO_FIRST_LETTER",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
// FIXME(emilio): Why does this live here? ;_;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
impl crate::values::computed::BorderImageWidth {
|
impl crate::values::computed::BorderImageWidth {
|
||||||
pub fn to_gecko_rect(&self, sides: &mut crate::gecko_bindings::structs::nsStyleSides) {
|
pub fn to_gecko_rect(&self, sides: &mut crate::gecko_bindings::structs::nsStyleSides) {
|
||||||
|
@ -177,7 +178,7 @@ impl crate::values::computed::BorderImageWidth {
|
||||||
l.to_gecko_style_coord(&mut sides.data_at_mut(${i}))
|
l.to_gecko_style_coord(&mut sides.data_at_mut(${i}))
|
||||||
},
|
},
|
||||||
BorderImageSideWidth::Number(n) => {
|
BorderImageSideWidth::Number(n) => {
|
||||||
sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n))
|
sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n.0))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -191,6 +192,7 @@ impl crate::values::computed::BorderImageWidth {
|
||||||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||||
use crate::values::computed::{LengthOrPercentage, Number};
|
use crate::values::computed::{LengthOrPercentage, Number};
|
||||||
use crate::values::generics::border::BorderImageSideWidth;
|
use crate::values::generics::border::BorderImageSideWidth;
|
||||||
|
use crate::values::generics::NonNegative;
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
crate::values::computed::BorderImageWidth::new(
|
crate::values::computed::BorderImageWidth::new(
|
||||||
|
@ -201,13 +203,13 @@ impl crate::values::computed::BorderImageWidth {
|
||||||
},
|
},
|
||||||
eStyleUnit_Factor => {
|
eStyleUnit_Factor => {
|
||||||
BorderImageSideWidth::Number(
|
BorderImageSideWidth::Number(
|
||||||
Number::from_gecko_style_coord(&sides.data_at(${i}))
|
NonNegative(Number::from_gecko_style_coord(&sides.data_at(${i}))
|
||||||
.expect("sides[${i}] could not convert to Number"))
|
.expect("sides[${i}] could not convert to Number")))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
BorderImageSideWidth::Length(
|
BorderImageSideWidth::Length(
|
||||||
LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i}))
|
NonNegative(LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i}))
|
||||||
.expect("sides[${i}] could not convert to LengthOrPercentager"))
|
.expect("sides[${i}] could not convert to LengthOrPercentage")))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
% endfor
|
% endfor
|
||||||
|
|
|
@ -295,7 +295,7 @@ ${helpers.predefined_type(
|
||||||
"-webkit-text-stroke-width",
|
"-webkit-text-stroke-width",
|
||||||
"BorderSideWidth",
|
"BorderSideWidth",
|
||||||
"crate::values::computed::NonNegativeLength::new(0.)",
|
"crate::values::computed::NonNegativeLength::new(0.)",
|
||||||
initial_specified_value="specified::BorderSideWidth::Length(specified::Length::zero())",
|
initial_specified_value="specified::BorderSideWidth::zero()",
|
||||||
computed_type="crate::values::computed::NonNegativeLength",
|
computed_type="crate::values::computed::NonNegativeLength",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
gecko_pref="layout.css.prefixes.webkit",
|
gecko_pref="layout.css.prefixes.webkit",
|
||||||
|
|
|
@ -12,7 +12,6 @@ use crate::properties::PropertyId;
|
||||||
use crate::values::computed::length::CalcLengthOrPercentage;
|
use crate::values::computed::length::CalcLengthOrPercentage;
|
||||||
use crate::values::computed::url::ComputedUrl;
|
use crate::values::computed::url::ComputedUrl;
|
||||||
use crate::values::computed::Angle as ComputedAngle;
|
use crate::values::computed::Angle as ComputedAngle;
|
||||||
use crate::values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
|
||||||
use crate::values::CSSFloat;
|
use crate::values::CSSFloat;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
|
@ -340,23 +339,6 @@ trivial_to_animated_value!(ComputedUrl);
|
||||||
trivial_to_animated_value!(bool);
|
trivial_to_animated_value!(bool);
|
||||||
trivial_to_animated_value!(f32);
|
trivial_to_animated_value!(f32);
|
||||||
|
|
||||||
impl ToAnimatedValue for ComputedBorderCornerRadius {
|
|
||||||
type AnimatedValue = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_animated_value(self) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
||||||
ComputedBorderCornerRadius::new(
|
|
||||||
(animated.0).0.width.clamp_to_non_negative(),
|
|
||||||
(animated.0).0.height.clamp_to_non_negative(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedZero for Au {
|
impl ToAnimatedZero for Au {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape
|
//! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape
|
||||||
|
|
||||||
use crate::values::computed::url::ComputedUrl;
|
use crate::values::computed::url::ComputedUrl;
|
||||||
use crate::values::computed::{Image, LengthOrPercentage};
|
use crate::values::computed::{Image, LengthOrPercentage, NonNegativeLengthOrPercentage};
|
||||||
use crate::values::generics::basic_shape as generic;
|
use crate::values::generics::basic_shape as generic;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
|
@ -24,10 +24,10 @@ pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
||||||
|
|
||||||
/// A computed basic shape.
|
/// A computed basic shape.
|
||||||
pub type BasicShape =
|
pub type BasicShape =
|
||||||
generic::BasicShape<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
|
generic::BasicShape<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// The computed value of `inset()`
|
/// The computed value of `inset()`
|
||||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage>;
|
pub type InsetRect = generic::InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A computed circle.
|
/// A computed circle.
|
||||||
pub type Circle = generic::Circle<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
|
pub type Circle = generic::Circle<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
//! Computed types for CSS values related to borders.
|
//! Computed types for CSS values related to borders.
|
||||||
|
|
||||||
use crate::values::animated::ToAnimatedZero;
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::computed::length::{LengthOrPercentage, NonNegativeLength};
|
use crate::values::computed::length::{NonNegativeLengthOrPercentage, NonNegativeLength};
|
||||||
use crate::values::computed::{Number, NumberOrPercentage};
|
use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage};
|
||||||
use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
|
use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
|
||||||
use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
|
use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
|
||||||
use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice;
|
use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice;
|
||||||
|
@ -22,16 +22,16 @@ pub use crate::values::specified::border::BorderImageRepeat;
|
||||||
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
||||||
|
|
||||||
/// A computed value for a single side of a `border-image-width` property.
|
/// A computed value for a single side of a `border-image-width` property.
|
||||||
pub type BorderImageSideWidth = GenericBorderImageSideWidth<LengthOrPercentage, Number>;
|
pub type BorderImageSideWidth = GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>;
|
||||||
|
|
||||||
/// A computed value for the `border-image-slice` property.
|
/// A computed value for the `border-image-slice` property.
|
||||||
pub type BorderImageSlice = GenericBorderImageSlice<NumberOrPercentage>;
|
pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>;
|
||||||
|
|
||||||
/// A computed value for the `border-radius` property.
|
/// A computed value for the `border-radius` property.
|
||||||
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
|
pub type BorderRadius = GenericBorderRadius<NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A computed value for the `border-*-radius` longhand properties.
|
/// A computed value for the `border-*-radius` longhand properties.
|
||||||
pub type BorderCornerRadius = GenericBorderCornerRadius<LengthOrPercentage>;
|
pub type BorderCornerRadius = GenericBorderCornerRadius<NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A computed value for the `border-spacing` longhand property.
|
/// A computed value for the `border-spacing` longhand property.
|
||||||
pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
|
pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
|
||||||
|
@ -40,7 +40,18 @@ impl BorderImageSideWidth {
|
||||||
/// Returns `1`.
|
/// Returns `1`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn one() -> Self {
|
pub fn one() -> Self {
|
||||||
GenericBorderImageSideWidth::Number(1.)
|
GenericBorderImageSideWidth::Number(NonNegative(1.))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorderImageSlice {
|
||||||
|
/// Returns the `100%` value.
|
||||||
|
#[inline]
|
||||||
|
pub fn hundred_percent() -> Self {
|
||||||
|
GenericBorderImageSlice {
|
||||||
|
offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()),
|
||||||
|
fill: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,26 +79,18 @@ impl BorderCornerRadius {
|
||||||
/// Returns `0 0`.
|
/// Returns `0 0`.
|
||||||
pub fn zero() -> Self {
|
pub fn zero() -> Self {
|
||||||
GenericBorderCornerRadius(Size::new(
|
GenericBorderCornerRadius(Size::new(
|
||||||
LengthOrPercentage::zero(),
|
NonNegativeLengthOrPercentage::zero(),
|
||||||
LengthOrPercentage::zero(),
|
NonNegativeLengthOrPercentage::zero(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToAnimatedZero for BorderCornerRadius {
|
|
||||||
#[inline]
|
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
|
||||||
// FIXME(nox): Why?
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BorderRadius {
|
impl BorderRadius {
|
||||||
/// Returns whether all the values are `0px`.
|
/// Returns whether all the values are `0px`.
|
||||||
pub fn all_zero(&self) -> bool {
|
pub fn all_zero(&self) -> bool {
|
||||||
fn all(corner: &BorderCornerRadius) -> bool {
|
fn all(corner: &BorderCornerRadius) -> bool {
|
||||||
fn is_zero(l: &LengthOrPercentage) -> bool {
|
fn is_zero(l: &NonNegativeLengthOrPercentage) -> bool {
|
||||||
*l == LengthOrPercentage::zero()
|
*l == NonNegativeLengthOrPercentage::zero()
|
||||||
}
|
}
|
||||||
is_zero(corner.0.width()) && is_zero(corner.0.height())
|
is_zero(corner.0.width()) && is_zero(corner.0.height())
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,6 +543,15 @@ pub enum NumberOrPercentage {
|
||||||
Number(Number),
|
Number(Number),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NumberOrPercentage {
|
||||||
|
fn clamp_to_non_negative(self) -> Self {
|
||||||
|
match self {
|
||||||
|
NumberOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p.clamp_to_non_negative()),
|
||||||
|
NumberOrPercentage::Number(n) => NumberOrPercentage::Number(n.max(0.)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToComputedValue for specified::NumberOrPercentage {
|
impl ToComputedValue for specified::NumberOrPercentage {
|
||||||
type ComputedValue = NumberOrPercentage;
|
type ComputedValue = NumberOrPercentage;
|
||||||
|
|
||||||
|
@ -572,6 +581,31 @@ impl ToComputedValue for specified::NumberOrPercentage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A non-negative <number-percentage>.
|
||||||
|
pub type NonNegativeNumberOrPercentage = NonNegative<NumberOrPercentage>;
|
||||||
|
|
||||||
|
impl NonNegativeNumberOrPercentage {
|
||||||
|
/// Returns the `100%` value.
|
||||||
|
#[inline]
|
||||||
|
pub fn hundred_percent() -> Self {
|
||||||
|
NonNegative(NumberOrPercentage::Percentage(Percentage::hundred()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToAnimatedValue for NonNegativeNumberOrPercentage {
|
||||||
|
type AnimatedValue = NumberOrPercentage;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_animated_value(self) -> Self::AnimatedValue {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||||
|
NonNegative(animated.clamp_to_non_negative())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A type used for opacity.
|
/// A type used for opacity.
|
||||||
pub type Opacity = CSSFloat;
|
pub type Opacity = CSSFloat;
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,8 @@ pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
)]
|
)]
|
||||||
pub enum BasicShape<H, V, LengthOrPercentage> {
|
pub enum BasicShape<H, V, LengthOrPercentage, NonNegativeLengthOrPercentage> {
|
||||||
Inset(#[css(field_bound)] InsetRect<LengthOrPercentage>),
|
Inset(#[css(field_bound)] InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>),
|
||||||
Circle(#[css(field_bound)] Circle<H, V, LengthOrPercentage>),
|
Circle(#[css(field_bound)] Circle<H, V, LengthOrPercentage>),
|
||||||
Ellipse(#[css(field_bound)] Ellipse<H, V, LengthOrPercentage>),
|
Ellipse(#[css(field_bound)] Ellipse<H, V, LengthOrPercentage>),
|
||||||
Polygon(Polygon<LengthOrPercentage>),
|
Polygon(Polygon<LengthOrPercentage>),
|
||||||
|
@ -105,9 +105,9 @@ pub enum BasicShape<H, V, LengthOrPercentage> {
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
)]
|
)]
|
||||||
pub struct InsetRect<LengthOrPercentage> {
|
pub struct InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage> {
|
||||||
pub rect: Rect<LengthOrPercentage>,
|
pub rect: Rect<LengthOrPercentage>,
|
||||||
pub round: Option<BorderRadius<LengthOrPercentage>>,
|
pub round: Option<BorderRadius<NonNegativeLengthOrPercentage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-shapes/#funcdef-circle>
|
/// <https://drafts.csswg.org/css-shapes/#funcdef-circle>
|
||||||
|
@ -258,9 +258,10 @@ impl<B, T, U> ToAnimatedZero for ShapeSource<B, T, U> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L> ToCss for InsetRect<L>
|
impl<Length, NonNegativeLength> ToCss for InsetRect<Length, NonNegativeLength>
|
||||||
where
|
where
|
||||||
L: ToCss + PartialEq,
|
Length: ToCss + PartialEq,
|
||||||
|
NonNegativeLength: ToCss + PartialEq,
|
||||||
{
|
{
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
|
|
|
@ -45,6 +45,8 @@ pub struct BorderImageSlice<NumberOrPercentage> {
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedValue,
|
||||||
|
ToAnimatedZero,
|
||||||
ToComputedValue,
|
ToComputedValue,
|
||||||
ToCss,
|
ToCss,
|
||||||
)]
|
)]
|
||||||
|
@ -106,19 +108,6 @@ pub struct BorderRadius<LengthOrPercentage> {
|
||||||
pub bottom_left: BorderCornerRadius<LengthOrPercentage>,
|
pub bottom_left: BorderCornerRadius<LengthOrPercentage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N> From<N> for BorderImageSlice<N>
|
|
||||||
where
|
|
||||||
N: Clone,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn from(value: N) -> Self {
|
|
||||||
Self {
|
|
||||||
offsets: Rect::all(value),
|
|
||||||
fill: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<L> BorderRadius<L> {
|
impl<L> BorderRadius<L> {
|
||||||
/// Returns a new `BorderRadius<L>`.
|
/// Returns a new `BorderRadius<L>`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -16,7 +16,7 @@ use crate::values::specified::border::BorderRadius;
|
||||||
use crate::values::specified::image::Image;
|
use crate::values::specified::image::Image;
|
||||||
use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition};
|
use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition};
|
||||||
use crate::values::specified::url::SpecifiedUrl;
|
use crate::values::specified::url::SpecifiedUrl;
|
||||||
use crate::values::specified::LengthOrPercentage;
|
use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage};
|
||||||
use crate::values::specified::SVGPathData;
|
use crate::values::specified::SVGPathData;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -32,10 +32,10 @@ pub type ClippingShape = generic::ClippingShape<BasicShape, SpecifiedUrl>;
|
||||||
pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
||||||
|
|
||||||
/// A specified basic shape.
|
/// A specified basic shape.
|
||||||
pub type BasicShape = generic::BasicShape<HorizontalPosition, VerticalPosition, LengthOrPercentage>;
|
pub type BasicShape = generic::BasicShape<HorizontalPosition, VerticalPosition, LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// The specified value of `inset()`
|
/// The specified value of `inset()`
|
||||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage>;
|
pub type InsetRect = generic::InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A specified circle.
|
/// A specified circle.
|
||||||
pub type Circle = generic::Circle<HorizontalPosition, VerticalPosition, LengthOrPercentage>;
|
pub type Circle = generic::Circle<HorizontalPosition, VerticalPosition, LengthOrPercentage>;
|
||||||
|
@ -199,10 +199,7 @@ impl InsetRect {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(generic::InsetRect {
|
Ok(generic::InsetRect { rect, round })
|
||||||
rect: rect,
|
|
||||||
round: round,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ use crate::values::generics::border::BorderRadius as GenericBorderRadius;
|
||||||
use crate::values::generics::border::BorderSpacing as GenericBorderSpacing;
|
use crate::values::generics::border::BorderSpacing as GenericBorderSpacing;
|
||||||
use crate::values::generics::rect::Rect;
|
use crate::values::generics::rect::Rect;
|
||||||
use crate::values::generics::size::Size;
|
use crate::values::generics::size::Size;
|
||||||
use crate::values::specified::length::{Length, LengthOrPercentage, NonNegativeLength};
|
use crate::values::specified::length::{NonNegativeLengthOrPercentage, NonNegativeLength};
|
||||||
use crate::values::specified::{AllowQuirks, Number, NumberOrPercentage};
|
use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage};
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
|
@ -71,28 +71,45 @@ pub enum BorderSideWidth {
|
||||||
/// `thick`
|
/// `thick`
|
||||||
Thick,
|
Thick,
|
||||||
/// `<length>`
|
/// `<length>`
|
||||||
Length(Length),
|
Length(NonNegativeLength),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A specified value for the `border-image-width` property.
|
/// A specified value for the `border-image-width` property.
|
||||||
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
||||||
|
|
||||||
/// A specified value for a single side of a `border-image-width` property.
|
/// A specified value for a single side of a `border-image-width` property.
|
||||||
pub type BorderImageSideWidth = GenericBorderImageSideWidth<LengthOrPercentage, Number>;
|
pub type BorderImageSideWidth = GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>;
|
||||||
|
|
||||||
/// A specified value for the `border-image-slice` property.
|
/// A specified value for the `border-image-slice` property.
|
||||||
pub type BorderImageSlice = GenericBorderImageSlice<NumberOrPercentage>;
|
pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>;
|
||||||
|
|
||||||
/// A specified value for the `border-radius` property.
|
/// A specified value for the `border-radius` property.
|
||||||
pub type BorderRadius = GenericBorderRadius<LengthOrPercentage>;
|
pub type BorderRadius = GenericBorderRadius<NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A specified value for the `border-*-radius` longhand properties.
|
/// A specified value for the `border-*-radius` longhand properties.
|
||||||
pub type BorderCornerRadius = GenericBorderCornerRadius<LengthOrPercentage>;
|
pub type BorderCornerRadius = GenericBorderCornerRadius<NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
/// A specified value for the `border-spacing` longhand properties.
|
/// A specified value for the `border-spacing` longhand properties.
|
||||||
pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
|
pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
|
||||||
|
|
||||||
|
impl BorderImageSlice {
|
||||||
|
/// Returns the `100%` value.
|
||||||
|
#[inline]
|
||||||
|
pub fn hundred_percent() -> Self {
|
||||||
|
GenericBorderImageSlice {
|
||||||
|
offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()),
|
||||||
|
fill: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BorderSideWidth {
|
impl BorderSideWidth {
|
||||||
|
/// Returns the `0px` value.
|
||||||
|
#[inline]
|
||||||
|
pub fn zero() -> Self {
|
||||||
|
BorderSideWidth::Length(NonNegativeLength::zero())
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses, with quirks.
|
/// Parses, with quirks.
|
||||||
pub fn parse_quirky<'i, 't>(
|
pub fn parse_quirky<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
|
@ -100,7 +117,7 @@ impl BorderSideWidth {
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(length) =
|
if let Ok(length) =
|
||||||
input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks))
|
input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks))
|
||||||
{
|
{
|
||||||
return Ok(BorderSideWidth::Length(length));
|
return Ok(BorderSideWidth::Length(length));
|
||||||
}
|
}
|
||||||
|
@ -130,9 +147,9 @@ impl ToComputedValue for BorderSideWidth {
|
||||||
// Spec: https://drafts.csswg.org/css-backgrounds-3/#line-width
|
// Spec: https://drafts.csswg.org/css-backgrounds-3/#line-width
|
||||||
// Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1312155#c0
|
// Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1312155#c0
|
||||||
match *self {
|
match *self {
|
||||||
BorderSideWidth::Thin => Length::from_px(1.).to_computed_value(context),
|
BorderSideWidth::Thin => NonNegativeLength::from_px(1.).to_computed_value(context),
|
||||||
BorderSideWidth::Medium => Length::from_px(3.).to_computed_value(context),
|
BorderSideWidth::Medium => NonNegativeLength::from_px(3.).to_computed_value(context),
|
||||||
BorderSideWidth::Thick => Length::from_px(5.).to_computed_value(context),
|
BorderSideWidth::Thick => NonNegativeLength::from_px(5.).to_computed_value(context),
|
||||||
BorderSideWidth::Length(ref length) => length.to_computed_value(context),
|
BorderSideWidth::Length(ref length) => length.to_computed_value(context),
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
|
@ -140,7 +157,7 @@ impl ToComputedValue for BorderSideWidth {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
BorderSideWidth::Length(ToComputedValue::from_computed_value(&computed.0))
|
BorderSideWidth::Length(ToComputedValue::from_computed_value(computed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +165,7 @@ impl BorderImageSideWidth {
|
||||||
/// Returns `1`.
|
/// Returns `1`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn one() -> Self {
|
pub fn one() -> Self {
|
||||||
GenericBorderImageSideWidth::Number(Number::new(1.))
|
GenericBorderImageSideWidth::Number(NonNegativeNumber::new(1.))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,11 +178,11 @@ impl Parse for BorderImageSideWidth {
|
||||||
return Ok(GenericBorderImageSideWidth::Auto);
|
return Ok(GenericBorderImageSideWidth::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(len) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
if let Ok(len) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) {
|
||||||
return Ok(GenericBorderImageSideWidth::Length(len));
|
return Ok(GenericBorderImageSideWidth::Length(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
let num = Number::parse_non_negative(context, input)?;
|
let num = NonNegativeNumber::parse(context, input)?;
|
||||||
Ok(GenericBorderImageSideWidth::Number(num))
|
Ok(GenericBorderImageSideWidth::Number(num))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,14 +193,11 @@ impl Parse for BorderImageSlice {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
let mut fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
||||||
let offsets = Rect::parse_with(context, input, NumberOrPercentage::parse_non_negative)?;
|
let offsets = Rect::parse_with(context, input, NonNegativeNumberOrPercentage::parse)?;
|
||||||
if !fill {
|
if !fill {
|
||||||
fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
||||||
}
|
}
|
||||||
Ok(GenericBorderImageSlice {
|
Ok(GenericBorderImageSlice { offsets, fill })
|
||||||
offsets: offsets,
|
|
||||||
fill: fill,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,9 +206,9 @@ impl Parse for BorderRadius {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let widths = Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?;
|
let widths = Rect::parse_with(context, input, NonNegativeLengthOrPercentage::parse)?;
|
||||||
let heights = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let heights = if input.try(|i| i.expect_delim('/')).is_ok() {
|
||||||
Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?
|
Rect::parse_with(context, input, NonNegativeLengthOrPercentage::parse)?
|
||||||
} else {
|
} else {
|
||||||
widths.clone()
|
widths.clone()
|
||||||
};
|
};
|
||||||
|
@ -213,7 +227,7 @@ impl Parse for BorderCornerRadius {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
Size::parse_with(context, input, LengthOrPercentage::parse_non_negative)
|
Size::parse_with(context, input, NonNegativeLengthOrPercentage::parse)
|
||||||
.map(GenericBorderCornerRadius)
|
.map(GenericBorderCornerRadius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +238,7 @@ impl Parse for BorderSpacing {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
Size::parse_with(context, input, |context, input| {
|
Size::parse_with(context, input, |context, input| {
|
||||||
Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes).map(From::from)
|
NonNegativeLength::parse_quirky(context, input, AllowQuirks::Yes).map(From::from)
|
||||||
})
|
})
|
||||||
.map(GenericBorderSpacing)
|
.map(GenericBorderSpacing)
|
||||||
}
|
}
|
||||||
|
|
|
@ -717,6 +717,16 @@ impl NonNegativeLength {
|
||||||
pub fn from_px(px_value: CSSFloat) -> Self {
|
pub fn from_px(px_value: CSSFloat) -> Self {
|
||||||
Length::from_px(px_value.max(0.)).into()
|
Length::from_px(px_value.max(0.)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a non-negative length, optionally with quirks.
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_quirky<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
allow_quirks: AllowQuirks,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
Ok(NonNegative(Length::parse_non_negative_quirky(context, input, allow_quirks)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Either a NonNegativeLength or the `auto` keyword.
|
/// Either a NonNegativeLength or the `auto` keyword.
|
||||||
|
|
|
@ -359,6 +359,26 @@ impl Parse for NumberOrPercentage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A non-negative <number> | <percentage>.
|
||||||
|
pub type NonNegativeNumberOrPercentage = NonNegative<NumberOrPercentage>;
|
||||||
|
|
||||||
|
impl NonNegativeNumberOrPercentage {
|
||||||
|
/// Returns the `100%` value.
|
||||||
|
#[inline]
|
||||||
|
pub fn hundred_percent() -> Self {
|
||||||
|
NonNegative(NumberOrPercentage::Percentage(Percentage::hundred()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parse for NonNegativeNumberOrPercentage {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
Ok(NonNegative(NumberOrPercentage::parse_non_negative(context, input)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)]
|
||||||
pub struct Opacity(Number);
|
pub struct Opacity(Number);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue