mirror of
https://github.com/servo/servo.git
synced 2025-07-17 20:33:40 +01:00
style: Derive more stuff for clip rects.
I feel a bit weird for using LenghtPercentageOrAuto to implement LengthOrAuto, but I don't think much other code will use it so it seemed a bit better to me. Differential Revision: https://phabricator.services.mozilla.com/D21863
This commit is contained in:
parent
e723a5b7d6
commit
e0b3e5f691
8 changed files with 143 additions and 254 deletions
|
@ -3748,6 +3748,7 @@ fn static_assert() {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
|
pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
|
|
||||||
match v {
|
match v {
|
||||||
Either::Second(_auto) => {
|
Either::Second(_auto) => {
|
||||||
|
@ -3757,15 +3758,21 @@ fn static_assert() {
|
||||||
self.gecko.mImageRegion.height = 0;
|
self.gecko.mImageRegion.height = 0;
|
||||||
}
|
}
|
||||||
Either::First(rect) => {
|
Either::First(rect) => {
|
||||||
self.gecko.mImageRegion.x = rect.left.map(Au::from).unwrap_or(Au(0)).0;
|
self.gecko.mImageRegion.x = match rect.left {
|
||||||
self.gecko.mImageRegion.y = rect.top.map(Au::from).unwrap_or(Au(0)).0;
|
LengthPercentage(v) => v.to_i32_au(),
|
||||||
|
Auto => 0,
|
||||||
|
};
|
||||||
|
self.gecko.mImageRegion.y = match rect.top {
|
||||||
|
LengthPercentage(v) => v.to_i32_au(),
|
||||||
|
Auto => 0,
|
||||||
|
};
|
||||||
self.gecko.mImageRegion.height = match rect.bottom {
|
self.gecko.mImageRegion.height = match rect.bottom {
|
||||||
Some(value) => (Au::from(value) - Au(self.gecko.mImageRegion.y)).0,
|
LengthPercentage(value) => (Au::from(value) - Au(self.gecko.mImageRegion.y)).0,
|
||||||
None => 0,
|
Auto => 0,
|
||||||
};
|
};
|
||||||
self.gecko.mImageRegion.width = match rect.right {
|
self.gecko.mImageRegion.width = match rect.right {
|
||||||
Some(value) => (Au::from(value) - Au(self.gecko.mImageRegion.x)).0,
|
LengthPercentage(value) => (Au::from(value) - Au(self.gecko.mImageRegion.x)).0,
|
||||||
None => 0,
|
Auto => 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3774,6 +3781,7 @@ fn static_assert() {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn clone__moz_image_region(&self) -> longhands::_moz_image_region::computed_value::T {
|
pub fn clone__moz_image_region(&self) -> longhands::_moz_image_region::computed_value::T {
|
||||||
use crate::values::{Auto, Either};
|
use crate::values::{Auto, Either};
|
||||||
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
use crate::values::computed::ClipRect;
|
use crate::values::computed::ClipRect;
|
||||||
|
|
||||||
// There is no ideal way to detect auto type for structs::nsRect and its components, so
|
// There is no ideal way to detect auto type for structs::nsRect and its components, so
|
||||||
|
@ -3786,10 +3794,10 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Either::First(ClipRect {
|
Either::First(ClipRect {
|
||||||
top: Some(Au(self.gecko.mImageRegion.y).into()),
|
top: LengthPercentage(Au(self.gecko.mImageRegion.y).into()),
|
||||||
right: Some(Au(self.gecko.mImageRegion.width + self.gecko.mImageRegion.x).into()),
|
right: LengthPercentage(Au(self.gecko.mImageRegion.width + self.gecko.mImageRegion.x).into()),
|
||||||
bottom: Some(Au(self.gecko.mImageRegion.height + self.gecko.mImageRegion.y).into()),
|
bottom: LengthPercentage(Au(self.gecko.mImageRegion.height + self.gecko.mImageRegion.y).into()),
|
||||||
left: Some(Au(self.gecko.mImageRegion.x).into()),
|
left: LengthPercentage(Au(self.gecko.mImageRegion.x).into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3846,38 +3854,43 @@ fn static_assert() {
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_TOP_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_TOP_AUTO;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_BOTTOM_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_BOTTOM_AUTO;
|
||||||
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
|
|
||||||
match v {
|
match v {
|
||||||
Either::First(rect) => {
|
Either::First(rect) => {
|
||||||
self.gecko.mClipFlags = NS_STYLE_CLIP_RECT as u8;
|
self.gecko.mClipFlags = NS_STYLE_CLIP_RECT as u8;
|
||||||
if let Some(left) = rect.left {
|
self.gecko.mClip.x = match rect.left {
|
||||||
self.gecko.mClip.x = left.to_i32_au();
|
LengthPercentage(l) => l.to_i32_au(),
|
||||||
} else {
|
Auto => {
|
||||||
self.gecko.mClip.x = 0;
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO as u8;
|
||||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO as u8;
|
0
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(top) = rect.top {
|
self.gecko.mClip.y = match rect.top {
|
||||||
self.gecko.mClip.y = top.to_i32_au();
|
LengthPercentage(l) => l.to_i32_au(),
|
||||||
} else {
|
Auto => {
|
||||||
self.gecko.mClip.y = 0;
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
|
||||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
|
0
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(bottom) = rect.bottom {
|
self.gecko.mClip.height = match rect.bottom {
|
||||||
self.gecko.mClip.height = (Au::from(bottom) - Au(self.gecko.mClip.y)).0;
|
LengthPercentage(l) => (Au::from(l) - Au(self.gecko.mClip.y)).0,
|
||||||
} else {
|
Auto => {
|
||||||
self.gecko.mClip.height = 1 << 30; // NS_MAXSIZE
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO as u8;
|
||||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO as u8;
|
1 << 30 // NS_MAXSIZE
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(right) = rect.right {
|
self.gecko.mClip.width = match rect.right {
|
||||||
self.gecko.mClip.width = (Au::from(right) - Au(self.gecko.mClip.x)).0;
|
LengthPercentage(l) => (Au::from(l) - Au(self.gecko.mClip.x)).0,
|
||||||
} else {
|
Auto => {
|
||||||
self.gecko.mClip.width = 1 << 30; // NS_MAXSIZE
|
self.gecko.mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO as u8;
|
||||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO as u8;
|
1 << 30 // NS_MAXSIZE
|
||||||
}
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
Either::Second(_auto) => {
|
Either::Second(_auto) => {
|
||||||
self.gecko.mClipFlags = NS_STYLE_CLIP_AUTO as u8;
|
self.gecko.mClipFlags = NS_STYLE_CLIP_AUTO as u8;
|
||||||
|
@ -3904,42 +3917,42 @@ fn static_assert() {
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_LEFT_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_LEFT_AUTO;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_RIGHT_AUTO;
|
||||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_TOP_AUTO;
|
use crate::gecko_bindings::structs::NS_STYLE_CLIP_TOP_AUTO;
|
||||||
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
use crate::values::computed::{ClipRect, ClipRectOrAuto};
|
use crate::values::computed::{ClipRect, ClipRectOrAuto};
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
|
|
||||||
if self.gecko.mClipFlags == NS_STYLE_CLIP_AUTO as u8 {
|
if self.gecko.mClipFlags == NS_STYLE_CLIP_AUTO as u8 {
|
||||||
ClipRectOrAuto::auto()
|
return ClipRectOrAuto::auto()
|
||||||
} else {
|
|
||||||
let left = if self.gecko.mClipFlags & NS_STYLE_CLIP_LEFT_AUTO as u8 != 0 {
|
|
||||||
debug_assert_eq!(self.gecko.mClip.x, 0);
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Au(self.gecko.mClip.x).into())
|
|
||||||
};
|
|
||||||
|
|
||||||
let top = if self.gecko.mClipFlags & NS_STYLE_CLIP_TOP_AUTO as u8 != 0 {
|
|
||||||
debug_assert_eq!(self.gecko.mClip.y, 0);
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Au(self.gecko.mClip.y).into())
|
|
||||||
};
|
|
||||||
|
|
||||||
let bottom = if self.gecko.mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO as u8 != 0 {
|
|
||||||
debug_assert_eq!(self.gecko.mClip.height, 1 << 30); // NS_MAXSIZE
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Au(self.gecko.mClip.y + self.gecko.mClip.height).into())
|
|
||||||
};
|
|
||||||
|
|
||||||
let right = if self.gecko.mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO as u8 != 0 {
|
|
||||||
debug_assert_eq!(self.gecko.mClip.width, 1 << 30); // NS_MAXSIZE
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(Au(self.gecko.mClip.x + self.gecko.mClip.width).into())
|
|
||||||
};
|
|
||||||
|
|
||||||
Either::First(ClipRect { top, right, bottom, left })
|
|
||||||
}
|
}
|
||||||
|
let left = if self.gecko.mClipFlags & NS_STYLE_CLIP_LEFT_AUTO as u8 != 0 {
|
||||||
|
debug_assert_eq!(self.gecko.mClip.x, 0);
|
||||||
|
Auto
|
||||||
|
} else {
|
||||||
|
LengthPercentage(Au(self.gecko.mClip.x).into())
|
||||||
|
};
|
||||||
|
|
||||||
|
let top = if self.gecko.mClipFlags & NS_STYLE_CLIP_TOP_AUTO as u8 != 0 {
|
||||||
|
debug_assert_eq!(self.gecko.mClip.y, 0);
|
||||||
|
Auto
|
||||||
|
} else {
|
||||||
|
LengthPercentage(Au(self.gecko.mClip.y).into())
|
||||||
|
};
|
||||||
|
|
||||||
|
let bottom = if self.gecko.mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO as u8 != 0 {
|
||||||
|
debug_assert_eq!(self.gecko.mClip.height, 1 << 30); // NS_MAXSIZE
|
||||||
|
Auto
|
||||||
|
} else {
|
||||||
|
LengthPercentage(Au(self.gecko.mClip.y + self.gecko.mClip.height).into())
|
||||||
|
};
|
||||||
|
|
||||||
|
let right = if self.gecko.mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO as u8 != 0 {
|
||||||
|
debug_assert_eq!(self.gecko.mClip.width, 1 << 30); // NS_MAXSIZE
|
||||||
|
Auto
|
||||||
|
} else {
|
||||||
|
LengthPercentage(Au(self.gecko.mClip.x + self.gecko.mClip.width).into())
|
||||||
|
};
|
||||||
|
|
||||||
|
Either::First(ClipRect { top, right, bottom, left })
|
||||||
}
|
}
|
||||||
|
|
||||||
<%
|
<%
|
||||||
|
|
|
@ -802,29 +802,29 @@ impl ToAnimatedZero for Visibility {
|
||||||
impl Animate for ClipRect {
|
impl Animate for ClipRect {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||||
use crate::values::computed::Length;
|
use crate::values::computed::LengthOrAuto;
|
||||||
let animate_component = |this: &Option<Length>, other: &Option<Length>| {
|
let animate_component = |this: &LengthOrAuto, other: &LengthOrAuto| {
|
||||||
match (this.animate(other, procedure)?, procedure) {
|
let result = this.animate(other, procedure)?;
|
||||||
(None, Procedure::Interpolate { .. }) => Ok(None),
|
if let Procedure::Interpolate { .. } = procedure {
|
||||||
(None, _) => Err(()),
|
return Ok(result);
|
||||||
(result, _) => Ok(result),
|
|
||||||
}
|
}
|
||||||
|
if result.is_auto() {
|
||||||
|
// FIXME(emilio): Why? A couple SMIL tests fail without this,
|
||||||
|
// but it seems extremely fishy.
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ClipRect {
|
Ok(ClipRect {
|
||||||
top: animate_component(&self.top, &other.top)?,
|
top: animate_component(&self.top, &other.top)?,
|
||||||
right: animate_component(&self.right, &other.right)?,
|
right: animate_component(&self.right, &other.right)?,
|
||||||
bottom: animate_component(&self.bottom, &other.bottom)?,
|
bottom: animate_component(&self.bottom, &other.bottom)?,
|
||||||
left: animate_component(&self.left, &other.left)?,
|
left: animate_component(&self.left, &other.left)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToAnimatedZero for ClipRect {
|
|
||||||
#[inline]
|
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
<%
|
<%
|
||||||
FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale',
|
FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale',
|
||||||
'HueRotate', 'Invert', 'Opacity', 'Saturate',
|
'HueRotate', 'Invert', 'Opacity', 'Saturate',
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"column-width",
|
"column-width",
|
||||||
"length::NonNegativeLengthOrAuto",
|
"length::NonNegativeLengthOrAuto",
|
||||||
"Either::Second(Auto)",
|
"computed::length::NonNegativeLengthOrAuto::auto()",
|
||||||
initial_specified_value="Either::Second(Auto)",
|
initial_specified_value="specified::length::NonNegativeLengthOrAuto::auto()",
|
||||||
extra_prefixes="moz",
|
extra_prefixes="moz",
|
||||||
animation_value_type="NonNegativeLengthOrAuto",
|
animation_value_type="NonNegativeLengthOrAuto",
|
||||||
servo_pref="layout.columns.enabled",
|
servo_pref="layout.columns.enabled",
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::values::generics::length::{
|
||||||
use crate::values::generics::NonNegative;
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::specified::length::ViewportPercentageLength;
|
use crate::values::specified::length::ViewportPercentageLength;
|
||||||
use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
|
use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
|
||||||
use crate::values::{specified, Auto, CSSFloat, Either, Normal};
|
use crate::values::{specified, CSSFloat, Either, Normal};
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use ordered_float::NotNan;
|
use ordered_float::NotNan;
|
||||||
|
@ -701,7 +701,10 @@ impl From<Au> for CSSPixelLength {
|
||||||
pub type Length = CSSPixelLength;
|
pub type Length = CSSPixelLength;
|
||||||
|
|
||||||
/// Either a computed `<length>` or the `auto` keyword.
|
/// Either a computed `<length>` or the `auto` keyword.
|
||||||
pub type LengthOrAuto = Either<Length, Auto>;
|
pub type LengthOrAuto = generics::GenericLengthPercentageOrAuto<Length>;
|
||||||
|
|
||||||
|
/// Either a non-negative `<length>` or the `auto` keyword.
|
||||||
|
pub type NonNegativeLengthOrAuto = generics::GenericLengthPercentageOrAuto<NonNegativeLength>;
|
||||||
|
|
||||||
/// Either a computed `<length>` or a `<number>` value.
|
/// Either a computed `<length>` or a `<number>` value.
|
||||||
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
||||||
|
@ -779,9 +782,6 @@ impl From<NonNegativeLength> for Au {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Either a computed NonNegativeLength or the `auto` keyword.
|
|
||||||
pub type NonNegativeLengthOrAuto = Either<NonNegativeLength, Auto>;
|
|
||||||
|
|
||||||
/// Either a computed NonNegativeLength or the `normal` keyword.
|
/// Either a computed NonNegativeLength or the `normal` keyword.
|
||||||
pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
|
pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent
|
||||||
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
||||||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||||
use super::generics::transform::IsParallelTo;
|
use super::generics::transform::IsParallelTo;
|
||||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||||
use super::specified;
|
use super::specified;
|
||||||
use super::{CSSFloat, CSSInteger};
|
use super::{CSSFloat, CSSInteger};
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
|
@ -27,8 +27,6 @@ use euclid::Size2D;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::f32;
|
use std::f32;
|
||||||
use std::fmt::{self, Write};
|
|
||||||
use style_traits::{CssWriter, ToCss};
|
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment};
|
pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment};
|
||||||
|
@ -62,7 +60,7 @@ pub use self::gecko::ScrollSnapPoint;
|
||||||
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
|
pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect};
|
||||||
pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
|
pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
|
||||||
pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber};
|
pub use self::length::{Length, LengthOrNumber, LengthPercentage, NonNegativeLengthOrNumber};
|
||||||
pub use self::length::{LengthPercentageOrAuto, MaxSize, Size};
|
pub use self::length::{LengthOrAuto, LengthPercentageOrAuto, MaxSize, Size};
|
||||||
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::list::ListStyleType;
|
pub use self::list::ListStyleType;
|
||||||
|
@ -637,52 +635,8 @@ impl From<CSSInteger> for PositiveInteger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
/// rect(...)
|
||||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
pub type ClipRect = generics::ClipRect<LengthOrAuto>;
|
||||||
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq)]
|
|
||||||
/// A computed cliprect for clip and image-region
|
|
||||||
pub struct ClipRect {
|
|
||||||
pub top: Option<Length>,
|
|
||||||
pub right: Option<Length>,
|
|
||||||
pub bottom: Option<Length>,
|
|
||||||
pub left: Option<Length>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for ClipRect {
|
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
{
|
|
||||||
dest.write_str("rect(")?;
|
|
||||||
if let Some(top) = self.top {
|
|
||||||
top.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(right) = self.right {
|
|
||||||
right.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(bottom) = self.bottom {
|
|
||||||
bottom.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(left) = self.left {
|
|
||||||
left.to_css(dest)?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto")?;
|
|
||||||
}
|
|
||||||
dest.write_str(")")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// rect(...) | auto
|
/// rect(...) | auto
|
||||||
pub type ClipRectOrAuto = Either<ClipRect, Auto>;
|
pub type ClipRectOrAuto = Either<ClipRect, Auto>;
|
||||||
|
|
|
@ -212,3 +212,14 @@ impl<T: Zero> Zero for NonNegative<T> {
|
||||||
ToCss,
|
ToCss,
|
||||||
)]
|
)]
|
||||||
pub struct GreaterThanOrEqualToOne<T>(pub T);
|
pub struct GreaterThanOrEqualToOne<T>(pub T);
|
||||||
|
|
||||||
|
/// A clip rect for clip and image-region
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)]
|
||||||
|
#[css(function = "rect", comma)]
|
||||||
|
pub struct ClipRect<LengthOrAuto> {
|
||||||
|
pub top: LengthOrAuto,
|
||||||
|
pub right: LengthOrAuto,
|
||||||
|
pub bottom: LengthOrAuto,
|
||||||
|
pub left: LengthOrAuto,
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::values::generics::length::{
|
||||||
use crate::values::generics::NonNegative;
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::specified::calc::CalcNode;
|
use crate::values::specified::calc::CalcNode;
|
||||||
use crate::values::specified::NonNegativeNumber;
|
use crate::values::specified::NonNegativeNumber;
|
||||||
use crate::values::{Auto, CSSFloat, Either, Normal};
|
use crate::values::{CSSFloat, Either, Normal};
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
|
@ -729,9 +729,6 @@ impl NonNegativeLength {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Either a NonNegativeLength or the `auto` keyword.
|
|
||||||
pub type NonNegativeLengthOrAuto = Either<NonNegativeLength, Auto>;
|
|
||||||
|
|
||||||
/// A `<length-percentage>` value. This can be either a `<length>`, a
|
/// A `<length-percentage>` value. This can be either a `<length>`, a
|
||||||
/// `<percentage>`, or a combination of both via `calc()`.
|
/// `<percentage>`, or a combination of both via `calc()`.
|
||||||
///
|
///
|
||||||
|
@ -997,7 +994,25 @@ impl NonNegativeLengthPercentage {
|
||||||
pub type LengthOrNormal = Either<Length, Normal>;
|
pub type LengthOrNormal = Either<Length, Normal>;
|
||||||
|
|
||||||
/// Either a `<length>` or the `auto` keyword.
|
/// Either a `<length>` or the `auto` keyword.
|
||||||
pub type LengthOrAuto = Either<Length, Auto>;
|
pub type LengthOrAuto = generics::LengthPercentageOrAuto<Length>;
|
||||||
|
|
||||||
|
impl LengthOrAuto {
|
||||||
|
/// Parses a length, allowing the unitless length quirk.
|
||||||
|
/// <https://quirks.spec.whatwg.org/#the-unitless-length-quirk>
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_quirky<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
allow_quirks: AllowQuirks,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
Self::parse_with(context, input, |context, input| {
|
||||||
|
Length::parse_quirky(context, input, allow_quirks)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Either a non-negative `<length>` or the `auto` keyword.
|
||||||
|
pub type NonNegativeLengthOrAuto = generics::LengthPercentageOrAuto<NonNegativeLength>;
|
||||||
|
|
||||||
/// Either a `<length>` or a `<number>`.
|
/// Either a `<length>` or a `<number>`.
|
||||||
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
pub type LengthOrNumber = GenericLengthOrNumber<Length, Number>;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use super::computed::{Context, ToComputedValue};
|
||||||
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth};
|
||||||
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||||
use super::generics::transform::IsParallelTo;
|
use super::generics::transform::IsParallelTo;
|
||||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||||
use super::{Auto, CSSFloat, CSSInteger, Either};
|
use super::{Auto, CSSFloat, CSSInteger, Either};
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
|
@ -60,7 +60,7 @@ pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient};
|
||||||
pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};
|
pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect};
|
||||||
pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth};
|
pub use self::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth};
|
||||||
pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber};
|
pub use self::length::{FontRelativeLength, Length, LengthOrNumber, NonNegativeLengthOrNumber};
|
||||||
pub use self::length::{LengthPercentage, LengthPercentageOrAuto};
|
pub use self::length::{LengthOrAuto, LengthPercentage, LengthPercentageOrAuto};
|
||||||
pub use self::length::{MaxSize, Size};
|
pub use self::length::{MaxSize, Size};
|
||||||
pub use self::length::{NoCalcLength, ViewportPercentageLength};
|
pub use self::length::{NoCalcLength, ViewportPercentageLength};
|
||||||
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
||||||
|
@ -605,99 +605,8 @@ pub type GridLine = GenericGridLine<Integer>;
|
||||||
/// `<grid-template-rows> | <grid-template-columns>`
|
/// `<grid-template-rows> | <grid-template-columns>`
|
||||||
pub type GridTemplateComponent = GenericGridTemplateComponent<LengthPercentage, Integer>;
|
pub type GridTemplateComponent = GenericGridTemplateComponent<LengthPercentage, Integer>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo)]
|
/// rect(...)
|
||||||
/// rect(<top>, <left>, <bottom>, <right>) used by clip and image-region
|
pub type ClipRect = generics::ClipRect<LengthOrAuto>;
|
||||||
#[css(function = "rect")]
|
|
||||||
pub struct ClipRect {
|
|
||||||
/// <top> (<length> | <auto>)
|
|
||||||
pub top: Option<Length>,
|
|
||||||
/// <right> (<length> | <auto>)
|
|
||||||
pub right: Option<Length>,
|
|
||||||
/// <bottom> (<length> | <auto>)
|
|
||||||
pub bottom: Option<Length>,
|
|
||||||
/// <left> (<length> | <auto>)
|
|
||||||
pub left: Option<Length>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for ClipRect {
|
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
{
|
|
||||||
dest.write_str("rect(")?;
|
|
||||||
|
|
||||||
if let Some(ref top) = self.top {
|
|
||||||
top.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref right) = self.right {
|
|
||||||
right.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref bottom) = self.bottom {
|
|
||||||
bottom.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto, ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref left) = self.left {
|
|
||||||
left.to_css(dest)?;
|
|
||||||
} else {
|
|
||||||
dest.write_str("auto")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest.write_str(")")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToComputedValue for ClipRect {
|
|
||||||
type ComputedValue = super::computed::ClipRect;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect {
|
|
||||||
super::computed::ClipRect {
|
|
||||||
top: self.top.as_ref().map(|top| top.to_computed_value(context)),
|
|
||||||
right: self
|
|
||||||
.right
|
|
||||||
.as_ref()
|
|
||||||
.map(|right| right.to_computed_value(context)),
|
|
||||||
bottom: self
|
|
||||||
.bottom
|
|
||||||
.as_ref()
|
|
||||||
.map(|bottom| bottom.to_computed_value(context)),
|
|
||||||
left: self
|
|
||||||
.left
|
|
||||||
.as_ref()
|
|
||||||
.map(|left| left.to_computed_value(context)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(computed: &super::computed::ClipRect) -> Self {
|
|
||||||
ClipRect {
|
|
||||||
top: computed
|
|
||||||
.top
|
|
||||||
.map(|top| ToComputedValue::from_computed_value(&top)),
|
|
||||||
right: computed
|
|
||||||
.right
|
|
||||||
.map(|right| ToComputedValue::from_computed_value(&right)),
|
|
||||||
bottom: computed
|
|
||||||
.bottom
|
|
||||||
.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
|
|
||||||
left: computed
|
|
||||||
.left
|
|
||||||
.map(|left| ToComputedValue::from_computed_value(&left)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for ClipRect {
|
impl Parse for ClipRect {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
|
@ -715,25 +624,16 @@ impl ClipRect {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
use crate::values::specified::Length;
|
input.expect_function_matching("rect")?;
|
||||||
|
|
||||||
fn parse_argument<'i, 't>(
|
fn parse_argument<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Option<Length>, ParseError<'i>> {
|
) -> Result<LengthOrAuto, ParseError<'i>> {
|
||||||
if input
|
LengthOrAuto::parse_quirky(context, input, allow_quirks)
|
||||||
.try(|input| input.expect_ident_matching("auto"))
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
Length::parse_quirky(context, input, allow_quirks).map(Some)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input.expect_function_matching("rect")?;
|
|
||||||
|
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let top = parse_argument(context, input, allow_quirks)?;
|
let top = parse_argument(context, input, allow_quirks)?;
|
||||||
let right;
|
let right;
|
||||||
|
@ -751,12 +651,8 @@ impl ClipRect {
|
||||||
bottom = parse_argument(context, input, allow_quirks)?;
|
bottom = parse_argument(context, input, allow_quirks)?;
|
||||||
left = parse_argument(context, input, allow_quirks)?;
|
left = parse_argument(context, input, allow_quirks)?;
|
||||||
}
|
}
|
||||||
Ok(ClipRect {
|
|
||||||
top: top,
|
Ok(ClipRect { top, right, bottom, left })
|
||||||
right: right,
|
|
||||||
bottom: bottom,
|
|
||||||
left: left,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue