From 989e1c2e686066c108535ef8a0c93decda56b8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 03:11:04 +0100 Subject: [PATCH 1/7] style: Remove outdated TODO. --- components/style/properties/longhand/list.mako.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 3b330c9066f..a0a620954a8 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -15,12 +15,6 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu // decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman, // upper-roman // -// TODO(bholley): Missing quite a few gecko properties here as well. -// -// In gecko, {upper,lower}-{roman,alpha} are implemented as @counter-styles in the -// UA, however they can also be set from pres attrs. When @counter-style is supported -// we may need to look into this and handle these differently. -// // [1]: http://dev.w3.org/csswg/css-counter-styles/ % if product == "servo": ${helpers.single_keyword("list-style-type", """ From ada45f4968eea2efa12929fd3a03cc930e8f2583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 03:11:44 +0100 Subject: [PATCH 2/7] style: Remove useless String::to_string call. --- components/style_derive/to_css.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index a0197dedc86..99948aaec97 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -79,7 +79,6 @@ fn derive_variant_arm( let mut expr = if let Some(keyword) = variant_attrs.keyword { assert!(bindings.is_empty()); - let keyword = keyword.to_string(); quote! { ::std::fmt::Write::write_str(dest, #keyword) } From 6da1b2fff5e52f2c795f2be557e185060127cc67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 03:12:12 +0100 Subject: [PATCH 3/7] style: Introduce css(skip_if) to conditionally skip serialization of a field. --- components/style_derive/to_css.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 99948aaec97..d9b781ee2ec 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -5,7 +5,7 @@ use cg::{self, WhereClause}; use darling::util::Override; use quote::{ToTokens, Tokens}; -use syn::{self, Data}; +use syn::{self, Data, Ident}; use synstructure::{BindingInfo, Structure, VariantInfo}; pub fn derive(input: syn::DeriveInput) -> Tokens { @@ -128,7 +128,15 @@ fn derive_variant_fields_expr( if !attrs.ignore_bound { where_clause.add_trait_bound(&first.ast().ty); } - return quote! { ::style_traits::ToCss::to_css(#first, dest) }; + let mut expr = quote! { ::style_traits::ToCss::to_css(#first, dest) }; + if let Some(condition) = attrs.skip_if { + expr = quote! { + if !#first.#condition() { + #expr + } + } + } + return expr; } let mut expr = derive_single_field_expr(first, attrs, where_clause); @@ -148,7 +156,7 @@ fn derive_single_field_expr( attrs: CssFieldAttrs, where_clause: &mut WhereClause, ) -> Tokens { - if attrs.iterable { + let mut expr = if attrs.iterable { if let Some(if_empty) = attrs.if_empty { return quote! { { @@ -173,7 +181,17 @@ fn derive_single_field_expr( where_clause.add_trait_bound(&field.ast().ty); } quote! { writer.item(#field)?; } + }; + + if let Some(condition) = attrs.skip_if { + expr = quote! { + if !#field.#condition() { + #expr + } + } } + + expr } #[darling(attributes(css), default)] @@ -203,4 +221,5 @@ struct CssFieldAttrs { ignore_bound: bool, iterable: bool, skip: bool, + skip_if: Option, } From 1f4b3556e631bda0dc6f6f8f8646e10dcfc3ac5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 03:16:07 +0100 Subject: [PATCH 4/7] style: reindent list-style-type. --- .../style/properties/longhand/list.mako.rs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index a0a620954a8..9befacb8675 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -17,23 +17,27 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu // // [1]: http://dev.w3.org/csswg/css-counter-styles/ % if product == "servo": - ${helpers.single_keyword("list-style-type", """ - disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha + ${helpers.single_keyword( + "list-style-type", + """disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha""", animation_value_type="discrete", spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type", - servo_restyle_damage="rebuild_and_reflow")} + servo_restyle_damage="rebuild_and_reflow", + )} % else: - ${helpers.predefined_type("list-style-type", - "ListStyleType", - "computed::ListStyleType::disc()", - initial_specified_value="specified::ListStyleType::disc()", - animation_value_type="discrete", - boxed=True, - spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type", - servo_restyle_damage="rebuild_and_reflow")} + ${helpers.predefined_type( + "list-style-type", + "ListStyleType", + "computed::ListStyleType::disc()", + initial_specified_value="specified::ListStyleType::disc()", + animation_value_type="discrete", + boxed=True, + spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type", + servo_restyle_damage="rebuild_and_reflow", + )} % endif ${helpers.predefined_type("list-style-image", From bf08c659a0396ad405d8213369931d6bb6cc0c68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 11:44:02 +0100 Subject: [PATCH 5/7] style: Switch css(skip_if) to use a Path for consistency. --- components/style_derive/to_css.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index d9b781ee2ec..f94da49cfaa 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -5,7 +5,7 @@ use cg::{self, WhereClause}; use darling::util::Override; use quote::{ToTokens, Tokens}; -use syn::{self, Data, Ident}; +use syn::{self, Data, Path}; use synstructure::{BindingInfo, Structure, VariantInfo}; pub fn derive(input: syn::DeriveInput) -> Tokens { @@ -131,7 +131,7 @@ fn derive_variant_fields_expr( let mut expr = quote! { ::style_traits::ToCss::to_css(#first, dest) }; if let Some(condition) = attrs.skip_if { expr = quote! { - if !#first.#condition() { + if !#condition(#first) { #expr } } @@ -185,7 +185,7 @@ fn derive_single_field_expr( if let Some(condition) = attrs.skip_if { expr = quote! { - if !#field.#condition() { + if !#condition(#field) { #expr } } @@ -221,5 +221,5 @@ struct CssFieldAttrs { ignore_bound: bool, iterable: bool, skip: bool, - skip_if: Option, + skip_if: Option, } From 951250882b6ca35cfff36e2c6e846193e7c1e0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 11:57:58 +0100 Subject: [PATCH 6/7] style: Document #[css(skip_if)] --- components/style_traits/values.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index aad75d51b8a..d6bd05b7b40 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -34,6 +34,9 @@ use std::fmt::{self, Write}; /// dimension token, like: ; /// * if `#[css(skip)]` is found on a field, the `ToCss` call for that field /// is skipped; +/// * if `#[css(skip_if = "function")]` is found on a field, the `ToCss` call +/// for that field is skipped if `function` returns true. This function is +/// provided the field as an argument; /// * finally, one can put `#[css(derive_debug)]` on the whole type, to /// implement `Debug` by a single call to `ToCss::to_css`. pub trait ToCss { From 0d7dae1f851650e1a81abccbf696e6fab4c3fc50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Mar 2018 13:20:39 +0100 Subject: [PATCH 7/7] style: Derive ToCss for TimingFunction. --- components/style/values/generics/transform.rs | 57 ++++--------------- 1 file changed, 10 insertions(+), 47 deletions(-) diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index 504198ab89c..7584e5cdf48 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -80,12 +80,13 @@ pub struct TransformOrigin { /// A generic timing function. /// /// -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum TimingFunction { /// `linear | ease | ease-in | ease-out | ease-in-out` Keyword(TimingKeyword), /// `cubic-bezier(, , , )` #[allow(missing_docs)] + #[css(comma, function)] CubicBezier { x1: Number, y1: Number, @@ -93,8 +94,10 @@ pub enum TimingFunction { y2: Number, }, /// `step-start | step-end | steps(, [ start | end ]?)` - Steps(Integer, StepPosition), + #[css(comma, function)] + Steps(Integer, #[css(skip_if = "is_end")] StepPosition), /// `frames()` + #[css(comma, function)] Frames(Integer), } @@ -119,6 +122,11 @@ pub enum StepPosition { End, } +#[inline] +fn is_end(position: &StepPosition) -> bool { + *position == StepPosition::End +} + impl TransformOrigin { /// Returns a new transform origin. pub fn new(horizontal: H, vertical: V, depth: D) -> Self { @@ -138,51 +146,6 @@ impl TimingFunction { } } -impl ToCss for TimingFunction -where - Integer: ToCss, - Number: ToCss, -{ - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - match *self { - TimingFunction::Keyword(keyword) => keyword.to_css(dest), - TimingFunction::CubicBezier { - ref x1, - ref y1, - ref x2, - ref y2, - } => { - dest.write_str("cubic-bezier(")?; - x1.to_css(dest)?; - dest.write_str(", ")?; - y1.to_css(dest)?; - dest.write_str(", ")?; - x2.to_css(dest)?; - dest.write_str(", ")?; - y2.to_css(dest)?; - dest.write_str(")") - }, - TimingFunction::Steps(ref intervals, position) => { - dest.write_str("steps(")?; - intervals.to_css(dest)?; - if position != StepPosition::End { - dest.write_str(", ")?; - position.to_css(dest)?; - } - dest.write_str(")") - }, - TimingFunction::Frames(ref frames) => { - dest.write_str("frames(")?; - frames.to_css(dest)?; - dest.write_str(")") - }, - } - } -} - impl TimingKeyword { /// Returns the keyword as a quadruplet of Bezier point coordinates /// `(x1, y1, x2, y2)`.