aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/values.rs2
-rw-r--r--components/style/properties/helpers/animated_properties.mako.rs16
-rw-r--r--components/style/properties/longhand/list.mako.rs2
-rw-r--r--components/style/properties/shorthand/list.mako.rs2
-rw-r--r--components/style/values/computed/length.rs19
-rw-r--r--components/style/values/generics/basic_shape.rs13
-rw-r--r--components/style/values/generics/gecko.rs25
-rw-r--r--components/style/values/generics/mod.rs30
-rw-r--r--components/style_derive/lib.rs2
-rw-r--r--components/style_derive/to_css.rs65
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)
});