Bug 567283 patch 4 - Support #rgba and #rrggbbaa colors in CSS. r?xidorn draft
authorL. David Baron <dbaron@dbaron.org>
Sun, 08 May 2016 09:56:15 -0700
changeset 364686 05852c6d4acfc77fb92a5988b0b46cd5bb8b7cb2
parent 364685 3b741d5b02444ae0aed17f97f450d121d67c7420
child 520363 1ee7feca00dc4db750863991be406b60a615370e
push id17539
push userdbaron@mozilla.com
push dateSun, 08 May 2016 16:56:29 +0000
reviewersxidorn
bugs567283
milestone49.0a1
Bug 567283 patch 4 - Support #rgba and #rrggbbaa colors in CSS. r?xidorn This adds support for #rgba and #rrggbbaa colors to CSS. This feature is specified in https://drafts.csswg.org/css-color-4/#hex-notation . This adds new types to nsCSSValue so that we can serialize the syntax that was specified, as we do for other distinctions in how colors are specified. It does not change the behavior of the hashless color quirk, which continues to support only 3 and 6 digit colors as specified in https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk (step 4). This changes property_database.js to remove various uses of 4 and 8 digit colors as invalid values. It then adds them in slightly fewer places as valid values, but more thoroughly testing both initial and non-initial values on 'color'. It marks two canvas tests explicitly testing this feature as no longer known to fail by removing their .ini files. Finally, it adjusts the web platform test testing the hashless color quirk to no longer treat 4 and 8 digit colors as invalid values. Removing the relevant test items seems like the right thing since they're in a section where 3 and 6 digit colors were skipped but other lengths were tested. Modifying this imported test is OK since: <jgraham> dbaron: Commit the change you want to m-c, it is (semi-)automatically upstreamed every so often (typically about once a week) MozReview-Commit-ID: IFq4HxaRkil
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/test/property_database.js
testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html.ini
testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html.ini
testing/web-platform/tests/quirks-mode/hashless-hex-color.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -6607,23 +6607,34 @@ CSSParserImpl::ParseColor(nsCSSValue& aV
   }
 
   nsCSSToken* tk = &mToken;
   nscolor rgba;
   switch (tk->mType) {
     case eCSSToken_ID:
     case eCSSToken_Hash:
       // #xxyyzz
-      // FIXME
-      if (NS_HexToRGBA(tk->mIdent, nsHexColorType::NoAlpha, &rgba)) {
-        MOZ_ASSERT(tk->mIdent.Length() == 3 || tk->mIdent.Length() == 6,
-                   "unexpected hex color length");
-        nsCSSUnit unit = tk->mIdent.Length() == 3 ?
-                           eCSSUnit_ShortHexColor :
-                           eCSSUnit_HexColor;
+      if (NS_HexToRGBA(tk->mIdent, nsHexColorType::AllowAlpha, &rgba)) {
+        nsCSSUnit unit;
+        switch (tk->mIdent.Length()) {
+          case 3:
+            unit = eCSSUnit_ShortHexColor;
+            break;
+          case 4:
+            unit = eCSSUnit_ShortHexColorAlpha;
+            break;
+          case 6:
+            unit = eCSSUnit_HexColor;
+            break;
+          default:
+            MOZ_FALLTHROUGH_ASSERT("unexpected hex color length");
+          case 8:
+            unit = eCSSUnit_HexColorAlpha;
+            break;
+        }
         aValue.SetIntegerColorValue(rgba, unit);
         return CSSParseResult::Ok;
       }
       break;
 
     case eCSSToken_Ident:
       if (NS_ColorNameToRGB(tk->mIdent, &rgba)) {
         aValue.SetStringValue(tk->mIdent, eCSSUnit_Ident);
@@ -6762,17 +6773,17 @@ CSSParserImpl::ParseColor(nsCSSValue& aV
           str.Append(tk->mIdent);
         }
         break;
       default:
         // There is a whole bunch of cases that are
         // not handled by this switch.  Ignore them.
         break;
     }
-    // FIXME
+    // The hashless color quirk does not support 4 & 8 digit colors with alpha.
     if (NS_HexToRGBA(str, nsHexColorType::NoAlpha, &rgba)) {
       aValue.SetIntegerColorValue(rgba, eCSSUnit_HexColor);
       return CSSParseResult::Ok;
     }
   }
 
   // It's not a color
   REPORT_UNEXPECTED_TOKEN(PEColorNotColor);
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -1442,28 +1442,36 @@ nsCSSValue::AppendToString(nsCSSProperty
         aResult.Append(comma);
         aResult.AppendInt(NS_GET_B(color), 10);
         if (showAlpha) {
           aResult.Append(comma);
           aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
         }
         aResult.Append(char16_t(')'));
       }
-    } else if (eCSSUnit_HexColor == unit) {
+    } else if (eCSSUnit_HexColor == unit ||
+               eCSSUnit_HexColorAlpha == unit) {
       nscolor color = GetColorValue();
       aResult.Append('#');
       aResult.AppendPrintf("%02x", NS_GET_R(color));
       aResult.AppendPrintf("%02x", NS_GET_G(color));
       aResult.AppendPrintf("%02x", NS_GET_B(color));
-    } else if (eCSSUnit_ShortHexColor == unit) {
+      if (eCSSUnit_HexColorAlpha == unit) {
+        aResult.AppendPrintf("%02x", NS_GET_A(color));
+      }
+    } else if (eCSSUnit_ShortHexColor == unit ||
+               eCSSUnit_ShortHexColorAlpha == unit) {
       nscolor color = GetColorValue();
       aResult.Append('#');
       aResult.AppendInt(NS_GET_R(color) / 0x11, 16);
       aResult.AppendInt(NS_GET_G(color) / 0x11, 16);
       aResult.AppendInt(NS_GET_B(color) / 0x11, 16);
+      if (eCSSUnit_ShortHexColorAlpha == unit) {
+        aResult.AppendInt(NS_GET_A(color) / 0x11, 16);
+      }
     } else {
       MOZ_ASSERT(IsFloatColorUnit());
       mValue.mFloatColor->AppendToString(unit, aResult);
     }
   }
   else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
     aResult.AppendLiteral("url(");
     nsStyleUtil::AppendEscapedCSSString(
@@ -1749,16 +1757,18 @@ nsCSSValue::AppendToString(nsCSSProperty
     case eCSSUnit_Calc_Divided: break;
     case eCSSUnit_Integer:      break;
     case eCSSUnit_Enumerated:   break;
     case eCSSUnit_EnumColor:             break;
     case eCSSUnit_RGBColor:              break;
     case eCSSUnit_RGBAColor:             break;
     case eCSSUnit_HexColor:              break;
     case eCSSUnit_ShortHexColor:         break;
+    case eCSSUnit_HexColorAlpha:         break;
+    case eCSSUnit_ShortHexColorAlpha:    break;
     case eCSSUnit_PercentageRGBColor:    break;
     case eCSSUnit_PercentageRGBAColor:   break;
     case eCSSUnit_HSLColor:              break;
     case eCSSUnit_HSLAColor:             break;
     case eCSSUnit_Percent:      aResult.Append(char16_t('%'));    break;
     case eCSSUnit_Number:       break;
     case eCSSUnit_Gradient:     break;
     case eCSSUnit_TokenStream:  break;
@@ -1927,16 +1937,18 @@ nsCSSValue::SizeOfExcludingThis(mozilla:
     case eCSSUnit_EnumColor:
       break;
 
     // Integer Color: nothing extra to measure.
     case eCSSUnit_RGBColor:
     case eCSSUnit_RGBAColor:
     case eCSSUnit_HexColor:
     case eCSSUnit_ShortHexColor:
+    case eCSSUnit_HexColorAlpha:
+    case eCSSUnit_ShortHexColorAlpha:
       break;
 
     // Float Color
     case eCSSUnit_PercentageRGBColor:
     case eCSSUnit_PercentageRGBAColor:
     case eCSSUnit_HSLColor:
     case eCSSUnit_HSLAColor:
       n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -327,23 +327,25 @@ enum nsCSSUnit {
   eCSSUnit_Integer      = 70,     // (int) simple value
   eCSSUnit_Enumerated   = 71,     // (int) value has enumerated meaning
 
   eCSSUnit_EnumColor           = 80,   // (int) enumerated color (kColorKTable)
   eCSSUnit_RGBColor            = 81,   // (nscolor) an opaque RGBA value specified as rgb()
   eCSSUnit_RGBAColor           = 82,   // (nscolor) an RGBA value specified as rgba()
   eCSSUnit_HexColor            = 83,   // (nscolor) an opaque RGBA value specified as #rrggbb
   eCSSUnit_ShortHexColor       = 84,   // (nscolor) an opaque RGBA value specified as #rgb
-  eCSSUnit_PercentageRGBColor  = 85,   // (nsCSSValueFloatColor*)
-  eCSSUnit_PercentageRGBAColor = 86,   // (nsCSSValueFloatColor*)
-  eCSSUnit_HSLColor            = 87,   // (nsCSSValueFloatColor*)
-  eCSSUnit_HSLAColor           = 88,   // (nsCSSValueFloatColor*)
+  eCSSUnit_HexColorAlpha       = 85,   // (nscolor) an opaque RGBA value specified as #rrggbbaa
+  eCSSUnit_ShortHexColorAlpha  = 86,   // (nscolor) an opaque RGBA value specified as #rgba
+  eCSSUnit_PercentageRGBColor  = 87,   // (nsCSSValueFloatColor*)
+  eCSSUnit_PercentageRGBAColor = 88,   // (nsCSSValueFloatColor*)
+  eCSSUnit_HSLColor            = 89,   // (nsCSSValueFloatColor*)
+  eCSSUnit_HSLAColor           = 90,   // (nsCSSValueFloatColor*)
 
-  eCSSUnit_Percent      = 90,     // (float) 1.0 == 100%) value is percentage of something
-  eCSSUnit_Number       = 91,     // (float) value is numeric (usually multiplier, different behavior that percent)
+  eCSSUnit_Percent      = 100,     // (float) 1.0 == 100%) value is percentage of something
+  eCSSUnit_Number       = 101,     // (float) value is numeric (usually multiplier, different behavior than percent)
 
   // Physical length units
   eCSSUnit_PhysicalMillimeter = 200,   // (float) 1/25.4 inch
 
   // Length units - relative
   // Viewport relative measure
   eCSSUnit_ViewportWidth  = 700,    // (float) 1% of the width of the initial containing block
   eCSSUnit_ViewportHeight = 701,    // (float) 1% of the height of the initial containing block
@@ -490,32 +492,34 @@ public:
 
   // Checks for the nsCSSValue being of a particular type of color unit:
   //
   //   - IsIntegerColorUnit returns true for:
   //       eCSSUnit_RGBColor             -- rgb(int,int,int)
   //       eCSSUnit_RGBAColor            -- rgba(int,int,int,float)
   //       eCSSUnit_HexColor             -- #rrggbb
   //       eCSSUnit_ShortHexColor        -- #rgb
+  //       eCSSUnit_HexColorAlpha        -- #rrggbbaa
+  //       eCSSUnit_ShortHexColorAlpha   -- #rgba
   //
-  //   - IsFLoatColorUnit returns true for:
+  //   - IsFloatColorUnit returns true for:
   //       eCSSUnit_PercentageRGBColor   -- rgb(%,%,%)
   //       eCSSUnit_PercentageRGBAColor  -- rgba(%,%,%,float)
   //       eCSSUnit_HSLColor             -- hsl(float,%,%)
   //       eCSSUnit_HSLAColor            -- hsla(float,%,%,float)
   //
   //   - IsNumericColorUnit returns true for any of the above units.
   //
   // Note that color keywords and system colors are represented by
   // eCSSUnit_EnumColor and eCSSUnit_Ident.
   bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); }
   bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); }
   bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); }
   static bool IsIntegerColorUnit(nsCSSUnit aUnit)
-  { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColor; }
+  { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColorAlpha; }
   static bool IsFloatColorUnit(nsCSSUnit aUnit)
   { return eCSSUnit_PercentageRGBColor <= aUnit &&
            aUnit <= eCSSUnit_HSLAColor; }
   static bool IsNumericColorUnit(nsCSSUnit aUnit)
   { return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit); }
 
   int32_t GetIntValue() const
   {
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1011,17 +1011,17 @@ var gCSSProperties = {
   "border-inline-end-color": {
     domProp: "borderInlineEndColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     logical: true,
     get_computed: logical_box_prop_get_computed,
     initial_values: [ "currentColor" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000" ]
   },
   "border-inline-end-style": {
     domProp: "borderInlineEndStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     logical: true,
     get_computed: logical_box_prop_get_computed,
     /* XXX hidden is sometimes the same as initial */
@@ -1259,17 +1259,17 @@ var gCSSProperties = {
   "border-inline-start-color": {
     domProp: "borderInlineStartColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     logical: true,
     get_computed: logical_box_prop_get_computed,
     initial_values: [ "currentColor" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000" ]
   },
   "border-inline-start-style": {
     domProp: "borderInlineStartStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     logical: true,
     get_computed: logical_box_prop_get_computed,
     /* XXX hidden is sometimes the same as initial */
@@ -2256,17 +2256,17 @@ var gCSSProperties = {
     invalid_values: [ "margin-box", "border-box border-box" ]
   },
   "background-color": {
     domProp: "backgroundColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "transparent", "rgba(255, 127, 15, 0)", "hsla(240, 97%, 50%, 0.0)", "rgba(0, 0, 0, 0)", "rgba(255,255,255,-3.7)" ],
     other_values: [ "green", "rgb(255, 0, 128)", "#fc2", "#96ed2a", "black", "rgba(255,255,0,3)", "hsl(240, 50%, 50%)", "rgb(50%, 50%, 50%)", "-moz-default-background-color" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "rgb(100, 100.0, 100)" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "rgb(100, 100.0, 100)" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "background-image": {
     domProp: "backgroundImage",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "none" ],
     other_values: [
@@ -2451,17 +2451,17 @@ var gCSSProperties = {
   },
   "border-bottom-color": {
     domProp: "borderBottomColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-bottom-style": {
     domProp: "borderBottomStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
@@ -2497,17 +2497,17 @@ var gCSSProperties = {
   },
   "border-color": {
     domProp: "borderColor",
     inherited: false,
     type: CSS_TYPE_TRUE_SHORTHAND,
     subproperties: [ "border-top-color", "border-right-color", "border-bottom-color", "border-left-color" ],
     initial_values: [ "currentColor", "currentColor currentColor", "currentColor currentColor currentColor", "currentColor currentColor currentcolor CURRENTcolor" ],
     other_values: [ "green", "currentColor green", "currentColor currentColor green", "currentColor currentColor currentColor green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "red rgb(nonsense)", "red 1px" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "red rgb(nonsense)", "red 1px" ],
     unbalanced_values: [ "red rgb(" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-left": {
     domProp: "borderLeft",
     inherited: false,
     type: CSS_TYPE_TRUE_SHORTHAND,
     subproperties: [ "border-left-color", "border-left-style", "border-left-width" ],
@@ -2517,17 +2517,17 @@ var gCSSProperties = {
   },
   "border-left-color": {
     domProp: "borderLeftColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-left-style": {
     domProp: "borderLeftStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
@@ -2564,17 +2564,17 @@ var gCSSProperties = {
   },
   "border-right-color": {
     domProp: "borderRightColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-right-style": {
     domProp: "borderRightStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
@@ -2634,17 +2634,17 @@ var gCSSProperties = {
   },
   "border-top-color": {
     domProp: "borderTopColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000" ],
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a" },
   },
   "border-top-style": {
     domProp: "borderTopStyle",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     /* XXX hidden is sometimes the same as initial */
     initial_values: [ "none" ],
@@ -2748,19 +2748,19 @@ var gCSSProperties = {
     invalid_values: [ "rect(auto, 3em, 2%, 5px)" ],
     quirks_values: { "rect(1, 2, 3, 4)": "rect(1px, 2px, 3px, 4px)" },
   },
   "color": {
     domProp: "color",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     /* XXX should test currentColor, but may or may not be initial */
-    initial_values: [ "black", "#000", "-moz-default-color" ],
-    other_values: [ "green", "#f3c", "#fed292", "rgba(45,300,12,2)", "transparent", "-moz-nativehyperlinktext", "rgba(255,128,0,0.5)" ],
-    invalid_values: [ "#f", "#ff", "#ffff", "#fffff", "#fffffff", "#ffffffff", "#fffffffff" ],
+    initial_values: [ "black", "#000", "#000f", "#000000ff", "rgb(0, 0, 0)", "rgba(0, 0, 0, 1.0)", "-moz-default-color" ],
+    other_values: [ "green", "#f3c", "#fed292", "rgba(45,300,12,2)", "transparent", "-moz-nativehyperlinktext", "rgba(255,128,0,0.5)", "#e0fc", "#10fcee72" ],
+    invalid_values: [ "#f", "#ff", "#fffff", "#fffffff", "#fffffffff" ],
     quirks_values: { "000000": "#000000", "96ed2a": "#96ed2a", "fff": "#ffffff", "ffffff": "#ffffff", },
   },
   "content": {
     domProp: "content",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     /* XXX needs to be on pseudo-elements */
     initial_values: [ "normal", "none" ],
@@ -3434,17 +3434,17 @@ var gCSSProperties = {
   },
   "outline-color": {
     domProp: "outlineColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ], // XXX should be invert
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000", "cc00ff" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000", "cc00ff" ]
   },
   "outline-offset": {
     domProp: "outlineOffset",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "0", "0px", "-0", "calc(0px)", "calc(3em + 2px - 2px - 3em)", "calc(-0em)" ],
     other_values: [ "-3px", "1em", "calc(3em)", "calc(7pt + 3 * 2em)", "calc(-3px)" ],
     invalid_values: [ "5%" ]
@@ -3702,17 +3702,17 @@ var gCSSProperties = {
   },
   "text-decoration-color": {
     domProp: "textDecorationColor",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "-moz-use-text-color" ],
     other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000", "ff00ff" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000", "ff00ff" ]
   },
   "text-decoration-line": {
     domProp: "textDecorationLine",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "none" ],
     other_values: [ "underline", "overline", "line-through", "blink", "blink line-through underline", "underline overline line-through blink", "-moz-anchor-decoration", "blink -moz-anchor-decoration" ],
     invalid_values: [ "none none", "underline none", "none underline", "line-through blink line-through", "underline overline line-through blink none", "underline overline line-throuh blink blink" ]
@@ -5017,17 +5017,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
     "border-block-end-color": {
       domProp: "borderBlockEndColor",
       inherited: false,
       type: CSS_TYPE_LONGHAND,
       logical: true,
       get_computed: logical_box_prop_get_computed,
       initial_values: [ "currentColor" ],
       other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-      invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
+      invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000" ]
     },
     "border-block-end-style": {
       domProp: "borderBlockEndStyle",
       inherited: false,
       type: CSS_TYPE_LONGHAND,
       logical: true,
       get_computed: logical_box_prop_get_computed,
       /* XXX hidden is sometimes the same as initial */
@@ -5067,17 +5067,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
     "border-block-start-color": {
       domProp: "borderBlockStartColor",
       inherited: false,
       type: CSS_TYPE_LONGHAND,
       logical: true,
       get_computed: logical_box_prop_get_computed,
       initial_values: [ "currentColor" ],
       other_values: [ "green", "rgba(255,128,0,0.5)", "transparent" ],
-      invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000" ]
+      invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000" ]
     },
     "border-block-start-style": {
       domProp: "borderBlockStartStyle",
       inherited: false,
       type: CSS_TYPE_LONGHAND,
       logical: true,
       get_computed: logical_box_prop_get_computed,
       /* XXX hidden is sometimes the same as initial */
@@ -7139,17 +7139,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
   };
   gCSSProperties["-webkit-text-fill-color"] = {
     domProp: "webkitTextFillColor",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "black", "#000", "#000000", "rgb(0,0,0)" ],
     other_values: [ "red", "rgba(255,255,255,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
   };
   gCSSProperties["-webkit-text-stroke"] = {
     domProp: "webkitTextStroke",
     inherited: true,
     type: CSS_TYPE_TRUE_SHORTHAND,
     prerequisites: { "color": "black" },
     subproperties: [ "-webkit-text-stroke-width", "-webkit-text-stroke-color" ],
     initial_values: [ "0 currentColor", "currentColor 0px", "0", "currentColor", "0px black" ],
@@ -7158,17 +7158,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
   };
   gCSSProperties["-webkit-text-stroke-color"] = {
     domProp: "webkitTextStrokeColor",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "black", "#000", "#000000", "rgb(0,0,0)" ],
     other_values: [ "red", "rgba(255,255,255,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
   };
   gCSSProperties["-webkit-text-stroke-width"] = {
     domProp: "webkitTextStrokeWidth",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "0", "0px", "0em", "0ex", "calc(0pt)", "calc(4px - 8px)" ],
     other_values: [ "thin", "medium", "thick", "17px", "0.2em", "calc(3*25px + 5em)", "calc(5px - 1px)" ],
     invalid_values: [ "5%", "1px calc(nonsense)", "1px red", "-0.1px", "-3px", "30%" ]
@@ -7519,17 +7519,17 @@ if (IsCSSPropertyPrefEnabled("layout.css
   };
   gCSSProperties["text-emphasis-color"] = {
     domProp: "textEmphasisColor",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     prerequisites: { "color": "black" },
     initial_values: [ "currentColor", "black", "rgb(0,0,0)" ],
     other_values: [ "red", "rgba(255,255,255,0.5)", "transparent" ],
-    invalid_values: [ "#0", "#00", "#0000", "#00000", "#0000000", "#00000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
+    invalid_values: [ "#0", "#00", "#00000", "#0000000", "#000000000", "000000", "ff00ff", "rgb(255,xxx,255)" ]
   };
   gCSSProperties["text-emphasis-position"] = {
     domProp: "textEmphasisPosition",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "over right", "right over" ],
     other_values: [ "over left", "left over", "under left", "left under", "under right", "right under" ],
     invalid_values: [ "over over", "left left", "over right left", "rubbish left", "over rubbish" ]
deleted file mode 100644
--- a/testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.hex4.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.fillStyle.parse.hex4.html]
-  type: testharness
-  [Canvas test: 2d.fillStyle.parse.hex4]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/2dcontext/fill-and-stroke-styles/2d.fillStyle.parse.hex8.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[2d.fillStyle.parse.hex8.html]
-  type: testharness
-  [Canvas test: 2d.fillStyle.parse.hex8]
-    expected: FAIL
-
--- a/testing/web-platform/tests/quirks-mode/hashless-hex-color.html
+++ b/testing/web-platform/tests/quirks-mode/hashless-hex-color.html
@@ -317,26 +317,23 @@
         {input:"url('a')", svg:'url(a)'},
         {input:"url('aa')", svg:'url(aa)'},
         {input:"url('aaa')", svg:'url(aaa)'},
         {input:"url('aaaa')", svg:'url(aaaa)'},
         {input:"url('aaaaa')", svg:'url(aaaaa)'},
         {input:"url('aaaaaa')", svg:'url(aaaaaa)'},
         {input:"#a"},
         {input:"#aa"},
-        {input:"#aaaa"},
         {input:"#aaaaa"},
         {input:"#aaaaaaa"},
         {input:"#1"},
         {input:"#11"},
-        {input:"#1111"},
         {input:"#11111"},
         {input:"#1111111"},
         {input:"#1a"},
-        {input:"#111a"},
         {input:"#1111a"},
         {input:"#111111a"},
         {input:"1%"},
         {input:"11%"},
         {input:"111%"},
         {input:"1111%"},
         {input:"11111%"},
         {input:"111111%"},