mirror of
https://github.com/servo/servo.git
synced 2025-07-16 11:53:39 +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)]
|
||||
pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
|
||||
use crate::values::Either;
|
||||
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||
|
||||
match v {
|
||||
Either::Second(_auto) => {
|
||||
|
@ -3757,15 +3758,21 @@ fn static_assert() {
|
|||
self.gecko.mImageRegion.height = 0;
|
||||
}
|
||||
Either::First(rect) => {
|
||||
self.gecko.mImageRegion.x = rect.left.map(Au::from).unwrap_or(Au(0)).0;
|
||||
self.gecko.mImageRegion.y = rect.top.map(Au::from).unwrap_or(Au(0)).0;
|
||||
self.gecko.mImageRegion.x = match rect.left {
|
||||
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 {
|
||||
Some(value) => (Au::from(value) - Au(self.gecko.mImageRegion.y)).0,
|
||||
None => 0,
|
||||
LengthPercentage(value) => (Au::from(value) - Au(self.gecko.mImageRegion.y)).0,
|
||||
Auto => 0,
|
||||
};
|
||||
self.gecko.mImageRegion.width = match rect.right {
|
||||
Some(value) => (Au::from(value) - Au(self.gecko.mImageRegion.x)).0,
|
||||
None => 0,
|
||||
LengthPercentage(value) => (Au::from(value) - Au(self.gecko.mImageRegion.x)).0,
|
||||
Auto => 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3774,6 +3781,7 @@ fn static_assert() {
|
|||
#[allow(non_snake_case)]
|
||||
pub fn clone__moz_image_region(&self) -> longhands::_moz_image_region::computed_value::T {
|
||||
use crate::values::{Auto, Either};
|
||||
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||
use crate::values::computed::ClipRect;
|
||||
|
||||
// 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 {
|
||||
top: Some(Au(self.gecko.mImageRegion.y).into()),
|
||||
right: Some(Au(self.gecko.mImageRegion.width + self.gecko.mImageRegion.x).into()),
|
||||
bottom: Some(Au(self.gecko.mImageRegion.height + self.gecko.mImageRegion.y).into()),
|
||||
left: Some(Au(self.gecko.mImageRegion.x).into()),
|
||||
top: LengthPercentage(Au(self.gecko.mImageRegion.y).into()),
|
||||
right: LengthPercentage(Au(self.gecko.mImageRegion.width + self.gecko.mImageRegion.x).into()),
|
||||
bottom: LengthPercentage(Au(self.gecko.mImageRegion.height + self.gecko.mImageRegion.y).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_RIGHT_AUTO;
|
||||
use crate::gecko_bindings::structs::NS_STYLE_CLIP_BOTTOM_AUTO;
|
||||
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||
use crate::values::Either;
|
||||
|
||||
match v {
|
||||
Either::First(rect) => {
|
||||
self.gecko.mClipFlags = NS_STYLE_CLIP_RECT as u8;
|
||||
if let Some(left) = rect.left {
|
||||
self.gecko.mClip.x = left.to_i32_au();
|
||||
} else {
|
||||
self.gecko.mClip.x = 0;
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO as u8;
|
||||
}
|
||||
self.gecko.mClip.x = match rect.left {
|
||||
LengthPercentage(l) => l.to_i32_au(),
|
||||
Auto => {
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO as u8;
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(top) = rect.top {
|
||||
self.gecko.mClip.y = top.to_i32_au();
|
||||
} else {
|
||||
self.gecko.mClip.y = 0;
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
|
||||
}
|
||||
self.gecko.mClip.y = match rect.top {
|
||||
LengthPercentage(l) => l.to_i32_au(),
|
||||
Auto => {
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_TOP_AUTO as u8;
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(bottom) = rect.bottom {
|
||||
self.gecko.mClip.height = (Au::from(bottom) - Au(self.gecko.mClip.y)).0;
|
||||
} else {
|
||||
self.gecko.mClip.height = 1 << 30; // NS_MAXSIZE
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO as u8;
|
||||
}
|
||||
self.gecko.mClip.height = match rect.bottom {
|
||||
LengthPercentage(l) => (Au::from(l) - Au(self.gecko.mClip.y)).0,
|
||||
Auto => {
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO as u8;
|
||||
1 << 30 // NS_MAXSIZE
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(right) = rect.right {
|
||||
self.gecko.mClip.width = (Au::from(right) - Au(self.gecko.mClip.x)).0;
|
||||
} else {
|
||||
self.gecko.mClip.width = 1 << 30; // NS_MAXSIZE
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO as u8;
|
||||
}
|
||||
self.gecko.mClip.width = match rect.right {
|
||||
LengthPercentage(l) => (Au::from(l) - Au(self.gecko.mClip.x)).0,
|
||||
Auto => {
|
||||
self.gecko.mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO as u8;
|
||||
1 << 30 // NS_MAXSIZE
|
||||
}
|
||||
};
|
||||
},
|
||||
Either::Second(_auto) => {
|
||||
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_RIGHT_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::Either;
|
||||
|
||||
if self.gecko.mClipFlags == NS_STYLE_CLIP_AUTO as u8 {
|
||||
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 })
|
||||
return ClipRectOrAuto::auto()
|
||||
}
|
||||
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 {
|
||||
#[inline]
|
||||
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
|
||||
use crate::values::computed::Length;
|
||||
let animate_component = |this: &Option<Length>, other: &Option<Length>| {
|
||||
match (this.animate(other, procedure)?, procedure) {
|
||||
(None, Procedure::Interpolate { .. }) => Ok(None),
|
||||
(None, _) => Err(()),
|
||||
(result, _) => Ok(result),
|
||||
use crate::values::computed::LengthOrAuto;
|
||||
let animate_component = |this: &LengthOrAuto, other: &LengthOrAuto| {
|
||||
let result = this.animate(other, procedure)?;
|
||||
if let Procedure::Interpolate { .. } = procedure {
|
||||
return 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 {
|
||||
top: animate_component(&self.top, &other.top)?,
|
||||
right: animate_component(&self.right, &other.right)?,
|
||||
top: animate_component(&self.top, &other.top)?,
|
||||
right: animate_component(&self.right, &other.right)?,
|
||||
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',
|
||||
'HueRotate', 'Invert', 'Opacity', 'Saturate',
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
${helpers.predefined_type(
|
||||
"column-width",
|
||||
"length::NonNegativeLengthOrAuto",
|
||||
"Either::Second(Auto)",
|
||||
initial_specified_value="Either::Second(Auto)",
|
||||
"computed::length::NonNegativeLengthOrAuto::auto()",
|
||||
initial_specified_value="specified::length::NonNegativeLengthOrAuto::auto()",
|
||||
extra_prefixes="moz",
|
||||
animation_value_type="NonNegativeLengthOrAuto",
|
||||
servo_pref="layout.columns.enabled",
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::values::generics::length::{
|
|||
use crate::values::generics::NonNegative;
|
||||
use crate::values::specified::length::ViewportPercentageLength;
|
||||
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 app_units::Au;
|
||||
use ordered_float::NotNan;
|
||||
|
@ -701,7 +701,10 @@ impl From<Au> for CSSPixelLength {
|
|||
pub type Length = CSSPixelLength;
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
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::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||
use super::generics::transform::IsParallelTo;
|
||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::specified;
|
||||
use super::{CSSFloat, CSSInteger};
|
||||
use crate::context::QuirksMode;
|
||||
|
@ -27,8 +27,6 @@ use euclid::Size2D;
|
|||
use std::cell::RefCell;
|
||||
use std::cmp;
|
||||
use std::f32;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ToCss};
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
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::length::{CSSPixelLength, ExtremumLength, NonNegativeLength};
|
||||
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};
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use self::list::ListStyleType;
|
||||
|
@ -637,52 +635,8 @@ impl From<CSSInteger> for PositiveInteger {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
|
||||
#[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(...)
|
||||
pub type ClipRect = generics::ClipRect<LengthOrAuto>;
|
||||
|
||||
/// rect(...) | auto
|
||||
pub type ClipRectOrAuto = Either<ClipRect, Auto>;
|
||||
|
|
|
@ -212,3 +212,14 @@ impl<T: Zero> Zero for NonNegative<T> {
|
|||
ToCss,
|
||||
)]
|
||||
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::specified::calc::CalcNode;
|
||||
use crate::values::specified::NonNegativeNumber;
|
||||
use crate::values::{Auto, CSSFloat, Either, Normal};
|
||||
use crate::values::{CSSFloat, Either, Normal};
|
||||
use crate::Zero;
|
||||
use app_units::Au;
|
||||
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
|
||||
/// `<percentage>`, or a combination of both via `calc()`.
|
||||
///
|
||||
|
@ -997,7 +994,25 @@ impl NonNegativeLengthPercentage {
|
|||
pub type LengthOrNormal = Either<Length, Normal>;
|
||||
|
||||
/// 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>`.
|
||||
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::{TrackList as GenericTrackList, TrackSize as GenericTrackSize};
|
||||
use super::generics::transform::IsParallelTo;
|
||||
use super::generics::{GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::generics::{self, GreaterThanOrEqualToOne, NonNegative};
|
||||
use super::{Auto, CSSFloat, CSSInteger, Either};
|
||||
use crate::context::QuirksMode;
|
||||
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::length::{AbsoluteLength, CalcLengthPercentage, CharacterWidth};
|
||||
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::{NoCalcLength, ViewportPercentageLength};
|
||||
pub use self::length::{NonNegativeLengthPercentage, NonNegativeLengthPercentageOrAuto};
|
||||
|
@ -605,99 +605,8 @@ pub type GridLine = GenericGridLine<Integer>;
|
|||
/// `<grid-template-rows> | <grid-template-columns>`
|
||||
pub type GridTemplateComponent = GenericGridTemplateComponent<LengthPercentage, Integer>;
|
||||
|
||||
#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo)]
|
||||
/// rect(<top>, <left>, <bottom>, <right>) used by clip and image-region
|
||||
#[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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// rect(...)
|
||||
pub type ClipRect = generics::ClipRect<LengthOrAuto>;
|
||||
|
||||
impl Parse for ClipRect {
|
||||
fn parse<'i, 't>(
|
||||
|
@ -715,25 +624,16 @@ impl ClipRect {
|
|||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
use crate::values::specified::Length;
|
||||
input.expect_function_matching("rect")?;
|
||||
|
||||
fn parse_argument<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allow_quirks: AllowQuirks,
|
||||
) -> Result<Option<Length>, ParseError<'i>> {
|
||||
if input
|
||||
.try(|input| input.expect_ident_matching("auto"))
|
||||
.is_ok()
|
||||
{
|
||||
Ok(None)
|
||||
} else {
|
||||
Length::parse_quirky(context, input, allow_quirks).map(Some)
|
||||
}
|
||||
) -> Result<LengthOrAuto, ParseError<'i>> {
|
||||
LengthOrAuto::parse_quirky(context, input, allow_quirks)
|
||||
}
|
||||
|
||||
input.expect_function_matching("rect")?;
|
||||
|
||||
input.parse_nested_block(|input| {
|
||||
let top = parse_argument(context, input, allow_quirks)?;
|
||||
let right;
|
||||
|
@ -751,12 +651,8 @@ impl ClipRect {
|
|||
bottom = parse_argument(context, input, allow_quirks)?;
|
||||
left = parse_argument(context, input, allow_quirks)?;
|
||||
}
|
||||
Ok(ClipRect {
|
||||
top: top,
|
||||
right: right,
|
||||
bottom: bottom,
|
||||
left: left,
|
||||
})
|
||||
|
||||
Ok(ClipRect { top, right, bottom, left })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue