Bug 1597642 - Have scale function and scale property accept percentage value. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D55012

--HG--
extra : moz-landing-system : lando
This commit is contained in:
enordin 2019-11-29 04:40:03 +00:00
Родитель 28517b934c
Коммит d69bff9bdb
9 изменённых файлов: 104 добавлений и 21 удалений

Просмотреть файл

@ -6,6 +6,7 @@
background: green; background: green;
width: 100px; width: 100px;
height: 100px; height: 100px;
-moz-transform: scale(0.5, 0.75);
} }
</style> </style>
</head> </head>

Просмотреть файл

@ -1,13 +1,13 @@
<html> <html>
<head> <head>
<!-- Percent values are not allowed for scale, so this shouldn't do anything --> <!-- Percent values should function the same as their equivalent numeric values: e.g. (50% == 0.5) -->
<style> <style>
body { margin: 0px; } body { margin: 0px; }
div { div {
background: green; background: green;
width: 100px; width: 100px;
height: 100px; height: 100px;
-moz-transform: scale(50%, 50%); -moz-transform: scale(50%, 75%);
} }
</style> </style>
</head> </head>

Просмотреть файл

@ -3626,9 +3626,23 @@ var gCSSProperties = {
"rotate(0.25turn)", "rotate(0.25turn)",
"rotate(0)", "rotate(0)",
"scalex(10)", "scalex(10)",
"scalex(10%)",
"scalex(-10)",
"scalex(-10%)",
"scaley(10)", "scaley(10)",
"scaley(10%)",
"scaley(-10)",
"scaley(-10%)",
"scale(10)", "scale(10)",
"scale(10%)",
"scale(10, 20)", "scale(10, 20)",
"scale(10%, 20%)",
"scale(-10)",
"scale(-10%)",
"scale(-10, 20)",
"scale(10%, -20%)",
"scale(10, 20%)",
"scale(-10, 20%)",
"skewx(30deg)", "skewx(30deg)",
"skewx(0)", "skewx(0)",
"skewy(0)", "skewy(0)",
@ -3663,9 +3677,13 @@ var gCSSProperties = {
"translate3d(2em, 3px, 1em)", "translate3d(2em, 3px, 1em)",
"translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)", "translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)",
"scale3d(4, 4, 4)", "scale3d(4, 4, 4)",
"scale3d(4%, 4%, 4%)",
"scale3d(-2, 3, -7)", "scale3d(-2, 3, -7)",
"scale3d(-2%, 3%, -7%)",
"scalez(4)", "scalez(4)",
"scalez(4%)",
"scalez(-6)", "scalez(-6)",
"scalez(-6%)",
"rotate3d(2, 3, 4, 45deg)", "rotate3d(2, 3, 4, 45deg)",
"rotate3d(-3, 7, 0, 12rad)", "rotate3d(-3, 7, 0, 12rad)",
"rotatex(15deg)", "rotatex(15deg)",
@ -3692,7 +3710,6 @@ var gCSSProperties = {
"translatex(red)", "translatex(red)",
"translatey()", "translatey()",
"matrix(1px, 2px, 3px, 4px, 5px, 6px)", "matrix(1px, 2px, 3px, 4px, 5px, 6px)",
"scale(150%)",
"skewx(red)", "skewx(red)",
"matrix(1%, 0, 0, 0, 0px, 0px)", "matrix(1%, 0, 0, 0, 0px, 0px)",
"matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1%, 2, 3, 4px,5px)",
@ -11484,15 +11501,25 @@ if (IsCSSPropertyPrefEnabled("layout.css.individual-transform.enabled")) {
initial_values: ["none"], initial_values: ["none"],
other_values: [ other_values: [
"10", "10",
"10%",
"10 20", "10 20",
"10% 20%",
"10 20 30", "10 20 30",
"10% 20% 30%",
"10 20% 30",
"-10",
"-10%",
"-10 20",
"-10% 20%",
"-10 20 -30",
"-10% 20% -30%",
"-10 20% -30",
"0 2.0", "0 2.0",
/* valid calc() values */ /* valid calc() values */
"calc(1 + 2)", "calc(1 + 2)",
"calc(10) calc(20) 30", "calc(10) calc(20) 30",
], ],
invalid_values: [ invalid_values: [
"150%",
"10px", "10px",
"10deg", "10deg",
"10, 20, 30", "10, 20, 30",
@ -12566,9 +12593,23 @@ if (false) {
"rotate(0.25turn)", "rotate(0.25turn)",
"rotate(0)", "rotate(0)",
"scalex(10)", "scalex(10)",
"scalex(10%)",
"scalex(-10)",
"scalex(-10%)",
"scaley(10)", "scaley(10)",
"scaley(10%)",
"scaley(-10)",
"scaley(-10%)",
"scale(10)", "scale(10)",
"scale(10%)",
"scale(10, 20)", "scale(10, 20)",
"scale(10%, 20%)",
"scale(-10)",
"scale(-10%)",
"scale(-10, 20)",
"scale(10%, -20%)",
"scale(10, 20%)",
"scale(-10, 20%)",
"skewx(30deg)", "skewx(30deg)",
"skewx(0)", "skewx(0)",
"skewy(0)", "skewy(0)",
@ -12603,9 +12644,13 @@ if (false) {
"translate3d(2em, 3px, 1em)", "translate3d(2em, 3px, 1em)",
"translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)", "translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)",
"scale3d(4, 4, 4)", "scale3d(4, 4, 4)",
"scale3d(4%, 4%, 4%)",
"scale3d(-2, 3, -7)", "scale3d(-2, 3, -7)",
"scale3d(-2%, 3%, -7%)",
"scalez(4)", "scalez(4)",
"scalez(4%)",
"scalez(-6)", "scalez(-6)",
"scalez(-6%)",
"rotate3d(2, 3, 4, 45deg)", "rotate3d(2, 3, 4, 45deg)",
"rotate3d(-3, 7, 0, 12rad)", "rotate3d(-3, 7, 0, 12rad)",
"rotatex(15deg)", "rotatex(15deg)",
@ -12631,7 +12676,6 @@ if (false) {
"translatex(red)", "translatex(red)",
"translatey()", "translatey()",
"matrix(1px, 2px, 3px, 4px, 5px, 6px)", "matrix(1px, 2px, 3px, 4px, 5px, 6px)",
"scale(150%)",
"skewx(red)", "skewx(red)",
"matrix(1%, 0, 0, 0, 0px, 0px)", "matrix(1%, 0, 0, 0, 0px, 0px)",
"matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1%, 2, 3, 4px,5px)",

Просмотреть файл

@ -12,7 +12,7 @@ use crate::values::generics::transform::{Matrix, Matrix3D};
use crate::values::specified::position::{ use crate::values::specified::position::{
HorizontalPositionKeyword, Side, VerticalPositionKeyword, HorizontalPositionKeyword, Side, VerticalPositionKeyword,
}; };
use crate::values::specified::{self, Angle, Integer, Length, LengthPercentage, Number}; use crate::values::specified::{self, Angle, Integer, Length, LengthPercentage, Number, NumberOrPercentage};
use crate::Zero; use crate::Zero;
use cssparser::Parser; use cssparser::Parser;
use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::{ParseError, StyleParseErrorKind};
@ -163,32 +163,32 @@ impl Transform {
Ok(generic::TransformOperation::Translate3D(tx, ty, tz)) Ok(generic::TransformOperation::Translate3D(tx, ty, tz))
}, },
"scale" => { "scale" => {
let sx = Number::parse(context, input)?; let sx = NumberOrPercentage::parse(context, input)?.to_number();
if input.try(|input| input.expect_comma()).is_ok() { if input.try(|input| input.expect_comma()).is_ok() {
let sy = Number::parse(context, input)?; let sy = NumberOrPercentage::parse(context, input)?.to_number();
Ok(generic::TransformOperation::Scale(sx, sy)) Ok(generic::TransformOperation::Scale(sx, sy))
} else { } else {
Ok(generic::TransformOperation::Scale(sx, sx)) Ok(generic::TransformOperation::Scale(sx, sx))
} }
}, },
"scalex" => { "scalex" => {
let sx = Number::parse(context, input)?; let sx = NumberOrPercentage::parse(context, input)?.to_number();
Ok(generic::TransformOperation::ScaleX(sx)) Ok(generic::TransformOperation::ScaleX(sx))
}, },
"scaley" => { "scaley" => {
let sy = Number::parse(context, input)?; let sy = NumberOrPercentage::parse(context, input)?.to_number();
Ok(generic::TransformOperation::ScaleY(sy)) Ok(generic::TransformOperation::ScaleY(sy))
}, },
"scalez" => { "scalez" => {
let sz = Number::parse(context, input)?; let sz = NumberOrPercentage::parse(context, input)?.to_number();
Ok(generic::TransformOperation::ScaleZ(sz)) Ok(generic::TransformOperation::ScaleZ(sz))
}, },
"scale3d" => { "scale3d" => {
let sx = Number::parse(context, input)?; let sx = NumberOrPercentage::parse(context, input)?.to_number();
input.expect_comma()?; input.expect_comma()?;
let sy = Number::parse(context, input)?; let sy = NumberOrPercentage::parse(context, input)?.to_number();
input.expect_comma()?; input.expect_comma()?;
let sz = Number::parse(context, input)?; let sz = NumberOrPercentage::parse(context, input)?.to_number();
Ok(generic::TransformOperation::Scale3D(sx, sy, sz)) Ok(generic::TransformOperation::Scale3D(sx, sy, sz))
}, },
"rotate" => { "rotate" => {
@ -445,6 +445,9 @@ impl Parse for Translate {
pub type Scale = generic::Scale<Number>; pub type Scale = generic::Scale<Number>;
impl Parse for Scale { impl Parse for Scale {
/// Scale accepts <number> | <percentage>, so we parse it as NumberOrPercentage,
/// and then convert into an Number if it's a Percentage.
/// https://github.com/w3c/csswg-drafts/pull/4396
fn parse<'i, 't>( fn parse<'i, 't>(
context: &ParserContext, context: &ParserContext,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
@ -453,11 +456,12 @@ impl Parse for Scale {
return Ok(generic::Scale::None); return Ok(generic::Scale::None);
} }
let sx = Number::parse(context, input)?; let sx = NumberOrPercentage::parse(context, input)?.to_number();
if let Ok(sy) = input.try(|i| Number::parse(context, i)) { if let Ok(sy) = input.try(|i| NumberOrPercentage::parse(context, i)) {
if let Ok(sz) = input.try(|i| Number::parse(context, i)) { let sy = sy.to_number();
if let Ok(sz) = input.try(|i| NumberOrPercentage::parse(context, i)) {
// 'scale: <number> <number> <number>' // 'scale: <number> <number> <number>'
return Ok(generic::Scale::Scale(sx, sy, sz)); return Ok(generic::Scale::Scale(sx, sy, sz.to_number()));
} }
// 'scale: <number> <number>' // 'scale: <number> <number>'

Просмотреть файл

@ -14,14 +14,28 @@
test_valid_value("scale", "none"); test_valid_value("scale", "none");
test_valid_value("scale", "1"); test_valid_value("scale", "1");
test_valid_value("scale", "1%", "0.01");
test_valid_value("scale", "100"); test_valid_value("scale", "100");
test_valid_value("scale", "100%", "1");
test_valid_value("scale", "100 100", "100"); test_valid_value("scale", "100 100", "100");
test_valid_value("scale", "100% 100%", "1");
test_valid_value("scale", "100 100 1", "100"); test_valid_value("scale", "100 100 1", "100");
test_valid_value("scale", "100% 100% 1", "1");
test_valid_value("scale", "-100");
test_valid_value("scale", "-100%", "-1");
test_valid_value("scale", "-100 -100", "-100");
test_valid_value("scale", "-100% -100%", "-1");
test_valid_value("scale", "-100 -100 1", "-100");
test_valid_value("scale", "-100% -100% 1", "-1");
test_valid_value("scale", "100 200"); test_valid_value("scale", "100 200");
test_valid_value("scale", "100% 200%", "1 2");
test_valid_value("scale", "100 200 1", "100 200"); test_valid_value("scale", "100 200 1", "100 200");
test_valid_value("scale", "100% 200% 1", "1 2");
test_valid_value("scale", "100 200 300"); test_valid_value("scale", "100 200 300");
</script> </script>
</body> </body>
</html> </html>

Просмотреть файл

@ -23,10 +23,13 @@ test_invalid_value("transform", "translateX(-4px, 5px)");
test_invalid_value("transform", "translateY(4%, 5%)"); test_invalid_value("transform", "translateY(4%, 5%)");
test_invalid_value("transform", "scale(6, 7, 8)"); test_invalid_value("transform", "scale(6, 7, 8)");
test_invalid_value("transform", "scale(6%, 7%, 8%)");
test_invalid_value("transform", "scaleX(1, 2)"); test_invalid_value("transform", "scaleX(1, 2)");
test_invalid_value("transform", "scaleX(1%, 2%)");
test_invalid_value("transform", "scaleY(3, 4)"); test_invalid_value("transform", "scaleY(3, 4)");
test_invalid_value("transform", "scaleY(3%, 4%)");
test_invalid_value("transform", "rotate(0, 0)"); test_invalid_value("transform", "rotate(0, 0)");
test_invalid_value("transform", "rotate(0, 0, 0)"); test_invalid_value("transform", "rotate(0, 0, 0)");

Просмотреть файл

@ -26,11 +26,27 @@ test_valid_value("transform", "translateY(5%)");
test_valid_value("transform", "scale(2)"); test_valid_value("transform", "scale(2)");
test_valid_value("transform", "scale(3, 4)"); test_valid_value("transform", "scale(3, 4)");
test_valid_value("transform", "scale(-2)");
test_valid_value("transform", "scale(-5, -6)"); test_valid_value("transform", "scale(-5, -6)");
test_valid_value("transform", "scale(250%)", "scale(2.5)");
test_valid_value("transform", "scale(325%, 475%)", "scale(3.25, 4.75)");
test_valid_value("transform", "scale(-250%)", "scale(-2.5)");
test_valid_value("transform", "scale(-500%, -620%)", "scale(-5, -6.2)");
test_valid_value("transform", "scaleX(7)"); test_valid_value("transform", "scaleX(7)");
test_valid_value("transform", "scaleX(720%)", "scaleX(7.2)");
test_valid_value("transform", "scaleY(-8)"); test_valid_value("transform", "scaleY(-8)");
test_valid_value("transform", "scaleY(-85%)", "scaleY(-0.85)");
test_valid_value("transform", "scale3d(0.5, 2.5, 3)");
test_valid_value("transform", "scale3d(50%, 250%, 300%)", "scale3d(0.5, 2.5, 3)");
test_valid_value("transform", "scale3d(-0.5, 2.5, -3)");
test_valid_value("transform", "scale3d(-50%, 250%, -300%)", "scale3d(-0.5, 2.5, -3)");
test_valid_value("transform", "rotate(0)", "rotate(0deg)"); test_valid_value("transform", "rotate(0)", "rotate(0deg)");
test_valid_value("transform", "rotate(90deg)"); test_valid_value("transform", "rotate(90deg)");

Просмотреть файл

@ -6,15 +6,15 @@
<link rel="author" title="Aryeh Gregor" href="mailto:ayg@aryeh.name"> <link rel="author" title="Aryeh Gregor" href="mailto:ayg@aryeh.name">
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#two-d-transform-functions"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#two-d-transform-functions">
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#funcdef-scale"> <link rel="help" href="http://www.w3.org/TR/css-transforms-1/#funcdef-scale">
<meta name="assert" content='This tests that scale(50%, 50%) does nothing, <meta name="assert" content='This tests that scale(50%, 75%) is equivalent to scale(0.5, 0.75),
because scale() is defined to take numbers and not percentages.'> because scale() is defined to accept both numbers and percentages.'>
<link rel="match" href="transform-scale-percent-ref.html"> <link rel="match" href="transform-scale-percent-ref.html">
<style> <style>
div { div {
background: green; background: green;
width: 100px; width: 100px;
height: 100px; height: 100px;
transform: scale(50%, 50%); transform: scale(50%, 75%);
} }
</style> </style>
</head> </head>

Просмотреть файл

@ -9,6 +9,7 @@
background: green; background: green;
width: 100px; width: 100px;
height: 100px; height: 100px;
transform: scale(0.5, 0.75)
} }
</style> </style>
</head> </head>