diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index ff3529bb53b..63f4a5abbfa 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -2776,6 +2776,34 @@ fn static_assert() { } +<%self:impl_trait style_struct_name="InheritedBox" + skip_longhands="image-orientation"> + // FIXME: Gecko uses a tricky way to store computed value of image-orientation + // within an u8. We could inline following glue codes by implementing all + // those tricky parts for Servo as well. But, it's not done yet just for + // convenience. + pub fn set_image_orientation(&mut self, v: longhands::image_orientation::computed_value::T) { + use properties::longhands::image_orientation::computed_value::T; + match v { + T::FromImage => { + unsafe { + bindings::Gecko_SetImageOrientationAsFromImage(&mut self.gecko); + } + }, + T::AngleWithFlipped(ref angle, flipped) => { + unsafe { + bindings::Gecko_SetImageOrientation(&mut self.gecko, angle.radians() as f64, flipped); + } + } + } + } + + pub fn copy_image_orientation_from(&mut self, other: &Self) { + unsafe { + bindings::Gecko_CopyImageOrientationFrom(&mut self.gecko, &other.gecko); + } + } + <%self:impl_trait style_struct_name="InheritedTable" skip_longhands="border-spacing"> @@ -2789,7 +2817,6 @@ fn static_assert() { self.gecko.mBorderSpacingCol = other.gecko.mBorderSpacingCol; self.gecko.mBorderSpacingRow = other.gecko.mBorderSpacingRow; } - diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index a4d78e7f3fc..ffa8c5ebddf 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -1332,6 +1332,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", computed_value::T(None) } + // Allow unitless zero angle for rotate() and skew() to align with gecko pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("none")).is_ok() { return Ok(SpecifiedValue(Vec::new())) @@ -1469,28 +1470,28 @@ ${helpers.predefined_type("scroll-snap-coordinate", }, "rotate" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(context,input)); + let theta = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::Rotate(theta)); Ok(()) })) }, "rotatex" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(context,input)); + let theta = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::RotateX(theta)); Ok(()) })) }, "rotatey" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(context,input)); + let theta = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::RotateY(theta)); Ok(()) })) }, "rotatez" => { try!(input.parse_nested_block(|input| { - let theta = try!(specified::Angle::parse(context,input)); + let theta = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::RotateZ(theta)); Ok(()) })) @@ -1503,7 +1504,7 @@ ${helpers.predefined_type("scroll-snap-coordinate", try!(input.expect_comma()); let az = try!(specified::parse_number(input)); try!(input.expect_comma()); - let theta = try!(specified::Angle::parse(context,input)); + let theta = try!(specified::Angle::parse_with_unitless(context,input)); // TODO(gw): Check the axis can be normalized!! result.push(SpecifiedOperation::Rotate3D(ax, ay, az, theta)); Ok(()) @@ -1511,9 +1512,9 @@ ${helpers.predefined_type("scroll-snap-coordinate", }, "skew" => { try!(input.parse_nested_block(|input| { - let theta_x = try!(specified::Angle::parse(context, input)); + let theta_x = try!(specified::Angle::parse_with_unitless(context, input)); if input.try(|input| input.expect_comma()).is_ok() { - let theta_y = try!(specified::Angle::parse(context, input)); + let theta_y = try!(specified::Angle::parse_with_unitless(context, input)); result.push(SpecifiedOperation::Skew(theta_x, Some(theta_y))); } else { result.push(SpecifiedOperation::Skew(theta_x, None)); @@ -1523,14 +1524,14 @@ ${helpers.predefined_type("scroll-snap-coordinate", }, "skewx" => { try!(input.parse_nested_block(|input| { - let theta_x = try!(specified::Angle::parse(context,input)); + let theta_x = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::SkewX(theta_x)); Ok(()) })) }, "skewy" => { try!(input.parse_nested_block(|input| { - let theta_y = try!(specified::Angle::parse(context,input)); + let theta_y = try!(specified::Angle::parse_with_unitless(context,input)); result.push(SpecifiedOperation::SkewY(theta_y)); Ok(()) })) diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index d57e5d42039..f0d316172e1 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -83,7 +83,7 @@ ${helpers.single_keyword("image-rendering", // Image Orientation <%helpers:longhand name="image-orientation" - products="None" + products="gecko" animation_type="none" spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \ /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation"> @@ -199,21 +199,23 @@ ${helpers.single_keyword("image-rendering", } } + // from-image | | [? flip] pub fn parse(context: &ParserContext, input: &mut Parser) -> Result { if input.try(|input| input.expect_ident_matching("from-image")).is_ok() { // Handle from-image Ok(SpecifiedValue { angle: None, flipped: false }) + } else if input.try(|input| input.expect_ident_matching("flip")).is_ok() { + // Handle flip + Ok(SpecifiedValue { angle: Some(Angle::zero()), flipped: true }) } else { - // Handle | ? flip + // Handle | 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(Angle::zero()) - } else { - angle - }; + if angle.is_none() { + return Err(()); + } - Ok(SpecifiedValue { angle: explicit_angle, flipped: flipped }) + let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok(); + Ok(SpecifiedValue { angle: angle, flipped: flipped }) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index f5ba7b7fb1d..89fe279c480 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -430,7 +430,6 @@ impl Parse for Angle { fn parse(_context: &ParserContext, input: &mut Parser) -> Result { match try!(input.next()) { Token::Dimension(ref value, ref unit) => Angle::parse_dimension(value.value, unit), - Token::Number(ref value) if value.value == 0. => Ok(Angle::zero()), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { input.parse_nested_block(CalcLengthOrPercentage::parse_angle) }, @@ -451,6 +450,22 @@ impl Angle { }; Ok(angle) } + /// Parse an angle, including unitless 0 degree. + /// Note that numbers without any AngleUnit, including unitless 0 + /// angle, should be invalid. However, some properties still accept + /// unitless 0 angle and stores it as '0deg'. We can remove this and + /// get back to the unified version Angle::parse once + /// https://github.com/w3c/csswg-drafts/issues/1162 is resolved. + pub fn parse_with_unitless(_context: &ParserContext, input: &mut Parser) -> Result { + match try!(input.next()) { + Token::Dimension(ref value, ref unit) => Angle::parse_dimension(value.value, unit), + Token::Number(ref value) if value.value == 0. => Ok(Angle::zero()), + Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { + input.parse_nested_block(CalcLengthOrPercentage::parse_angle) + }, + _ => Err(()) + } + } } #[allow(missing_docs)] diff --git a/tests/unit/style/parsing/inherited_box.rs b/tests/unit/style/parsing/inherited_box.rs index dbe364b7adf..749641c79cf 100644 --- a/tests/unit/style/parsing/inherited_box.rs +++ b/tests/unit/style/parsing/inherited_box.rs @@ -17,7 +17,7 @@ fn image_orientation_longhand_should_parse_properly() { assert_eq!(from_image, SpecifiedValue { angle: None, flipped: false }); let flip = parse_longhand!(image_orientation, "flip"); - assert_eq!(flip, SpecifiedValue { angle: None, flipped: true }); + assert_eq!(flip, SpecifiedValue { angle: Some(Angle::from_degrees(0.0)), flipped: true }); let zero = parse_longhand!(image_orientation, "0deg"); assert_eq!(zero, SpecifiedValue { angle: Some(Angle::from_degrees(0.0)), flipped: false });