--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -6936,18 +6936,16 @@ CSSParserImpl::ParseHue(float& aAngle)
if (mToken.mType == eCSSToken_Number) {
aAngle = mToken.mNumber;
return true;
}
UngetToken();
// <angle>
nsCSSValue angleValue;
- // The '0' value is handled by <number> parsing, so use VARIANT_ANGLE flag
- // instead of VARIANT_ANGLE_OR_ZERO.
if (ParseSingleTokenVariant(angleValue, VARIANT_ANGLE, nullptr)) {
// Convert double value of GetAngleValueInDegrees() to float.
aAngle = angleValue.GetAngleValueInDegrees();
// And then clamp it as finite values in float.
aAngle = mozilla::clamped(aAngle,
-std::numeric_limits<float>::max(),
std::numeric_limits<float>::max());
return true;
@@ -7757,28 +7755,28 @@ CSSParserImpl::ParseVariant(nsCSSValue&
if (nsCSSProps::FindKeyword(keyword, aKeywordTable, value)) {
aValue.SetIntValue(value, eCSSUnit_Enumerated);
return CSSParseResult::Ok;
}
}
}
}
// Check VARIANT_NUMBER and VARIANT_INTEGER before VARIANT_LENGTH or
- // VARIANT_ZERO_ANGLE.
+ // VARIANT_ANGLE.
if (((aVariantMask & VARIANT_NUMBER) != 0) &&
(eCSSToken_Number == tk->mType)) {
aValue.SetFloatValue(tk->mNumber, eCSSUnit_Number);
return CSSParseResult::Ok;
}
if (((aVariantMask & VARIANT_INTEGER) != 0) &&
(eCSSToken_Number == tk->mType) && tk->mIntegerValid) {
aValue.SetIntValue(tk->mInteger, eCSSUnit_Integer);
return CSSParseResult::Ok;
}
- if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE |
+ if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE_DIMENSION |
VARIANT_FREQUENCY | VARIANT_TIME)) != 0 &&
eCSSToken_Dimension == tk->mType) ||
((aVariantMask & (VARIANT_LENGTH | VARIANT_ZERO_ANGLE)) != 0 &&
eCSSToken_Number == tk->mType &&
tk->mNumber == 0.0f)) {
if ((aVariantMask & VARIANT_NONNEGATIVE_DIMENSION) != 0 &&
tk->mNumber < 0.0) {
UngetToken();
@@ -10224,22 +10222,21 @@ CSSParserImpl::ParseLinearGradient(nsCSS
// back the first token (which we may have checked for "to" above) and try to
// parse expression as <legacy-gradient-line>? <color-stop-list>
bool haveGradientLine = IsLegacyGradientLine(mToken.mType, mToken.mIdent);
UngetToken();
if (haveGradientLine) {
// Parse a <legacy-gradient-line>
cssGradient->mIsLegacySyntax = true;
- // In -webkit-linear-gradient expressions (handled below), we need to accept
- // unitless 0 for angles, to match WebKit/Blink.
- int32_t angleFlags = (aFlags & eGradient_WebkitLegacy) ?
- VARIANT_ANGLE | VARIANT_ZERO_ANGLE :
- VARIANT_ANGLE;
-
+ // NB: We can't allow unitless angles in legacy moz-prefixed gradients,
+ // because it could be ambiguous with box position values in cases like:
+ // -moz-linear-gradient(0 0, yellow, blue)
+ uint32_t angleFlags = (aFlags & eGradient_MozLegacy)
+ ? VARIANT_ANGLE_DIMENSION : VARIANT_ANGLE;
bool haveAngle =
ParseSingleTokenVariant(cssGradient->mAngle, angleFlags, nullptr);
// If we got an angle, we might now have a comma, ending the gradient-line.
bool haveAngleComma = haveAngle && ExpectSymbol(',', true);
// If we're webkit-prefixed & didn't get an angle,
// OR if we're moz-prefixed & didn't get an angle+comma,
@@ -10383,20 +10380,25 @@ CSSParserImpl::ParseRadialGradient(nsCSS
// <legacy-gradient-line>
bool haveGradientLine = false;
// if we already encountered a shape or size,
// we can not have a gradient-line in legacy syntax
if (!haveShape && !haveSize) {
haveGradientLine = IsLegacyGradientLine(ty, id);
}
if (haveGradientLine) {
+ // NB: We can't allow unitless angles in legacy moz-prefixed gradients,
+ // because it could be ambiguous with box position values.
+ uint32_t angleFlags = (aFlags & eGradient_MozLegacy)
+ ? VARIANT_ANGLE_DIMENSION : VARIANT_ANGLE;
+
// Note: -webkit-radial-gradient() doesn't accept angles.
bool haveAngle = (aFlags & eGradient_WebkitLegacy)
? false
- : ParseSingleTokenVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr);
+ : ParseSingleTokenVariant(cssGradient->mAngle, angleFlags, nullptr);
// If we got an angle, we might now have a comma, ending the gradient-line
if (!haveAngle || !ExpectSymbol(',', true)) {
if (!ParseBoxPositionValues(cssGradient->mBgPos, false)) {
SkipUntil(')');
return false;
}
@@ -15891,24 +15893,24 @@ static bool GetFunctionParseInformation(
static const uint32_t kVariantMasks[eNumVariantMasks][kMaxElemsPerFunction] = {
{VARIANT_LPCALC},
{VARIANT_LCALC},
{VARIANT_LB},
{VARIANT_LPCALC, VARIANT_LPCALC},
{VARIANT_LBCALC, VARIANT_LBCALC},
{VARIANT_LPCALC, VARIANT_LPCALC, VARIANT_LCALC},
{VARIANT_LBCALC, VARIANT_LBCALC, VARIANT_LBCALC},
- {VARIANT_ANGLE_OR_ZERO},
- {VARIANT_ANGLE_OR_ZERO, VARIANT_ANGLE_OR_ZERO},
+ {VARIANT_ANGLE},
+ {VARIANT_ANGLE, VARIANT_ANGLE},
{VARIANT_NUMBER},
{VARIANT_LENGTH|VARIANT_NONNEGATIVE_DIMENSION},
{VARIANT_LB|VARIANT_NONNEGATIVE_DIMENSION},
{VARIANT_NUMBER, VARIANT_NUMBER},
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER},
- {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_ANGLE_OR_ZERO},
+ {VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_ANGLE},
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
VARIANT_NUMBER, VARIANT_NUMBER},
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
VARIANT_LPNCALC, VARIANT_LPNCALC},
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER},
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -180,16 +180,20 @@ var validGradientAndElementValues = [
"-moz-linear-gradient(blue calc(0px) ,green calc(25%) ,red calc(40px) ,blue calc(60px) , yellow calc(100px))",
"-moz-linear-gradient(-33deg, blue calc(-25%) ,red 40px)",
"-moz-linear-gradient(10deg, blue calc(100px + -25%),red calc(40px))",
"-moz-linear-gradient(10deg, blue calc(-25px),red calc(100%))",
"-moz-linear-gradient(.414rad, blue calc(100px + -25px) ,green calc(100px + -25px) ,red calc(100px + -25%) ,blue calc(-25px) , yellow calc(-25px))",
"-moz-linear-gradient(1turn, blue calc(-25%) ,green calc(25px) ,red calc(25%),blue calc(0px),white 50px, yellow calc(-25px))",
+ "-moz-linear-gradient(top left 0, red, blue)",
+ "-moz-linear-gradient(5px 5px 0, red, blue)",
+ "linear-gradient(0, red, blue)",
+
"radial-gradient(red, blue)",
"radial-gradient(red, yellow, blue)",
"radial-gradient(red 1px, yellow 20%, blue 24em, green)",
"radial-gradient(red, yellow, green, blue 50%)",
"radial-gradient(red -50%, yellow -25%, green, blue)",
"radial-gradient(red -99px, yellow, green, blue 120%)",
"radial-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
@@ -383,20 +387,16 @@ var invalidGradientAndElementValues = [
/* no quirks mode colors */
"linear-gradient(red, ff00ff)",
/* no quirks mode colors */
"-moz-radial-gradient(10% bottom, ffffff, black) scroll no-repeat",
/* no quirks mode lengths */
"-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
"-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
"linear-gradient(red -99, yellow, green, blue 120%)",
- /* Unitless 0 is invalid as an <angle> */
- "-moz-linear-gradient(top left 0, red, blue)",
- "-moz-linear-gradient(5px 5px 0, red, blue)",
- "linear-gradient(0, red, blue)",
/* Invalid color, calc() or -moz-image-rect() function */
"linear-gradient(red, rgb(0, rubbish, 0) 50%, red)",
"linear-gradient(red, red calc(50% + rubbish), red)",
"linear-gradient(to top calc(50% + rubbish), red, blue)",
/* Old syntax */
"-moz-linear-gradient(10px 10px, 20px, 30px 30px, 40px, from(blue), to(red))",
"-moz-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
"-moz-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
@@ -5946,16 +5946,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
"grayscale(0)",
"grayscale(50%)",
"grayscale(1)",
"grayscale(1.0)",
"grayscale(2)",
"grayscale(350%)",
"grayscale(4.567)",
+ "hue-rotate(0)",
"hue-rotate(0deg)",
"hue-rotate(90deg)",
"hue-rotate(540deg)",
"hue-rotate(-90deg)",
"hue-rotate(10grad)",
"hue-rotate(1.6rad)",
"hue-rotate(-1.6rad)",
"hue-rotate(0.5turn)",
@@ -6061,17 +6062,16 @@ if (IsCSSPropertyPrefEnabled("layout.css
"grayscale(0.5 0.5)",
"grayscale(0.5,)",
"grayscale(0.5, 0.5)",
"grayscale(#my-filter)",
"grayscale(10px)",
"grayscale(-1)",
"hue-rotate()",
- "hue-rotate(0)",
"hue-rotate(0.5 0.5)",
"hue-rotate(0.5,)",
"hue-rotate(0.5, 0.5)",
"hue-rotate(#my-filter)",
"hue-rotate(10px)",
"hue-rotate(-1)",
"hue-rotate(45deg,)",
@@ -6754,24 +6754,26 @@ if (IsCSSPropertyPrefEnabled("layout.css
"0.5turn flip",
"0.75turn",
"0.75turn flip",
// Rounded values.
"-45deg flip",
"65deg flip",
"400deg flip",
+
+ // Unitless angles.
+ "0",
+ "0 flip",
],
invalid_values: [
"none",
"0deg none",
"flip 0deg",
"flip 0deg",
- "0",
- "0 flip",
"flip 0",
"0deg from-image",
"from-image 0deg",
"flip from-image",
"from-image flip",
]
};
}