Bug 1207734 - Part 7.b. (stylo) Implement translate property styling.
MozReview-Commit-ID: HtvrUEEGTdX
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -3127,17 +3127,17 @@ fn static_assert() {
transition-timing-function transition-property
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
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""" %>
+ shape-outside contain touch-action translate""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
// We manually-implement the |display| property until we get general
// infrastructure for preffing certain values.
<% display_keyword = Keyword("display", "inline block inline-block table inline-table table-row-group " +
"table-header-group table-footer-group table-row table-column-group " +
"table-column table-cell table-caption list-item flex none " +
"inline-flex grid inline-grid ruby ruby-base ruby-base-container " +
@@ -3553,16 +3553,17 @@ fn static_assert() {
horizontal: LengthOrPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[0])
.expect("Expected length or percentage for horizontal value of perspective-origin"),
vertical: LengthOrPercentage::from_gecko_style_coord(&self.gecko.mPerspectiveOrigin[1])
.expect("Expected length or percentage for vertical value of perspective-origin"),
}
}
${impl_individual_transform('rotate', 'Rotate', 'mSpecifiedRotate')}
+ ${impl_individual_transform('translate', 'Translate', 'mSpecifiedTranslate')}
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;
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_SCROLL;
use gecko_bindings::structs::NS_STYLE_WILL_CHANGE_TRANSFORM;
use properties::PropertyId;
use properties::longhands::will_change::computed_value::T;
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -394,16 +394,23 @@
${helpers.predefined_type("rotate", "Rotate",
"generics::transform::Rotate::None",
animation_value_type="ComputedValue",
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",
+ 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",
"auto smooth",
gecko_pref="layout.css.scroll-behavior.property-enabled",
products="gecko",
spec="https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior",
animation_value_type="discrete")}
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -60,17 +60,17 @@ pub use self::list::ListStyleType;
pub use self::outline::OutlineStyle;
pub use self::percentage::Percentage;
pub use self::position::{Position, GridAutoFlow, GridTemplateAreas};
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
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};
+pub use self::transform::{TimingFunction, Transform, TransformOperation, TransformOrigin, Rotate, Translate};
pub use self::ui::MozForceBrokenImageIcon;
#[cfg(feature = "gecko")]
pub mod align;
pub mod angle;
pub mod background;
pub mod basic_shape;
pub mod border;
--- a/servo/components/style/values/computed/transform.rs
+++ b/servo/components/style/values/computed/transform.rs
@@ -10,16 +10,17 @@ use super::{CSSFloat, Either};
use values::animated::ToAnimatedZero;
use values::computed::{Angle, Integer, Length, LengthOrPercentage, Number, Percentage};
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::TimingFunction as GenericTimingFunction;
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
use values::generics::transform::Rotate as GenericRotate;
+use values::generics::transform::Translate as GenericTranslate;
/// A single operation in a computed CSS `transform`
pub type TransformOperation = GenericTransformOperation<
Angle,
Number,
Length,
Integer,
LengthOrNumber,
@@ -313,8 +314,33 @@ impl Rotate {
match *operation {
GenericTransformOperation::Rotate(angle) => GenericRotate::Rotate(angle),
GenericTransformOperation::Rotate3D(rx, ry, rz, angle) =>
GenericRotate::Rotate3D(rx, ry, rz, angle),
ref x => unreachable!("Found unexpected value for rotate property: {:?}", x),
}
}
}
+
+/// A computed CSS `translate`
+pub type Translate = GenericTranslate<LengthOrPercentage, Length>;
+
+impl Translate {
+ /// Convert TransformOperation to Translate.
+ pub fn to_transform_operation(&self) -> Option<TransformOperation> {
+ match *self {
+ GenericTranslate::None => None,
+ GenericTranslate::TranslateX(tx) => Some(GenericTransformOperation::TranslateX(tx)),
+ GenericTranslate::Translate(tx, ty) => Some(GenericTransformOperation::Translate(tx, Some(ty))),
+ GenericTranslate::Translate3D(tx, ty, tz) => Some(GenericTransformOperation::Translate3D(tx, ty, tz)),
+ }
+ }
+
+ /// Convert Translate to TransformOperation.
+ pub fn from_transform_operation(operation: &TransformOperation) -> Translate {
+ match *operation {
+ GenericTransformOperation::TranslateX(tx) => GenericTranslate::TranslateX(tx),
+ GenericTransformOperation::Translate(tx, Some(ty)) => GenericTranslate::Translate(tx, ty),
+ GenericTransformOperation::Translate3D(tx, ty, tz) => GenericTranslate::Translate3D(tx, ty, tz),
+ ref x => unreachable!("Found unexpected value for translate: {:?}", x),
+ }
+ }
+}
\ No newline at end of file
--- a/servo/components/style/values/generics/transform.rs
+++ b/servo/components/style/values/generics/transform.rs
@@ -764,8 +764,24 @@ pub fn get_normalized_vector_and_angle<T
pub enum Rotate<Number, Angle> {
/// 'none'
None,
/// '<angle>'
Rotate(Angle),
/// '<number>{3} <angle>'
Rotate3D(Number, Number, Number, Angle),
}
+
+#[derive(ToComputedValue, Animate, ComputeSquaredDistance, ToAnimatedZero)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
+/// A value of the `Translate` property
+///
+/// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
+pub enum Translate<LengthOrPercentage, Length> {
+ /// 'none'
+ None,
+ /// '<length-percentage>'
+ TranslateX(LengthOrPercentage),
+ /// '<length-percentage> <length-percentage>'
+ Translate(LengthOrPercentage, LengthOrPercentage),
+ /// '<length-percentage> <length-percentage> <length>'
+ Translate3D(LengthOrPercentage, LengthOrPercentage, Length),
+}
\ No newline at end of file
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -57,17 +57,17 @@ pub use self::rect::LengthOrNumberRect;
pub use self::percentage::Percentage;
pub use self::position::{Position, PositionComponent, GridAutoFlow, GridTemplateAreas};
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind};
pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth};
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};
+pub use self::transform::{TimingFunction, Transform, TransformOrigin, Rotate, Translate};
pub use self::ui::MozForceBrokenImageIcon;
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
#[cfg(feature = "gecko")]
pub mod align;
pub mod angle;
pub mod background;
pub mod basic_shape;
--- a/servo/components/style/values/specified/transform.rs
+++ b/servo/components/style/values/specified/transform.rs
@@ -8,16 +8,17 @@ use cssparser::Parser;
use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind;
use style_traits::{ParseError, StyleParseErrorKind};
use values::computed::{Context, LengthOrPercentage as ComputedLengthOrPercentage};
use values::computed::{Percentage as ComputedPercentage, ToComputedValue};
use values::computed::transform::TimingFunction as ComputedTimingFunction;
use values::generics::transform::{Matrix3D, Transform as GenericTransform};
use values::generics::transform::Rotate as GenericRotate;
+use values::generics::transform::Translate as GenericTranslate;
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction, Matrix};
use values::generics::transform::{TimingKeyword, TransformOrigin as GenericTransformOrigin};
use values::generics::transform::TransformOperation as GenericTransformOperation;
use values::specified::{self, Angle, Number, Length, Integer};
use values::specified::{LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrNumber};
use values::specified::position::{Side, X, Y};
/// A single operation in a specified CSS `transform`
@@ -531,8 +532,35 @@ impl Parse for Rotate {
}
// 'rotate: <angle>'
let angle = specified::Angle::parse(context, input)?;
Ok(GenericRotate::Rotate(angle))
}
}
+/// A specified CSS `translate`
+pub type Translate = GenericTranslate<LengthOrPercentage, Length>;
+
+impl Parse for Translate {
+ 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(GenericTranslate::None);
+ }
+
+ let tx = specified::LengthOrPercentage::parse(context, input)?;
+ if let Ok(ty) = input.try(|i| specified::LengthOrPercentage::parse(context, i)) {
+ if let Ok(tz) = input.try(|i| specified::Length::parse(context, i)) {
+ // 'translate: <length-percentage> <length-percentage> <length>'
+ return Ok(GenericTranslate::Translate3D(tx, ty, tz));
+ }
+
+ // translate: <length-percentage> <length-percentage>'
+ return Ok(GenericTranslate::Translate(tx, ty));
+ }
+
+ // 'translate: <length-percentage> '
+ Ok(GenericTranslate::TranslateX(tx))
+ }
+}