From 90bae7f80260334ba35a0c26584d6393c4e20241 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 20 May 2017 01:36:34 +0200 Subject: [PATCH] =?UTF-8?q?Derive=20HasViewportPercentage=20=F0=9F=8D=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 20 +++-- components/style/Cargo.toml | 1 + components/style/lib.rs | 2 + components/style/macros.rs | 13 --- components/style/properties/helpers.mako.rs | 9 +- .../properties/longhand/background.mako.rs | 19 +---- .../style/properties/longhand/border.mako.rs | 31 +------ .../style/properties/longhand/box.mako.rs | 78 ++---------------- .../style/properties/longhand/effects.mako.rs | 8 +- .../style/properties/longhand/font.mako.rs | 9 +- .../longhand/inherited_table.mako.rs | 9 +- .../longhand/inherited_text.mako.rs | 52 ++---------- .../style/properties/longhand/outline.mako.rs | 10 +-- .../properties/longhand/position.mako.rs | 8 +- components/style/values/computed/mod.rs | 2 +- components/style/values/generics/image.rs | 78 ++---------------- components/style/values/generics/position.rs | 10 +-- components/style/values/mod.rs | 26 +----- components/style/values/specified/grid.rs | 13 +-- components/style/values/specified/image.rs | 2 +- components/style/values/specified/length.rs | 82 ++----------------- components/style/values/specified/mod.rs | 39 ++------- components/style_derive/Cargo.toml | 15 ++++ .../style_derive/has_viewport_percentage.rs | 56 +++++++++++++ components/style_derive/lib.rs | 18 ++++ components/style_traits/lib.rs | 2 + components/style_traits/viewport.rs | 42 ++++++++++ 27 files changed, 202 insertions(+), 452 deletions(-) create mode 100644 components/style_derive/Cargo.toml create mode 100644 components/style_derive/has_viewport_percentage.rs create mode 100644 components/style_derive/lib.rs diff --git a/Cargo.lock b/Cargo.lock index ce3bd10234a..d0f8619e1ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -605,7 +605,7 @@ name = "deny_public_fields" version = "0.0.1" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1146,7 +1146,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1346,7 +1346,7 @@ version = "0.0.1" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2859,6 +2859,7 @@ dependencies = [ "servo_config 0.0.1", "servo_url 0.0.1", "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "style_derive 0.0.1", "style_traits 0.0.1", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2866,6 +2867,15 @@ dependencies = [ "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "style_derive" +version = "0.0.1" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "style_tests" version = "0.0.1" @@ -2945,7 +2955,7 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3650,7 +3660,7 @@ dependencies = [ "checksum swapper 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca610b32bb8bfc5e7f705480c3a1edfeb70b6582495d343872c8bee0dcf758c" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ccc9780bf1aa601943988c2876ab22413c01ad1739689aa6af18d0aa0b3f38b" +"checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c" "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e" "checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c" "checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047" diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 8cc372343e8..aa650663efa 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -58,6 +58,7 @@ serde_derive = {version = "0.9", optional = true} servo_atoms = {path = "../atoms", optional = true} servo_config = {path = "../config", optional = true} smallvec = "0.3.3" +style_derive = {path = "../style_derive"} style_traits = {path = "../style_traits"} servo_url = {path = "../url", optional = true} time = "0.1" diff --git a/components/style/lib.rs b/components/style/lib.rs index 7eb74bd6d42..eaeb50a4059 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -78,6 +78,8 @@ extern crate selectors; #[cfg(feature = "servo")] extern crate servo_url; extern crate smallvec; #[macro_use] +extern crate style_derive; +#[macro_use] extern crate style_traits; extern crate time; #[allow(unused_extern_crates)] diff --git a/components/style/macros.rs b/components/style/macros.rs index ce040891a74..092dc7bb8f2 100644 --- a/components/style/macros.rs +++ b/components/style/macros.rs @@ -38,19 +38,6 @@ macro_rules! define_numbered_css_keyword_enum { } } -/// A macro used to implement HasViewportPercentage trait -/// for a given type that may never contain viewport units. -macro_rules! no_viewport_percentage { - ($name: ident) => { - impl $crate::values::HasViewportPercentage for $name { - #[inline] - fn has_viewport_percentage(&self) -> bool { - false - } - } - }; -} - /// A macro for implementing `ComputedValueAsSpecified`, `Parse` /// and `HasViewportPercentage` traits for the enums defined /// using `define_css_keyword_enum` macro. diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 16236150cd9..29b7e9e3f8b 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -81,13 +81,6 @@ use values::HasViewportPercentage; use style_traits::ToCss; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let &SpecifiedValue(ref vec) = self; - vec.iter().any(|ref x| x.has_viewport_percentage()) - } - } - pub mod single_value { use cssparser::Parser; use parser::{Parse, ParserContext}; @@ -168,7 +161,7 @@ } /// The specified value of ${name}. - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Vec); diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 3b41a5714cf..7e2fd6b2196 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -236,13 +236,7 @@ ${helpers.single_keyword("background-origin", } } - impl HasViewportPercentage for ExplicitSize { - fn has_viewport_percentage(&self) -> bool { - return self.width.has_viewport_percentage() || self.height.has_viewport_percentage(); - } - } - - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub struct ExplicitSize { @@ -266,16 +260,7 @@ ${helpers.single_keyword("background-origin", } } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::Explicit(ref explicit_size) => explicit_size.has_viewport_percentage(), - _ => false - } - } - } - - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { Explicit(ExplicitSize), diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index e5270e30fb9..8b1adaf02bc 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -208,17 +208,6 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", use values::HasViewportPercentage; use values::specified::{LengthOrNumber, Number}; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let mut viewport_percentage = false; - for value in self.0.iter() { - let vp = value.has_viewport_percentage(); - viewport_percentage = vp || viewport_percentage; - } - viewport_percentage - } - } - pub mod computed_value { use values::computed::LengthOrNumber; #[derive(Debug, Clone, PartialEq)] @@ -227,7 +216,7 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", pub LengthOrNumber, pub LengthOrNumber); } - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Vec); @@ -402,20 +391,6 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", use values::HasViewportPercentage; use values::specified::{LengthOrPercentage, Number}; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let mut viewport_percentage = false; - for value in self.0.clone() { - let vp = match value { - SingleSpecifiedValue::LengthOrPercentage(len) => len.has_viewport_percentage(), - _ => false, - }; - viewport_percentage = vp || viewport_percentage; - } - viewport_percentage - } - } - pub mod computed_value { use values::computed::{LengthOrPercentage, Number}; #[derive(Debug, Clone, PartialEq)] @@ -432,7 +407,7 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", } } - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Vec); @@ -458,7 +433,7 @@ ${helpers.predefined_type("border-image-source", "ImageLayer", } } - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SingleSpecifiedValue { LengthOrPercentage(LengthOrPercentage), diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 86b2e7d95e2..cc5733523db 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -274,18 +274,9 @@ ${helpers.single_keyword("position", "static absolute relative fixed", ${helpers.gecko_keyword_conversion(vertical_align.keyword)} - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::LengthOrPercentage(ref length) => length.has_viewport_percentage(), - _ => false - } - } - } - /// The `vertical-align` value. #[allow(non_camel_case_types)] - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { % for keyword in vertical_align_keywords: @@ -1048,15 +1039,6 @@ ${helpers.single_keyword("animation-fill-mode", use values::HasViewportPercentage; use values::specified::LengthOrPercentage; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::Repeat(ref length) => length.has_viewport_percentage(), - _ => false - } - } - } - pub mod computed_value { use values::computed::LengthOrPercentage; @@ -1065,7 +1047,7 @@ ${helpers.single_keyword("animation-fill-mode", pub struct T(pub Option); } - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { None, @@ -1253,7 +1235,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", /// Multiple transform functions compose a transformation. /// /// Some transformations can be expressed by other more general functions. - #[derive(Clone, Debug, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedOperation { /// Represents a 2D 2x3 matrix. @@ -1328,41 +1310,6 @@ ${helpers.predefined_type("scroll-snap-coordinate", } } - impl HasViewportPercentage for SpecifiedOperation { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedOperation::Translate(ref l1, None) | - SpecifiedOperation::TranslateX(ref l1) | - SpecifiedOperation::TranslateY(ref l1) => { - l1.has_viewport_percentage() - } - SpecifiedOperation::TranslateZ(ref l1) => { - l1.has_viewport_percentage() - } - SpecifiedOperation::Translate(ref l1, Some(ref l2)) => { - l1.has_viewport_percentage() || - l2.has_viewport_percentage() - } - SpecifiedOperation::Translate3D(ref l1, ref l2, ref l3) => { - l1.has_viewport_percentage() || - l2.has_viewport_percentage() || - l3.has_viewport_percentage() - }, - SpecifiedOperation::Perspective(ref length) => length.has_viewport_percentage(), - SpecifiedOperation::PrefixedMatrix{ ref e, ref f, .. } => { - e.has_viewport_percentage() || - f.has_viewport_percentage() - }, - SpecifiedOperation::PrefixedMatrix3D{ ref m41, ref m42, ref m43, .. } => { - m41.has_viewport_percentage() || - m42.has_viewport_percentage() || - m43.has_viewport_percentage() - }, - _ => false - } - } - } - impl ToCss for SpecifiedOperation { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { use self::SpecifiedOperation::*; @@ -1422,14 +1369,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", } } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let &SpecifiedValue(ref specified_ops) = self; - specified_ops.iter().any(|ref x| x.has_viewport_percentage()) - } - } - - #[derive(Clone, Debug, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Vec); @@ -2223,15 +2163,7 @@ ${helpers.single_keyword("transform-style", } } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.horizontal.has_viewport_percentage() || - self.vertical.has_viewport_percentage() || - self.depth.has_viewport_percentage() - } - } - - #[derive(Clone, Debug, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { horizontal: LengthOrPercentage, diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index b56f105c492..c10e1b8f018 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -98,13 +98,7 @@ ${helpers.predefined_type("clip", use values::specified::{Angle, CSSColor, Length, Shadow}; use values::specified::url::SpecifiedUrl; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.0.iter().any(|ref x| x.has_viewport_percentage()) - } - } - - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Vec); diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 9461d1a688f..2ed4e170cc4 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -2108,7 +2108,6 @@ ${helpers.single_keyword_system("font-variant-position", pub use self::computed_value::T as SpecifiedValue; impl ComputedValueAsSpecified for SpecifiedValue {} - no_viewport_percentage!(SpecifiedValue); pub mod computed_value { pub type T = f32; @@ -2235,7 +2234,7 @@ ${helpers.single_keyword("-moz-math-variant", use values::computed::ComputedValueAsSpecified; use values::specified::length::{AU_PER_PT, FontBaseSize, NoCalcLength}; - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] pub struct SpecifiedValue(pub NoCalcLength); pub mod computed_value { @@ -2273,12 +2272,6 @@ ${helpers.single_keyword("-moz-math-variant", } } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.0.has_viewport_percentage() - } - } - #[inline] pub fn get_initial_value() -> computed_value::T { Au((NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * AU_PER_PT) as i32) diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs index b6c1ad3d604..e83d5143904 100644 --- a/components/style/properties/longhand/inherited_table.mako.rs +++ b/components/style/properties/longhand/inherited_table.mako.rs @@ -65,14 +65,7 @@ ${helpers.single_keyword("caption-side", "top bottom", } } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.horizontal.has_viewport_percentage() || - self.vertical.as_ref().map_or(false, |v| v.has_viewport_percentage()) - } - } - - #[derive(Clone, Debug, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { pub horizontal: Length, diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index a1f6dfc0418..e967bb0eba1 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -12,16 +12,7 @@ use style_traits::ToCss; use values::HasViewportPercentage; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::LengthOrPercentage(ref length) => length.has_viewport_percentage(), - _ => false - } - } - } - - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { Normal, @@ -415,16 +406,7 @@ ${helpers.single_keyword("text-align-last", use values::HasViewportPercentage; use values::specified::AllowQuirks; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::Specified(ref length) => length.has_viewport_percentage(), - _ => false - } - } - } - - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { Normal, @@ -501,16 +483,7 @@ ${helpers.single_keyword("text-align-last", use values::HasViewportPercentage; use values::specified::AllowQuirks; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - match *self { - SpecifiedValue::Specified(ref length) => length.has_viewport_percentage(), - _ => false - } - } - } - - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum SpecifiedValue { Normal, @@ -722,26 +695,11 @@ ${helpers.single_keyword("text-align-last", use values::specified::Shadow; use values::HasViewportPercentage; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let &SpecifiedValue(ref vec) = self; - vec.iter().any(|ref x| x.has_viewport_percentage()) - } - } - - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Vec); - impl HasViewportPercentage for SpecifiedTextShadow { - fn has_viewport_percentage(&self) -> bool { - self.offset_x.has_viewport_percentage() || - self.offset_y.has_viewport_percentage() || - self.blur_radius.has_viewport_percentage() - } - } - - #[derive(Clone, PartialEq, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedTextShadow { pub offset_x: specified::Length, diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index fcfebe6a00e..88d34f964d5 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -81,16 +81,10 @@ ${helpers.predefined_type("outline-color", "CSSColor", "computed::CSSColor::Curr specified::parse_border_width(context, input).map(SpecifiedValue) } - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - let &SpecifiedValue(ref length) = self; - length.has_viewport_percentage() - } - } - - #[derive(Debug, Clone, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub specified::Length); + pub mod computed_value { use app_units::Au; pub type T = Au; diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 0cea82301cc..a556481dc2b 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -181,17 +181,11 @@ ${helpers.predefined_type("flex-basis", use values::HasViewportPercentage; use values::specified::{AllowQuirks, ${MinMax}Length}; - impl HasViewportPercentage for SpecifiedValue { - fn has_viewport_percentage(&self) -> bool { - self.0.has_viewport_percentage() - } - } - pub mod computed_value { pub type T = ::values::computed::${MinMax}Length; } - #[derive(PartialEq, Clone, Debug)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(${MinMax}Length); diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 7101192be1a..8c537eb3694 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -175,7 +175,7 @@ impl ToComputedValue for T } /// A computed `` value. -#[derive(Clone, PartialEq, PartialOrd, Copy, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] pub enum Angle { /// An angle with degree unit diff --git a/components/style/values/generics/image.rs b/components/style/values/generics/image.rs index 55bb8d20d43..2b42314eb00 100644 --- a/components/style/values/generics/image.rs +++ b/components/style/values/generics/image.rs @@ -32,7 +32,7 @@ pub enum Image { /// A CSS gradient. /// https://drafts.csswg.org/css-images/#gradients -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Gradient { /// Gradients can be linear or radial. @@ -45,7 +45,7 @@ pub struct Gradient pub compat_mode: CompatMode, } -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// Whether we used the modern notation or the compatibility `-webkit` prefix. pub enum CompatMode { @@ -56,7 +56,7 @@ pub enum CompatMode { } /// A gradient kind. -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum GradientKind { /// A linear gradient. @@ -66,7 +66,7 @@ pub enum GradientKind { } /// A radial gradient's ending shape. -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum EndingShape { /// A circular gradient. @@ -76,7 +76,7 @@ pub enum EndingShape { } /// A circle shape. -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Circle { /// A circle radius. @@ -86,7 +86,7 @@ pub enum Circle { } /// An ellipse shape. -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Ellipse { /// An ellipse pair of radii. @@ -104,10 +104,11 @@ define_css_keyword_enum!(ShapeExtent: "contain" => Contain, "cover" => Cover ); +no_viewport_percentage!(ShapeExtent); /// A gradient item. /// https://drafts.csswg.org/css-images-4/#color-stop-syntax -#[derive(Clone, Copy, PartialEq, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum GradientItem { /// A color stop. @@ -118,7 +119,7 @@ pub enum GradientItem { /// A color stop. /// https://drafts.csswg.org/css-images/#typedef-color-stop-list -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct ColorStop { /// The color of this stop. @@ -281,17 +282,6 @@ impl ToCss for Gradient } } -impl HasViewportPercentage for Gradient - where L: HasViewportPercentage, - LoP: HasViewportPercentage, - P: HasViewportPercentage, -{ - fn has_viewport_percentage(&self) -> bool { - self.kind.has_viewport_percentage() || - self.items.iter().any(|i| i.has_viewport_percentage()) - } -} - impl ToComputedValue for Gradient where D: ToComputedValue, L: ToComputedValue, @@ -333,21 +323,6 @@ impl GradientKind { } } -impl HasViewportPercentage for GradientKind - where L: HasViewportPercentage, - LoP: HasViewportPercentage, - P: HasViewportPercentage -{ - fn has_viewport_percentage(&self) -> bool { - match *self { - GradientKind::Linear(_) => false, - GradientKind::Radial(ref shape, ref position) => { - shape.has_viewport_percentage() || position.has_viewport_percentage() - }, - } - } -} - impl ToComputedValue for GradientKind where D: ToComputedValue, L: ToComputedValue, @@ -423,22 +398,6 @@ impl ToCss for EndingShape } } -impl HasViewportPercentage for EndingShape - where L: HasViewportPercentage, LoP: HasViewportPercentage, -{ - fn has_viewport_percentage(&self) -> bool { - match *self { - EndingShape::Circle(Circle::Radius(ref length)) => { - length.has_viewport_percentage() - }, - EndingShape::Ellipse(Ellipse::Radii(ref x, ref y)) => { - x.has_viewport_percentage() || y.has_viewport_percentage() - }, - _ => false, - } - } -} - impl ToComputedValue for EndingShape where L: ToComputedValue, LoP: ToComputedValue, { @@ -497,17 +456,6 @@ impl ToCss for GradientItem } } -impl HasViewportPercentage for GradientItem - where L: HasViewportPercentage, -{ - fn has_viewport_percentage(&self) -> bool { - match *self { - GradientItem::ColorStop(ref stop) => stop.has_viewport_percentage(), - GradientItem::InterpolationHint(ref hint) => hint.has_viewport_percentage(), - } - } -} - impl ToComputedValue for GradientItem where C: ToComputedValue, L: ToComputedValue, { @@ -562,14 +510,6 @@ impl ToCss for ColorStop } } -impl HasViewportPercentage for ColorStop - where L: HasViewportPercentage, -{ - fn has_viewport_percentage(&self) -> bool { - self.position.as_ref().map_or(false, HasViewportPercentage::has_viewport_percentage) - } -} - impl ToComputedValue for ColorStop where C: ToComputedValue, L: ToComputedValue, { diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 1b805b8ff08..7e13919d30c 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -5,10 +5,9 @@ //! Generic types for CSS handling of specified and computed values of //! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position) -use values::HasViewportPercentage; use values::computed::{Context, ToComputedValue}; -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position). pub struct Position { @@ -28,13 +27,6 @@ impl Position { } } -impl HasViewportPercentage for Position { - #[inline] - fn has_viewport_percentage(&self) -> bool { - self.horizontal.has_viewport_percentage() || self.vertical.has_viewport_percentage() - } -} - impl ToComputedValue for Position { type ComputedValue = Position<::ComputedValue, ::ComputedValue>; diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index 63bcc366bad..6a6469a1742 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -16,6 +16,7 @@ use std::borrow::Cow; use std::fmt::{self, Debug}; use std::hash; use style_traits::ToCss; +pub use style_traits::HasViewportPercentage; pub mod computed; pub mod generics; @@ -30,24 +31,11 @@ pub type CSSInteger = i32; /// The default font size. pub const FONT_MEDIUM_PX: i32 = 16; -/// A trait used to query whether this value has viewport units. -pub trait HasViewportPercentage { - /// Returns true if this value has viewport units. - fn has_viewport_percentage(&self) -> bool; -} - -impl HasViewportPercentage for Box { - #[inline] - fn has_viewport_percentage(&self) -> bool { - (**self).has_viewport_percentage() - } -} - define_keyword_type!(None_, "none"); define_keyword_type!(Auto, "auto"); define_keyword_type!(Normal, "normal"); -#[derive(Clone, PartialEq, Copy)] +#[derive(Clone, Copy, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A struct representing one of two kinds of values. pub enum Either { @@ -75,15 +63,6 @@ impl ToCss for Either { } } -impl HasViewportPercentage for Either { - 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 Parse for Either { fn parse(context: &ParserContext, input: &mut Parser) -> Result, ()> { if let Ok(v) = input.try(|i| A::parse(context, i)) { @@ -209,3 +188,4 @@ define_css_keyword_enum!(ExtremumLength: "-moz-min-content" => MinContent, "-moz-fit-content" => FitContent, "-moz-available" => FillAvailable); +no_viewport_percentage!(ExtremumLength); diff --git a/components/style/values/specified/grid.rs b/components/style/values/specified/grid.rs index 45f888d9702..a4a8b930ef8 100644 --- a/components/style/values/specified/grid.rs +++ b/components/style/values/specified/grid.rs @@ -221,7 +221,7 @@ impl ToComputedValue for TrackBreadth { } } -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A `` type for explicit grid track sizing. Like ``, this is /// generic only to avoid code bloat. It only takes `` @@ -321,17 +321,6 @@ impl ToCss for TrackSize { } } -impl HasViewportPercentage for TrackSize { - #[inline] - fn has_viewport_percentage(&self) -> bool { - match *self { - TrackSize::Breadth(ref b) => b.has_viewport_percentage(), - TrackSize::MinMax(ref inf_b, ref b) => inf_b.has_viewport_percentage() || b.has_viewport_percentage(), - TrackSize::FitContent(ref lop) => lop.has_viewport_percentage(), - } - } -} - impl ToComputedValue for TrackSize { type ComputedValue = TrackSize; diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index 9266bec885b..d14e9b492b2 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -54,7 +54,7 @@ pub type GradientKind = GenericGradientKind< >; /// A specified gradient line direction. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum LineDirection { /// An angular direction. diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index d117593738c..331901bf8c6 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -531,7 +531,7 @@ impl NoCalcLength { /// This is commonly used for the `` values. /// /// https://drafts.csswg.org/css-values/#lengths -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum Length { /// The internal length type that cannot parse `calc` @@ -549,15 +549,6 @@ impl From for Length { } } -impl HasViewportPercentage for Length { - fn has_viewport_percentage(&self) -> bool { - match *self { - Length::NoCalc(ref inner) => inner.has_viewport_percentage(), - Length::Calc(ref calc) => calc.has_viewport_percentage(), - } - } -} - impl ToCss for Length { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -713,7 +704,7 @@ impl Either { /// As of today, only `-moz-image-rect` supports percentages without length. /// This is not a regression, and that's a non-standard extension anyway, so I'm /// not implementing it for now. -#[derive(Clone, PartialEq, Copy, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Percentage(pub CSSFloat); @@ -754,7 +745,7 @@ impl Parse for Percentage { impl ComputedValueAsSpecified for Percentage {} /// A length or a percentage value. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentage { @@ -786,16 +777,6 @@ impl From for LengthOrPercentage { } } -impl HasViewportPercentage for LengthOrPercentage { - fn has_viewport_percentage(&self) -> bool { - match *self { - LengthOrPercentage::Length(ref length) => length.has_viewport_percentage(), - LengthOrPercentage::Calc(ref calc) => calc.has_viewport_percentage(), - _ => false - } - } -} - impl ToCss for LengthOrPercentage { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -914,7 +895,7 @@ impl LengthOrPercentage { } /// Either a ``, a ``, or the `auto` keyword. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentageOrAuto { @@ -938,16 +919,6 @@ impl From for LengthOrPercentageOrAuto { } } -impl HasViewportPercentage for LengthOrPercentageOrAuto { - fn has_viewport_percentage(&self) -> bool { - match *self { - LengthOrPercentageOrAuto::Length(ref length) => length.has_viewport_percentage(), - LengthOrPercentageOrAuto::Calc(ref calc) => calc.has_viewport_percentage(), - _ => false - } - } -} - impl ToCss for LengthOrPercentageOrAuto { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1036,7 +1007,7 @@ impl LengthOrPercentageOrAuto { } /// Either a ``, a ``, or the `none` keyword. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum LengthOrPercentageOrNone { @@ -1046,16 +1017,6 @@ pub enum LengthOrPercentageOrNone { None, } -impl HasViewportPercentage for LengthOrPercentageOrNone { - fn has_viewport_percentage(&self) -> bool { - match *self { - LengthOrPercentageOrNone::Length(ref length) => length.has_viewport_percentage(), - LengthOrPercentageOrNone::Calc(ref calc) => calc.has_viewport_percentage(), - _ => false - } - } -} - impl ToCss for LengthOrPercentageOrNone { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1133,7 +1094,7 @@ pub type LengthOrAuto = Either; /// Either a `` or a `` or the `auto` keyword or the /// `content` keyword. -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum LengthOrPercentageOrAutoOrContent { /// A ``. @@ -1185,16 +1146,6 @@ impl LengthOrPercentageOrAutoOrContent { } } -impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent { - fn has_viewport_percentage(&self) -> bool { - match *self { - LengthOrPercentageOrAutoOrContent::Length(ref length) => length.has_viewport_percentage(), - LengthOrPercentageOrAutoOrContent::Calc(ref calc) => calc.has_viewport_percentage(), - _ => false - } - } -} - impl ToCss for LengthOrPercentageOrAutoOrContent { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1227,7 +1178,7 @@ impl LengthOrNumber { /// A value suitable for a `min-width` or `min-height` property. /// Unlike `max-width` or `max-height` properties, a MinLength can be /// `auto`, and cannot be `none`. -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum MinLength { @@ -1236,15 +1187,6 @@ pub enum MinLength { ExtremumLength(ExtremumLength), } -impl HasViewportPercentage for MinLength { - fn has_viewport_percentage(&self) -> bool { - match *self { - MinLength::LengthOrPercentage(ref lop) => lop.has_viewport_percentage(), - _ => false - } - } -} - impl ToCss for MinLength { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1277,7 +1219,7 @@ impl MinLength { } /// A value suitable for a `max-width` or `max-height` property. -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum MaxLength { @@ -1286,14 +1228,6 @@ pub enum MaxLength { ExtremumLength(ExtremumLength), } -impl HasViewportPercentage for MaxLength { - fn has_viewport_percentage(&self) -> bool { - match *self { - MaxLength::LengthOrPercentage(ref lop) => lop.has_viewport_percentage(), - _ => false - } - } -} impl ToCss for MaxLength { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 3fb46c473b9..d687c4aaff9 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -21,7 +21,7 @@ use std::fmt; use std::io::Write; use style_traits::ToCss; use style_traits::values::specified::AllowedNumericType; -use super::{Auto, CSSFloat, CSSInteger, HasViewportPercentage, Either, None_}; +use super::{Auto, CSSFloat, CSSInteger, Either, None_}; use super::computed::{self, Context}; use super::computed::{Shadow as ComputedShadow, ToComputedValue}; use super::generics::BorderRadiusSize as GenericBorderRadiusSize; @@ -76,8 +76,6 @@ impl ComputedValueAsSpecified for SpecifiedUrl {} no_viewport_percentage!(SpecifiedUrl); } -no_viewport_percentage!(i32); // For PropertyDeclaration::Order - #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] @@ -289,7 +287,7 @@ impl Parse for BorderRadiusSize { } } -#[derive(Clone, PartialEq, Copy, Debug)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] /// An angle consisting of a value and a unit. /// @@ -455,7 +453,7 @@ pub fn parse_border_width(context: &ParserContext, input: &mut Parser) -> Result }) } -#[derive(Clone, PartialEq, Debug)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub enum BorderWidth { @@ -507,15 +505,6 @@ impl ToCss for BorderWidth { } } -impl HasViewportPercentage for BorderWidth { - fn has_viewport_percentage(&self) -> bool { - match *self { - BorderWidth::Thin | BorderWidth::Medium | BorderWidth::Thick => false, - BorderWidth::Width(ref length) => length.has_viewport_percentage() - } - } -} - impl ToComputedValue for BorderWidth { type ComputedValue = Au; @@ -950,7 +939,7 @@ pub type TrackList = GenericTrackList; /// ` | none` pub type TrackListOrNone = Either; -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] pub struct Shadow { @@ -962,15 +951,6 @@ pub struct Shadow { pub inset: bool, } -impl HasViewportPercentage for Shadow { - fn has_viewport_percentage(&self) -> bool { - self.offset_x.has_viewport_percentage() || - self.offset_y.has_viewport_percentage() || - self.blur_radius.has_viewport_percentage() || - self.spread_radius.has_viewport_percentage() - } -} - impl ToComputedValue for Shadow { type ComputedValue = ComputedShadow; @@ -1230,16 +1210,7 @@ impl LengthOrPercentageOrNumber { } } -impl HasViewportPercentage for ClipRect { - fn has_viewport_percentage(&self) -> bool { - self.top.as_ref().map_or(false, |x| x.has_viewport_percentage()) || - self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) || - self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) || - self.left.as_ref().map_or(false, |x| x.has_viewport_percentage()) - } -} - -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// rect(, , , ) used by clip and image-region pub struct ClipRect { diff --git a/components/style_derive/Cargo.toml b/components/style_derive/Cargo.toml new file mode 100644 index 00000000000..d56f3225689 --- /dev/null +++ b/components/style_derive/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "style_derive" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +publish = false + +[lib] +path = "lib.rs" +proc-macro = true + +[dependencies] +quote = "0.3" +syn = "0.11" +synstructure = "0.5.2" diff --git a/components/style_derive/has_viewport_percentage.rs b/components/style_derive/has_viewport_percentage.rs new file mode 100644 index 00000000000..24e4b919c22 --- /dev/null +++ b/components/style_derive/has_viewport_percentage.rs @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use quote; +use syn; +use synstructure; + +pub fn derive(input: syn::DeriveInput) -> quote::Tokens { + let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let mut where_clause = where_clause.clone(); + for param in &input.generics.ty_params { + where_clause.predicates.push(where_predicate(syn::Ty::Path(None, param.ident.clone().into()))) + } + + let style = synstructure::BindStyle::Ref.into(); + let match_body = synstructure::each_variant(&input, &style, |bindings, _| { + let (first, rest) = match bindings.split_first() { + None => return Some(quote!(false)), + Some(pair) => pair, + }; + let mut expr = quote!(::style_traits::HasViewportPercentage::has_viewport_percentage(#first)); + for binding in rest { + where_clause.predicates.push(where_predicate(binding.field.ty.clone())); + expr = quote!(#expr || ::style_traits::HasViewportPercentage::has_viewport_percentage(#binding)); + } + Some(expr) + }); + + quote! { + impl #impl_generics ::style_traits::HasViewportPercentage for #name #ty_generics #where_clause { + #[allow(unused_variables, unused_imports)] + #[inline] + fn has_viewport_percentage(&self) -> bool { + match *self { + #match_body + } + } + } + } +} + +fn where_predicate(ty: syn::Ty) -> syn::WherePredicate { + syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { + bound_lifetimes: vec![], + bounded_ty: ty, + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: vec![], + trait_ref: syn::parse_path("::style_traits::HasViewportPercentage").unwrap(), + }, + syn::TraitBoundModifier::None + )], + }) +} diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs new file mode 100644 index 00000000000..fd47a962ce9 --- /dev/null +++ b/components/style_derive/lib.rs @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate proc_macro; +#[macro_use] extern crate quote; +extern crate syn; +extern crate synstructure; + +use proc_macro::TokenStream; + +mod has_viewport_percentage; + +#[proc_macro_derive(HasViewportPercentage)] +pub fn derive_has_viewport_percentage(stream: TokenStream) -> TokenStream { + let input = syn::parse_derive_input(&stream.to_string()).unwrap(); + has_viewport_percentage::derive(input).to_string().parse().unwrap() +} diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index 95cd0b3e3dd..a7c20f051dc 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -63,6 +63,8 @@ pub enum CSSPixel {} pub mod cursor; #[macro_use] pub mod values; +#[macro_use] pub mod viewport; pub use values::{ToCss, OneOrMoreCommaSeparated}; +pub use viewport::HasViewportPercentage; diff --git a/components/style_traits/viewport.rs b/components/style_traits/viewport.rs index 378e17c93c4..05e39f2b370 100644 --- a/components/style_traits/viewport.rs +++ b/components/style_traits/viewport.rs @@ -20,6 +20,48 @@ define_css_keyword_enum!(Orientation: "portrait" => Portrait, "landscape" => Landscape); +/// A trait used to query whether this value has viewport units. +pub trait HasViewportPercentage { + /// Returns true if this value has viewport units. + fn has_viewport_percentage(&self) -> bool; +} + +/// A macro used to implement HasViewportPercentage trait +/// for a given type that may never contain viewport units. +#[macro_export] +macro_rules! no_viewport_percentage { + ($($name: ident),+) => { + $(impl $crate::HasViewportPercentage for $name { + #[inline] + fn has_viewport_percentage(&self) -> bool { + false + } + })+ + }; +} + +no_viewport_percentage!(bool, f32); + +impl HasViewportPercentage for Box { + #[inline] + fn has_viewport_percentage(&self) -> bool { + (**self).has_viewport_percentage() + } +} + +impl HasViewportPercentage for Option { + #[inline] + fn has_viewport_percentage(&self) -> bool { + self.as_ref().map_or(false, T::has_viewport_percentage) + } +} + +impl HasViewportPercentage for Vec { + #[inline] + fn has_viewport_percentage(&self) -> bool { + self.iter().any(T::has_viewport_percentage) + } +} /// A set of viewport descriptors: ///