diff options
-rw-r--r-- | components/style/properties/helpers.mako.rs | 70 | ||||
-rw-r--r-- | components/style/values/specified/font.rs | 26 | ||||
-rw-r--r-- | components/style_derive/to_css.rs | 15 | ||||
-rw-r--r-- | components/style_traits/values.rs | 17 |
4 files changed, 48 insertions, 80 deletions
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 1be21cd377c..43c912516f3 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -83,10 +83,6 @@ need_animatable=need_animatable, **kwargs)"> #[allow(unused_imports)] use smallvec::SmallVec; - % if allow_empty: - use std::fmt::{self, Write}; - use style_traits::{CssWriter, Separator, ToCss}; - % endif pub mod single_value { #[allow(unused_imports)] @@ -120,23 +116,22 @@ use values::computed::ComputedVecIter; /// The computed value, effectively a list of single values. - #[derive(Clone, Debug, MallocSizeOf, PartialEq)] - % if need_animatable or animation_value_type == "ComputedValue": - #[derive(Animate, ComputeSquaredDistance)] - % endif - % if not allow_empty: % if separator == "Comma": #[css(comma)] % endif - #[derive(ToCss)] + #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] + % if need_animatable or animation_value_type == "ComputedValue": + #[derive(Animate, ComputeSquaredDistance)] % endif pub struct T( - % if allow_empty and allow_empty != "NotInitial": - pub Vec<single_value::T>, - % else: % if not allow_empty: #[css(iterable)] + % else: + #[css(if_empty = "none", iterable)] % endif + % if allow_empty and allow_empty != "NotInitial": + pub Vec<single_value::T>, + % else: pub SmallVec<[single_value::T; 1]>, % endif ); @@ -165,63 +160,20 @@ } } - % if allow_empty: - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result - where - W: Write, - { - let mut iter = self.0.iter(); - if let Some(val) = iter.next() { - val.to_css(dest)?; - } else { - return dest.write_str("none"); - } - for i in iter { - dest.write_str(::style_traits::${separator}::separator())?; - i.to_css(dest)?; - } - Ok(()) - } - } - % endif - /// The specified value of ${name}. - #[derive(Clone, Debug, MallocSizeOf, PartialEq)] - % if not allow_empty: % if separator == "Comma": #[css(comma)] % endif - #[derive(ToCss)] - % endif + #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] pub struct SpecifiedValue( % if not allow_empty: #[css(iterable)] + % else: + #[css(if_empty = "none", iterable)] % endif pub Vec<single_value::SpecifiedValue>, ); - % if allow_empty: - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result - where - W: Write, - { - let mut iter = self.0.iter(); - if let Some(val) = iter.next() { - val.to_css(dest)?; - } else { - return dest.write_str("none"); - } - for i in iter { - dest.write_str(::style_traits::${separator}::separator())?; - i.to_css(dest)?; - } - Ok(()) - } - } - % endif - pub fn get_initial_value() -> computed_value::T { % if allow_empty and allow_empty != "NotInitial": computed_value::T(vec![]) diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index 7d442b49126..adf59df7e45 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -736,9 +736,12 @@ pub enum VariantAlternates { HistoricalForms, } -#[derive(Clone, Debug, MallocSizeOf, PartialEq)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] /// List of Variant Alternates -pub struct VariantAlternatesList(pub Box<[VariantAlternates]>); +pub struct VariantAlternatesList( + #[css(if_empty = "normal", iterable)] + pub Box<[VariantAlternates]>, +); impl VariantAlternatesList { /// Returns the length of all variant alternates. @@ -759,25 +762,6 @@ impl VariantAlternatesList { } } -impl ToCss for VariantAlternatesList { - fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result - where - W: Write, - { - if self.0.is_empty() { - return dest.write_str("normal"); - } - - let mut iter = self.0.iter(); - iter.next().unwrap().to_css(dest)?; - for alternate in iter { - dest.write_str(" ")?; - alternate.to_css(dest)?; - } - Ok(()) - } -} - #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] /// Control over the selection of these alternate glyphs pub enum FontVariantAlternates { diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 4e394ba605b..a0197dedc86 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -150,6 +150,20 @@ fn derive_single_field_expr( where_clause: &mut WhereClause, ) -> Tokens { if attrs.iterable { + if let Some(if_empty) = attrs.if_empty { + return quote! { + { + let mut iter = #field.iter().peekable(); + if iter.peek().is_none() { + writer.item(&::style_traits::values::Verbatim(#if_empty))?; + } else { + for item in iter { + writer.item(&item)?; + } + } + } + }; + } quote! { for item in #field.iter() { writer.item(&item)?; @@ -186,6 +200,7 @@ pub struct CssVariantAttrs { #[darling(attributes(css), default)] #[derive(Default, FromField)] struct CssFieldAttrs { + if_empty: Option<String>, ignore_bound: bool, iterable: bool, skip: bool, diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index 188fccc9691..aad75d51b8a 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -27,6 +27,8 @@ use std::fmt::{self, Write}; /// * if `#[css(iterable)]` is found on a function variant, that variant needs /// to have a single member, and that member needs to be iterable. The /// iterable will be serialized as the arguments for the function; +/// * an iterable field can also be annotated with `#[css(if_empty = "foo")]` +/// to print `"foo"` if the iterator is empty; /// * if `#[css(dimension)]` is found on a variant, that variant needs /// to have a single member. The variant would be serialized as a CSS /// dimension token, like: <member><identifier>; @@ -210,6 +212,21 @@ where } } +/// A wrapper type that implements `ToCss` by printing its inner field. +pub struct Verbatim<'a, T>(pub &'a T) +where + T: ?Sized + 'a; + +impl<'a, T> ToCss for Verbatim<'a, T> +where + T: AsRef<str> + ?Sized + 'a, +{ + #[inline] + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { + dest.write_str(self.0.as_ref()) + } +} + /// Type used as the associated type in the `OneOrMoreSeparated` trait on a /// type to indicate that a serialized list of elements of this type is /// separated by commas. |