diff options
author | CJ Ku <cku@mozilla.com> | 2018-01-25 12:44:20 +0900 |
---|---|---|
committer | Brian Birtles <birtles@gmail.com> | 2018-01-31 22:12:26 +0000 |
commit | 62c0c6feee8304eb40d0dcb574b6d1b98249eccc (patch) | |
tree | 38d222da8bb21cdb5c853090930d362fdc43284f | |
parent | a8c133d07ed75f1da89d5e24b45d4043bfb79471 (diff) | |
download | servo-62c0c6feee8304eb40d0dcb574b6d1b98249eccc.tar.gz servo-62c0c6feee8304eb40d0dcb574b6d1b98249eccc.zip |
Implement rotate property styling
-rw-r--r-- | components/script/dom/webidls/CSSStyleDeclaration.webidl | 1 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 36 | ||||
-rw-r--r-- | components/style/properties/longhand/box.mako.rs | 8 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/computed/transform.rs | 25 | ||||
-rw-r--r-- | components/style/values/generics/transform.rs | 14 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/specified/transform.rs | 28 | ||||
-rw-r--r-- | tests/wpt/metadata/css/css-transforms/parsing/rotate-parsing-invalid.html.ini | 13 |
9 files changed, 113 insertions, 16 deletions
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl index a7eb0289b84..987a95edb22 100644 --- a/components/script/dom/webidls/CSSStyleDeclaration.webidl +++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl @@ -189,6 +189,7 @@ partial interface CSSStyleDeclaration { [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString transform-style; [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 direction; [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString unicodeBidi; diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 64a729dad5c..a4de0ed7b5d 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3016,13 +3016,45 @@ fn static_assert() { ${impl_copy_animation_value(ident, gecko_ffi_name)} </%def> +<%def name="impl_individual_transform(ident, type, gecko_ffi_name)"> + pub fn set_${ident}(&mut self, other: values::computed::${type}) { + unsafe { self.gecko.${gecko_ffi_name}.clear() }; + + if let Some(operation) = other.to_transform_operation() { + convert_transform(&[operation], &mut self.gecko.${gecko_ffi_name}) + } + } + + pub fn copy_${ident}_from(&mut self, other: &Self) { + unsafe { self.gecko.${gecko_ffi_name}.set(&other.gecko.${gecko_ffi_name}); } + } + + pub fn reset_${ident}(&mut self, other: &Self) { + self.copy_${ident}_from(other) + } + + pub fn clone_${ident}(&self) -> values::computed::${type} { + use values::generics::transform::${type}; + + if self.gecko.${gecko_ffi_name}.mRawPtr.is_null() { + return ${type}::None; + } + + let list = unsafe { (*self.gecko.${gecko_ffi_name}.to_safe().get()).mHead.as_ref() }; + + let mut transform = clone_transform_from_list(list); + debug_assert_eq!(transform.0.len(), 1); + ${type}::from_transform_operation(&transform.0.pop().unwrap()) + } +</%def> + <% skip_box_longhands= """display overflow-y vertical-align animation-name animation-delay animation-duration animation-direction animation-fill-mode animation-play-state animation-iteration-count animation-timing-function transition-duration transition-delay transition-timing-function transition-property - page-break-before page-break-after + page-break-before page-break-after rotate scroll-snap-points-x scroll-snap-points-y scroll-snap-type-x scroll-snap-type-y scroll-snap-coordinate perspective-origin -moz-binding will-change @@ -3454,6 +3486,8 @@ fn static_assert() { } } + ${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')} + pub fn set_will_change(&mut self, v: longhands::will_change::computed_value::T) { use gecko_bindings::bindings::{Gecko_AppendWillChange, Gecko_ClearWillChange}; use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_OPACITY; diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index d1b26de1154..f42a0861724 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -390,6 +390,14 @@ ${helpers.predefined_type("transform", "Transform", flags="CREATES_STACKING_CONTEXT FIXPOS_CB", spec="https://drafts.csswg.org/css-transforms/#propdef-transform")} +${helpers.predefined_type("rotate", "Rotate", + "generics::transform::Rotate::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")} + // CSSOM View Module // https://www.w3.org/TR/cssom-view-1/ ${helpers.single_keyword("scroll-behavior", diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 4156e784c9e..75ea1586719 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}; +pub use self::transform::{TimingFunction, Transform, TransformOperation, TransformOrigin, Rotate}; 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 4ad043850c8..8f5d1a645d1 100644 --- a/components/style/values/computed/transform.rs +++ b/components/style/values/computed/transform.rs @@ -12,6 +12,7 @@ use values::computed::{Angle, Integer, Length, LengthOrPercentage, Number, Perce 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::TimingFunction as GenericTimingFunction; use values::generics::transform::TransformOrigin as GenericTransformOrigin; @@ -293,3 +294,27 @@ impl ToAnimatedZero for Transform { .collect::<Result<Vec<_>, _>>()?)) } } + +/// A computed CSS `rotate` +pub type Rotate = GenericRotate<Number, Angle>; + +impl Rotate { + /// Convert TransformOperation to Rotate. + pub fn to_transform_operation(&self) -> Option<TransformOperation> { + match *self { + GenericRotate::None => None, + GenericRotate::Rotate(angle) => Some(GenericTransformOperation::Rotate(angle)), + GenericRotate::Rotate3D(rx, ry, rz, angle) => Some(GenericTransformOperation::Rotate3D(rx, ry, rz, angle)), + } + } + + /// Convert Rotate to TransformOperation. + pub fn from_transform_operation(operation: &TransformOperation) -> Rotate { + match *operation { + GenericTransformOperation::Rotate(angle) => GenericRotate::Rotate(angle), + GenericTransformOperation::Rotate3D(rx, ry, rz, angle) => + GenericRotate::Rotate3D(rx, ry, rz, angle), + _ => unreachable!("Found unexpected value for rotate property"), + } + } +} diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index 7c2bb57546e..e1fc8c01fa2 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -668,3 +668,17 @@ pub fn get_normalized_vector_and_angle<T: Zero>( (vector.x, vector.y, vector.z, angle) } } + +#[derive(Animate, ComputeSquaredDistance, ToAnimatedZero, ToComputedValue)] +#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)] +/// A value of the `Rotate` property +/// +/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms> +pub enum Rotate<Number, Angle> { + /// 'none' + None, + /// '<angle>' + Rotate(Angle), + /// '<number>{3} <angle>' + Rotate3D(Number, Number, Number, Angle), +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 877580f799d..a19ed04b753 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}; +pub use self::transform::{TimingFunction, Transform, TransformOrigin, Rotate}; 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 a8437d558cc..3f766a086c6 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -14,6 +14,7 @@ use values::computed::transform::TimingFunction as ComputedTimingFunction; 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::TransformOperation as GenericTransformOperation; use values::specified::{self, Angle, Number, Length, Integer}; use values::specified::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrNumber}; @@ -508,3 +509,30 @@ impl ToComputedValue for TimingFunction { } } } + +/// A specified CSS `rotate` +pub type Rotate = GenericRotate<Number, Angle>; + +impl Parse for Rotate { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result<Self, ParseError<'i>> { + if input.try(|i| i.expect_ident_matching("none")).is_ok() { + return Ok(GenericRotate::None); + } + + if let Some(rx) = input.try(|i| Number::parse(context, i)).ok() { + // 'rotate: <number>{3} <angle>' + let ry = Number::parse(context, input)?; + let rz = Number::parse(context, input)?; + let angle = specified::Angle::parse(context, input)?; + return Ok(GenericRotate::Rotate3D(rx, ry, rz, angle)); + } + + // 'rotate: <angle>' + let angle = specified::Angle::parse(context, input)?; + Ok(GenericRotate::Rotate(angle)) + } +} + diff --git a/tests/wpt/metadata/css/css-transforms/parsing/rotate-parsing-invalid.html.ini b/tests/wpt/metadata/css/css-transforms/parsing/rotate-parsing-invalid.html.ini deleted file mode 100644 index b28de4b2e0f..00000000000 --- a/tests/wpt/metadata/css/css-transforms/parsing/rotate-parsing-invalid.html.ini +++ /dev/null @@ -1,13 +0,0 @@ -[rotate-parsing-invalid.html] - [e.style['rotate'\] = "100px" should not set the property value] - expected: FAIL - - [e.style['rotate'\] = "100 400deg" should not set the property value] - expected: FAIL - - [e.style['rotate'\] = "100 200 400deg" should not set the property value] - expected: FAIL - - [e.style['rotate'\] = "100 200 300 500 400deg" should not set the property value] - expected: FAIL - |