--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -594,17 +594,17 @@ protected:
void SetParsingCompoundProperty(bool aBool) {
mParsingCompoundProperty = aBool;
}
bool IsParsingCompoundProperty(void) const {
return mParsingCompoundProperty;
}
/* Functions for transform Parsing */
- bool ParseSingleTransform(nsCSSValue& aValue, bool& aIs3D);
+ bool ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue, bool& aIs3D);
bool ParseFunction(const nsString &aFunction, const int32_t aAllowedTypes[],
uint16_t aMinElems, uint16_t aMaxElems,
nsCSSValue &aValue);
bool ParseFunctionInternals(const int32_t aVariantMask[],
uint16_t aMinElems,
uint16_t aMaxElems,
InfallibleTArray<nsCSSValue>& aOutput);
@@ -8338,20 +8338,21 @@ CSSParserImpl::ParseFunction(const nsStr
*
* @param aToken The token identifying the function.
* @param aMinElems [out] The minimum number of elements to read.
* @param aMaxElems [out] The maximum number of elements to read
* @param aVariantMask [out] The variant mask to use during parsing
* @return Whether the information was loaded successfully.
*/
static bool GetFunctionParseInformation(nsCSSKeyword aToken,
- uint16_t &aMinElems,
- uint16_t &aMaxElems,
- const int32_t *& aVariantMask,
- bool &aIs3D)
+ bool aIsPrefixed,
+ uint16_t &aMinElems,
+ uint16_t &aMaxElems,
+ const int32_t *& aVariantMask,
+ bool &aIs3D)
{
/* These types represent the common variant masks that will be used to
* parse out the individual functions. The order in the enumeration
* must match the order in which the masks are declared.
*/
enum { eLengthPercentCalc,
eLengthCalc,
eTwoLengthPercentCalcs,
@@ -8359,17 +8360,19 @@ static bool GetFunctionParseInformation(
eAngle,
eTwoAngles,
eNumber,
ePositiveLength,
eTwoNumbers,
eThreeNumbers,
eThreeNumbersOneAngle,
eMatrix,
+ eMatrixPrefixed,
eMatrix3d,
+ eMatrix3dPrefixed,
eNumVariantMasks };
static const int32_t kMaxElemsPerFunction = 16;
static const int32_t kVariantMasks[eNumVariantMasks][kMaxElemsPerFunction] = {
{VARIANT_LPCALC},
{VARIANT_LENGTH|VARIANT_CALC},
{VARIANT_LPCALC, VARIANT_LPCALC},
{VARIANT_LPCALC, VARIANT_LPCALC, VARIANT_LENGTH|VARIANT_CALC},
{VARIANT_ANGLE_OR_ZERO},
@@ -8377,23 +8380,29 @@ static bool GetFunctionParseInformation(
{VARIANT_NUMBER},
{VARIANT_LENGTH|VARIANT_POSITIVE_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_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}};
+ 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,
+ VARIANT_LPNCALC, VARIANT_LPNCALC, VARIANT_LNCALC, VARIANT_NUMBER}};
#ifdef DEBUG
static const uint8_t kVariantMaskLengths[eNumVariantMasks] =
- {1, 1, 2, 3, 1, 2, 1, 1, 2, 3, 4, 6, 16};
+ {1, 1, 2, 3, 1, 2, 1, 1, 2, 3, 4, 6, 6, 16, 16};
#endif
int32_t variantIndex = eNumVariantMasks;
aIs3D = false;
switch (aToken) {
case eCSSKeyword_translatex:
@@ -8476,23 +8485,23 @@ static bool GetFunctionParseInformation(
case eCSSKeyword_skewy:
/* Exactly one angle. */
variantIndex = eAngle;
aMinElems = 1U;
aMaxElems = 1U;
break;
case eCSSKeyword_matrix:
/* Six values, all numbers. */
- variantIndex = eMatrix;
+ variantIndex = aIsPrefixed ? eMatrixPrefixed : eMatrix;
aMinElems = 6U;
aMaxElems = 6U;
break;
case eCSSKeyword_matrix3d:
/* 16 matrix values, all numbers */
- variantIndex = eMatrix3d;
+ variantIndex = aIsPrefixed ? eMatrix3dPrefixed : eMatrix3d;
aMinElems = 16U;
aMaxElems = 16U;
aIs3D = true;
break;
case eCSSKeyword_perspective:
/* Exactly one scale number. */
variantIndex = ePositiveLength;
aMinElems = 1U;
@@ -8519,31 +8528,32 @@ static bool GetFunctionParseInformation(
return true;
}
/* Reads a single transform function from the tokenizer stream, reporting an
* error if something goes wrong.
*/
bool
-CSSParserImpl::ParseSingleTransform(nsCSSValue& aValue, bool& aIs3D)
+CSSParserImpl::ParseSingleTransform(bool aIsPrefixed,
+ nsCSSValue& aValue, bool& aIs3D)
{
if (!GetToken(true))
return false;
if (mToken.mType != eCSSToken_Function) {
UngetToken();
return false;
}
const int32_t* variantMask;
uint16_t minElems, maxElems;
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
- if (!GetFunctionParseInformation(keyword,
+ if (!GetFunctionParseInformation(keyword, aIsPrefixed,
minElems, maxElems, variantMask, aIs3D))
return false;
// Bug 721136: Normalize the identifier to lowercase, except that things
// like scaleX should have the last character capitalized. This matches
// what other browsers do.
nsContentUtils::ASCIIToLower(mToken.mIdent);
switch (keyword) {
@@ -8584,17 +8594,17 @@ bool CSSParserImpl::ParseTransform(bool
// 'inherit', 'initial', and 'none' must be alone
if (!ExpectEndProperty()) {
return false;
}
} else {
nsCSSValueList* cur = value.SetListValue();
for (;;) {
bool is3D;
- if (!ParseSingleTransform(cur->mValue, is3D)) {
+ if (!ParseSingleTransform(aIsPrefixed, cur->mValue, is3D)) {
return false;
}
if (is3D && !nsLayoutUtils::Are3DTransformsEnabled()) {
return false;
}
if (CheckEndProperty()) {
break;
}
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -3882,53 +3882,58 @@ var gCSSProperties = {
"translate(3%, 5px)", "translate(5px, 3%)",
"matrix(1, 2, 3, 4, 5, 6)",
/* valid calc() values */
"translatex(calc(5px + 10%))",
"translatey(calc(0.25 * 5px + 10% / 3))",
"translate(calc(5px - 10% * 3))",
"translate(calc(5px - 3 * 10%), 50px)",
"translate(-50px, calc(5px - 10% * 3))",
+ /* valid only when prefixed */
+ "matrix(1, 2, 3, 4, 5px, 6%)",
+ "matrix(1, 2, 3, 4, 5%, 6px)",
+ "matrix(1, 2, 3, 4, 5%, 6%)",
+ "matrix(1, 2, 3, 4, 5px, 6em)",
+ "matrix(1, 0, 0, 1, calc(5px * 3), calc(10% - 3px))",
].concat(SpecialPowers.getBoolPref("layout.3d-transforms.enabled") ? [
"translatez(1px)", "translatez(4em)", "translatez(-4px)",
"translatez(0px)", "translatez(2px) translatez(5px)",
"translate3d(3px, 4px, 5px)", "translate3d(2em, 3px, 1em)",
"translatex(2px) translate3d(4px, 5px, 6px) translatey(1px)",
"scale3d(4, 4, 4)", "scale3d(-2, 3, -7)", "scalez(4)",
"scalez(-6)", "rotate3d(2, 3, 4, 45deg)",
"rotate3d(-3, 7, 0, 12rad)", "rotatex(15deg)", "rotatey(-12grad)",
"rotatez(72rad)", "rotatex(0.125turn)", "perspective(1000px)",
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)",
+ /* valid only when prefixed */
+ "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13px, 14em, 15px, 16)",
+ "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20%, 10%, 15, 16)",
] : []),
invalid_values: ["1px", "#0000ff", "red", "auto",
"translatex(1)", "translatey(1)", "translate(2)",
"translate(-3, -4)",
"translatex(1px 1px)", "translatex(translatex(1px))",
"translatex(#0000ff)", "translatex(red)", "translatey()",
"matrix(1px, 2px, 3px, 4px, 5px, 6px)", "scale(150%)",
"skewx(red)", "matrix(1%, 0, 0, 0, 0px, 0px)",
"matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1, 2%, 3, 4px, 5px)",
- "matrix(0, 1, 2, 3%, 4%, 5%)", "matrix(1, 2, 3, 4, 5px, 6%)",
- "matrix(1, 2, 3, 4, 5%, 6px)", "matrix(1, 2, 3, 4, 5%, 6%)",
- "matrix(1, 2, 3, 4, 5px, 6em)",
+ "matrix(0, 1, 2, 3%, 4%, 5%)",
/* invalid calc() values */
"translatey(-moz-min(5px,10%))",
"translatex(-moz-max(5px,10%))",
"translate(10px, calc(min(5px,10%)))",
"translate(calc(max(5px,10%)), 10%)",
"matrix(1, 0, 0, 1, max(5px * 3), calc(10% - 3px))"
].concat(SpecialPowers.getBoolPref("layout.3d-transforms.enabled") ? [
"perspective(0px)", "perspective(-10px)", "matrix3d(dinosaur)",
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)",
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)",
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15%, 16)",
"matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16px)",
"rotatey(words)", "rotatex(7)", "translate3d(3px, 4px, 1px, 7px)",
- "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13px, 14em, 15px, 16)",
- "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20%, 10%, 15, 16)"
] : [])
},
"-moz-transform-origin": {
domProp: "MozTransformOrigin",
inherited: false,
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
alias_for: "transform-origin",
subproperties: [ "transform-origin" ],