From 174f5f7128927191efd4aef80a19c229b1c3cff1 Mon Sep 17 00:00:00 2001 From: CJ Ku Date: Thu, 25 Jan 2018 12:50:15 +0900 Subject: [PATCH] Implement scale property styling --- .../dom/webidls/CSSStyleDeclaration.webidl | 1 + components/style/properties/gecko.mako.rs | 4 ++- .../style/properties/longhand/box.mako.rs | 8 +++++ components/style/values/computed/mod.rs | 2 +- components/style/values/computed/transform.rs | 26 ++++++++++++++++ components/style/values/generics/transform.rs | 16 ++++++++++ components/style/values/specified/mod.rs | 2 +- .../style/values/specified/transform.rs | 31 ++++++++++++++++++- .../parsing/scale-parsing-invalid.html.ini | 7 ----- 9 files changed, 86 insertions(+), 11 deletions(-) delete mode 100644 tests/wpt/metadata/css/css-transforms/parsing/scale-parsing-invalid.html.ini diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index 598e7d3cb876..b6df01769473 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -190,6 +190,7 @@ partial interface CSSStyleDeclaration { [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString backfaceVisibility; [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString backface-visibility; [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString rotate; + [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString scale; [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString translate; [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString direction; diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 0c75b67afd78..7b86d29106c8 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3061,7 +3061,8 @@ fn static_assert() { overscroll-behavior-x overscroll-behavior-y overflow-clip-box-inline overflow-clip-box-block perspective-origin -moz-binding will-change - shape-outside contain touch-action translate""" %> + shape-outside contain touch-action translate + scale""" %> <%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}"> // We manually-implement the |display| property until we get general @@ -3488,6 +3489,7 @@ fn static_assert() { ${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')} ${impl_individual_transform('translate', 'Translate', 'mSpecifiedTranslate')} + ${impl_individual_transform('scale', 'Scale', 'mSpecifiedScale')} pub fn set_will_change(&mut self, v: longhands::will_change::computed_value::T) { use gecko_bindings::bindings::{Gecko_AppendWillChange, Gecko_ClearWillChange}; diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 454461a9bf69..286bf6b7ea9e 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -398,6 +398,14 @@ ${helpers.predefined_type("rotate", "Rotate", gecko_pref="layout.css.individual-transform.enabled", spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms")} +${helpers.predefined_type("scale", "Scale", + "generics::transform::Scale::None", + animation_value_type="ComputedValue", + boxed=True, + flags="CREATES_STACKING_CONTEXT FIXPOS_CB", + gecko_pref="layout.css.individual-transform.enabled", + spec="https://drafts.csswg.org/css-transforms-2/#individual-transforms")} + ${helpers.predefined_type("translate", "Translate", "generics::transform::Translate::None", animation_value_type="ComputedValue", diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 4bbd73e8f351..c91256d7e6e6 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -73,7 +73,7 @@ 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}; +pub use self::transform::{TimingFunction, Transform, TransformOperation, TransformOrigin, Rotate, Translate, Scale}; 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 a3ea8b46daf3..17b2fa705408 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -13,6 +13,7 @@ use values::computed::{LengthOrNumber, LengthOrPercentageOrNumber}; use values::generics::transform::{self, Matrix as GenericMatrix, Matrix3D as GenericMatrix3D}; use values::generics::transform::{Transform as GenericTransform, TransformOperation as GenericTransformOperation}; use values::generics::transform::Rotate as GenericRotate; +use values::generics::transform::Scale as GenericScale; use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; use values::generics::transform::Translate as GenericTranslate; @@ -344,3 +345,28 @@ impl Translate { } } } + +/// A computed CSS `scale` +pub type Scale = GenericScale; + +impl Scale { + /// Convert TransformOperation to Scale. + pub fn to_transform_operation(&self) -> Option { + match *self { + GenericScale::None => None, + GenericScale::ScaleX(sx) => Some(GenericTransformOperation::ScaleX(sx)), + GenericScale::Scale(sx, sy) => Some(GenericTransformOperation::Scale(sx, Some(sy))), + GenericScale::Scale3D(sx, sy, sz) => Some(GenericTransformOperation::Scale3D(sx, sy, sz)), + } + } + + /// Convert Scale to TransformOperation. + pub fn from_transform_operation(operation: &TransformOperation) -> Scale { + match *operation { + GenericTransformOperation::ScaleX(sx) => GenericScale::ScaleX(sx), + GenericTransformOperation::Scale(sx, Some(sy)) => GenericScale::Scale(sx, sy), + GenericTransformOperation::Scale3D(sx, sy, sz) => GenericScale::Scale3D(sx, sy, sz), + _ => unreachable!("Found unexpected value for scale"), + } + } +} diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index d7a5bfb7bc50..9ea641c047de 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -683,6 +683,22 @@ pub enum Rotate { Rotate3D(Number, Number, Number, Angle), } +#[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] +/// A value of the `Scale` property +/// +/// +pub enum Scale { + /// 'none' + None, + /// '' + ScaleX(Number), + /// '{2}' + Scale(Number, Number), + /// '{3}' + Scale3D(Number, Number, Number), +} + #[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)] #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] /// A value of the `Translate` property diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 6feadb33288a..bff8af54aaa4 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -69,7 +69,7 @@ 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}; +pub use self::transform::{TimingFunction, Transform, TransformOrigin, Rotate, Translate, Scale}; 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 b731dfb17f62..d98b4c9da6fa 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -15,6 +15,7 @@ use values::generics::transform::{Matrix3D, Transform as GenericTransform}; use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction, Matrix}; use values::generics::transform::{TimingKeyword, TransformOrigin as GenericTransformOrigin}; use values::generics::transform::Rotate as GenericRotate; +use values::generics::transform::Scale as GenericScale; use values::generics::transform::TransformOperation as GenericTransformOperation; use values::generics::transform::Translate as GenericTranslate; use values::specified::{self, Angle, Number, Length, Integer}; @@ -523,7 +524,7 @@ impl Parse for Rotate { return Ok(GenericRotate::None); } - if let Some(rx) = input.try(|i| Number::parse(context, i)).ok() { + if let Ok(rx) = input.try(|i| Number::parse(context, i)) { // 'rotate: {3} ' let ry = Number::parse(context, input)?; let rz = Number::parse(context, input)?; @@ -564,3 +565,31 @@ impl Parse for Translate { Ok(GenericTranslate::TranslateX(tx)) } } + +/// A specified CSS `scale` +pub type Scale = GenericScale; + +impl Parse for Scale { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result> { + if input.try(|i| i.expect_ident_matching("none")).is_ok() { + return Ok(GenericScale::None); + } + + let sx = Number::parse(context, input)?; + if let Ok(sy) = input.try(|i| Number::parse(context, i)) { + if let Ok(sz) = input.try(|i| Number::parse(context, i)) { + // 'scale: ' + return Ok(GenericScale::Scale3D(sx, sy, sz)); + } + + // 'scale: ' + return Ok(GenericScale::Scale(sx, sy)); + } + + // 'scale: ' + Ok(GenericScale::ScaleX(sx)) + } +} diff --git a/tests/wpt/metadata/css/css-transforms/parsing/scale-parsing-invalid.html.ini b/tests/wpt/metadata/css/css-transforms/parsing/scale-parsing-invalid.html.ini deleted file mode 100644 index df96fb9b65e1..000000000000 --- a/tests/wpt/metadata/css/css-transforms/parsing/scale-parsing-invalid.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[scale-parsing-invalid.html] - [e.style['scale'\] = "100px" should not set the property value] - expected: FAIL - - [e.style['scale'\] = "100 200 300 400" should not set the property value] - expected: FAIL -