diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-09 08:15:16 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-09 08:15:16 -0600 |
commit | 35f328d7174c93bb6ef5913a206496779fb8d3bf (patch) | |
tree | 03b0ccc27588ea916c5b173f5b1b0e6c3324cc39 /components | |
parent | 99f125721017e0f46a5b01b8771245395b7cb880 (diff) | |
parent | c4fc49c55908f62b3a63ab72da492db9017d1aff (diff) | |
download | servo-35f328d7174c93bb6ef5913a206496779fb8d3bf.tar.gz servo-35f328d7174c93bb6ef5913a206496779fb8d3bf.zip |
Auto merge of #14049 - Wafflespeanut:lon, r=SimonSapin
Add a generic type for sharing some CSS types
<!-- Please describe your changes on the following line: -->
This would be useful for types such as `T(pub Option<U>)` or any type that's a mixture of two types (like `LengthOrFoo` for example). Well, it's a bit ugly, especially because we have to address the types as `Either::First` and `Either::Second` everywhere, but I don't have a brighter idea :smile:
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
<!-- Either: -->
- [x] These changes do not require tests because it's a refactor
r? @SimonSapin (cc @Manishearth @emilio)
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14049)
<!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r-- | components/layout/display_list_builder.rs | 11 | ||||
-rw-r--r-- | components/layout/fragment.rs | 5 | ||||
-rw-r--r-- | components/style/properties/helpers.mako.rs | 2 | ||||
-rw-r--r-- | components/style/properties/helpers/animated_properties.mako.rs | 5 | ||||
-rw-r--r-- | components/style/properties/longhand/effects.mako.rs | 2 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 3 | ||||
-rw-r--r-- | components/style/values/computed/length.rs | 58 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 1 | ||||
-rw-r--r-- | components/style/values/mod.rs | 105 | ||||
-rw-r--r-- | components/style/values/specified/length.rs | 49 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 1 |
11 files changed, 125 insertions, 117 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 3e5328afc27..ec881ea9bcb 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -52,9 +52,8 @@ use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMod use style::properties::{self, ServoComputedValues}; use style::properties::style_structs; use style::servo::restyle_damage::REPAINT; -use style::values::RGBA; -use style::values::computed; -use style::values::computed::{Gradient, GradientKind, LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto}; +use style::values::{self, Either, RGBA, computed}; +use style::values::computed::{Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection}; use style_traits::cursor::Cursor; use table_cell::CollapsedBordersForCell; @@ -1563,7 +1562,7 @@ impl FragmentDisplayListBuilding for Fragment { let transform = self.transform_matrix(&border_box); let perspective = match self.style().get_effects().perspective { - LengthOrNone::Length(d) => { + Either::First(length) => { let perspective_origin = self.style().get_effects().perspective_origin; let perspective_origin = Point2D::new(model::specified(perspective_origin.horizontal, @@ -1578,11 +1577,11 @@ impl FragmentDisplayListBuilding for Fragment { -perspective_origin.y, 0.0); - let perspective_matrix = create_perspective_matrix(d); + let perspective_matrix = create_perspective_matrix(length); pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform) } - LengthOrNone::None => { + Either::Second(values::None_) => { Matrix4D::identity() } }; diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 265f140ab63..7ff692e913b 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -49,7 +49,8 @@ use style::properties::ServoComputedValues; use style::selector_impl::RestyleDamage; use style::servo::restyle_damage::RECONSTRUCT_FLOW; use style::str::char_is_whitespace; -use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto}; +use style::values::Either; +use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::LengthOrPercentageOrNone; use text; use text::TextRunScanner; @@ -2586,7 +2587,7 @@ impl Fragment { // TODO(mrobinson): Determine if this is necessary, since blocks with // transformations already create stacking contexts. - if self.style().get_effects().perspective != LengthOrNone::None { + if let Either::First(ref _length) = self.style().get_effects().perspective { return true } diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index fe7bac7efe9..9c0aa616136 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -178,7 +178,7 @@ use parser::{ParserContext, ParserContextExtraData}; use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; % endif - #[allow(unused_imports)] + use values::{Auto, Either, None_, Normal}; use cascade_info::CascadeInfo; use error_reporting::ParseErrorReporter; use parser::Parse; diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 8b8e3c0b92f..39f9abaf29b 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -22,6 +22,7 @@ use std::cmp; use std::fmt; use style_traits::ToCss; use super::ComputedValues; +use values::Either; use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{BorderRadiusSize, LengthOrNone}; use values::computed::{CalcLengthOrPercentage, LengthOrPercentage}; @@ -682,8 +683,8 @@ impl Interpolate for BoxShadow { impl Interpolate for LengthOrNone { fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> { match (*self, *other) { - (LengthOrNone::Length(ref len), LengthOrNone::Length(ref other)) => - len.interpolate(&other, progress).map(LengthOrNone::Length), + (Either::First(ref length), Either::First(ref other)) => + length.interpolate(&other, progress).map(Either::First), _ => Err(()), } } diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index 5949bc48704..87595133b91 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -1395,7 +1395,7 @@ ${helpers.single_keyword("transform-style", ${helpers.predefined_type("perspective", "LengthOrNone", - "computed::LengthOrNone::None", + "Either::Second(None_)", products="servo", animatable=True)} diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index ca72c0c38aa..dfa2593e1cb 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -30,6 +30,7 @@ use logical_geometry::WritingMode; use parser::{ParserContext, ParserContextExtraData}; use style_traits::ToCss; use stylesheets::Origin; +#[cfg(feature = "servo")] use values::Either; use values::{HasViewportPercentage, computed}; use cascade_info::CascadeInfo; use rule_tree::StrongRuleNode; @@ -1249,7 +1250,7 @@ impl ComputedValues { if effects.transform.0.is_some() { return transform_style::T::flat; } - if effects.perspective != computed::LengthOrNone::None { + if let Either::First(ref _length) = effects.perspective { return transform_style::T::flat; } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 5d3044c3ac7..b08c3806ceb 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -7,7 +7,7 @@ use ordered_float::NotNaN; use std::fmt; use style_traits::ToCss; use super::{Number, ToComputedValue, Context}; -use values::{CSSFloat, specified}; +use values::{CSSFloat, Either, None_, specified}; pub use cssparser::Color as CSSColor; pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; @@ -452,61 +452,7 @@ impl ToCss for LengthOrPercentageOrNone { } } -#[derive(PartialEq, Clone, Copy)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum LengthOrNone { - Length(Au), - None, -} - -impl fmt::Debug for LengthOrNone { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - LengthOrNone::Length(length) => write!(f, "{:?}", length), - LengthOrNone::None => write!(f, "none"), - } - } -} - -impl ToComputedValue for specified::LengthOrNone { - type ComputedValue = LengthOrNone; - - #[inline] - fn to_computed_value(&self, context: &Context) -> LengthOrNone { - match *self { - specified::LengthOrNone::Length(specified::Length::Calc(calc, range)) => { - LengthOrNone::Length(range.clamp(calc.to_computed_value(context).length())) - } - specified::LengthOrNone::Length(value) => { - LengthOrNone::Length(value.to_computed_value(context)) - } - specified::LengthOrNone::None => { - LengthOrNone::None - } - } - } - - #[inline] - fn from_computed_value(computed: &LengthOrNone) -> Self { - match *computed { - LengthOrNone::Length(au) => { - specified::LengthOrNone::Length(ToComputedValue::from_computed_value(&au)) - } - LengthOrNone::None => { - specified::LengthOrNone::None - } - } - } -} - -impl ToCss for LengthOrNone { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - LengthOrNone::Length(length) => length.to_css(dest), - LengthOrNone::None => dest.write_str("none"), - } - } -} +pub type LengthOrNone = Either<Length, None_>; #[derive(Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index c73fcd73e83..14e4f49d76c 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -12,6 +12,7 @@ use super::{CSSFloat, specified}; pub use cssparser::Color as CSSColor; pub use self::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; +pub use super::{Either, None_}; pub use super::specified::{Angle, BorderStyle, Time, UrlExtraData, UrlOrNone}; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto}; pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone}; diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 46d7b304d0b..485b46c82a2 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -6,7 +6,11 @@ //! //! [values]: https://drafts.csswg.org/css-values/ -pub use cssparser::RGBA; +pub use cssparser::{RGBA, Parser}; + +use parser::Parse; +use std::fmt::{self, Debug}; +use style_traits::ToCss; macro_rules! define_numbered_css_keyword_enum { ($name: ident: $( $css: expr => $variant: ident = $value: expr ),+,) => { @@ -59,3 +63,102 @@ impl<T> HasViewportPercentage for T where T: NoViewportPercentage { } } +use self::computed::ComputedValueAsSpecified; + +macro_rules! define_keyword_type { + ($name: ident, $css: expr) => { + #[derive(Clone, PartialEq, Copy)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct $name; + + impl ::style_traits::ToCss for $name { + fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result where W: ::std::fmt::Write { + write!(dest, $css) + } + } + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, $css) + } + } + + impl Parse for $name { + fn parse(input: &mut ::cssparser::Parser) -> Result<$name, ()> { + input.expect_ident_matching($css).map(|_| $name) + } + } + + impl ComputedValueAsSpecified for $name {} + impl NoViewportPercentage for $name {} + }; +} + +define_keyword_type!(None_, "none"); +define_keyword_type!(Auto, "auto"); +define_keyword_type!(Normal, "normal"); + +#[derive(Clone, PartialEq, Copy)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +pub enum Either<A, B> { + First(A), + Second(B), +} + +impl<A: Debug, B: Debug> Debug for Either<A, B> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Either::First(ref v) => v.fmt(f), + Either::Second(ref v) => v.fmt(f), + } + } +} + +impl<A: ToCss, B: ToCss> ToCss for Either<A, B> { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + Either::First(ref v) => v.to_css(dest), + Either::Second(ref v) => v.to_css(dest), + } + } +} + +impl<A: HasViewportPercentage, B: HasViewportPercentage> HasViewportPercentage for Either<A, B> { + fn has_viewport_percentage(&self) -> bool { + match *self { + Either::First(ref v) => v.has_viewport_percentage(), + Either::Second(ref v) => v.has_viewport_percentage(), + } + } +} + +impl<A: Parse, B: Parse> Parse for Either<A, B> { + fn parse(input: &mut Parser) -> Result<Either<A, B>, ()> { + if let Ok(v) = input.try(|i| A::parse(i)) { + Ok(Either::First(v)) + } else { + B::parse(input).map(Either::Second) + } + } +} + +use self::computed::{Context, ToComputedValue}; + +impl<A: ToComputedValue, B: ToComputedValue> ToComputedValue for Either<A, B> { + type ComputedValue = Either<A::ComputedValue, B::ComputedValue>; + + fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { + match *self { + Either::First(ref a) => Either::First(a.to_computed_value(context)), + Either::Second(ref a) => Either::Second(a.to_computed_value(context)), + } + } + + #[inline] + fn from_computed_value(computed: &Self::ComputedValue) -> Self { + match *computed { + Either::First(ref a) => Either::First(ToComputedValue::from_computed_value(a)), + Either::Second(ref a) => Either::Second(ToComputedValue::from_computed_value(a)), + } + } +} diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index a0ed172cab1..a8b33cb041e 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -13,7 +13,7 @@ use std::ops::Mul; use style_traits::ToCss; use style_traits::values::specified::AllowedNumericType; use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time}; -use values::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, computed}; +use values::{CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, computed}; pub use super::image::{AngleOrCorner, ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use super::image::{GradientKind, HorizontalDirection, Image, LengthOrKeyword, LengthOrPercentageOrKeyword}; @@ -908,55 +908,12 @@ impl LengthOrPercentageOrNone { } } -#[derive(Clone, PartialEq, Copy, Debug)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub enum LengthOrNone { - Length(Length), - None, -} - -impl HasViewportPercentage for LengthOrNone { - fn has_viewport_percentage(&self) -> bool { - match *self { - LengthOrNone::Length(ref length) => length.has_viewport_percentage(), - _ => false - } - } -} +pub type LengthOrNone = Either<Length, None_>; -impl ToCss for LengthOrNone { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - LengthOrNone::Length(length) => length.to_css(dest), - LengthOrNone::None => dest.write_str("none"), - } - } -} impl LengthOrNone { - fn parse_internal(input: &mut Parser, context: AllowedNumericType) - -> Result<LengthOrNone, ()> - { - match try!(input.next()) { - Token::Dimension(ref value, ref unit) if context.is_ok(value.value) => - Length::parse_dimension(value.value, unit).map(LengthOrNone::Length), - Token::Number(ref value) if value.value == 0. => - Ok(LengthOrNone::Length(Length::Absolute(Au(0)))), - Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => - input.parse_nested_block(|input| { - CalcLengthOrPercentage::parse_length(input, context) - }).map(LengthOrNone::Length), - Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => - Ok(LengthOrNone::None), - _ => Err(()) - } - } - #[inline] - pub fn parse(input: &mut Parser) -> Result<LengthOrNone, ()> { - LengthOrNone::parse_internal(input, AllowedNumericType::All) - } #[inline] pub fn parse_non_negative(input: &mut Parser) -> Result<LengthOrNone, ()> { - LengthOrNone::parse_internal(input, AllowedNumericType::NonNegative) + Length::parse_internal(input, AllowedNumericType::NonNegative).map(Either::First) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 92a8532f52d..339c565a240 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -83,7 +83,6 @@ impl ToCss for CSSRGBA { } } - #[derive(Clone, Debug)] pub struct SimplifiedSumNode { values: Vec<SimplifiedValueNode>, |