commit b15cf7f3d9980c5bc3a99ed8441b7e505c0de6bd
parent ba0e228d4f7b04b68d872b2465eb3fc0488ffa02
Author: sickl8 <sickl8@protonmail.com>
Date: Fri, 28 Nov 2025 10:55:44 +0000
Bug 1362499 - Add compat support for unitless perspective for webkit transform and perspective properties. r=emilio,firefox-style-system-reviewers
Added tests for invalid `transform` and `perspective` properties, and unitless valid tests for their `-webkit-` counterparts
Bug 1362499 - Added tests for invalid tests for transform and perspective, and valid ones for their webkit counterparts. r?emilio
- Added invalid unitless `calc()` test for `-webkit-perspective`
- Updated `property_database.js` to pass mochi tests
Differential Revision: https://phabricator.services.mozilla.com/D274128
Diffstat:
9 files changed, 179 insertions(+), 7 deletions(-)
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
@@ -11566,9 +11566,12 @@ var gCSSProperties = {
"-webkit-transform": {
domProp: "webkitTransform",
inherited: false,
- type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+ type: CSS_TYPE_LEGACY_SHORTHAND,
alias_for: "transform",
subproperties: ["transform"],
+ initial_values: ["none"],
+ other_values: ["perspective(1000)", "perspective(25)"],
+ invalid_values: [],
},
"-webkit-transform-origin": {
domProp: "webkitTransformOrigin",
@@ -11594,9 +11597,12 @@ var gCSSProperties = {
"-webkit-perspective": {
domProp: "webkitPerspective",
inherited: false,
- type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
+ type: CSS_TYPE_LEGACY_SHORTHAND,
alias_for: "perspective",
subproperties: ["perspective"],
+ initial_values: ["none"],
+ other_values: ["1000", "25"],
+ invalid_values: ["calc(1000)", "calc(25)"],
},
"-webkit-perspective-origin": {
domProp: "webkitPerspectiveOrigin",
diff --git a/servo/components/style/properties/longhands/box.mako.rs b/servo/components/style/properties/longhands/box.mako.rs
@@ -170,7 +170,7 @@ ${helpers.predefined_type(
"Transform",
"generics::transform::Transform::none()",
engines="gecko servo",
- extra_prefixes=transform_extra_prefixes,
+ extra_prefixes="moz:layout.css.prefixes.transforms",
flags="CAN_ANIMATE_ON_COMPOSITOR",
spec="https://drafts.csswg.org/css-transforms/#propdef-transform",
servo_restyle_damage="recalculate_overflow",
@@ -395,7 +395,7 @@ ${helpers.predefined_type(
engines="gecko servo",
gecko_ffi_name="mChildPerspective",
spec="https://drafts.csswg.org/css-transforms/#perspective",
- extra_prefixes=transform_extra_prefixes,
+ extra_prefixes="moz:layout.css.prefixes.transforms",
servo_restyle_damage = "recalculate_overflow",
affects="overflow",
)}
diff --git a/servo/components/style/properties/shorthands/box.mako.rs b/servo/components/style/properties/shorthands/box.mako.rs
@@ -225,3 +225,48 @@ ${helpers.two_properties_shorthand(
}
}
</%helpers:shorthand>
+
+<%helpers:shorthand name="-webkit-perspective"
+ engines="gecko servo"
+ sub_properties="perspective"
+ derive_serialize="True"
+ flags="IS_LEGACY_SHORTHAND"
+ spec="https://github.com/whatwg/compat/issues/100">
+ pub fn parse_value<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Longhands, ParseError<'i>> {
+ use crate::values::specified::Length;
+ use crate::values::generics::NonNegative;
+ use crate::values::specified::AllowQuirks;
+ use crate::values::specified::Perspective;
+ use crate::properties::longhands::perspective;
+
+ if let Ok(l) = input.try_parse(|input| Length::parse_non_negative_quirky(context, input, AllowQuirks::Always)) {
+ Ok(expanded! {
+ perspective: Perspective::Length(NonNegative(l)),
+ })
+ } else {
+ Ok(expanded! {
+ perspective: perspective::parse(context, input)?
+ })
+ }
+ }
+</%helpers:shorthand>
+
+<%helpers:shorthand name="-webkit-transform"
+ engines="gecko servo"
+ sub_properties="transform"
+ derive_serialize="True"
+ flags="IS_LEGACY_SHORTHAND"
+ spec="https://github.com/whatwg/compat/issues/100">
+ pub fn parse_value<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Longhands, ParseError<'i>> {
+ use crate::values::specified::Transform;
+ Ok(expanded! {
+ transform: Transform::parse_legacy(context, input)?,
+ })
+ }
+</%helpers:shorthand>
diff --git a/servo/components/style/values/specified/transform.rs b/servo/components/style/values/specified/transform.rs
@@ -13,7 +13,7 @@ use crate::values::specified::position::{
HorizontalPositionKeyword, Side, VerticalPositionKeyword,
};
use crate::values::specified::{
- self, Angle, Integer, Length, LengthPercentage, Number, NumberOrPercentage,
+ self, AllowQuirks, Angle, Integer, Length, LengthPercentage, Number, NumberOrPercentage,
};
use crate::Zero;
use cssparser::Parser;
@@ -100,7 +100,26 @@ impl TransformOrigin {
}
}
+/// Whether to allow unitless values for perspective in prefixed transform properties.
+///
+/// See: https://github.com/whatwg/compat/issues/100
+#[allow(missing_docs)]
+pub enum AllowUnitlessPerspective {
+ No,
+ Yes,
+}
+
impl Transform {
+ /// Parse the transform property value, allowing unitless perspective values.
+ ///
+ /// This is used for `-webkit-transform` which allows unitless values for perspective.
+ #[inline]
+ pub(crate) fn parse_legacy<'i, 't>(
+ context: &ParserContext,
+ input: &mut Parser<'i, 't>,
+ ) -> Result<Self, ParseError<'i>> {
+ Self::parse_internal(context, input, AllowUnitlessPerspective::Yes)
+ }
/// Internal parse function for deciding if we wish to accept prefixed values or not
///
/// `transform` allows unitless zero angles as an exception, see:
@@ -108,6 +127,7 @@ impl Transform {
fn parse_internal<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
+ allow_unitless_perspective: AllowUnitlessPerspective,
) -> Result<Self, ParseError<'i>> {
use style_traits::{Separator, Space};
@@ -282,7 +302,13 @@ impl Transform {
Ok(generic::TransformOperation::SkewY(theta))
},
"perspective" => {
- let p = match input.try_parse(|input| specified::Length::parse_non_negative(context, input)) {
+ let p = match input.try_parse(|input| {
+ if matches!(allow_unitless_perspective, AllowUnitlessPerspective::Yes) {
+ specified::Length::parse_non_negative_quirky(context, input, AllowQuirks::Always)
+ } else {
+ specified::Length::parse_non_negative(context, input)
+ }
+ }) {
Ok(p) => generic::PerspectiveFunction::Length(p),
Err(..) => {
input.expect_ident_matching("none")?;
@@ -310,7 +336,7 @@ impl Parse for Transform {
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
- Transform::parse_internal(context, input)
+ Transform::parse_internal(context, input, AllowUnitlessPerspective::No)
}
}
diff --git a/testing/web-platform/tests/css/css-transforms/parsing/perspective-invalid.html b/testing/web-platform/tests/css/css-transforms/parsing/perspective-invalid.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Transform Module Level 2: parsing perspective with invalid values</title>
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#perspective-property">
+<meta name="assert" content="perspective supports only the grammar 'none | <length [0,∞]>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("perspective", "1000");
+test_invalid_value("perspective", "-1px");
+test_invalid_value("perspective", "80%");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-transforms/parsing/transform-invalid.html b/testing/web-platform/tests/css/css-transforms/parsing/transform-invalid.html
@@ -42,6 +42,8 @@ test_invalid_value("transform", "skewX(0, 0)");
test_invalid_value("transform", "skewY(0, 0)");
test_invalid_value("transform", "scaleX(2), scaleY(3)");
+
+test_invalid_value("transform", "perspective(1000)");
</script>
</body>
</html>
diff --git a/testing/web-platform/tests/css/css-transforms/parsing/webkit-perspective-invalid.tentative.html b/testing/web-platform/tests/css/css-transforms/parsing/webkit-perspective-invalid.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Compatibility: parsing -webkit-perspective with invalid values</title>
+<link rel="help" href="https://compat.spec.whatwg.org/#propdef--webkit-perspective">
+<link rel="help" href="https://github.com/whatwg/compat/issues/100">
+<meta name="assert" content="-webkit-perspective also supports '<number [0,∞]>' in addition to 'none | <length [0,∞]>', but not 'calc([ <number [0,∞]> ])'">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("-webkit-perspective", "calc(1000)");
+test_invalid_value("-webkit-perspective", "calc(25)");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-transforms/parsing/webkit-perspective-valid.tentative.html b/testing/web-platform/tests/css/css-transforms/parsing/webkit-perspective-valid.tentative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Compatibility: parsing -webkit-perspective with valid values</title>
+<link rel="help" href="https://compat.spec.whatwg.org/#propdef--webkit-perspective">
+<link rel="help" href="https://github.com/whatwg/compat/issues/100">
+<meta name="assert" content="-webkit-perspective also supports '<number [0,∞]>' in addition to 'none | <length [0,∞]>'">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("-webkit-perspective", "initial");
+test_valid_value("-webkit-perspective", "inherit");
+test_valid_value("-webkit-perspective", "unset");
+test_valid_value("-webkit-perspective", "revert");
+test_valid_value("-webkit-perspective", "revert-layer");
+
+test_valid_value("-webkit-perspective", "none");
+test_valid_value("-webkit-perspective", "1000", "1000px");
+test_valid_value("-webkit-perspective", "25", "25px");
+test_valid_value("-webkit-perspective", "12px", "12px");
+test_valid_value("-webkit-perspective", "3.5em", "3.5em");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/css/css-transforms/parsing/webkit-transform-valid.tentative.html b/testing/web-platform/tests/css/css-transforms/parsing/webkit-transform-valid.tentative.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Compatibility: parsing -webkit-transform with valid values</title>
+<link rel="help" href="https://compat.spec.whatwg.org/#propdef--webkit-transform">
+<link rel="help" href="https://github.com/whatwg/compat/issues/100">
+<meta name="assert" content="-webkit-transform additionally supports the function call 'perspective([ <number [0,∞]> ])' in '<transform-list>'">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("-webkit-transform", "initial");
+test_valid_value("-webkit-transform", "inherit");
+test_valid_value("-webkit-transform", "unset");
+test_valid_value("-webkit-transform", "revert");
+test_valid_value("-webkit-transform", "revert-layer");
+
+test_valid_value("-webkit-transform", "perspective(1000)", "perspective(1000px)");
+test_valid_value("-webkit-transform", "perspective(25)", "perspective(25px)");
+test_valid_value("-webkit-transform", "perspective(12px)");
+test_valid_value("-webkit-transform", "perspective(3.5em)");
+</script>
+</body>
+</html>