Bug 774169, patch 4: Revert bug 719054 for prefixed -moz-transform but leave it for unprefixed transform. r=bzbarsky
authorL. David Baron <dbaron@dbaron.org>
Tue, 18 Sep 2012 11:37:14 -0700
changeset 107510 125d2728927e5731e7418b6d7a953b42243c70d9
parent 107509 110a5d25c8f2a24b5004afc17f5f51b5a7699916
child 107511 8f5d6fe4410e862d0b10af81b9deb60b6f9d92f0
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersbzbarsky
bugs774169, 719054
milestone18.0a1
Bug 774169, patch 4: Revert bug 719054 for prefixed -moz-transform but leave it for unprefixed transform. r=bzbarsky
layout/style/nsCSSParser.cpp
layout/style/test/property_database.js
layout/style/test/test_value_storage.html
--- 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" ],
--- a/layout/style/test/test_value_storage.html
+++ b/layout/style/test/test_value_storage.html
@@ -151,17 +151,19 @@ function test_property(property)
       serialize_func(gComputedStyle.getPropertyValue(property), step1comp,
          "serialize+parse should be identity transform for '" +
          property + ": " + value + "'");
     }
 
     if ("subproperties" in info &&
         // Using setProperty over subproperties is not sufficient for
         // system fonts, since the shorthand does more than its parts.
-        (property != "font" || !(value in gSystemFont))) {
+        (property != "font" || !(value in gSystemFont)) &&
+        // Likewise for special compatibility values of transform
+        (property != "-moz-transform" || !value.match(/^matrix.*(px|em|%)/))) {
       gDeclaration.removeProperty(property);
       for (idx in info.subproperties) {
         var subprop = info.subproperties[idx];
         gDeclaration.setProperty(subprop, step1vals[idx], "");
       }
 
       // Now that all the subprops are set, check their values.  Note that we
       // need this in a separate loop, in case parts of the shorthand affect