mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #20236 - emilio:to-css-skip-if, r=nox
Introduce #[css(skip_if)] This is most of #20224 but without the actual counter() fix since it's waiting on a WPT update. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20236) <!-- Reviewable:end -->
This commit is contained in:
commit
8133f788cf
4 changed files with 50 additions and 68 deletions
|
@ -15,31 +15,29 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
|
||||||
// decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman,
|
// decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman,
|
||||||
// upper-roman
|
// upper-roman
|
||||||
//
|
//
|
||||||
// TODO(bholley): Missing quite a few gecko properties here as well.
|
|
||||||
//
|
|
||||||
// In gecko, {upper,lower}-{roman,alpha} are implemented as @counter-styles in the
|
|
||||||
// UA, however they can also be set from pres attrs. When @counter-style is supported
|
|
||||||
// we may need to look into this and handle these differently.
|
|
||||||
//
|
|
||||||
// [1]: http://dev.w3.org/csswg/css-counter-styles/
|
// [1]: http://dev.w3.org/csswg/css-counter-styles/
|
||||||
% if product == "servo":
|
% if product == "servo":
|
||||||
${helpers.single_keyword("list-style-type", """
|
${helpers.single_keyword(
|
||||||
disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha
|
"list-style-type",
|
||||||
|
"""disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha
|
||||||
arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao
|
arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao
|
||||||
malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch
|
malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch
|
||||||
cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha""",
|
cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha""",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
|
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
|
||||||
servo_restyle_damage="rebuild_and_reflow")}
|
servo_restyle_damage="rebuild_and_reflow",
|
||||||
|
)}
|
||||||
% else:
|
% else:
|
||||||
${helpers.predefined_type("list-style-type",
|
${helpers.predefined_type(
|
||||||
"ListStyleType",
|
"list-style-type",
|
||||||
"computed::ListStyleType::disc()",
|
"ListStyleType",
|
||||||
initial_specified_value="specified::ListStyleType::disc()",
|
"computed::ListStyleType::disc()",
|
||||||
animation_value_type="discrete",
|
initial_specified_value="specified::ListStyleType::disc()",
|
||||||
boxed=True,
|
animation_value_type="discrete",
|
||||||
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
|
boxed=True,
|
||||||
servo_restyle_damage="rebuild_and_reflow")}
|
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type",
|
||||||
|
servo_restyle_damage="rebuild_and_reflow",
|
||||||
|
)}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
${helpers.predefined_type("list-style-image",
|
${helpers.predefined_type("list-style-image",
|
||||||
|
|
|
@ -80,12 +80,13 @@ pub struct TransformOrigin<H, V, Depth> {
|
||||||
/// A generic timing function.
|
/// A generic timing function.
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-timing-1/#single-timing-function-production>
|
/// <https://drafts.csswg.org/css-timing-1/#single-timing-function-production>
|
||||||
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||||
pub enum TimingFunction<Integer, Number> {
|
pub enum TimingFunction<Integer, Number> {
|
||||||
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
/// `linear | ease | ease-in | ease-out | ease-in-out`
|
||||||
Keyword(TimingKeyword),
|
Keyword(TimingKeyword),
|
||||||
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
|
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
#[css(comma, function)]
|
||||||
CubicBezier {
|
CubicBezier {
|
||||||
x1: Number,
|
x1: Number,
|
||||||
y1: Number,
|
y1: Number,
|
||||||
|
@ -93,8 +94,10 @@ pub enum TimingFunction<Integer, Number> {
|
||||||
y2: Number,
|
y2: Number,
|
||||||
},
|
},
|
||||||
/// `step-start | step-end | steps(<integer>, [ start | end ]?)`
|
/// `step-start | step-end | steps(<integer>, [ start | end ]?)`
|
||||||
Steps(Integer, StepPosition),
|
#[css(comma, function)]
|
||||||
|
Steps(Integer, #[css(skip_if = "is_end")] StepPosition),
|
||||||
/// `frames(<integer>)`
|
/// `frames(<integer>)`
|
||||||
|
#[css(comma, function)]
|
||||||
Frames(Integer),
|
Frames(Integer),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +122,11 @@ pub enum StepPosition {
|
||||||
End,
|
End,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_end(position: &StepPosition) -> bool {
|
||||||
|
*position == StepPosition::End
|
||||||
|
}
|
||||||
|
|
||||||
impl<H, V, D> TransformOrigin<H, V, D> {
|
impl<H, V, D> TransformOrigin<H, V, D> {
|
||||||
/// Returns a new transform origin.
|
/// Returns a new transform origin.
|
||||||
pub fn new(horizontal: H, vertical: V, depth: D) -> Self {
|
pub fn new(horizontal: H, vertical: V, depth: D) -> Self {
|
||||||
|
@ -138,51 +146,6 @@ impl<Integer, Number> TimingFunction<Integer, Number> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Integer, Number> ToCss for TimingFunction<Integer, Number>
|
|
||||||
where
|
|
||||||
Integer: ToCss,
|
|
||||||
Number: ToCss,
|
|
||||||
{
|
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
{
|
|
||||||
match *self {
|
|
||||||
TimingFunction::Keyword(keyword) => keyword.to_css(dest),
|
|
||||||
TimingFunction::CubicBezier {
|
|
||||||
ref x1,
|
|
||||||
ref y1,
|
|
||||||
ref x2,
|
|
||||||
ref y2,
|
|
||||||
} => {
|
|
||||||
dest.write_str("cubic-bezier(")?;
|
|
||||||
x1.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
y1.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
x2.to_css(dest)?;
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
y2.to_css(dest)?;
|
|
||||||
dest.write_str(")")
|
|
||||||
},
|
|
||||||
TimingFunction::Steps(ref intervals, position) => {
|
|
||||||
dest.write_str("steps(")?;
|
|
||||||
intervals.to_css(dest)?;
|
|
||||||
if position != StepPosition::End {
|
|
||||||
dest.write_str(", ")?;
|
|
||||||
position.to_css(dest)?;
|
|
||||||
}
|
|
||||||
dest.write_str(")")
|
|
||||||
},
|
|
||||||
TimingFunction::Frames(ref frames) => {
|
|
||||||
dest.write_str("frames(")?;
|
|
||||||
frames.to_css(dest)?;
|
|
||||||
dest.write_str(")")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TimingKeyword {
|
impl TimingKeyword {
|
||||||
/// Returns the keyword as a quadruplet of Bezier point coordinates
|
/// Returns the keyword as a quadruplet of Bezier point coordinates
|
||||||
/// `(x1, y1, x2, y2)`.
|
/// `(x1, y1, x2, y2)`.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use cg::{self, WhereClause};
|
use cg::{self, WhereClause};
|
||||||
use darling::util::Override;
|
use darling::util::Override;
|
||||||
use quote::{ToTokens, Tokens};
|
use quote::{ToTokens, Tokens};
|
||||||
use syn::{self, Data};
|
use syn::{self, Data, Path};
|
||||||
use synstructure::{BindingInfo, Structure, VariantInfo};
|
use synstructure::{BindingInfo, Structure, VariantInfo};
|
||||||
|
|
||||||
pub fn derive(input: syn::DeriveInput) -> Tokens {
|
pub fn derive(input: syn::DeriveInput) -> Tokens {
|
||||||
|
@ -79,7 +79,6 @@ fn derive_variant_arm(
|
||||||
|
|
||||||
let mut expr = if let Some(keyword) = variant_attrs.keyword {
|
let mut expr = if let Some(keyword) = variant_attrs.keyword {
|
||||||
assert!(bindings.is_empty());
|
assert!(bindings.is_empty());
|
||||||
let keyword = keyword.to_string();
|
|
||||||
quote! {
|
quote! {
|
||||||
::std::fmt::Write::write_str(dest, #keyword)
|
::std::fmt::Write::write_str(dest, #keyword)
|
||||||
}
|
}
|
||||||
|
@ -129,7 +128,15 @@ fn derive_variant_fields_expr(
|
||||||
if !attrs.ignore_bound {
|
if !attrs.ignore_bound {
|
||||||
where_clause.add_trait_bound(&first.ast().ty);
|
where_clause.add_trait_bound(&first.ast().ty);
|
||||||
}
|
}
|
||||||
return quote! { ::style_traits::ToCss::to_css(#first, dest) };
|
let mut expr = quote! { ::style_traits::ToCss::to_css(#first, dest) };
|
||||||
|
if let Some(condition) = attrs.skip_if {
|
||||||
|
expr = quote! {
|
||||||
|
if !#condition(#first) {
|
||||||
|
#expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut expr = derive_single_field_expr(first, attrs, where_clause);
|
let mut expr = derive_single_field_expr(first, attrs, where_clause);
|
||||||
|
@ -149,7 +156,7 @@ fn derive_single_field_expr(
|
||||||
attrs: CssFieldAttrs,
|
attrs: CssFieldAttrs,
|
||||||
where_clause: &mut WhereClause,
|
where_clause: &mut WhereClause,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
if attrs.iterable {
|
let mut expr = if attrs.iterable {
|
||||||
if let Some(if_empty) = attrs.if_empty {
|
if let Some(if_empty) = attrs.if_empty {
|
||||||
return quote! {
|
return quote! {
|
||||||
{
|
{
|
||||||
|
@ -174,7 +181,17 @@ fn derive_single_field_expr(
|
||||||
where_clause.add_trait_bound(&field.ast().ty);
|
where_clause.add_trait_bound(&field.ast().ty);
|
||||||
}
|
}
|
||||||
quote! { writer.item(#field)?; }
|
quote! { writer.item(#field)?; }
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(condition) = attrs.skip_if {
|
||||||
|
expr = quote! {
|
||||||
|
if !#condition(#field) {
|
||||||
|
#expr
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr
|
||||||
}
|
}
|
||||||
|
|
||||||
#[darling(attributes(css), default)]
|
#[darling(attributes(css), default)]
|
||||||
|
@ -204,4 +221,5 @@ struct CssFieldAttrs {
|
||||||
ignore_bound: bool,
|
ignore_bound: bool,
|
||||||
iterable: bool,
|
iterable: bool,
|
||||||
skip: bool,
|
skip: bool,
|
||||||
|
skip_if: Option<Path>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,9 @@ use std::fmt::{self, Write};
|
||||||
/// dimension token, like: <member><identifier>;
|
/// dimension token, like: <member><identifier>;
|
||||||
/// * if `#[css(skip)]` is found on a field, the `ToCss` call for that field
|
/// * if `#[css(skip)]` is found on a field, the `ToCss` call for that field
|
||||||
/// is skipped;
|
/// is skipped;
|
||||||
|
/// * if `#[css(skip_if = "function")]` is found on a field, the `ToCss` call
|
||||||
|
/// for that field is skipped if `function` returns true. This function is
|
||||||
|
/// provided the field as an argument;
|
||||||
/// * finally, one can put `#[css(derive_debug)]` on the whole type, to
|
/// * finally, one can put `#[css(derive_debug)]` on the whole type, to
|
||||||
/// implement `Debug` by a single call to `ToCss::to_css`.
|
/// implement `Debug` by a single call to `ToCss::to_css`.
|
||||||
pub trait ToCss {
|
pub trait ToCss {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue