diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-12-10 13:57:14 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-10 13:57:14 -0800 |
commit | 37c4051d21f5baacdf843510c8b111202ac2e876 (patch) | |
tree | c1f52fa5a3e4e8326dc912bd88803d1efa145d7d | |
parent | 872ec89a9c546eb05246b5047aabfc032d140eff (diff) | |
parent | faddb0c3bbd5300b0c0b611033283fe950d5f8d8 (diff) | |
download | servo-37c4051d21f5baacdf843510c8b111202ac2e876.tar.gz servo-37c4051d21f5baacdf843510c8b111202ac2e876.zip |
Auto merge of #14498 - dpyro:image-orientation, r=canaltinova
Added image-orientation property
<!-- Please describe your changes on the following line: -->
Implemented as per the MDN documentation—I could not find a current CSS draft. I am not sure if this is the complete correct metadata for the longhand helper:
```
<%helpers:longhand name="image-orientation”
experimental=“True”
animatable=“False”>
```
Also I am not sure how to test this and would appreciate help in creating a testing strategy.
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #13877.
<!-- Either: -->
- [X] There are tests for these changes
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- 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/14498)
<!-- Reviewable:end -->
-rw-r--r-- | components/style/properties/longhand/inherited_box.mako.rs | 133 | ||||
-rw-r--r-- | tests/unit/style/parsing/inherited_box.rs | 31 | ||||
-rw-r--r-- | tests/unit/style/parsing/mod.rs | 1 |
3 files changed, 165 insertions, 0 deletions
diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index 15b65ee418d..7eca5ab0ee5 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -50,6 +50,139 @@ ${helpers.single_keyword("image-rendering", custom_consts=image_rendering_custom_consts, animatable=False)} +// Image Orientation +// https://drafts.csswg.org/css-images/#the-image-orientation +<%helpers:longhand name="image-orientation" + products="None" + animatable="False"> + use std::fmt; + use style_traits::ToCss; + use values::specified::Angle; + + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + + use std::f32::consts::PI; + use values::CSSFloat; + const TWO_PI: CSSFloat = 2.0*PI; + + #[derive(Clone, PartialEq, Copy, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub struct SpecifiedValue { + pub angle: Option<Angle>, + pub flipped: bool + } + + impl ToCss for SpecifiedValue { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + if let Some(angle) = self.angle { + try!(angle.to_css(dest)); + if self.flipped { + dest.write_str(" flipped") + } else { + Ok(()) + } + } else { + if self.flipped { + dest.write_str("flipped") + } else { + dest.write_str("from-image") + } + } + } + } + + pub mod computed_value { + use values::specified::Angle; + + #[derive(Clone, PartialEq, Copy, Debug)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub enum T { + FromImage, + AngleWithFlipped(Angle, bool), + } + } + + const INITIAL_ANGLE: Angle = Angle(0.0); + + #[inline] + pub fn get_initial_value() -> computed_value::T { + computed_value::T::AngleWithFlipped(INITIAL_ANGLE, false) + } + + // According to CSS Content Module Level 3: + // The computed value of the property is calculated by rounding the specified angle + // to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn. + #[inline] + fn normalize_angle(angle: &Angle) -> Angle { + let radians = angle.radians(); + let rounded_quarter_turns = (4.0 * radians / TWO_PI).round(); + let normalized_quarter_turns = (rounded_quarter_turns % 4.0 + 4.0) % 4.0; + let normalized_radians = normalized_quarter_turns/4.0 * TWO_PI; + Angle::from_radians(normalized_radians) + } + + impl ToComputedValue for SpecifiedValue { + type ComputedValue = computed_value::T; + + #[inline] + fn to_computed_value(&self, _: &Context) -> computed_value::T { + if let Some(ref angle) = self.angle { + let normalized_angle = normalize_angle(angle); + computed_value::T::AngleWithFlipped(normalized_angle, self.flipped) + } else { + if self.flipped { + computed_value::T::AngleWithFlipped(INITIAL_ANGLE, true) + } else { + computed_value::T::FromImage + } + } + } + + #[inline] + fn from_computed_value(computed: &computed_value::T) -> Self { + match *computed { + computed_value::T::FromImage => SpecifiedValue { angle: None, flipped: false }, + computed_value::T::AngleWithFlipped(angle, flipped) => + SpecifiedValue { angle: Some(angle), flipped: flipped }, + } + } + } + + impl ToCss for computed_value::T { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + match *self { + computed_value::T::FromImage => dest.write_str("from-image"), + computed_value::T::AngleWithFlipped(angle, flipped) => { + try!(angle.to_css(dest)); + if flipped { + try!(dest.write_str(" flipped")); + } + Ok(()) + }, + } + } + } + + pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { + if input.try(|input| input.expect_ident_matching("from-image")).is_ok() { + // Handle from-image + Ok(SpecifiedValue { angle: None, flipped: false }) + } else { + // Handle <angle> | <angle>? flip + let angle = input.try(|input| Angle::parse(context, input)).ok(); + let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok(); + let explicit_angle = if angle.is_none() && !flipped { + Some(INITIAL_ANGLE) + } else { + angle + }; + + Ok(SpecifiedValue { angle: explicit_angle, flipped: flipped }) + } + } +</%helpers:longhand> + // Used in the bottom-up flow construction traversal to avoid constructing flows for // descendants of nodes with `display: none`. <%helpers:longhand name="-servo-under-display-none" diff --git a/tests/unit/style/parsing/inherited_box.rs b/tests/unit/style/parsing/inherited_box.rs new file mode 100644 index 00000000000..0fc78ed6131 --- /dev/null +++ b/tests/unit/style/parsing/inherited_box.rs @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use cssparser::Parser; +use media_queries::CSSErrorReporterTest; +use style::parser::ParserContext; +use style::stylesheets::Origin; + +#[test] +fn image_orientation_longhand_should_parse_properly() { + use std::f32::consts::PI; + use style::properties::longhands::image_orientation; + use style::properties::longhands::image_orientation::SpecifiedValue; + use style::values::specified::Angle; + + let from_image = parse_longhand!(image_orientation, "from-image"); + assert_eq!(from_image, SpecifiedValue { angle: None, flipped: false }); + + let flip = parse_longhand!(image_orientation, "flip"); + assert_eq!(flip, SpecifiedValue { angle: None, flipped: true }); + + let zero = parse_longhand!(image_orientation, "0deg"); + assert_eq!(zero, SpecifiedValue { angle: Some(Angle::from_radians(0.0)), flipped: false }); + + let negative_rad = parse_longhand!(image_orientation, "-1rad"); + assert_eq!(negative_rad, SpecifiedValue { angle: Some(Angle::from_radians(-1.0)), flipped: false }); + + let flip_with_180 = parse_longhand!(image_orientation, "180deg flip"); + assert_eq!(flip_with_180, SpecifiedValue { angle: Some(Angle::from_radians(PI)), flipped: true }); +} diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs index 369e0b66bf0..05bd3e8d912 100644 --- a/tests/unit/style/parsing/mod.rs +++ b/tests/unit/style/parsing/mod.rs @@ -52,6 +52,7 @@ mod basic_shape; mod border; mod font; mod image; +mod inherited_box; mod inherited_text; mod mask; mod position; |