mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +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
|
||||
//! Ideally, it would be in geckolib itself, but coherence
|
||||
//! forces us to keep the traits and implementations here
|
||||
//!
|
||||
//! FIXME(emilio): This file should generally just die.
|
||||
|
||||
#![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::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto};
|
||||
use crate::values::computed::{Percentage, TextAlign};
|
||||
use crate::values::generics::NonNegative;
|
||||
use crate::values::generics::box_::VerticalAlign;
|
||||
use crate::values::generics::grid::{TrackListValue, TrackSize};
|
||||
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.
|
||||
impl From<nsStyleCoord_CalcValue> for NonNegativeLengthOrPercentageOrAuto {
|
||||
fn from(other: nsStyleCoord_CalcValue) -> Self {
|
||||
use crate::values::generics::NonNegative;
|
||||
use style_traits::values::specified::AllowedNumericType;
|
||||
NonNegative(if other.mLength < 0 || other.mPercent < 0. {
|
||||
LengthOrPercentageOrAuto::Calc(CalcLengthOrPercentage::with_clamping_mode(
|
||||
|
@ -675,6 +677,7 @@ pub mod basic_shape {
|
|||
use crate::values::generics::basic_shape::{
|
||||
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::{GeometryBox, ShapeBox, ShapeSource};
|
||||
use crate::values::generics::border::BorderRadius as GenericBorderRadius;
|
||||
|
@ -838,10 +841,10 @@ pub mod basic_shape {
|
|||
fn from(other: &'a nsStyleCorners) -> Self {
|
||||
let get_corner = |index| {
|
||||
BorderCornerRadius::new(
|
||||
LengthOrPercentage::from_gecko_style_coord(&other.data_at(index))
|
||||
.expect("<border-radius> should be a length, percentage, or calc value"),
|
||||
LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1))
|
||||
.expect("<border-radius> should be a length, percentage, or calc value"),
|
||||
NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index))
|
||||
.expect("<border-radius> should be a length, percentage, or calc value")),
|
||||
NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1))
|
||||
.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 {
|
||||
use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL;
|
||||
use crate::values::computed::{BorderImageSlice, NumberOrPercentage};
|
||||
type NumberOrPercentageRect = crate::values::generics::rect::Rect<NumberOrPercentage>;
|
||||
use crate::values::computed::{BorderImageSlice, NonNegativeNumberOrPercentage};
|
||||
type NumberOrPercentageRect = crate::values::generics::rect::Rect<NonNegativeNumberOrPercentage>;
|
||||
|
||||
BorderImageSlice {
|
||||
offsets:
|
||||
|
|
|
@ -153,14 +153,15 @@ ${helpers.predefined_type(
|
|||
${helpers.predefined_type(
|
||||
"border-image-slice",
|
||||
"BorderImageSlice",
|
||||
initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()",
|
||||
initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()",
|
||||
initial_value="computed::BorderImageSlice::hundred_percent()",
|
||||
initial_specified_value="specified::BorderImageSlice::hundred_percent()",
|
||||
spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice",
|
||||
animation_value_type="discrete",
|
||||
flags="APPLIES_TO_FIRST_LETTER",
|
||||
boxed=True,
|
||||
)}
|
||||
|
||||
// FIXME(emilio): Why does this live here? ;_;
|
||||
#[cfg(feature = "gecko")]
|
||||
impl crate::values::computed::BorderImageWidth {
|
||||
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}))
|
||||
},
|
||||
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
|
||||
|
@ -191,6 +192,7 @@ impl crate::values::computed::BorderImageWidth {
|
|||
use crate::gecko::values::GeckoStyleCoordConvertible;
|
||||
use crate::values::computed::{LengthOrPercentage, Number};
|
||||
use crate::values::generics::border::BorderImageSideWidth;
|
||||
use crate::values::generics::NonNegative;
|
||||
|
||||
Some(
|
||||
crate::values::computed::BorderImageWidth::new(
|
||||
|
@ -201,13 +203,13 @@ impl crate::values::computed::BorderImageWidth {
|
|||
},
|
||||
eStyleUnit_Factor => {
|
||||
BorderImageSideWidth::Number(
|
||||
Number::from_gecko_style_coord(&sides.data_at(${i}))
|
||||
.expect("sides[${i}] could not convert to Number"))
|
||||
NonNegative(Number::from_gecko_style_coord(&sides.data_at(${i}))
|
||||
.expect("sides[${i}] could not convert to Number")))
|
||||
},
|
||||
_ => {
|
||||
BorderImageSideWidth::Length(
|
||||
LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i}))
|
||||
.expect("sides[${i}] could not convert to LengthOrPercentager"))
|
||||
NonNegative(LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i}))
|
||||
.expect("sides[${i}] could not convert to LengthOrPercentage")))
|
||||
},
|
||||
},
|
||||
% endfor
|
||||
|
|
|
@ -295,7 +295,7 @@ ${helpers.predefined_type(
|
|||
"-webkit-text-stroke-width",
|
||||
"BorderSideWidth",
|
||||
"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",
|
||||
products="gecko",
|
||||
gecko_pref="layout.css.prefixes.webkit",
|
||||
|
|
|
@ -12,7 +12,6 @@ use crate::properties::PropertyId;
|
|||
use crate::values::computed::length::CalcLengthOrPercentage;
|
||||
use crate::values::computed::url::ComputedUrl;
|
||||
use crate::values::computed::Angle as ComputedAngle;
|
||||
use crate::values::computed::BorderCornerRadius as ComputedBorderCornerRadius;
|
||||
use crate::values::CSSFloat;
|
||||
use app_units::Au;
|
||||
use euclid::{Point2D, Size2D};
|
||||
|
@ -340,23 +339,6 @@ trivial_to_animated_value!(ComputedUrl);
|
|||
trivial_to_animated_value!(bool);
|
||||
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 {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape
|
||||
|
||||
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 std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
@ -24,10 +24,10 @@ pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
|||
|
||||
/// A computed basic shape.
|
||||
pub type BasicShape =
|
||||
generic::BasicShape<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
|
||||
generic::BasicShape<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||
|
||||
/// The computed value of `inset()`
|
||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage>;
|
||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||
|
||||
/// A computed circle.
|
||||
pub type Circle = generic::Circle<LengthOrPercentage, LengthOrPercentage, LengthOrPercentage>;
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
//! Computed types for CSS values related to borders.
|
||||
|
||||
use crate::values::animated::ToAnimatedZero;
|
||||
use crate::values::computed::length::{LengthOrPercentage, NonNegativeLength};
|
||||
use crate::values::computed::{Number, NumberOrPercentage};
|
||||
use crate::values::generics::NonNegative;
|
||||
use crate::values::computed::length::{NonNegativeLengthOrPercentage, NonNegativeLength};
|
||||
use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage};
|
||||
use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
|
||||
use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth;
|
||||
use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice;
|
||||
|
@ -22,16 +22,16 @@ pub use crate::values::specified::border::BorderImageRepeat;
|
|||
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
||||
|
||||
/// 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.
|
||||
pub type BorderImageSlice = GenericBorderImageSlice<NumberOrPercentage>;
|
||||
pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>;
|
||||
|
||||
/// 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.
|
||||
pub type BorderCornerRadius = GenericBorderCornerRadius<LengthOrPercentage>;
|
||||
pub type BorderCornerRadius = GenericBorderCornerRadius<NonNegativeLengthOrPercentage>;
|
||||
|
||||
/// A computed value for the `border-spacing` longhand property.
|
||||
pub type BorderSpacing = GenericBorderSpacing<NonNegativeLength>;
|
||||
|
@ -40,7 +40,18 @@ impl BorderImageSideWidth {
|
|||
/// Returns `1`.
|
||||
#[inline]
|
||||
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`.
|
||||
pub fn zero() -> Self {
|
||||
GenericBorderCornerRadius(Size::new(
|
||||
LengthOrPercentage::zero(),
|
||||
LengthOrPercentage::zero(),
|
||||
NonNegativeLengthOrPercentage::zero(),
|
||||
NonNegativeLengthOrPercentage::zero(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToAnimatedZero for BorderCornerRadius {
|
||||
#[inline]
|
||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
||||
// FIXME(nox): Why?
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
impl BorderRadius {
|
||||
/// Returns whether all the values are `0px`.
|
||||
pub fn all_zero(&self) -> bool {
|
||||
fn all(corner: &BorderCornerRadius) -> bool {
|
||||
fn is_zero(l: &LengthOrPercentage) -> bool {
|
||||
*l == LengthOrPercentage::zero()
|
||||
fn is_zero(l: &NonNegativeLengthOrPercentage) -> bool {
|
||||
*l == NonNegativeLengthOrPercentage::zero()
|
||||
}
|
||||
is_zero(corner.0.width()) && is_zero(corner.0.height())
|
||||
}
|
||||
|
|
|
@ -543,6 +543,15 @@ pub enum NumberOrPercentage {
|
|||
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 {
|
||||
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.
|
||||
pub type Opacity = CSSFloat;
|
||||
|
||||
|
|
|
@ -85,8 +85,8 @@ pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
|
|||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
pub enum BasicShape<H, V, LengthOrPercentage> {
|
||||
Inset(#[css(field_bound)] InsetRect<LengthOrPercentage>),
|
||||
pub enum BasicShape<H, V, LengthOrPercentage, NonNegativeLengthOrPercentage> {
|
||||
Inset(#[css(field_bound)] InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>),
|
||||
Circle(#[css(field_bound)] Circle<H, V, LengthOrPercentage>),
|
||||
Ellipse(#[css(field_bound)] Ellipse<H, V, LengthOrPercentage>),
|
||||
Polygon(Polygon<LengthOrPercentage>),
|
||||
|
@ -105,9 +105,9 @@ pub enum BasicShape<H, V, LengthOrPercentage> {
|
|||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
)]
|
||||
pub struct InsetRect<LengthOrPercentage> {
|
||||
pub struct InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage> {
|
||||
pub rect: Rect<LengthOrPercentage>,
|
||||
pub round: Option<BorderRadius<LengthOrPercentage>>,
|
||||
pub round: Option<BorderRadius<NonNegativeLengthOrPercentage>>,
|
||||
}
|
||||
|
||||
/// <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
|
||||
L: ToCss + PartialEq,
|
||||
Length: ToCss + PartialEq,
|
||||
NonNegativeLength: ToCss + PartialEq,
|
||||
{
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
|
|
|
@ -45,6 +45,8 @@ pub struct BorderImageSlice<NumberOrPercentage> {
|
|||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToAnimatedValue,
|
||||
ToAnimatedZero,
|
||||
ToComputedValue,
|
||||
ToCss,
|
||||
)]
|
||||
|
@ -106,19 +108,6 @@ pub struct BorderRadius<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> {
|
||||
/// Returns a new `BorderRadius<L>`.
|
||||
#[inline]
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::values::specified::border::BorderRadius;
|
|||
use crate::values::specified::image::Image;
|
||||
use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition};
|
||||
use crate::values::specified::url::SpecifiedUrl;
|
||||
use crate::values::specified::LengthOrPercentage;
|
||||
use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage};
|
||||
use crate::values::specified::SVGPathData;
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
|
@ -32,10 +32,10 @@ pub type ClippingShape = generic::ClippingShape<BasicShape, SpecifiedUrl>;
|
|||
pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>;
|
||||
|
||||
/// 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()`
|
||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage>;
|
||||
pub type InsetRect = generic::InsetRect<LengthOrPercentage, NonNegativeLengthOrPercentage>;
|
||||
|
||||
/// A specified circle.
|
||||
pub type Circle = generic::Circle<HorizontalPosition, VerticalPosition, LengthOrPercentage>;
|
||||
|
@ -199,10 +199,7 @@ impl InsetRect {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
Ok(generic::InsetRect {
|
||||
rect: rect,
|
||||
round: round,
|
||||
})
|
||||
Ok(generic::InsetRect { rect, 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::rect::Rect;
|
||||
use crate::values::generics::size::Size;
|
||||
use crate::values::specified::length::{Length, LengthOrPercentage, NonNegativeLength};
|
||||
use crate::values::specified::{AllowQuirks, Number, NumberOrPercentage};
|
||||
use crate::values::specified::length::{NonNegativeLengthOrPercentage, NonNegativeLength};
|
||||
use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage};
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
|
@ -71,28 +71,45 @@ pub enum BorderSideWidth {
|
|||
/// `thick`
|
||||
Thick,
|
||||
/// `<length>`
|
||||
Length(Length),
|
||||
Length(NonNegativeLength),
|
||||
}
|
||||
|
||||
/// A specified value for the `border-image-width` property.
|
||||
pub type BorderImageWidth = Rect<BorderImageSideWidth>;
|
||||
|
||||
/// 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.
|
||||
pub type BorderImageSlice = GenericBorderImageSlice<NumberOrPercentage>;
|
||||
pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>;
|
||||
|
||||
/// 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.
|
||||
pub type BorderCornerRadius = GenericBorderCornerRadius<LengthOrPercentage>;
|
||||
pub type BorderCornerRadius = GenericBorderCornerRadius<NonNegativeLengthOrPercentage>;
|
||||
|
||||
/// A specified value for the `border-spacing` longhand properties.
|
||||
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 {
|
||||
/// Returns the `0px` value.
|
||||
#[inline]
|
||||
pub fn zero() -> Self {
|
||||
BorderSideWidth::Length(NonNegativeLength::zero())
|
||||
}
|
||||
|
||||
/// Parses, with quirks.
|
||||
pub fn parse_quirky<'i, 't>(
|
||||
context: &ParserContext,
|
||||
|
@ -100,7 +117,7 @@ impl BorderSideWidth {
|
|||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
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));
|
||||
}
|
||||
|
@ -130,9 +147,9 @@ impl ToComputedValue for BorderSideWidth {
|
|||
// Spec: https://drafts.csswg.org/css-backgrounds-3/#line-width
|
||||
// Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1312155#c0
|
||||
match *self {
|
||||
BorderSideWidth::Thin => Length::from_px(1.).to_computed_value(context),
|
||||
BorderSideWidth::Medium => Length::from_px(3.).to_computed_value(context),
|
||||
BorderSideWidth::Thick => Length::from_px(5.).to_computed_value(context),
|
||||
BorderSideWidth::Thin => NonNegativeLength::from_px(1.).to_computed_value(context),
|
||||
BorderSideWidth::Medium => NonNegativeLength::from_px(3.).to_computed_value(context),
|
||||
BorderSideWidth::Thick => NonNegativeLength::from_px(5.).to_computed_value(context),
|
||||
BorderSideWidth::Length(ref length) => length.to_computed_value(context),
|
||||
}
|
||||
.into()
|
||||
|
@ -140,7 +157,7 @@ impl ToComputedValue for BorderSideWidth {
|
|||
|
||||
#[inline]
|
||||
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`.
|
||||
#[inline]
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
let num = Number::parse_non_negative(context, input)?;
|
||||
let num = NonNegativeNumber::parse(context, input)?;
|
||||
Ok(GenericBorderImageSideWidth::Number(num))
|
||||
}
|
||||
}
|
||||
|
@ -176,14 +193,11 @@ impl Parse for BorderImageSlice {
|
|||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
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 {
|
||||
fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
||||
}
|
||||
Ok(GenericBorderImageSlice {
|
||||
offsets: offsets,
|
||||
fill: fill,
|
||||
})
|
||||
Ok(GenericBorderImageSlice { offsets, fill })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,9 +206,9 @@ impl Parse for BorderRadius {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> 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() {
|
||||
Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?
|
||||
Rect::parse_with(context, input, NonNegativeLengthOrPercentage::parse)?
|
||||
} else {
|
||||
widths.clone()
|
||||
};
|
||||
|
@ -213,7 +227,7 @@ impl Parse for BorderCornerRadius {
|
|||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
Size::parse_with(context, input, LengthOrPercentage::parse_non_negative)
|
||||
Size::parse_with(context, input, NonNegativeLengthOrPercentage::parse)
|
||||
.map(GenericBorderCornerRadius)
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +238,7 @@ impl Parse for BorderSpacing {
|
|||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -717,6 +717,16 @@ impl NonNegativeLength {
|
|||
pub fn from_px(px_value: CSSFloat) -> Self {
|
||||
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.
|
||||
|
|
|
@ -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)]
|
||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)]
|
||||
pub struct Opacity(Number);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue