diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 7b86d29106c..27bc26f932d 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -62,6 +62,7 @@ use values::computed::{NonNegativeLength, ToComputedValue, Percentage}; use values::computed::font::{FontSize, SingleFontFamily}; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; use values::computed::outline::OutlineStyle; +use values::generics::transform::TransformStyle; use computed_values::border_style; pub mod style_structs { @@ -3345,6 +3346,25 @@ fn static_assert() { self.copy_transition_property_from(other) } + // Hand-written because the Mako helpers transform `Preserve3d` into `PRESERVE3D`. + pub fn set_transform_style(&mut self, v: TransformStyle) { + self.gecko.mTransformStyle = match v { + TransformStyle::Flat => structs::NS_STYLE_TRANSFORM_STYLE_FLAT as u8, + TransformStyle::Preserve3d => structs::NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D as u8, + }; + } + + // Hand-written because the Mako helpers transform `Preserve3d` into `PRESERVE3D`. + pub fn clone_transform_style(&self) -> TransformStyle { + match self.gecko.mTransformStyle as u32 { + structs::NS_STYLE_TRANSFORM_STYLE_FLAT => TransformStyle::Flat, + structs::NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D => TransformStyle::Preserve3d, + _ => panic!("illegal transform style"), + } + } + + ${impl_simple_copy('transform_style', 'mTransformStyle')} + ${impl_transition_count('property', 'Property')} pub fn animations_equals(&self, other: &Self) -> bool { diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 286bf6b7ea9..6de6486fa4d 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -526,14 +526,16 @@ ${helpers.single_keyword("transform-box", gecko_inexhaustive="True", animation_value_type="discrete")} -// `auto` keyword is not supported in gecko yet. -${helpers.single_keyword("transform-style", - "auto flat preserve-3d" if product == "servo" else - "flat preserve-3d", - spec="https://drafts.csswg.org/css-transforms/#transform-style-property", - extra_prefixes="moz webkit", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", - animation_value_type="discrete")} +${helpers.predefined_type( + "transform-style", + "TransformStyle", + "computed::TransformStyle::" + ("Auto" if product == "servo" else "Flat"), + spec="https://drafts.csswg.org/css-transforms-2/#transform-style-property", + needs_context=False, + extra_prefixes="moz webkit", + flags="CREATES_STACKING_CONTEXT FIXPOS_CB", + animation_value_type="discrete", +)} ${helpers.predefined_type("transform-origin", "TransformOrigin", diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index c91256d7e6e..874424f45c3 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -73,7 +73,8 @@ pub use self::svg::MozContextProperties; pub use self::table::XSpan; pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextAlign, TextOverflow, WordSpacing}; pub use self::time::Time; -pub use self::transform::{TimingFunction, Transform, TransformOperation, TransformOrigin, Rotate, Translate, Scale}; +pub use self::transform::{Rotate, Scale, TimingFunction, Transform, TransformOperation}; +pub use self::transform::{TransformOrigin, TransformStyle, Translate}; pub use self::ui::MozForceBrokenImageIcon; #[cfg(feature = "gecko")] diff --git a/components/style/values/computed/transform.rs b/components/style/values/computed/transform.rs index 17b2fa70540..bcf90f3966c 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -18,6 +18,8 @@ use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; use values::generics::transform::Translate as GenericTranslate; +pub use values::generics::transform::TransformStyle; + /// A single operation in a computed CSS `transform` pub type TransformOperation = GenericTransformOperation< Angle, diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index e8b8c2e0678..432934cc1e4 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -714,3 +714,13 @@ pub enum Translate { /// ' ' Translate3D(LengthOrPercentage, LengthOrPercentage, Length), } + +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss)] +pub enum TransformStyle { + #[cfg(feature = "servo")] + Auto, + Flat, + #[css(keyword = "preserve-3d")] + Preserve3d, +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index bff8af54aaa..9875914c2d4 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -69,7 +69,8 @@ pub use self::table::XSpan; pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextDecorationLine}; pub use self::text::{TextAlign, TextAlignKeyword, TextOverflow, WordSpacing}; pub use self::time::Time; -pub use self::transform::{TimingFunction, Transform, TransformOrigin, Rotate, Translate, Scale}; +pub use self::transform::{Rotate, Scale, TimingFunction, Transform}; +pub use self::transform::{TransformOrigin, TransformStyle, Translate}; pub use self::ui::MozForceBrokenImageIcon; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs index d98b4c9da6f..e2965cfefc5 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -22,6 +22,8 @@ use values::specified::{self, Angle, Number, Length, Integer}; use values::specified::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrNumber}; use values::specified::position::{Side, X, Y}; +pub use values::generics::transform::TransformStyle; + /// A single operation in a specified CSS `transform` pub type TransformOperation = GenericTransformOperation< Angle, diff --git a/components/style_derive/parse.rs b/components/style_derive/parse.rs index 48533e45f2f..79ada00878f 100644 --- a/components/style_derive/parse.rs +++ b/components/style_derive/parse.rs @@ -21,7 +21,9 @@ pub fn derive(input: DeriveInput) -> Tokens { ); let variant_attrs = cg::parse_variant_attrs::(variant); - let identifier = cg::to_css_identifier(variant.ident.as_ref()); + let identifier = cg::to_css_identifier( + &variant_attrs.keyword.as_ref().unwrap_or(&variant.ident).as_ref(), + ); let ident = &variant.ident; match_body = quote! { diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 57d04f00547..f9ac8fcbdd5 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -23,10 +23,19 @@ pub fn derive(input: DeriveInput) -> Tokens { if variant_attrs.dimension { assert_eq!(bindings.len(), 1); - assert!(variant_attrs.function.is_none(), "That makes no sense"); + assert!( + variant_attrs.function.is_none() && variant_attrs.keyword.is_none(), + "That makes no sense" + ); } - let mut expr = if !bindings.is_empty() { + let mut expr = if let Some(keyword) = variant_attrs.keyword { + assert!(bindings.is_empty()); + let keyword = keyword.to_string(); + quote! { + ::std::fmt::Write::write_str(dest, #keyword) + } + } else if !bindings.is_empty() { let mut expr = quote! {}; if variant_attrs.iterable { assert_eq!(bindings.len(), 1); @@ -128,6 +137,7 @@ pub struct CssVariantAttrs { pub iterable: bool, pub comma: bool, pub dimension: bool, + pub keyword: Option, pub aliases: Option, }