Bug 1448763 part 2 - Remove serialization code for specified value. r?emilio draft
authorXidorn Quan <me@upsuper.org>
Thu, 05 Apr 2018 13:36:31 +1000
changeset 777683 f36ec0a41b2c67834f87292eea0b9a05022c10c8
parent 777682 19ac679c06e453e22c7bd124a72768ba28ac6b94
child 777684 485f40d2e8245ddafcececc08f0fc1a6eed0de79
push id105263
push userxquan@mozilla.com
push dateThu, 05 Apr 2018 05:22:06 +0000
reviewersemilio
bugs1448763
milestone61.0a1
Bug 1448763 part 2 - Remove serialization code for specified value. r?emilio MozReview-Commit-ID: 2DTGHb7GH4T
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -984,288 +984,16 @@ nsCSSValue::AtomizeIdentValue()
 {
   MOZ_ASSERT(mUnit == eCSSUnit_Ident);
   RefPtr<nsAtom> atom = NS_Atomize(GetStringBufferValue());
   Reset();
   mUnit = eCSSUnit_AtomIdent;
   mValue.mAtom = atom.forget().take();
 }
 
-namespace {
-
-struct CSSValueSerializeCalcOps {
-  CSSValueSerializeCalcOps(nsCSSPropertyID aProperty, nsAString& aResult)
-    : mProperty(aProperty),
-      mResult(aResult)
-  {
-  }
-
-  typedef nsCSSValue input_type;
-  typedef nsCSSValue::Array input_array_type;
-
-  static nsCSSUnit GetUnit(const input_type& aValue) {
-    return aValue.GetUnit();
-  }
-
-  void Append(const char* aString)
-  {
-    mResult.AppendASCII(aString);
-  }
-
-  void AppendLeafValue(const input_type& aValue)
-  {
-    MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Percent ||
-               aValue.IsLengthUnit() ||
-               aValue.GetUnit() == eCSSUnit_Number,
-               "unexpected unit");
-    aValue.AppendToString(mProperty, mResult);
-  }
-
-  void AppendCoefficient(const input_type& aValue)
-  {
-    MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
-    aValue.AppendToString(mProperty, mResult);
-  }
-
-private:
-  nsCSSPropertyID mProperty;
-  nsAString &mResult;
-};
-
-} // namespace
-
-void
-nsCSSValue::AppendPolygonToString(nsCSSPropertyID aProperty,
-                                  nsAString& aResult) const
-{
-  const nsCSSValue::Array* array = GetArrayValue();
-  MOZ_ASSERT(array->Count() > 1 && array->Count() <= 3,
-             "Polygons must have name and at least one more value.");
-  // When the array has 2 elements, the item on index 1 is the coordinate
-  // pair list.
-  // When the array has 3 elements, the item on index 1 is a fill-rule
-  // and item on index 2 is the coordinate pair list.
-  size_t index = 1;
-  if (array->Count() == 3) {
-    const nsCSSValue& fillRuleValue = array->Item(index);
-    MOZ_ASSERT(fillRuleValue.GetUnit() == eCSSUnit_Enumerated,
-               "Expected polygon fill rule.");
-    int32_t fillRule = fillRuleValue.GetIntValue();
-    AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(fillRule,
-                                                  nsCSSProps::kFillRuleKTable),
-                       aResult);
-    aResult.AppendLiteral(", ");
-    ++index;
-  }
-  array->Item(index).AppendToString(aProperty, aResult);
-}
-
-inline void
-nsCSSValue::AppendPositionCoordinateToString(
-                const nsCSSValue& aValue, nsCSSPropertyID aProperty,
-                nsAString& aResult) const
-{
-  if (aValue.GetUnit() == eCSSUnit_Enumerated) {
-    int32_t intValue = aValue.GetIntValue();
-    AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                          nsCSSProps::kShapeRadiusKTable), aResult);
-  } else {
-    aValue.AppendToString(aProperty, aResult);
-  }
-}
-
-void
-nsCSSValue::AppendCircleOrEllipseToString(nsCSSKeyword aFunctionId,
-                                          nsCSSPropertyID aProperty,
-                                          nsAString& aResult) const
-{
-  const nsCSSValue::Array* array = GetArrayValue();
-  size_t count = aFunctionId == eCSSKeyword_circle ? 2 : 3;
-  MOZ_ASSERT(array->Count() == count + 1, "wrong number of arguments");
-
-  bool hasRadii = array->Item(1).GetUnit() != eCSSUnit_Null;
-
-  // closest-side is the default, so we don't need to
-  // output it if all values are closest-side.
-  if (array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
-      StyleShapeRadius(array->Item(1).GetIntValue()) == StyleShapeRadius::ClosestSide &&
-      (aFunctionId == eCSSKeyword_circle ||
-       (array->Item(2).GetUnit() == eCSSUnit_Enumerated &&
-        StyleShapeRadius(array->Item(2).GetIntValue()) == StyleShapeRadius::ClosestSide))) {
-    hasRadii = false;
-  } else {
-    AppendPositionCoordinateToString(array->Item(1), aProperty, aResult);
-
-    if (hasRadii && aFunctionId == eCSSKeyword_ellipse) {
-      aResult.Append(' ');
-      AppendPositionCoordinateToString(array->Item(2), aProperty, aResult);
-    }
-  }
-
-  if (hasRadii) {
-    aResult.Append(' ');
-  }
-
-  // Any position specified?
-  if (array->Item(count).GetUnit() != eCSSUnit_Array) {
-    MOZ_ASSERT(array->Item(count).GetUnit() == eCSSUnit_Null,
-               "unexpected value");
-    // We only serialize to the 2 or 4 value form
-    // |circle()| is valid, but should be expanded
-    // to |circle(at 50% 50%)|
-    aResult.AppendLiteral("at 50% 50%");
-    return;
-  }
-
-  aResult.AppendLiteral("at ");
-  array->Item(count).AppendBasicShapePositionToString(aResult);
-}
-
-// https://drafts.csswg.org/css-shapes/#basic-shape-serialization
-// basic-shape asks us to omit a lot of redundant things whilst serializing
-// position values. Other specs are not clear about this
-// (https://github.com/w3c/csswg-drafts/issues/368), so for now we special-case
-// basic shapes only
-void
-nsCSSValue::AppendBasicShapePositionToString(nsAString& aResult) const
-{
-  const nsCSSValue::Array* array = GetArrayValue();
-  // We always parse these into an array of four elements
-  MOZ_ASSERT(array->Count() == 4,
-             "basic-shape position value doesn't have enough elements");
-
-  const nsCSSValue &xEdge   = array->Item(0);
-  const nsCSSValue &xOffset = array->Item(1);
-  const nsCSSValue &yEdge   = array->Item(2);
-  const nsCSSValue &yOffset = array->Item(3);
-
-  MOZ_ASSERT(xEdge.GetUnit() == eCSSUnit_Enumerated &&
-             yEdge.GetUnit() == eCSSUnit_Enumerated &&
-             xOffset.IsLengthPercentCalcUnit() &&
-             yOffset.IsLengthPercentCalcUnit() &&
-             xEdge.GetIntValue() != NS_STYLE_IMAGELAYER_POSITION_CENTER &&
-             yEdge.GetIntValue() != NS_STYLE_IMAGELAYER_POSITION_CENTER,
-             "Ensure invariants from ParsePositionValueBasicShape "
-             "haven't been modified");
-  if (xEdge.GetIntValue() == NS_STYLE_IMAGELAYER_POSITION_LEFT &&
-      yEdge.GetIntValue() == NS_STYLE_IMAGELAYER_POSITION_TOP) {
-    // We can omit these defaults
-    xOffset.AppendToString(eCSSProperty_UNKNOWN, aResult);
-    aResult.Append(' ');
-    yOffset.AppendToString(eCSSProperty_UNKNOWN, aResult);
-  } else {
-    // We only serialize to the two or four valued form
-    xEdge.AppendToString(eCSSProperty_object_position, aResult);
-    aResult.Append(' ');
-    xOffset.AppendToString(eCSSProperty_UNKNOWN, aResult);
-    aResult.Append(' ');
-    yEdge.AppendToString(eCSSProperty_object_position, aResult);
-    aResult.Append(' ');
-    yOffset.AppendToString(eCSSProperty_UNKNOWN, aResult);
-  }
-}
-
-// Helper to append |aString| with the shorthand sides notation used in e.g.
-// 'padding'. |aProperties| and |aValues| are expected to have 4 elements.
-/*static*/ void
-nsCSSValue::AppendSidesShorthandToString(const nsCSSPropertyID aProperties[],
-                                         const nsCSSValue* aValues[],
-                                         nsAString& aString)
-{
-  const nsCSSValue& value1 = *aValues[0];
-  const nsCSSValue& value2 = *aValues[1];
-  const nsCSSValue& value3 = *aValues[2];
-  const nsCSSValue& value4 = *aValues[3];
-
-  MOZ_ASSERT(value1.GetUnit() != eCSSUnit_Null, "null value 1");
-  value1.AppendToString(aProperties[0], aString);
-  if (value1 != value2 || value1 != value3 || value1 != value4) {
-    aString.Append(char16_t(' '));
-    MOZ_ASSERT(value2.GetUnit() != eCSSUnit_Null, "null value 2");
-    value2.AppendToString(aProperties[1], aString);
-    if (value1 != value3 || value2 != value4) {
-      aString.Append(char16_t(' '));
-      MOZ_ASSERT(value3.GetUnit() != eCSSUnit_Null, "null value 3");
-      value3.AppendToString(aProperties[2], aString);
-      if (value2 != value4) {
-        aString.Append(char16_t(' '));
-        MOZ_ASSERT(value4.GetUnit() != eCSSUnit_Null, "null value 4");
-        value4.AppendToString(aProperties[3], aString);
-      }
-    }
-  }
-}
-
-/*static*/ void
-nsCSSValue::AppendBasicShapeRadiusToString(const nsCSSPropertyID aProperties[],
-                                           const nsCSSValue* aValues[],
-                                           nsAString& aResult)
-{
-  bool needY = false;
-  const nsCSSValue* xVals[4];
-  const nsCSSValue* yVals[4];
-  for (int i = 0; i < 4; i++) {
-    if (aValues[i]->GetUnit() == eCSSUnit_Pair) {
-      needY = true;
-      xVals[i] = &aValues[i]->GetPairValue().mXValue;
-      yVals[i] = &aValues[i]->GetPairValue().mYValue;
-    } else {
-      xVals[i] = yVals[i] = aValues[i];
-    }
-  }
-
-  AppendSidesShorthandToString(aProperties, xVals, aResult);
-  if (needY) {
-    aResult.AppendLiteral(" / ");
-    AppendSidesShorthandToString(aProperties, yVals, aResult);
-  }
-}
-
-void
-nsCSSValue::AppendInsetToString(nsCSSPropertyID aProperty,
-                                nsAString& aResult) const
-{
-  const nsCSSValue::Array* array = GetArrayValue();
-  MOZ_ASSERT(array->Count() == 6,
-             "inset function has wrong number of arguments");
-  if (array->Item(1).GetUnit() != eCSSUnit_Null) {
-    array->Item(1).AppendToString(aProperty, aResult);
-    if (array->Item(2).GetUnit() != eCSSUnit_Null) {
-      aResult.Append(' ');
-      array->Item(2).AppendToString(aProperty, aResult);
-      if (array->Item(3).GetUnit() != eCSSUnit_Null) {
-        aResult.Append(' ');
-        array->Item(3).AppendToString(aProperty, aResult);
-        if (array->Item(4).GetUnit() != eCSSUnit_Null) {
-          aResult.Append(' ');
-          array->Item(4).AppendToString(aProperty, aResult);
-        }
-      }
-    }
-  }
-
-  if (array->Item(5).GetUnit() == eCSSUnit_Array) {
-    const nsCSSPropertyID* subprops =
-      nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius);
-    const nsCSSValue::Array* radius = array->Item(5).GetArrayValue();
-    MOZ_ASSERT(radius->Count() == 4, "expected 4 radii values");
-    const nsCSSValue* vals[4] = {
-      &(radius->Item(0)),
-      &(radius->Item(1)),
-      &(radius->Item(2)),
-      &(radius->Item(3))
-    };
-    aResult.AppendLiteral(" round ");
-    AppendBasicShapeRadiusToString(subprops, vals, aResult);
-  } else {
-    MOZ_ASSERT(array->Item(5).GetUnit() == eCSSUnit_Null,
-               "unexpected value");
-  }
-}
-
 /* static */ void
 nsCSSValue::AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult)
 {
   auto legacy = aValue & NS_STYLE_ALIGN_LEGACY;
   if (legacy) {
     aValue &= ~legacy;
     aResult.AppendLiteral("legacy ");
   }
@@ -1288,810 +1016,16 @@ nsCSSValue::AppendAlignJustifyValueToStr
   if (aValue == NS_STYLE_ALIGN_LAST_BASELINE) {
     aResult.AppendLiteral("last ");
     aValue = NS_STYLE_ALIGN_BASELINE;
   }
   const auto& kwtable(nsCSSProps::kAlignAllKeywords);
   AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(aValue, kwtable), aResult);
 }
 
-/**
- * Returns a re-ordered version of an csCSSValue::Array representing a shadow
- * item (including a drop-shadow() filter function) suitable for serialization.
- */
-static already_AddRefed<nsCSSValue::Array>
-GetReorderedShadowArrayForSerialization(const nsCSSValue::Array* aOriginalArray)
-{
-  MOZ_ASSERT(aOriginalArray);
-
-  RefPtr<nsCSSValue::Array> reorderArray = nsCSSValue::Array::Create(6);
-
-  reorderArray->Item(0) = aOriginalArray->Item(4); // Color
-  for (uint8_t i = 0; i < 4; i++) {
-    reorderArray->Item(i + 1) = aOriginalArray->Item(i); // Length
-  }
-  reorderArray->Item(5) = aOriginalArray->Item(5); // Inset
-
-  return reorderArray.forget();
-}
-
-void
-nsCSSValue::AppendToString(nsCSSPropertyID aProperty,
-                           nsAString& aResult) const
-{
-  // eCSSProperty_UNKNOWN gets used for some recursive calls below.
-  MOZ_ASSERT((0 <= aProperty &&
-              aProperty <= eCSSProperty_COUNT_no_shorthands) ||
-             aProperty == eCSSProperty_UNKNOWN ||
-             aProperty == eCSSProperty_DOM,
-             "property ID out of range");
-
-  nsCSSUnit unit = GetUnit();
-  if (unit == eCSSUnit_Null) {
-    return;
-  }
-
-  if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
-    if (unit == eCSSUnit_Attr) {
-      aResult.AppendLiteral("attr(");
-    }
-    nsAutoString  buffer;
-    GetStringValue(buffer);
-    if (unit == eCSSUnit_String) {
-      nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
-    } else {
-      nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
-    }
-  }
-  else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Symbols) {
-    switch (unit) {
-      case eCSSUnit_Counter:  aResult.AppendLiteral("counter(");  break;
-      case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
-      case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
-      case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
-      case eCSSUnit_Symbols: aResult.AppendLiteral("symbols("); break;
-      default: break;
-    }
-
-    nsCSSValue::Array *array = GetArrayValue();
-
-    // CSSParserImpl::ParseShadowItem stores shadow items in a specific order
-    // that does not match the order we use when serializing computed shadow
-    // items. In order to match the computed value order, we shuffle the items
-    // in the shadow array before serializing it.
-    RefPtr<nsCSSValue::Array> reordered;
-    if (aProperty == eCSSProperty_text_shadow ||
-        aProperty == eCSSProperty_box_shadow ||
-        aProperty == eCSSProperty_filter) {
-      reordered = GetReorderedShadowArrayForSerialization(array);
-      array = reordered.get();
-    }
-
-    bool mark = false;
-    for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
-      if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
-        if ((unit == eCSSUnit_Array &&
-             eCSSProperty_transition_timing_function != aProperty) ||
-            unit == eCSSUnit_Symbols)
-          aResult.Append(' ');
-        else if (unit != eCSSUnit_Steps)
-          aResult.AppendLiteral(", ");
-      }
-      if (unit == eCSSUnit_Steps && i == 1) {
-        MOZ_ASSERT(array->Item(i).GetUnit() == eCSSUnit_Enumerated,
-                   "unexpected value");
-        int32_t side = array->Item(i).GetIntValue();
-        MOZ_ASSERT(side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
-                   side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END ||
-                   side == -1,
-                   "unexpected value");
-        if (side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
-          aResult.AppendLiteral(", start");
-        } else if (side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END) {
-          aResult.AppendLiteral(", end");
-        }
-        continue;
-      }
-      if (unit == eCSSUnit_Symbols && i == 0) {
-        MOZ_ASSERT(array->Item(i).GetUnit() == eCSSUnit_Enumerated,
-                   "unexpected value");
-        int32_t system = array->Item(i).GetIntValue();
-        if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
-          AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
-                  system, nsCSSProps::kCounterSystemKTable), aResult);
-          mark = true;
-        }
-        continue;
-      }
-      nsCSSPropertyID prop =
-        ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
-         i == array->Count() - 1)
-        ? eCSSProperty_list_style_type : aProperty;
-      if (array->Item(i).GetUnit() != eCSSUnit_Null) {
-        array->Item(i).AppendToString(prop, aResult);
-        mark = true;
-      }
-    }
-    if (eCSSUnit_Array == unit &&
-        aProperty == eCSSProperty_transition_timing_function) {
-      aResult.Append(')');
-    }
-  }
-  /* Although Function is backed by an Array, we'll handle it separately
-   * because it's a bit quirky.
-   */
-  else if (eCSSUnit_Function == unit) {
-    const nsCSSValue::Array* array = GetArrayValue();
-    MOZ_ASSERT(array->Count() >= 1,
-               "Functions must have at least one element for the name.");
-
-    const nsCSSValue& functionName = array->Item(0);
-    MOZ_ASSERT(functionName.GetUnit() == eCSSUnit_Enumerated,
-               "Functions must have an enumerated name.");
-    // The first argument is always of nsCSSKeyword type.
-    const nsCSSKeyword functionId = functionName.GetKeywordValue();
-
-    // minmax(auto, <flex>) is equivalent to (and is our internal representation
-    // of) <flex>, and both are serialized as <flex>
-    if (functionId == eCSSKeyword_minmax &&
-        array->Count() == 3 &&
-        array->Item(1).GetUnit() == eCSSUnit_Auto &&
-        array->Item(2).GetUnit() == eCSSUnit_FlexFraction) {
-      array->Item(2).AppendToString(aProperty, aResult);
-      MOZ_ASSERT(aProperty == eCSSProperty_grid_template_columns ||
-                 aProperty == eCSSProperty_grid_template_rows ||
-                 aProperty == eCSSProperty_grid_auto_columns ||
-                 aProperty == eCSSProperty_grid_auto_rows);
-      return;
-    }
-
-    /* Append the function name. */
-    NS_ConvertASCIItoUTF16 ident(nsCSSKeywords::GetStringValue(functionId));
-    // Bug 721136: Normalize the identifier to lowercase, except that things
-    // like scaleX should have the last character capitalized.  This matches
-    // what other browsers do.
-    switch (functionId) {
-      case eCSSKeyword_rotatex:
-      case eCSSKeyword_scalex:
-      case eCSSKeyword_skewx:
-      case eCSSKeyword_translatex:
-        ident.Replace(ident.Length() - 1, 1, char16_t('X'));
-        break;
-
-      case eCSSKeyword_rotatey:
-      case eCSSKeyword_scaley:
-      case eCSSKeyword_skewy:
-      case eCSSKeyword_translatey:
-        ident.Replace(ident.Length() - 1, 1, char16_t('Y'));
-        break;
-
-      case eCSSKeyword_rotatez:
-      case eCSSKeyword_scalez:
-      case eCSSKeyword_translatez:
-        ident.Replace(ident.Length() - 1, 1, char16_t('Z'));
-        break;
-
-      default:
-        break;
-    }
-    nsStyleUtil::AppendEscapedCSSIdent(ident, aResult);
-    aResult.Append('(');
-
-    switch (functionId) {
-      case eCSSKeyword_polygon:
-        AppendPolygonToString(aProperty, aResult);
-        break;
-
-      case eCSSKeyword_circle:
-      case eCSSKeyword_ellipse:
-        AppendCircleOrEllipseToString(functionId, aProperty, aResult);
-        break;
-
-      case eCSSKeyword_inset:
-        AppendInsetToString(aProperty, aResult);
-        break;
-
-      default: {
-        // Now, step through the function contents, writing each of
-        // them as we go.
-        for (size_t index = 1; index < array->Count(); ++index) {
-          array->Item(index).AppendToString(aProperty, aResult);
-
-          /* If we're not at the final element, append a comma. */
-          if (index + 1 != array->Count())
-            aResult.AppendLiteral(", ");
-        }
-      }
-    }
-
-    /* Finally, append the closing parenthesis. */
-    aResult.Append(')');
-  }
-  else if (IsCalcUnit()) {
-    MOZ_ASSERT(GetUnit() == eCSSUnit_Calc, "unexpected unit");
-    CSSValueSerializeCalcOps ops(aProperty, aResult);
-    css::SerializeCalc(*this, ops);
-  }
-  else if (eCSSUnit_Integer == unit) {
-    aResult.AppendInt(GetIntValue(), 10);
-  }
-  else if (eCSSUnit_Enumerated == unit) {
-    int32_t intValue = GetIntValue();
-    switch(aProperty) {
-
-
-    case eCSSProperty_text_combine_upright:
-      if (intValue <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) {
-        AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
-                           aResult);
-      } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) {
-        aResult.AppendLiteral("digits 2");
-      } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) {
-        aResult.AppendLiteral("digits 3");
-      } else {
-        aResult.AppendLiteral("digits 4");
-      }
-      break;
-
-    case eCSSProperty_text_decoration_line:
-      if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
-        AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
-                           aResult);
-      } else {
-        // Ignore the "override all" internal value.
-        // (It doesn't have a string representation.)
-        intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
-        nsStyleUtil::AppendBitmaskCSSValue(
-          aProperty, intValue,
-          NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
-          NS_STYLE_TEXT_DECORATION_LINE_BLINK,
-          aResult);
-      }
-      break;
-
-    case eCSSProperty_paint_order:
-      static_assert
-        (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
-         "SVGStyleStruct::mPaintOrder and the following cast not big enough");
-      nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()),
-                                         aResult);
-      break;
-
-    case eCSSProperty_font_synthesis:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_FONT_SYNTHESIS_WEIGHT,
-                                         NS_FONT_SYNTHESIS_STYLE,
-                                         aResult);
-      break;
-
-    case eCSSProperty_font_variant_east_asian:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_FONT_VARIANT_EAST_ASIAN_JIS78,
-                                         NS_FONT_VARIANT_EAST_ASIAN_RUBY,
-                                         aResult);
-      break;
-
-    case eCSSProperty_font_variant_ligatures:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_FONT_VARIANT_LIGATURES_NONE,
-                                         NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
-                                         aResult);
-      break;
-
-    case eCSSProperty_font_variant_numeric:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_FONT_VARIANT_NUMERIC_LINING,
-                                         NS_FONT_VARIANT_NUMERIC_ORDINAL,
-                                         aResult);
-      break;
-
-    case eCSSProperty_grid_auto_flow:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_STYLE_GRID_AUTO_FLOW_ROW,
-                                         NS_STYLE_GRID_AUTO_FLOW_DENSE,
-                                         aResult);
-      break;
-
-    case eCSSProperty_grid_column_start:
-    case eCSSProperty_grid_column_end:
-    case eCSSProperty_grid_row_start:
-    case eCSSProperty_grid_row_end:
-      // "span" is the only enumerated-unit value for these properties
-      aResult.AppendLiteral("span");
-      break;
-
-    case eCSSProperty_touch_action:
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_STYLE_TOUCH_ACTION_NONE,
-                                         NS_STYLE_TOUCH_ACTION_MANIPULATION,
-                                         aResult);
-      break;
-
-    case eCSSProperty_clip_path:
-      AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                            nsCSSProps::kClipPathGeometryBoxKTable),
-                         aResult);
-      break;
-
-    case eCSSProperty_shape_outside:
-      AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                            nsCSSProps::kShapeOutsideShapeBoxKTable),
-                         aResult);
-      break;
-
-    case eCSSProperty_contain:
-      if (intValue & NS_STYLE_CONTAIN_STRICT) {
-        NS_ASSERTION(intValue == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
-                     "contain: strict should imply contain: layout style paint");
-        // Only output strict.
-        intValue = NS_STYLE_CONTAIN_STRICT;
-      }
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty,
-                                         intValue,
-                                         NS_STYLE_CONTAIN_STRICT,
-                                         NS_STYLE_CONTAIN_PAINT,
-                                         aResult);
-      break;
-
-    case eCSSProperty_align_content:
-    case eCSSProperty_justify_content: {
-      AppendAlignJustifyValueToString(intValue & NS_STYLE_ALIGN_ALL_BITS, aResult);
-      auto fallback = intValue >> NS_STYLE_ALIGN_ALL_SHIFT;
-      if (fallback) {
-        MOZ_ASSERT(nsCSSProps::ValueToKeywordEnum(fallback & ~NS_STYLE_ALIGN_FLAG_BITS,
-                                                  nsCSSProps::kAlignSelfPosition)
-                   != eCSSKeyword_UNKNOWN, "unknown fallback value");
-        aResult.Append(' ');
-        AppendAlignJustifyValueToString(fallback, aResult);
-      }
-      break;
-    }
-
-    case eCSSProperty_align_items:
-    case eCSSProperty_align_self:
-    case eCSSProperty_justify_items:
-    case eCSSProperty_justify_self:
-      AppendAlignJustifyValueToString(intValue, aResult);
-      break;
-
-    case eCSSProperty_text_emphasis_position: {
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
-                                         NS_STYLE_TEXT_EMPHASIS_POSITION_OVER,
-                                         NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT,
-                                         aResult);
-      break;
-    }
-
-    case eCSSProperty_text_emphasis_style: {
-      auto fill = intValue & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK;
-      AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
-        fill, nsCSSProps::kTextEmphasisStyleFillKTable), aResult);
-      aResult.Append(' ');
-      auto shape = intValue & NS_STYLE_TEXT_EMPHASIS_STYLE_SHAPE_MASK;
-      AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
-        shape, nsCSSProps::kTextEmphasisStyleShapeKTable), aResult);
-      break;
-    }
-
-    default:
-      const nsCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue);
-      AppendASCIItoUTF16(name, aResult);
-      break;
-    }
-  }
-  else if (eCSSUnit_EnumColor == unit) {
-    // we can lookup the property in the ColorTable and then
-    // get a string mapping the name
-    nsAutoCString str;
-    if (nsCSSProps::GetColorName(GetIntValue(), str)){
-      AppendASCIItoUTF16(str, aResult);
-    } else {
-      MOZ_ASSERT(false, "bad color value");
-    }
-  }
-  else if (IsNumericColorUnit(unit)) {
-    nscolor color = GetColorValue();
-    // For brevity, we omit the alpha component if it's equal to 255 (full
-    // opaque). Also, we use "rgba" rather than "rgb" when the color includes
-    // the non-opaque alpha value, for backwards-compat (even though they're
-    // aliases as of css-color-4).
-    // e.g.:
-    //   rgba(1, 2, 3, 1.0) => rgb(1, 2, 3)
-    //   rgba(1, 2, 3, 0.5) => rgba(1, 2, 3, 0.5)
-
-    uint8_t a = NS_GET_A(color);
-    bool showAlpha = (a != 255);
-
-    if (showAlpha) {
-      aResult.AppendLiteral("rgba(");
-    } else {
-      aResult.AppendLiteral("rgb(");
-    }
-
-    NS_NAMED_LITERAL_STRING(comma, ", ");
-
-    aResult.AppendInt(NS_GET_R(color), 10);
-    aResult.Append(comma);
-    aResult.AppendInt(NS_GET_G(color), 10);
-    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_ComplexColor == unit) {
-    StyleComplexColor color = GetStyleComplexColorValue();
-    nsCSSValue serializable;
-    if (color.IsCurrentColor()) {
-      serializable.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
-    } else if (color.IsNumericColor()) {
-      serializable.SetColorValue(color.mColor);
-    } else {
-      MOZ_ASSERT_UNREACHABLE("Cannot serialize a complex color");
-    }
-    serializable.AppendToString(aProperty, aResult);
-  }
-  else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
-    aResult.AppendLiteral("url(");
-    nsStyleUtil::AppendEscapedCSSString(
-      nsDependentString(GetOriginalURLValue()), aResult);
-    aResult.Append(')');
-  }
-  else if (eCSSUnit_Element == unit) {
-    aResult.AppendLiteral("-moz-element(#");
-    nsAutoString tmpStr;
-    GetStringValue(tmpStr);
-    nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult);
-    aResult.Append(')');
-  }
-  else if (eCSSUnit_Percent == unit) {
-    aResult.AppendFloat(GetPercentValue() * 100.0f);
-  }
-  else if (eCSSUnit_Percent < unit) {  // length unit
-    aResult.AppendFloat(GetFloatValue());
-  }
-  else if (eCSSUnit_Gradient == unit) {
-    nsCSSValueGradient* gradient = GetGradientValue();
-
-    if (gradient->mIsLegacySyntax) {
-      if (gradient->mIsMozLegacySyntax) {
-        aResult.AppendLiteral("-moz-");
-      } else {
-        aResult.AppendLiteral("-webkit-");
-      }
-    }
-    if (gradient->mIsRepeating) {
-      aResult.AppendLiteral("repeating-");
-    }
-    if (gradient->mIsRadial) {
-      aResult.AppendLiteral("radial-gradient(");
-    } else {
-      aResult.AppendLiteral("linear-gradient(");
-    }
-
-    bool needSep = false;
-    if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
-      if (!gradient->mIsExplicitSize) {
-        if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
-          MOZ_ASSERT(gradient->GetRadialShape().GetUnit() ==
-                     eCSSUnit_Enumerated,
-                     "bad unit for radial gradient shape");
-          int32_t intValue = gradient->GetRadialShape().GetIntValue();
-          MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
-                     "radial gradient with linear shape?!");
-          AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                                 nsCSSProps::kRadialGradientShapeKTable),
-                             aResult);
-          needSep = true;
-        }
-
-        if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
-          if (needSep) {
-            aResult.Append(' ');
-          }
-          MOZ_ASSERT(gradient->GetRadialSize().GetUnit() == eCSSUnit_Enumerated,
-                     "bad unit for radial gradient size");
-          int32_t intValue = gradient->GetRadialSize().GetIntValue();
-          AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                                 nsCSSProps::kRadialGradientSizeKTable),
-                             aResult);
-          needSep = true;
-        }
-      } else {
-        MOZ_ASSERT(gradient->GetRadiusX().GetUnit() != eCSSUnit_None,
-                   "bad unit for radial gradient explicit size");
-        gradient->GetRadiusX().AppendToString(aProperty, aResult);
-        if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) {
-          aResult.Append(' ');
-          gradient->GetRadiusY().AppendToString(aProperty, aResult);
-        }
-        needSep = true;
-      }
-    }
-    if (!gradient->mIsRadial &&
-        !(gradient->mIsLegacySyntax && gradient->mIsMozLegacySyntax)) {
-      if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
-          gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None);
-        MOZ_ASSERT(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
-                   gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
-                   "unexpected unit");
-        if (!gradient->mIsLegacySyntax) {
-          aResult.AppendLiteral("to ");
-        }
-        bool didAppendX = false;
-        if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
-          gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
-                                                  aResult);
-          didAppendX = true;
-        }
-        if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
-          if (didAppendX) {
-            // We're appending both an x-keyword and a y-keyword.
-            // Add a space between them here.
-            aResult.Append(' ');
-          }
-          gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
-                                                  aResult);
-        }
-        needSep = true;
-      } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
-        gradient->mAngle.AppendToString(aProperty, aResult);
-        needSep = true;
-      }
-    } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
-        gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
-        gradient->mAngle.GetUnit() != eCSSUnit_None) {
-      if (needSep) {
-        aResult.Append(' ');
-      }
-      if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
-        aResult.AppendLiteral("at ");
-      }
-      if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
-        gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
-                                                aResult);
-        aResult.Append(' ');
-      }
-      if (gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
-        gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
-                                                aResult);
-        aResult.Append(' ');
-      }
-      if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->mIsLegacySyntax,
-                   "angle is allowed only for legacy syntax");
-        gradient->mAngle.AppendToString(aProperty, aResult);
-      }
-      needSep = true;
-    }
-
-    if (gradient->mIsRadial && gradient->mIsLegacySyntax &&
-        (gradient->GetRadialShape().GetUnit() != eCSSUnit_None ||
-         gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) {
-      MOZ_ASSERT(!gradient->mIsExplicitSize);
-      if (needSep) {
-        aResult.AppendLiteral(", ");
-      }
-      if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated,
-                   "bad unit for radial gradient shape");
-        int32_t intValue = gradient->GetRadialShape().GetIntValue();
-        MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
-                   "radial gradient with linear shape?!");
-        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                               nsCSSProps::kRadialGradientShapeKTable),
-                           aResult);
-        aResult.Append(' ');
-      }
-
-      if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
-        MOZ_ASSERT(gradient->GetRadialSize().GetUnit() == eCSSUnit_Enumerated,
-                   "bad unit for radial gradient size");
-        int32_t intValue = gradient->GetRadialSize().GetIntValue();
-        AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
-                               nsCSSProps::kRadialGradientSizeKTable),
-                           aResult);
-      }
-      needSep = true;
-    }
-    if (needSep) {
-      aResult.AppendLiteral(", ");
-    }
-
-    for (uint32_t i = 0 ;;) {
-      bool isInterpolationHint = gradient->mStops[i].mIsInterpolationHint;
-      if (!isInterpolationHint) {
-        gradient->mStops[i].mColor.AppendToString(aProperty, aResult);
-      }
-      if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
-        if (!isInterpolationHint) {
-          aResult.Append(' ');
-        }
-        gradient->mStops[i].mLocation.AppendToString(aProperty, aResult);
-      }
-      if (++i == gradient->mStops.Length()) {
-        break;
-      }
-      aResult.AppendLiteral(", ");
-    }
-
-    aResult.Append(')');
-  } else if (eCSSUnit_TokenStream == unit) {
-    nsCSSPropertyID shorthand = mValue.mTokenStream->mShorthandPropertyID;
-    if (shorthand == eCSSProperty_UNKNOWN ||
-        aProperty == eCSSProperty__x_system_font) {
-      // We treat serialization of aliases like '-moz-transform' as a special
-      // case, since it really wants to be serialized as if it were a longhand
-      // even though it is implemented as a shorthand. We also need to
-      // serialize -x-system-font's token stream value, even though the
-      // value is set through the font shorthand.  This serialization
-      // of -x-system-font is needed when we need to output the
-      // 'font' shorthand followed by a number of overriding font
-      // longhand components.
-      aResult.Append(mValue.mTokenStream->mTokenStream);
-    }
-  } else if (eCSSUnit_Pair == unit) {
-    if (eCSSProperty_font_variant_alternates == aProperty) {
-      int32_t intValue = GetPairValue().mXValue.GetIntValue();
-      nsAutoString out;
-
-      // simple, enumerated values
-      nsStyleUtil::AppendBitmaskCSSValue(aProperty,
-          intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
-          NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
-          NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
-          out);
-
-      // functional values
-      const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
-      AutoTArray<gfxAlternateValue,8> altValues;
-
-      nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
-      nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
-      aResult.Append(out);
-    } else {
-      GetPairValue().AppendToString(aProperty, aResult);
-    }
-  } else if (eCSSUnit_Triplet == unit) {
-    GetTripletValue().AppendToString(aProperty, aResult);
-  } else if (eCSSUnit_Rect == unit) {
-    GetRectValue().AppendToString(aProperty, aResult);
-  } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
-    GetListValue()->AppendToString(aProperty, aResult);
-  } else if (eCSSUnit_SharedList == unit) {
-    GetSharedListValue()->AppendToString(aProperty, aResult);
-  } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
-    switch (aProperty) {
-      case eCSSProperty_font_feature_settings:
-        nsStyleUtil::AppendFontFeatureSettings(*this, aResult);
-        break;
-      default:
-        GetPairListValue()->AppendToString(aProperty, aResult);
-        break;
-    }
-  } else if (eCSSUnit_GridTemplateAreas == unit) {
-    const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas();
-    MOZ_ASSERT(!areas->mTemplates.IsEmpty(),
-               "Unexpected empty array in GridTemplateAreasValue");
-    nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult);
-    for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) {
-      aResult.Append(char16_t(' '));
-      nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult);
-    }
-  } else if (eCSSUnit_FontFamilyList == unit) {
-    nsStyleUtil::AppendEscapedCSSFontFamilyList(mValue.mFontFamilyList,
-                                                aResult);
-  } else if (eCSSUnit_AtomIdent == unit) {
-    nsDependentAtomString buffer(GetAtomValue());
-    nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
-  }
-
-  switch (unit) {
-    case eCSSUnit_Null:         break;
-    case eCSSUnit_Auto:         aResult.AppendLiteral("auto");     break;
-    case eCSSUnit_Inherit:      aResult.AppendLiteral("inherit");  break;
-    case eCSSUnit_Initial:      aResult.AppendLiteral("initial");  break;
-    case eCSSUnit_Unset:        aResult.AppendLiteral("unset");    break;
-    case eCSSUnit_None:         aResult.AppendLiteral("none");     break;
-    case eCSSUnit_Normal:       aResult.AppendLiteral("normal");   break;
-    case eCSSUnit_System_Font:  aResult.AppendLiteral("-moz-use-system-font"); break;
-    case eCSSUnit_All:          aResult.AppendLiteral("all"); break;
-    case eCSSUnit_Dummy:
-    case eCSSUnit_DummyInherit:
-      MOZ_ASSERT(false, "should never serialize");
-      break;
-
-    case eCSSUnit_FontFamilyList: break;
-    case eCSSUnit_String:       break;
-    case eCSSUnit_Ident:        break;
-    case eCSSUnit_AtomIdent:    break;
-    case eCSSUnit_URL:          break;
-    case eCSSUnit_Image:        break;
-    case eCSSUnit_Element:      break;
-    case eCSSUnit_Array:        break;
-    case eCSSUnit_Attr:
-    case eCSSUnit_Cubic_Bezier:
-    case eCSSUnit_Steps:
-    case eCSSUnit_Symbols:
-    case eCSSUnit_Counter:
-    case eCSSUnit_Counters:     aResult.Append(char16_t(')'));    break;
-    case eCSSUnit_Local_Font:   break;
-    case eCSSUnit_Font_Format:  break;
-    case eCSSUnit_Function:     break;
-    case eCSSUnit_Calc:         break;
-    case eCSSUnit_Calc_Plus:    break;
-    case eCSSUnit_Calc_Minus:   break;
-    case eCSSUnit_Calc_Times_L: break;
-    case eCSSUnit_Calc_Times_R: break;
-    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_ComplexColor:          break;
-    case eCSSUnit_Percent:      aResult.Append(char16_t('%'));    break;
-    case eCSSUnit_Number:       break;
-    case eCSSUnit_Gradient:     break;
-    case eCSSUnit_TokenStream:  break;
-    case eCSSUnit_Pair:         break;
-    case eCSSUnit_Triplet:      break;
-    case eCSSUnit_Rect:         break;
-    case eCSSUnit_List:         break;
-    case eCSSUnit_ListDep:      break;
-    case eCSSUnit_SharedList:   break;
-    case eCSSUnit_PairList:     break;
-    case eCSSUnit_PairListDep:  break;
-    case eCSSUnit_GridTemplateAreas:     break;
-
-    case eCSSUnit_Inch:         aResult.AppendLiteral("in");   break;
-    case eCSSUnit_Millimeter:   aResult.AppendLiteral("mm");   break;
-    case eCSSUnit_Centimeter:   aResult.AppendLiteral("cm");   break;
-    case eCSSUnit_Point:        aResult.AppendLiteral("pt");   break;
-    case eCSSUnit_Pica:         aResult.AppendLiteral("pc");   break;
-    case eCSSUnit_Quarter:      aResult.AppendLiteral("q");    break;
-
-    case eCSSUnit_ViewportWidth:  aResult.AppendLiteral("vw");   break;
-    case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh");   break;
-    case eCSSUnit_ViewportMin:    aResult.AppendLiteral("vmin"); break;
-    case eCSSUnit_ViewportMax:    aResult.AppendLiteral("vmax"); break;
-
-    case eCSSUnit_EM:           aResult.AppendLiteral("em");   break;
-    case eCSSUnit_XHeight:      aResult.AppendLiteral("ex");   break;
-    case eCSSUnit_Char:         aResult.AppendLiteral("ch");   break;
-    case eCSSUnit_RootEM:       aResult.AppendLiteral("rem");  break;
-
-    case eCSSUnit_Pixel:        aResult.AppendLiteral("px");   break;
-
-    case eCSSUnit_Degree:       aResult.AppendLiteral("deg");  break;
-    case eCSSUnit_Grad:         aResult.AppendLiteral("grad"); break;
-    case eCSSUnit_Radian:       aResult.AppendLiteral("rad");  break;
-    case eCSSUnit_Turn:         aResult.AppendLiteral("turn");  break;
-
-    case eCSSUnit_Hertz:        aResult.AppendLiteral("Hz");   break;
-    case eCSSUnit_Kilohertz:    aResult.AppendLiteral("kHz");  break;
-
-    case eCSSUnit_Seconds:      aResult.Append(char16_t('s'));    break;
-    case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms");   break;
-
-    case eCSSUnit_FlexFraction: aResult.AppendLiteral("fr");   break;
-  }
-}
-
 size_t
 nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
 
   switch (GetUnit()) {
     // No value: nothing extra to measure.
     case eCSSUnit_Null:
@@ -2300,137 +1234,16 @@ nsCSSValueList::Clone() const
 void
 nsCSSValueList::CloneInto(nsCSSValueList* aList) const
 {
   NS_ASSERTION(!aList->mNext, "Must be an empty list!");
   aList->mValue = mValue;
   aList->mNext = mNext ? mNext->Clone() : nullptr;
 }
 
-static void
-AppendValueListToString(const nsCSSValueList* val,
-                        nsCSSPropertyID aProperty, nsAString& aResult)
-{
-  for (;;) {
-    val->mValue.AppendToString(aProperty, aResult);
-    val = val->mNext;
-    if (!val)
-      break;
-
-    if (nsCSSProps::PropHasFlags(aProperty,
-                                 CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
-      aResult.Append(char16_t(','));
-    aResult.Append(char16_t(' '));
-  }
-}
-
-static void
-AppendGridTemplateToString(const nsCSSValueList* val,
-                           nsCSSPropertyID aProperty, nsAString& aResult)
-{
-  // This is called for the "list" that's the top-level value of the property.
-  bool isSubgrid = false;
-  for (;;) {
-    bool addSpaceSeparator = true;
-    nsCSSUnit unit = val->mValue.GetUnit();
-
-    if (unit == eCSSUnit_Enumerated &&
-        val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) {
-      MOZ_ASSERT(!isSubgrid, "saw subgrid once already");
-      isSubgrid = true;
-      aResult.AppendLiteral("subgrid");
-
-    } else if (unit == eCSSUnit_Pair) {
-      // This is a repeat 'auto-fill' / 'auto-fit'.
-      const nsCSSValuePair& pair = val->mValue.GetPairValue();
-      switch (pair.mXValue.GetIntValue()) {
-        case NS_STYLE_GRID_REPEAT_AUTO_FILL:
-          aResult.AppendLiteral("repeat(auto-fill, ");
-          break;
-        case NS_STYLE_GRID_REPEAT_AUTO_FIT:
-          aResult.AppendLiteral("repeat(auto-fit, ");
-          break;
-        default:
-          MOZ_ASSERT_UNREACHABLE("unexpected enum value");
-      }
-      const nsCSSValueList* repeatList = pair.mYValue.GetListValue();
-      if (repeatList->mValue.GetUnit() != eCSSUnit_Null) {
-        aResult.Append('[');
-        AppendValueListToString(repeatList->mValue.GetListValue(), aProperty,
-                                aResult);
-        aResult.Append(']');
-        if (!isSubgrid) {
-          aResult.Append(' ');
-        }
-      } else if (isSubgrid) {
-        aResult.AppendLiteral("[]");
-      }
-      if (!isSubgrid) {
-        repeatList = repeatList->mNext;
-        repeatList->mValue.AppendToString(aProperty, aResult);
-        repeatList = repeatList->mNext;
-        if (repeatList->mValue.GetUnit() != eCSSUnit_Null) {
-          aResult.AppendLiteral(" [");
-          AppendValueListToString(repeatList->mValue.GetListValue(), aProperty,
-                                  aResult);
-          aResult.Append(']');
-        }
-      }
-      aResult.Append(')');
-
-    } else if (unit == eCSSUnit_Null) {
-      // Empty or omitted <line-names>.
-      if (isSubgrid) {
-        aResult.AppendLiteral("[]");
-      } else {
-        // Serializes to nothing.
-        addSpaceSeparator = false;  // Avoid a double space.
-      }
-
-    } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
-      // Non-empty <line-names>
-      aResult.Append('[');
-      AppendValueListToString(val->mValue.GetListValue(), aProperty, aResult);
-      aResult.Append(']');
-
-    } else {
-      // <track-size>
-      val->mValue.AppendToString(aProperty, aResult);
-      if (!isSubgrid &&
-          val->mNext &&
-          val->mNext->mValue.GetUnit() == eCSSUnit_Null &&
-          !val->mNext->mNext) {
-        // Break out of the loop early to avoid a trailing space.
-        break;
-      }
-    }
-
-    val = val->mNext;
-    if (!val) {
-      break;
-    }
-
-    if (addSpaceSeparator) {
-      aResult.Append(char16_t(' '));
-    }
-  }
-}
-
-void
-nsCSSValueList::AppendToString(nsCSSPropertyID aProperty,
-                               nsAString& aResult) const
-{
-  if (aProperty == eCSSProperty_grid_template_columns ||
-      aProperty == eCSSProperty_grid_template_rows) {
-    AppendGridTemplateToString(this, aProperty, aResult);
-  } else {
-    AppendValueListToString(this, aProperty, aResult);
-  }
-}
-
 /* static */ bool
 nsCSSValueList::Equal(const nsCSSValueList* aList1,
                       const nsCSSValueList* aList2)
 {
   if (aList1 == aList2) {
     return true;
   }
 
@@ -2473,25 +1286,16 @@ nsCSSValueList_heap::SizeOfIncludingThis
 nsCSSValueSharedList::~nsCSSValueSharedList()
 {
   if (mHead) {
     NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
     delete mHead;
   }
 }
 
-void
-nsCSSValueSharedList::AppendToString(nsCSSPropertyID aProperty,
-                                     nsAString& aResult) const
-{
-  if (mHead) {
-    mHead->AppendToString(aProperty, aResult);
-  }
-}
-
 bool
 nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
 {
   return nsCSSValueList::Equal(mHead, aOther.mHead);
 }
 
 size_t
 nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
@@ -2521,58 +1325,16 @@ nsCSSRect::nsCSSRect(const nsCSSRect& aC
   MOZ_COUNT_CTOR(nsCSSRect);
 }
 
 nsCSSRect::~nsCSSRect()
 {
   MOZ_COUNT_DTOR(nsCSSRect);
 }
 
-void
-nsCSSRect::AppendToString(nsCSSPropertyID aProperty,
-                          nsAString& aResult) const
-{
-  MOZ_ASSERT(mTop.GetUnit() != eCSSUnit_Null &&
-             mTop.GetUnit() != eCSSUnit_Inherit &&
-             mTop.GetUnit() != eCSSUnit_Initial &&
-             mTop.GetUnit() != eCSSUnit_Unset,
-             "parser should have used a bare value");
-
-  if (eCSSProperty_border_image_slice == aProperty ||
-      eCSSProperty_border_image_width == aProperty ||
-      eCSSProperty_border_image_outset == aProperty) {
-    nsCSSPropertyID props[] = { aProperty, aProperty, aProperty, aProperty };
-    const nsCSSValue* values[] = { &mTop, &mRight, &mBottom, &mLeft };
-    nsCSSValue::AppendSidesShorthandToString(props, values,
-                                             aResult);
-  } else if (eCSSProperty_DOM == aProperty) {
-     NS_NAMED_LITERAL_STRING(space, " ");
-
-    mTop.AppendToString(aProperty, aResult);
-    aResult.Append(space);
-    mRight.AppendToString(aProperty, aResult);
-    aResult.Append(space);
-    mBottom.AppendToString(aProperty, aResult);
-    aResult.Append(space);
-    mLeft.AppendToString(aProperty, aResult);
-  } else {
-    NS_NAMED_LITERAL_STRING(comma, ", ");
-
-    aResult.AppendLiteral("rect(");
-    mTop.AppendToString(aProperty, aResult);
-    aResult.Append(comma);
-    mRight.AppendToString(aProperty, aResult);
-    aResult.Append(comma);
-    mBottom.AppendToString(aProperty, aResult);
-    aResult.Append(comma);
-    mLeft.AppendToString(aProperty, aResult);
-    aResult.Append(char16_t(')'));
-  }
-}
-
 void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
 {
   mTop = aValue;
   mRight = aValue;
   mBottom = aValue;
   mLeft = aValue;
 }
 
@@ -2599,27 +1361,16 @@ static_assert(eSideTop == 0 && eSideRigh
   &nsCSSRect::mTop,
   &nsCSSRect::mRight,
   &nsCSSRect::mBottom,
   &nsCSSRect::mLeft,
 };
 
 // --- nsCSSValuePair -----------------
 
-void
-nsCSSValuePair::AppendToString(nsCSSPropertyID aProperty,
-                               nsAString& aResult) const
-{
-  mXValue.AppendToString(aProperty, aResult);
-  if (mYValue.GetUnit() != eCSSUnit_Null) {
-    aResult.Append(char16_t(' '));
-    mYValue.AppendToString(aProperty, aResult);
-  }
-}
-
 size_t
 nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
   n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
   n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
   return n;
 }
@@ -2634,31 +1385,16 @@ nsCSSValuePair_heap::SizeOfIncludingThis
     n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
     n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
   }
   return n;
 }
 
 // --- nsCSSValueTriplet -----------------
 
-void
-nsCSSValueTriplet::AppendToString(nsCSSPropertyID aProperty,
-                                  nsAString& aResult) const
-{
-  mXValue.AppendToString(aProperty, aResult);
-  if (mYValue.GetUnit() != eCSSUnit_Null) {
-    aResult.Append(char16_t(' '));
-    mYValue.AppendToString(aProperty, aResult);
-    if (mZValue.GetUnit() != eCSSUnit_Null) {
-      aResult.Append(char16_t(' '));
-      mZValue.AppendToString(aProperty, aResult);
-    }
-  }
-}
-
 size_t
 nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   // Only measure it if it's unshared, to avoid double-counting.
   size_t n = 0;
   if (mRefCnt <= 1) {
     n += aMallocSizeOf(this);
     n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
@@ -2687,45 +1423,16 @@ nsCSSValuePairList::Clone() const
     dest = dest->mNext;
     src = src->mNext;
   }
 
   MOZ_ASSERT(result, "shouldn't return null; supposed to be infallible");
   return result;
 }
 
-void
-nsCSSValuePairList::AppendToString(nsCSSPropertyID aProperty,
-                                   nsAString& aResult) const
-{
-  const nsCSSValuePairList* item = this;
-  for (;;) {
-    MOZ_ASSERT(item->mXValue.GetUnit() != eCSSUnit_Null,
-               "unexpected null unit");
-    item->mXValue.AppendToString(aProperty, aResult);
-    if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
-        item->mXValue.GetUnit() != eCSSUnit_Initial &&
-        item->mXValue.GetUnit() != eCSSUnit_Unset &&
-        item->mYValue.GetUnit() != eCSSUnit_Null) {
-      aResult.Append(char16_t(' '));
-      item->mYValue.AppendToString(aProperty, aResult);
-    }
-    item = item->mNext;
-    if (!item)
-      break;
-
-    if (nsCSSProps::PropHasFlags(aProperty,
-                                 CSS_PROPERTY_VALUE_LIST_USES_COMMAS) ||
-        aProperty == eCSSProperty_clip_path ||
-        aProperty == eCSSProperty_shape_outside)
-      aResult.Append(char16_t(','));
-    aResult.Append(char16_t(' '));
-  }
-}
-
 /* static */ bool
 nsCSSValuePairList::Equal(const nsCSSValuePairList* aList1,
                           const nsCSSValuePairList* aList2)
 {
   if (aList1 == aList2) {
     return true;
   }
 
@@ -3364,58 +2071,16 @@ nsCSSValueFloatColor::GetColorValue(nsCS
 }
 
 bool
 nsCSSValueFloatColor::IsNonTransparentColor() const
 {
   return mAlpha > 0.0f;
 }
 
-void
-nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const
-{
-  // Similar to the rgb()/rgba() case in nsCSSValue::AppendToString. We omit the
-  // alpha component if it's equal to 1.0f (full opaque). Also, we try to
-  // preserve the author-specified function name, unless it's rgba()/hsla() and
-  // we're omitting the alpha component - then we use rgb()/hsl().
-  MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
-
-  bool showAlpha = (mAlpha != 1.0f);
-  bool isHSL = (aUnit == eCSSUnit_HSLColor ||
-                aUnit == eCSSUnit_HSLAColor);
-
-  if (isHSL) {
-    aResult.AppendLiteral("hsl");
-  } else {
-    aResult.AppendLiteral("rgb");
-  }
-  if (showAlpha && (aUnit == eCSSUnit_HSLAColor || aUnit == eCSSUnit_PercentageRGBAColor)) {
-    aResult.AppendLiteral("a(");
-  } else {
-    aResult.Append('(');
-  }
-  if (isHSL) {
-    aResult.AppendFloat(mComponent1 * 360.0f);
-    aResult.AppendLiteral(", ");
-  } else {
-    aResult.AppendFloat(mComponent1 * 100.0f);
-    aResult.AppendLiteral("%, ");
-  }
-  aResult.AppendFloat(mComponent2 * 100.0f);
-  aResult.AppendLiteral("%, ");
-  aResult.AppendFloat(mComponent3 * 100.0f);
-  if (showAlpha) {
-    aResult.AppendLiteral("%, ");
-    aResult.AppendFloat(mAlpha);
-    aResult.Append(')');
-  } else {
-    aResult.AppendLiteral("%)");
-  }
-}
-
 size_t
 nsCSSValueFloatColor::SizeOfIncludingThis(
                                       mozilla::MallocSizeOf aMallocSizeOf) const
 {
   // Only measure it if it's unshared, to avoid double-counting.
   size_t n = 0;
   if (mRefCnt <= 1) {
     n += aMallocSizeOf(this);
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -651,22 +651,16 @@ public:
   nsCSSValue&  operator=(nsCSSValue&& aCopy);
   bool        operator==(const nsCSSValue& aOther) const;
 
   bool operator!=(const nsCSSValue& aOther) const
   {
     return !(*this == aOther);
   }
 
-  /**
-   * Serialize |this| as a specified value for |aProperty| and append
-   * it to |aResult|.
-   */
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
-
   nsCSSUnit GetUnit() const { return mUnit; }
   bool      IsLengthUnit() const
     { return eCSSUnit_ViewportWidth <= mUnit && mUnit <= eCSSUnit_Pixel; }
   bool      IsLengthPercentCalcUnit() const
     { return IsLengthUnit() || mUnit == eCSSUnit_Percent || IsCalcUnit(); }
   /**
    * What the spec calls relative length units is, for us, split
    * between relative length units and pixel length units.
@@ -998,41 +992,23 @@ public:
     BufferFromString(const nsString& aValue);
 
   // Convert the given Ident value into AtomIdent.
   void AtomizeIdentValue();
 
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   static void
-  AppendSidesShorthandToString(const nsCSSPropertyID aProperties[],
-                               const nsCSSValue* aValues[],
-                               nsAString& aString);
-  static void
-  AppendBasicShapeRadiusToString(const nsCSSPropertyID aProperties[],
-                                 const nsCSSValue* aValues[],
-                                 nsAString& aResult);
-  static void
   AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult);
 
 private:
   static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
     return static_cast<char16_t*>(aBuffer->Data());
   }
 
-  void AppendPolygonToString(nsCSSPropertyID aProperty,
-                             nsAString& aResult) const;
-  void AppendPositionCoordinateToString(const nsCSSValue& aValue,
-                                        nsCSSPropertyID aProperty,
-                                        nsAString& aResult) const;
-  void AppendCircleOrEllipseToString(
-           nsCSSKeyword aFunctionId,
-           nsCSSPropertyID aProperty, nsAString& aResult) const;
-  void AppendBasicShapePositionToString(nsAString& aResult) const;
-  void AppendInsetToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
 protected:
   nsCSSUnit mUnit;
   union {
     int32_t    mInt;
     float      mFloat;
     // Note: the capacity of the buffer may exceed the length of the string.
     // If we're of a string type, mString is not null.
     nsStringBuffer* MOZ_OWNING_REF mString;
@@ -1146,17 +1122,16 @@ private:
 
 // Prefer nsCSSValue::Array for lists of fixed size.
 struct nsCSSValueList {
   nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
   ~nsCSSValueList();
 
   nsCSSValueList* Clone() const;  // makes a deep copy. Infallible.
   void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
 
   static bool Equal(const nsCSSValueList* aList1,
                     const nsCSSValueList* aList2);
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   nsCSSValue      mValue;
   nsCSSValueList* mNext;
@@ -1208,18 +1183,16 @@ struct nsCSSValueSharedList final {
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   ~nsCSSValueSharedList();
 
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
 
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
-
   bool operator==(nsCSSValueSharedList const& aOther) const;
   bool operator!=(const nsCSSValueSharedList& aOther) const
   { return !(*this == aOther); }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   nsCSSValueList* mHead;
 };
@@ -1248,18 +1221,16 @@ nsCSSValue::GetListValue() const
   }
 }
 
 struct nsCSSRect {
   nsCSSRect(void);
   nsCSSRect(const nsCSSRect& aCopy);
   ~nsCSSRect();
 
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
-
   bool operator==(const nsCSSRect& aOther) const {
     return mTop == aOther.mTop &&
            mRight == aOther.mRight &&
            mBottom == aOther.mBottom &&
            mLeft == aOther.mLeft;
   }
 
   bool operator!=(const nsCSSRect& aOther) const {
@@ -1389,18 +1360,16 @@ struct nsCSSValuePair {
     mYValue.Reset();
   }
 
   bool HasValue() const {
     return mXValue.GetUnit() != eCSSUnit_Null ||
            mYValue.GetUnit() != eCSSUnit_Null;
   }
 
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
-
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   nsCSSValue mXValue;
   nsCSSValue mYValue;
 };
 
 // nsCSSValuePair_heap differs from nsCSSValuePair only in being
 // refcounted.  It should not be necessary to use this class directly;
@@ -1480,18 +1449,16 @@ struct nsCSSValueTriplet {
     }
 
     bool HasValue() const {
         return mXValue.GetUnit() != eCSSUnit_Null ||
                mYValue.GetUnit() != eCSSUnit_Null ||
                mZValue.GetUnit() != eCSSUnit_Null;
     }
 
-    void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
-
     nsCSSValue mXValue;
     nsCSSValue mYValue;
     nsCSSValue mZValue;
 };
 
 // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
 // refcounted.  It should not be necessary to use this class directly;
 // it's an implementation detail of nsCSSValue.
@@ -1543,17 +1510,16 @@ nsCSSValue::GetTripletValue() const
 }
 
 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
 struct nsCSSValuePairList {
   nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
   ~nsCSSValuePairList();
 
   nsCSSValuePairList* Clone() const; // makes a deep copy. Infallible.
-  void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
 
   static bool Equal(const nsCSSValuePairList* aList1,
                     const nsCSSValuePairList* aList2);
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   nsCSSValue          mXValue;
   nsCSSValue          mYValue;
@@ -1864,18 +1830,16 @@ public:
 
   nscolor GetColorValue(nsCSSUnit aUnit) const;
   float Comp1() const { return mComponent1; }
   float Comp2() const { return mComponent2; }
   float Comp3() const { return mComponent3; }
   float Alpha() const { return mAlpha; }
   bool IsNonTransparentColor() const;
 
-  void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const;
-
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor)
 
 private:
   // The range of each component is.
   // [0, 1] for HSLColor and HSLAColor. mComponent1 for hue, mComponent2 for
   //                                    saturation, mComponent3 for lightness.