diff options
-rw-r--r-- | components/style/gecko/values.rs | 2 | ||||
-rw-r--r-- | components/style/properties/helpers/animated_properties.mako.rs | 16 | ||||
-rw-r--r-- | components/style/properties/longhand/list.mako.rs | 2 | ||||
-rw-r--r-- | components/style/properties/shorthand/list.mako.rs | 2 | ||||
-rw-r--r-- | components/style/values/computed/length.rs | 19 | ||||
-rw-r--r-- | components/style/values/generics/basic_shape.rs | 13 | ||||
-rw-r--r-- | components/style/values/generics/gecko.rs | 25 | ||||
-rw-r--r-- | components/style/values/generics/mod.rs | 30 | ||||
-rw-r--r-- | components/style_derive/lib.rs | 2 | ||||
-rw-r--r-- | components/style_derive/to_css.rs | 65 |
10 files changed, 98 insertions, 78 deletions
diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index f2a92e1ec89..041387dd54c 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -401,7 +401,7 @@ impl CounterStyleOrNone { use gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name; use gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols; match self { - CounterStyleOrNone::None_ => unsafe { + CounterStyleOrNone::None => unsafe { set_name(gecko_value, atom!("none").into_addrefed()); }, CounterStyleOrNone::Name(name) => unsafe { diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index f89bd2ef2db..a03d55070aa 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -1246,7 +1246,14 @@ impl Animatable for LengthOrPercentageOrNone { (LengthOrPercentageOrNone::None, LengthOrPercentageOrNone::None) => { Ok(LengthOrPercentageOrNone::None) } - _ => Err(()) + (this, other) => { + let this = <Option<CalcLengthOrPercentage>>::from(this); + let other = <Option<CalcLengthOrPercentage>>::from(other); + match this.add_weighted(&other, self_portion, other_portion) { + Ok(Some(result)) => Ok(LengthOrPercentageOrNone::Calc(result)), + _ => Err(()), + } + }, } } @@ -1273,7 +1280,12 @@ impl Animatable for LengthOrPercentageOrNone { LengthOrPercentageOrNone::Percentage(ref other)) => { this.compute_distance(other) }, - _ => Err(()) + (this, other) => { + // If one of the element is Auto, Option<> will be None, and the returned distance is Err(()) + let this = <Option<CalcLengthOrPercentage>>::from(this); + let other = <Option<CalcLengthOrPercentage>>::from(other); + this.compute_distance(&other) + }, } } } diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 6f25334698e..7b5b2879dd9 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -63,7 +63,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu pub fn from_gecko_keyword(value: u32) -> Self { use gecko_bindings::structs; SpecifiedValue::CounterStyle(if value == structs::NS_STYLE_LIST_STYLE_NONE { - CounterStyleOrNone::None_ + CounterStyleOrNone::None } else { <% values = """disc circle square decimal lower-roman diff --git a/components/style/properties/shorthand/list.mako.rs b/components/style/properties/shorthand/list.mako.rs index 4ea2647e141..8f591760ec7 100644 --- a/components/style/properties/shorthand/list.mako.rs +++ b/components/style/properties/shorthand/list.mako.rs @@ -62,7 +62,7 @@ list_style_type::SpecifiedValue::none % else: use values::generics::CounterStyleOrNone; - list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None_) + list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None) % endif } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 3d59a51ff42..7e765daf623 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -157,6 +157,25 @@ impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> { } } +impl From<LengthOrPercentageOrNone> for Option<CalcLengthOrPercentage> { + fn from(len: LengthOrPercentageOrNone) -> Option<CalcLengthOrPercentage> { + match len { + LengthOrPercentageOrNone::Percentage(this) => { + Some(CalcLengthOrPercentage::new(Au(0), Some(this))) + } + LengthOrPercentageOrNone::Length(this) => { + Some(CalcLengthOrPercentage::new(this, None)) + } + LengthOrPercentageOrNone::Calc(this) => { + Some(this) + } + LengthOrPercentageOrNone::None => { + None + } + } + } +} + impl ToCss for CalcLengthOrPercentage { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match (self.length, self.percentage) { diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs index cd8e315f3b3..1d54a90dbca 100644 --- a/components/style/values/generics/basic_shape.rs +++ b/components/style/values/generics/basic_shape.rs @@ -92,7 +92,7 @@ pub struct Ellipse<H, V, LengthOrPercentage> { /// https://drafts.csswg.org/css-shapes/#typedef-shape-radius #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue)] +#[derive(Clone, Copy, Debug, PartialEq, ToComputedValue, ToCss)] pub enum ShapeRadius<LengthOrPercentage> { Length(LengthOrPercentage), ClosestSide, @@ -161,17 +161,6 @@ impl<L> Default for ShapeRadius<L> { fn default() -> Self { ShapeRadius::ClosestSide } } -impl<L: ToCss> ToCss for ShapeRadius<L> { - #[inline] - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - ShapeRadius::Length(ref lop) => lop.to_css(dest), - ShapeRadius::ClosestSide => dest.write_str("closest-side"), - ShapeRadius::FarthestSide => dest.write_str("farthest-side"), - } - } -} - impl<L: ToCss> ToCss for Polygon<L> { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { dest.write_str("polygon(")?; diff --git a/components/style/values/generics/gecko.rs b/components/style/values/generics/gecko.rs index 52c7b130992..31c62078861 100644 --- a/components/style/values/generics/gecko.rs +++ b/components/style/values/generics/gecko.rs @@ -5,15 +5,13 @@ //! Generic types for legacy Gecko-only properties that should probably be //! unshipped at some point in the future. -use std::fmt; -use style_traits::ToCss; - /// A generic value for scroll snap points. -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] pub enum ScrollSnapPoint<LengthOrPercentage> { /// `none` None, /// `repeat(<length-or-percentage>)` + #[css(function)] Repeat(LengthOrPercentage) } @@ -33,22 +31,3 @@ impl<L> ScrollSnapPoint<L> { } } } - -impl<L> ToCss for ScrollSnapPoint<L> -where - L: ToCss, -{ - fn to_css<W>(&self, dest: &mut W) -> fmt::Result - where - W: fmt::Write, - { - match *self { - ScrollSnapPoint::None => dest.write_str("none"), - ScrollSnapPoint::Repeat(ref length) => { - dest.write_str("repeat(")?; - length.to_css(dest)?; - dest.write_str(")") - }, - } - } -} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index 4d0a3315560..3d218b0bdf5 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -54,13 +54,14 @@ impl SymbolsType { /// /// Since wherever <counter-style> is used, 'none' is a valid value as /// well, we combine them into one type to make code simpler. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Eq, PartialEq, ToCss)] pub enum CounterStyleOrNone { - /// none - None_, - /// <counter-style-name> + /// `none` + None, + /// `<counter-style-name>` Name(CustomIdent), - /// symbols() + /// `symbols()` + #[css(function)] Symbols(SymbolsType, Symbols), } @@ -84,7 +85,7 @@ impl Parse for CounterStyleOrNone { return Ok(CounterStyleOrNone::Name(name)); } if input.try(|i| i.expect_ident_matching("none")).is_ok() { - return Ok(CounterStyleOrNone::None_); + return Ok(CounterStyleOrNone::None); } if input.try(|i| i.expect_function_matching("symbols")).is_ok() { return input.parse_nested_block(|input| { @@ -108,23 +109,6 @@ impl Parse for CounterStyleOrNone { } } -impl ToCss for CounterStyleOrNone { - #[inline] - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match self { - &CounterStyleOrNone::None_ => dest.write_str("none"), - &CounterStyleOrNone::Name(ref name) => name.to_css(dest), - &CounterStyleOrNone::Symbols(ref symbols_type, ref symbols) => { - dest.write_str("symbols(")?; - symbols_type.to_css(dest)?; - dest.write_str(" ")?; - symbols.to_css(dest)?; - dest.write_str(")") - } - } - } -} - /// A settings tag, defined by a four-character tag and a setting value /// /// For font-feature-settings, this is a tag and an integer, diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index 0f39a7deca1..6264e8186e1 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -25,7 +25,7 @@ pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream { to_computed_value::derive(input).to_string().parse().unwrap() } -#[proc_macro_derive(ToCss)] +#[proc_macro_derive(ToCss, attributes(css))] pub fn derive_to_css(stream: TokenStream) -> TokenStream { let input = syn::parse_derive_input(&stream.to_string()).unwrap(); to_css::derive(input).to_string().parse().unwrap() diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index f85fe1ce418..8531b39ab46 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -16,24 +16,61 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens { let style = synstructure::BindStyle::Ref.into(); let match_body = synstructure::each_variant(&input, &style, |bindings, variant| { - if bindings.is_empty() { - let identifier = to_css_identifier(variant.ident.as_ref()); - return Some(quote! { + let mut identifier = to_css_identifier(variant.ident.as_ref()); + let mut expr = if bindings.is_empty() { + quote! { ::std::fmt::Write::write_str(dest, #identifier) - }); - } - let (first, rest) = bindings.split_first().expect("unit variants are not yet supported"); - where_clause.predicates.push(where_predicate(first.field.ty.clone())); - let mut expr = quote! { - ::style_traits::ToCss::to_css(#first, dest) + } + } else { + let (first, rest) = bindings.split_first().expect("unit variants are not yet supported"); + where_clause.predicates.push(where_predicate(first.field.ty.clone())); + let mut expr = quote! { + ::style_traits::ToCss::to_css(#first, dest) + }; + for binding in rest { + where_clause.predicates.push(where_predicate(binding.field.ty.clone())); + expr = quote! { + #expr?; + ::std::fmt::Write::write_str(dest, " ")?; + ::style_traits::ToCss::to_css(#binding, dest) + }; + } + expr }; - for binding in rest { - where_clause.predicates.push(where_predicate(binding.field.ty.clone())); + let mut css_attrs = variant.attrs.iter().filter(|attr| attr.name() == "css"); + let is_function = css_attrs.next().map_or(false, |attr| { + match attr.value { + syn::MetaItem::List(ref ident, ref items) if ident.as_ref() == "css" => { + let mut nested = items.iter(); + let is_function = nested.next().map_or(false, |attr| { + match *attr { + syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref ident)) => { + if ident.as_ref() != "function" { + panic!("only `#[css(function)]` is supported for now") + } + true + }, + _ => panic!("only `#[css(<ident>)]` is supported for now"), + } + }); + if nested.next().is_some() { + panic!("only `#[css()]` or `#[css(<ident>)]` is supported for now") + } + is_function + }, + _ => panic!("only `#[css(...)]` is supported for now"), + } + }); + if css_attrs.next().is_some() { + panic!("only a single `#[css(...)]` attribute is supported for now"); + } + if is_function { + identifier.push_str("("); expr = quote! { + ::std::fmt::Write::write_str(dest, #identifier)?; #expr?; - ::std::fmt::Write::write_str(dest, " ")?; - ::style_traits::ToCss::to_css(#binding, dest) - }; + ::std::fmt::Write::write_str(dest, ")") + } } Some(expr) }); |