mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Introduce #[css(function)] for #[derive(ToCss)]
Any variant with this attribute gets serialised as a CSS function, using the variant name as the function name.
This commit is contained in:
parent
fd1ab75af9
commit
43a5257a0c
7 changed files with 66 additions and 66 deletions
|
@ -401,7 +401,7 @@ impl CounterStyleOrNone {
|
||||||
use gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name;
|
use gecko_bindings::bindings::Gecko_SetCounterStyleToName as set_name;
|
||||||
use gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols;
|
use gecko_bindings::bindings::Gecko_SetCounterStyleToSymbols as set_symbols;
|
||||||
match self {
|
match self {
|
||||||
CounterStyleOrNone::None_ => unsafe {
|
CounterStyleOrNone::None => unsafe {
|
||||||
set_name(gecko_value, atom!("none").into_addrefed());
|
set_name(gecko_value, atom!("none").into_addrefed());
|
||||||
},
|
},
|
||||||
CounterStyleOrNone::Name(name) => unsafe {
|
CounterStyleOrNone::Name(name) => unsafe {
|
||||||
|
|
|
@ -63,7 +63,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
|
||||||
pub fn from_gecko_keyword(value: u32) -> Self {
|
pub fn from_gecko_keyword(value: u32) -> Self {
|
||||||
use gecko_bindings::structs;
|
use gecko_bindings::structs;
|
||||||
SpecifiedValue::CounterStyle(if value == structs::NS_STYLE_LIST_STYLE_NONE {
|
SpecifiedValue::CounterStyle(if value == structs::NS_STYLE_LIST_STYLE_NONE {
|
||||||
CounterStyleOrNone::None_
|
CounterStyleOrNone::None
|
||||||
} else {
|
} else {
|
||||||
<%
|
<%
|
||||||
values = """disc circle square decimal lower-roman
|
values = """disc circle square decimal lower-roman
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
list_style_type::SpecifiedValue::none
|
list_style_type::SpecifiedValue::none
|
||||||
% else:
|
% else:
|
||||||
use values::generics::CounterStyleOrNone;
|
use values::generics::CounterStyleOrNone;
|
||||||
list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None_)
|
list_style_type::SpecifiedValue::CounterStyle(CounterStyleOrNone::None)
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
//! Generic types for legacy Gecko-only properties that should probably be
|
//! Generic types for legacy Gecko-only properties that should probably be
|
||||||
//! unshipped at some point in the future.
|
//! unshipped at some point in the future.
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use style_traits::ToCss;
|
|
||||||
|
|
||||||
/// A generic value for scroll snap points.
|
/// 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> {
|
pub enum ScrollSnapPoint<LengthOrPercentage> {
|
||||||
/// `none`
|
/// `none`
|
||||||
None,
|
None,
|
||||||
/// `repeat(<length-or-percentage>)`
|
/// `repeat(<length-or-percentage>)`
|
||||||
|
#[css(function)]
|
||||||
Repeat(LengthOrPercentage)
|
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(")")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -54,13 +54,14 @@ impl SymbolsType {
|
||||||
///
|
///
|
||||||
/// Since wherever <counter-style> is used, 'none' is a valid value as
|
/// Since wherever <counter-style> is used, 'none' is a valid value as
|
||||||
/// well, we combine them into one type to make code simpler.
|
/// 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 {
|
pub enum CounterStyleOrNone {
|
||||||
/// none
|
/// `none`
|
||||||
None_,
|
None,
|
||||||
/// <counter-style-name>
|
/// `<counter-style-name>`
|
||||||
Name(CustomIdent),
|
Name(CustomIdent),
|
||||||
/// symbols()
|
/// `symbols()`
|
||||||
|
#[css(function)]
|
||||||
Symbols(SymbolsType, Symbols),
|
Symbols(SymbolsType, Symbols),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ impl Parse for CounterStyleOrNone {
|
||||||
return Ok(CounterStyleOrNone::Name(name));
|
return Ok(CounterStyleOrNone::Name(name));
|
||||||
}
|
}
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
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() {
|
if input.try(|i| i.expect_function_matching("symbols")).is_ok() {
|
||||||
return input.parse_nested_block(|input| {
|
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
|
/// A settings tag, defined by a four-character tag and a setting value
|
||||||
///
|
///
|
||||||
/// For font-feature-settings, this is a tag and an integer,
|
/// For font-feature-settings, this is a tag and an integer,
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream {
|
||||||
to_computed_value::derive(input).to_string().parse().unwrap()
|
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 {
|
pub fn derive_to_css(stream: TokenStream) -> TokenStream {
|
||||||
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
|
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
|
||||||
to_css::derive(input).to_string().parse().unwrap()
|
to_css::derive(input).to_string().parse().unwrap()
|
||||||
|
|
|
@ -16,24 +16,61 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
|
||||||
|
|
||||||
let style = synstructure::BindStyle::Ref.into();
|
let style = synstructure::BindStyle::Ref.into();
|
||||||
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
|
let match_body = synstructure::each_variant(&input, &style, |bindings, variant| {
|
||||||
if bindings.is_empty() {
|
let mut identifier = to_css_identifier(variant.ident.as_ref());
|
||||||
let identifier = to_css_identifier(variant.ident.as_ref());
|
let mut expr = if bindings.is_empty() {
|
||||||
return Some(quote! {
|
quote! {
|
||||||
::std::fmt::Write::write_str(dest, #identifier)
|
::std::fmt::Write::write_str(dest, #identifier)
|
||||||
});
|
}
|
||||||
}
|
} else {
|
||||||
let (first, rest) = bindings.split_first().expect("unit variants are not yet supported");
|
let (first, rest) = bindings.split_first().expect("unit variants are not yet supported");
|
||||||
where_clause.predicates.push(where_predicate(first.field.ty.clone()));
|
where_clause.predicates.push(where_predicate(first.field.ty.clone()));
|
||||||
let mut expr = quote! {
|
let mut expr = quote! {
|
||||||
::style_traits::ToCss::to_css(#first, dest)
|
::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)
|
|
||||||
};
|
};
|
||||||
|
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
|
||||||
|
};
|
||||||
|
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, ")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(expr)
|
Some(expr)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue