aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/properties/helpers.mako.rs70
-rw-r--r--components/style/values/specified/font.rs26
-rw-r--r--components/style_derive/to_css.rs15
-rw-r--r--components/style_traits/values.rs17
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.