Bug 1420113 - Part 1: Move nsCSSCounterStyleRule to its own file. r?xidorn draft
authorCameron McCormack <cam@mcc.id.au>
Thu, 23 Nov 2017 18:04:26 +0800
changeset 703007 1b07573d80a0f7a6227a3bff1d3c6a4150310b19
parent 703006 0e8a3e4f9b179538216ffe6b8df29760508051e0
child 703008 e25297ecc757091b0ab4722f96ea0737c752bdbc
push id90663
push userbmo:cam@mcc.id.au
push dateFri, 24 Nov 2017 06:58:45 +0000
reviewersxidorn
bugs1420113
milestone59.0a1
Bug 1420113 - Part 1: Move nsCSSCounterStyleRule to its own file. r?xidorn MozReview-Commit-ID: 765dOTUOBEQ
layout/style/moz.build
layout/style/nsCSSCounterStyleRule.cpp
layout/style/nsCSSRules.cpp
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -207,16 +207,17 @@ UNIFIED_SOURCES += [
     'IncrementalClearCOMRuleArray.cpp',
     'LayerAnimationInfo.cpp',
     'Loader.cpp',
     'MediaList.cpp',
     'MediaQueryList.cpp',
     'nsAnimationManager.cpp',
     'nsComputedDOMStyle.cpp',
     'nsCSSAnonBoxes.cpp',
+    'nsCSSCounterStyleRule.cpp',
     'nsCSSDataBlock.cpp',
     'nsCSSKeywords.cpp',
     'nsCSSParser.cpp',
     'nsCSSProps.cpp',
     'nsCSSPseudoClasses.cpp',
     'nsCSSRuleProcessor.cpp',
     'nsCSSRules.cpp',
     'nsCSSScanner.cpp',
new file mode 100644
--- /dev/null
+++ b/layout/style/nsCSSCounterStyleRule.cpp
@@ -0,0 +1,462 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* a Gecko @counter-style rule */
+
+#include "nsCSSCounterStyleRule.h"
+
+#include "mozAutoDocUpdate.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/dom/CSSCounterStyleRuleBinding.h"
+#include "nsCSSParser.h"
+#include "nsStyleUtil.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+nsCSSCounterStyleRule::nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy)
+  : Rule(aCopy)
+  , mName(aCopy.mName)
+  , mGeneration(aCopy.mGeneration)
+{
+  for (size_t i = 0; i < ArrayLength(mValues); ++i) {
+    mValues[i] = aCopy.mValues[i];
+  }
+}
+
+nsCSSCounterStyleRule::~nsCSSCounterStyleRule()
+{
+}
+
+/* virtual */ already_AddRefed<css::Rule>
+nsCSSCounterStyleRule::Clone() const
+{
+  RefPtr<css::Rule> clone = new nsCSSCounterStyleRule(*this);
+  return clone.forget();
+}
+
+nsCSSCounterStyleRule::Getter const
+nsCSSCounterStyleRule::kGetters[] = {
+#define CSS_COUNTER_DESC(name_, method_) &nsCSSCounterStyleRule::Get##method_,
+#include "nsCSSCounterDescList.h"
+#undef CSS_COUNTER_DESC
+};
+
+NS_IMPL_ADDREF_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
+NS_IMPL_RELEASE_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
+
+// QueryInterface implementation for nsCSSCounterStyleRule
+// If this ever gets its own cycle-collection bits, reevaluate our IsCCLeaf
+// implementation.
+NS_INTERFACE_MAP_BEGIN(nsCSSCounterStyleRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
+NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+
+bool
+nsCSSCounterStyleRule::IsCCLeaf() const
+{
+  return Rule::IsCCLeaf();
+}
+
+#ifdef DEBUG
+void
+nsCSSCounterStyleRule::List(FILE* out, int32_t aIndent) const
+{
+  nsCString baseInd, descInd;
+  for (int32_t indent = aIndent; --indent >= 0; ) {
+    baseInd.AppendLiteral("  ");
+  }
+  descInd = baseInd;
+  descInd.AppendLiteral("  ");
+
+  nsDependentAtomString name(mName);
+  fprintf_stderr(out, "%s@counter-style %s (rev.%u) {\n",
+                 baseInd.get(), NS_ConvertUTF16toUTF8(name).get(),
+                 mGeneration);
+  // TODO
+  fprintf_stderr(out, "%s}\n", baseInd.get());
+}
+#endif
+
+/* virtual */ int32_t
+nsCSSCounterStyleRule::GetType() const
+{
+  return Rule::COUNTER_STYLE_RULE;
+}
+
+uint16_t
+nsCSSCounterStyleRule::Type() const
+{
+  return nsIDOMCSSRule::COUNTER_STYLE_RULE;
+}
+
+void
+nsCSSCounterStyleRule::GetCssTextImpl(nsAString& aCssText) const
+{
+  aCssText.AssignLiteral(u"@counter-style ");
+  nsDependentAtomString name(mName);
+  nsStyleUtil::AppendEscapedCSSIdent(name, aCssText);
+  aCssText.AppendLiteral(u" {\n");
+  for (nsCSSCounterDesc id = nsCSSCounterDesc(0);
+       id < eCSSCounterDesc_COUNT;
+       id = nsCSSCounterDesc(id + 1)) {
+    if (mValues[id].GetUnit() != eCSSUnit_Null) {
+      nsAutoString tmp;
+      // This is annoying.  We want to be a const method, but kGetters stores
+      // XPCOM method pointers, which aren't const methods.  The thing is,
+      // none of those mutate "this".  So it's OK to cast away const here.
+      (const_cast<nsCSSCounterStyleRule*>(this)->*kGetters[id])(tmp);
+      aCssText.AppendLiteral(u"  ");
+      AppendASCIItoUTF16(nsCSSProps::GetStringValue(id), aCssText);
+      aCssText.AppendLiteral(u": ");
+      aCssText.Append(tmp);
+      aCssText.AppendLiteral(u";\n");
+    }
+  }
+  aCssText.AppendLiteral(u"}");
+}
+
+// nsIDOMCSSCounterStyleRule methods
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetName(nsAString& aName)
+{
+  aName.Truncate();
+  nsDependentAtomString name(mName);
+  nsStyleUtil::AppendEscapedCSSIdent(name, aName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::SetName(const nsAString& aName)
+{
+  nsCSSParser parser;
+  if (RefPtr<nsAtom> name = parser.ParseCounterStyleName(aName, nullptr)) {
+    nsIDocument* doc = GetDocument();
+    MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
+
+    mName = name;
+
+    if (StyleSheet* sheet = GetStyleSheet()) {
+      if (sheet->IsGecko()) {
+        sheet->AsGecko()->SetModifiedByChildRule();
+      }
+      if (doc) {
+        doc->StyleRuleChanged(sheet, this);
+      }
+    }
+  }
+  return NS_OK;
+}
+
+int32_t
+nsCSSCounterStyleRule::GetSystem() const
+{
+  const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
+  switch (system.GetUnit()) {
+    case eCSSUnit_Enumerated:
+      return system.GetIntValue();
+    case eCSSUnit_Pair:
+      return system.GetPairValue().mXValue.GetIntValue();
+    default:
+      return NS_STYLE_COUNTER_SYSTEM_SYMBOLIC;
+  }
+}
+
+const nsCSSValue&
+nsCSSCounterStyleRule::GetSystemArgument() const
+{
+  const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
+  MOZ_ASSERT(system.GetUnit() == eCSSUnit_Pair,
+             "Invalid system value");
+  return system.GetPairValue().mYValue;
+}
+
+void
+nsCSSCounterStyleRule::SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValue)
+{
+  MOZ_ASSERT(aDescID >= 0 && aDescID < eCSSCounterDesc_COUNT,
+             "descriptor ID out of range");
+
+  nsIDocument* doc = GetDocument();
+  MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
+
+  mValues[aDescID] = aValue;
+  mGeneration++;
+
+  if (StyleSheet* sheet = GetStyleSheet()) {
+    if (sheet->IsGecko()) {
+      sheet->AsGecko()->SetModifiedByChildRule();
+    }
+    if (doc) {
+      doc->StyleRuleChanged(sheet, this);
+    }
+  }
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetSystem(nsAString& aSystem)
+{
+  const nsCSSValue& value = GetDesc(eCSSCounterDesc_System);
+  if (value.GetUnit() == eCSSUnit_Null) {
+    aSystem.Truncate();
+    return NS_OK;
+  }
+
+  aSystem = NS_ConvertASCIItoUTF16(nsCSSProps::ValueToKeyword(
+          GetSystem(), nsCSSProps::kCounterSystemKTable));
+  if (value.GetUnit() == eCSSUnit_Pair) {
+    aSystem.Append(' ');
+    GetSystemArgument().AppendToString(eCSSProperty_UNKNOWN, aSystem);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetSymbols(nsAString& aSymbols)
+{
+  const nsCSSValue& value = GetDesc(eCSSCounterDesc_Symbols);
+
+  aSymbols.Truncate();
+  if (value.GetUnit() == eCSSUnit_List) {
+    for (const nsCSSValueList* item = value.GetListValue();
+         item; item = item->mNext) {
+      item->mValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
+      if (item->mNext) {
+        aSymbols.Append(' ');
+      }
+    }
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetAdditiveSymbols(nsAString& aSymbols)
+{
+  const nsCSSValue& value = GetDesc(eCSSCounterDesc_AdditiveSymbols);
+
+  aSymbols.Truncate();
+  if (value.GetUnit() == eCSSUnit_PairList) {
+    for (const nsCSSValuePairList* item = value.GetPairListValue();
+         item; item = item->mNext) {
+      item->mXValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
+      aSymbols.Append(' ');
+      item->mYValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
+      if (item->mNext) {
+        aSymbols.AppendLiteral(", ");
+      }
+    }
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetRange(nsAString& aRange)
+{
+  const nsCSSValue& value = GetDesc(eCSSCounterDesc_Range);
+
+  switch (value.GetUnit()) {
+    case eCSSUnit_Auto:
+      aRange.AssignLiteral(u"auto");
+      break;
+
+    case eCSSUnit_PairList:
+      aRange.Truncate();
+      for (const nsCSSValuePairList* item = value.GetPairListValue();
+          item; item = item->mNext) {
+        const nsCSSValue& lower = item->mXValue;
+        const nsCSSValue& upper = item->mYValue;
+        if (lower.GetUnit() == eCSSUnit_Enumerated) {
+          NS_ASSERTION(lower.GetIntValue() ==
+                       NS_STYLE_COUNTER_RANGE_INFINITE,
+                       "Unrecognized keyword");
+          aRange.AppendLiteral("infinite");
+        } else {
+          aRange.AppendInt(lower.GetIntValue());
+        }
+        aRange.Append(' ');
+        if (upper.GetUnit() == eCSSUnit_Enumerated) {
+          NS_ASSERTION(upper.GetIntValue() ==
+                       NS_STYLE_COUNTER_RANGE_INFINITE,
+                       "Unrecognized keyword");
+          aRange.AppendLiteral("infinite");
+        } else {
+          aRange.AppendInt(upper.GetIntValue());
+        }
+        if (item->mNext) {
+          aRange.AppendLiteral(", ");
+        }
+      }
+      break;
+
+    default:
+      aRange.Truncate();
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetSpeakAs(nsAString& aSpeakAs)
+{
+  const nsCSSValue& value = GetDesc(eCSSCounterDesc_SpeakAs);
+
+  switch (value.GetUnit()) {
+    case eCSSUnit_Enumerated:
+      switch (value.GetIntValue()) {
+        case NS_STYLE_COUNTER_SPEAKAS_BULLETS:
+          aSpeakAs.AssignLiteral(u"bullets");
+          break;
+        case NS_STYLE_COUNTER_SPEAKAS_NUMBERS:
+          aSpeakAs.AssignLiteral(u"numbers");
+          break;
+        case NS_STYLE_COUNTER_SPEAKAS_WORDS:
+          aSpeakAs.AssignLiteral(u"words");
+          break;
+        case NS_STYLE_COUNTER_SPEAKAS_SPELL_OUT:
+          aSpeakAs.AssignLiteral(u"spell-out");
+          break;
+        default:
+          NS_NOTREACHED("Unknown speech synthesis");
+      }
+      break;
+
+    case eCSSUnit_Auto:
+    case eCSSUnit_AtomIdent:
+      aSpeakAs.Truncate();
+      value.AppendToString(eCSSProperty_UNKNOWN, aSpeakAs);
+      break;
+
+    case eCSSUnit_Null:
+      aSpeakAs.Truncate();
+      break;
+
+    default:
+      NS_NOTREACHED("Unknown speech synthesis");
+      aSpeakAs.Truncate();
+  }
+  return NS_OK;
+}
+
+nsresult
+nsCSSCounterStyleRule::GetDescriptor(nsCSSCounterDesc aDescID,
+                                     nsAString& aValue)
+{
+  NS_ASSERTION(aDescID == eCSSCounterDesc_Negative ||
+               aDescID == eCSSCounterDesc_Prefix ||
+               aDescID == eCSSCounterDesc_Suffix ||
+               aDescID == eCSSCounterDesc_Pad ||
+               aDescID == eCSSCounterDesc_Fallback,
+               "Unexpected descriptor");
+  const nsCSSValue& value = GetDesc(aDescID);
+  aValue.Truncate();
+  if (value.GetUnit() != eCSSUnit_Null) {
+    value.AppendToString(eCSSProperty_UNKNOWN, aValue);
+  }
+  return NS_OK;
+}
+
+#define CSS_COUNTER_DESC_GETTER(name_)                    \
+NS_IMETHODIMP                                             \
+nsCSSCounterStyleRule::Get##name_(nsAString& a##name_)    \
+{                                                         \
+  return GetDescriptor(eCSSCounterDesc_##name_, a##name_);\
+}
+CSS_COUNTER_DESC_GETTER(Negative)
+CSS_COUNTER_DESC_GETTER(Prefix)
+CSS_COUNTER_DESC_GETTER(Suffix)
+CSS_COUNTER_DESC_GETTER(Pad)
+CSS_COUNTER_DESC_GETTER(Fallback)
+#undef CSS_COUNTER_DESC_GETTER
+
+/* static */ bool
+nsCSSCounterStyleRule::CheckDescValue(int32_t aSystem,
+                                      nsCSSCounterDesc aDescID,
+                                      const nsCSSValue& aValue)
+{
+  switch (aDescID) {
+    case eCSSCounterDesc_System:
+      if (aValue.GetUnit() != eCSSUnit_Pair) {
+        return aValue.GetIntValue() == aSystem;
+      } else {
+        return aValue.GetPairValue().mXValue.GetIntValue() == aSystem;
+      }
+
+    case eCSSCounterDesc_Symbols:
+      switch (aSystem) {
+        case NS_STYLE_COUNTER_SYSTEM_NUMERIC:
+        case NS_STYLE_COUNTER_SYSTEM_ALPHABETIC:
+          // for these two system, the list must contain at least 2 elements
+          return aValue.GetListValue()->mNext;
+        case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
+          // for extends system, no symbols should be set
+          return false;
+        default:
+          return true;
+      }
+
+    case eCSSCounterDesc_AdditiveSymbols:
+      switch (aSystem) {
+        case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
+          return false;
+        default:
+          return true;
+      }
+
+    default:
+      return true;
+  }
+}
+
+nsresult
+nsCSSCounterStyleRule::SetDescriptor(nsCSSCounterDesc aDescID,
+                                     const nsAString& aValue)
+{
+  nsCSSParser parser;
+  nsCSSValue value;
+  nsIURI* baseURL = nullptr;
+  nsIPrincipal* principal = nullptr;
+  if (StyleSheet* sheet = GetStyleSheet()) {
+    baseURL = sheet->GetBaseURI();
+    principal = sheet->Principal();
+  }
+  if (parser.ParseCounterDescriptor(aDescID, aValue, nullptr,
+                                    baseURL, principal, value)) {
+    if (CheckDescValue(GetSystem(), aDescID, value)) {
+      SetDesc(aDescID, value);
+    }
+  }
+  return NS_OK;
+}
+
+#define CSS_COUNTER_DESC_SETTER(name_)                        \
+NS_IMETHODIMP                                                 \
+nsCSSCounterStyleRule::Set##name_(const nsAString& a##name_)  \
+{                                                             \
+  return SetDescriptor(eCSSCounterDesc_##name_, a##name_);    \
+}
+CSS_COUNTER_DESC_SETTER(System)
+CSS_COUNTER_DESC_SETTER(Symbols)
+CSS_COUNTER_DESC_SETTER(AdditiveSymbols)
+CSS_COUNTER_DESC_SETTER(Negative)
+CSS_COUNTER_DESC_SETTER(Prefix)
+CSS_COUNTER_DESC_SETTER(Suffix)
+CSS_COUNTER_DESC_SETTER(Range)
+CSS_COUNTER_DESC_SETTER(Pad)
+CSS_COUNTER_DESC_SETTER(Fallback)
+CSS_COUNTER_DESC_SETTER(SpeakAs)
+#undef CSS_COUNTER_DESC_SETTER
+
+/* virtual */ size_t
+nsCSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  return aMallocSizeOf(this);
+}
+
+/* virtual */ JSObject*
+nsCSSCounterStyleRule::WrapObject(JSContext* aCx,
+                                  JS::Handle<JSObject*> aGivenProto)
+{
+  return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto);
+}
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -2,17 +2,16 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
 
 #include "nsCSSRules.h"
-#include "nsCSSCounterStyleRule.h"
 #include "nsCSSFontFaceRule.h"
 
 #include "mozilla/Attributes.h"
 
 #include "nsCSSValue.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/css/ImportRule.h"
@@ -34,21 +33,19 @@
 #include "nsError.h"
 #include "nsStyleUtil.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "nsCSSParser.h"
 #include "nsDOMClassInfoID.h"
 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
 #include "mozilla/dom/CSSFontFaceRuleBinding.h"
 #include "mozilla/dom/CSSFontFeatureValuesRuleBinding.h"
-#include "mozilla/dom/CSSCounterStyleRuleBinding.h"
 #include "StyleRule.h"
 #include "nsFont.h"
 #include "nsIURI.h"
-#include "mozAutoDocUpdate.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // base class for all rule types in a CSS style sheet
 
@@ -2111,456 +2108,8 @@ CSSSupportsRule::SizeOfIncludingThis(Mal
 {
   size_t n = aMallocSizeOf(this);
   n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
   n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
   return n;
 }
 
 } // namespace mozilla
-
-// -------------------------------------------
-// nsCSSCounterStyleRule
-//
-
-nsCSSCounterStyleRule::nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy)
-  : Rule(aCopy)
-  , mName(aCopy.mName)
-  , mGeneration(aCopy.mGeneration)
-{
-  for (size_t i = 0; i < ArrayLength(mValues); ++i) {
-    mValues[i] = aCopy.mValues[i];
-  }
-}
-
-nsCSSCounterStyleRule::~nsCSSCounterStyleRule()
-{
-}
-
-/* virtual */ already_AddRefed<css::Rule>
-nsCSSCounterStyleRule::Clone() const
-{
-  RefPtr<css::Rule> clone = new nsCSSCounterStyleRule(*this);
-  return clone.forget();
-}
-
-nsCSSCounterStyleRule::Getter const
-nsCSSCounterStyleRule::kGetters[] = {
-#define CSS_COUNTER_DESC(name_, method_) &nsCSSCounterStyleRule::Get##method_,
-#include "nsCSSCounterDescList.h"
-#undef CSS_COUNTER_DESC
-};
-
-NS_IMPL_ADDREF_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
-
-// QueryInterface implementation for nsCSSCounterStyleRule
-// If this ever gets its own cycle-collection bits, reevaluate our IsCCLeaf
-// implementation.
-NS_INTERFACE_MAP_BEGIN(nsCSSCounterStyleRule)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
-
-bool
-nsCSSCounterStyleRule::IsCCLeaf() const
-{
-  return Rule::IsCCLeaf();
-}
-
-#ifdef DEBUG
-void
-nsCSSCounterStyleRule::List(FILE* out, int32_t aIndent) const
-{
-  nsCString baseInd, descInd;
-  for (int32_t indent = aIndent; --indent >= 0; ) {
-    baseInd.AppendLiteral("  ");
-  }
-  descInd = baseInd;
-  descInd.AppendLiteral("  ");
-
-  nsDependentAtomString name(mName);
-  fprintf_stderr(out, "%s@counter-style %s (rev.%u) {\n",
-                 baseInd.get(), NS_ConvertUTF16toUTF8(name).get(),
-                 mGeneration);
-  // TODO
-  fprintf_stderr(out, "%s}\n", baseInd.get());
-}
-#endif
-
-/* virtual */ int32_t
-nsCSSCounterStyleRule::GetType() const
-{
-  return Rule::COUNTER_STYLE_RULE;
-}
-
-uint16_t
-nsCSSCounterStyleRule::Type() const
-{
-  return nsIDOMCSSRule::COUNTER_STYLE_RULE;
-}
-
-void
-nsCSSCounterStyleRule::GetCssTextImpl(nsAString& aCssText) const
-{
-  aCssText.AssignLiteral(u"@counter-style ");
-  nsDependentAtomString name(mName);
-  nsStyleUtil::AppendEscapedCSSIdent(name, aCssText);
-  aCssText.AppendLiteral(u" {\n");
-  for (nsCSSCounterDesc id = nsCSSCounterDesc(0);
-       id < eCSSCounterDesc_COUNT;
-       id = nsCSSCounterDesc(id + 1)) {
-    if (mValues[id].GetUnit() != eCSSUnit_Null) {
-      nsAutoString tmp;
-      // This is annoying.  We want to be a const method, but kGetters stores
-      // XPCOM method pointers, which aren't const methods.  The thing is,
-      // none of those mutate "this".  So it's OK to cast away const here.
-      (const_cast<nsCSSCounterStyleRule*>(this)->*kGetters[id])(tmp);
-      aCssText.AppendLiteral(u"  ");
-      AppendASCIItoUTF16(nsCSSProps::GetStringValue(id), aCssText);
-      aCssText.AppendLiteral(u": ");
-      aCssText.Append(tmp);
-      aCssText.AppendLiteral(u";\n");
-    }
-  }
-  aCssText.AppendLiteral(u"}");
-}
-
-// nsIDOMCSSCounterStyleRule methods
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetName(nsAString& aName)
-{
-  aName.Truncate();
-  nsDependentAtomString name(mName);
-  nsStyleUtil::AppendEscapedCSSIdent(name, aName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::SetName(const nsAString& aName)
-{
-  nsCSSParser parser;
-  if (RefPtr<nsAtom> name = parser.ParseCounterStyleName(aName, nullptr)) {
-    nsIDocument* doc = GetDocument();
-    MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
-
-    mName = name;
-
-    if (StyleSheet* sheet = GetStyleSheet()) {
-      if (sheet->IsGecko()) {
-        sheet->AsGecko()->SetModifiedByChildRule();
-      }
-      if (doc) {
-        doc->StyleRuleChanged(sheet, this);
-      }
-    }
-  }
-  return NS_OK;
-}
-
-int32_t
-nsCSSCounterStyleRule::GetSystem() const
-{
-  const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
-  switch (system.GetUnit()) {
-    case eCSSUnit_Enumerated:
-      return system.GetIntValue();
-    case eCSSUnit_Pair:
-      return system.GetPairValue().mXValue.GetIntValue();
-    default:
-      return NS_STYLE_COUNTER_SYSTEM_SYMBOLIC;
-  }
-}
-
-const nsCSSValue&
-nsCSSCounterStyleRule::GetSystemArgument() const
-{
-  const nsCSSValue& system = GetDesc(eCSSCounterDesc_System);
-  MOZ_ASSERT(system.GetUnit() == eCSSUnit_Pair,
-             "Invalid system value");
-  return system.GetPairValue().mYValue;
-}
-
-void
-nsCSSCounterStyleRule::SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValue)
-{
-  MOZ_ASSERT(aDescID >= 0 && aDescID < eCSSCounterDesc_COUNT,
-             "descriptor ID out of range");
-
-  nsIDocument* doc = GetDocument();
-  MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
-
-  mValues[aDescID] = aValue;
-  mGeneration++;
-
-  if (StyleSheet* sheet = GetStyleSheet()) {
-    if (sheet->IsGecko()) {
-      sheet->AsGecko()->SetModifiedByChildRule();
-    }
-    if (doc) {
-      doc->StyleRuleChanged(sheet, this);
-    }
-  }
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetSystem(nsAString& aSystem)
-{
-  const nsCSSValue& value = GetDesc(eCSSCounterDesc_System);
-  if (value.GetUnit() == eCSSUnit_Null) {
-    aSystem.Truncate();
-    return NS_OK;
-  }
-
-  aSystem = NS_ConvertASCIItoUTF16(nsCSSProps::ValueToKeyword(
-          GetSystem(), nsCSSProps::kCounterSystemKTable));
-  if (value.GetUnit() == eCSSUnit_Pair) {
-    aSystem.Append(' ');
-    GetSystemArgument().AppendToString(eCSSProperty_UNKNOWN, aSystem);
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetSymbols(nsAString& aSymbols)
-{
-  const nsCSSValue& value = GetDesc(eCSSCounterDesc_Symbols);
-
-  aSymbols.Truncate();
-  if (value.GetUnit() == eCSSUnit_List) {
-    for (const nsCSSValueList* item = value.GetListValue();
-         item; item = item->mNext) {
-      item->mValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
-      if (item->mNext) {
-        aSymbols.Append(' ');
-      }
-    }
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetAdditiveSymbols(nsAString& aSymbols)
-{
-  const nsCSSValue& value = GetDesc(eCSSCounterDesc_AdditiveSymbols);
-
-  aSymbols.Truncate();
-  if (value.GetUnit() == eCSSUnit_PairList) {
-    for (const nsCSSValuePairList* item = value.GetPairListValue();
-         item; item = item->mNext) {
-      item->mXValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
-      aSymbols.Append(' ');
-      item->mYValue.AppendToString(eCSSProperty_UNKNOWN, aSymbols);
-      if (item->mNext) {
-        aSymbols.AppendLiteral(", ");
-      }
-    }
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetRange(nsAString& aRange)
-{
-  const nsCSSValue& value = GetDesc(eCSSCounterDesc_Range);
-
-  switch (value.GetUnit()) {
-    case eCSSUnit_Auto:
-      aRange.AssignLiteral(u"auto");
-      break;
-
-    case eCSSUnit_PairList:
-      aRange.Truncate();
-      for (const nsCSSValuePairList* item = value.GetPairListValue();
-          item; item = item->mNext) {
-        const nsCSSValue& lower = item->mXValue;
-        const nsCSSValue& upper = item->mYValue;
-        if (lower.GetUnit() == eCSSUnit_Enumerated) {
-          NS_ASSERTION(lower.GetIntValue() ==
-                       NS_STYLE_COUNTER_RANGE_INFINITE,
-                       "Unrecognized keyword");
-          aRange.AppendLiteral("infinite");
-        } else {
-          aRange.AppendInt(lower.GetIntValue());
-        }
-        aRange.Append(' ');
-        if (upper.GetUnit() == eCSSUnit_Enumerated) {
-          NS_ASSERTION(upper.GetIntValue() ==
-                       NS_STYLE_COUNTER_RANGE_INFINITE,
-                       "Unrecognized keyword");
-          aRange.AppendLiteral("infinite");
-        } else {
-          aRange.AppendInt(upper.GetIntValue());
-        }
-        if (item->mNext) {
-          aRange.AppendLiteral(", ");
-        }
-      }
-      break;
-
-    default:
-      aRange.Truncate();
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCSSCounterStyleRule::GetSpeakAs(nsAString& aSpeakAs)
-{
-  const nsCSSValue& value = GetDesc(eCSSCounterDesc_SpeakAs);
-
-  switch (value.GetUnit()) {
-    case eCSSUnit_Enumerated:
-      switch (value.GetIntValue()) {
-        case NS_STYLE_COUNTER_SPEAKAS_BULLETS:
-          aSpeakAs.AssignLiteral(u"bullets");
-          break;
-        case NS_STYLE_COUNTER_SPEAKAS_NUMBERS:
-          aSpeakAs.AssignLiteral(u"numbers");
-          break;
-        case NS_STYLE_COUNTER_SPEAKAS_WORDS:
-          aSpeakAs.AssignLiteral(u"words");
-          break;
-        case NS_STYLE_COUNTER_SPEAKAS_SPELL_OUT:
-          aSpeakAs.AssignLiteral(u"spell-out");
-          break;
-        default:
-          NS_NOTREACHED("Unknown speech synthesis");
-      }
-      break;
-
-    case eCSSUnit_Auto:
-    case eCSSUnit_AtomIdent:
-      aSpeakAs.Truncate();
-      value.AppendToString(eCSSProperty_UNKNOWN, aSpeakAs);
-      break;
-
-    case eCSSUnit_Null:
-      aSpeakAs.Truncate();
-      break;
-
-    default:
-      NS_NOTREACHED("Unknown speech synthesis");
-      aSpeakAs.Truncate();
-  }
-  return NS_OK;
-}
-
-nsresult
-nsCSSCounterStyleRule::GetDescriptor(nsCSSCounterDesc aDescID,
-                                     nsAString& aValue)
-{
-  NS_ASSERTION(aDescID == eCSSCounterDesc_Negative ||
-               aDescID == eCSSCounterDesc_Prefix ||
-               aDescID == eCSSCounterDesc_Suffix ||
-               aDescID == eCSSCounterDesc_Pad ||
-               aDescID == eCSSCounterDesc_Fallback,
-               "Unexpected descriptor");
-  const nsCSSValue& value = GetDesc(aDescID);
-  aValue.Truncate();
-  if (value.GetUnit() != eCSSUnit_Null) {
-    value.AppendToString(eCSSProperty_UNKNOWN, aValue);
-  }
-  return NS_OK;
-}
-
-#define CSS_COUNTER_DESC_GETTER(name_)                    \
-NS_IMETHODIMP                                             \
-nsCSSCounterStyleRule::Get##name_(nsAString& a##name_)    \
-{                                                         \
-  return GetDescriptor(eCSSCounterDesc_##name_, a##name_);\
-}
-CSS_COUNTER_DESC_GETTER(Negative)
-CSS_COUNTER_DESC_GETTER(Prefix)
-CSS_COUNTER_DESC_GETTER(Suffix)
-CSS_COUNTER_DESC_GETTER(Pad)
-CSS_COUNTER_DESC_GETTER(Fallback)
-#undef CSS_COUNTER_DESC_GETTER
-
-/* static */ bool
-nsCSSCounterStyleRule::CheckDescValue(int32_t aSystem,
-                                      nsCSSCounterDesc aDescID,
-                                      const nsCSSValue& aValue)
-{
-  switch (aDescID) {
-    case eCSSCounterDesc_System:
-      if (aValue.GetUnit() != eCSSUnit_Pair) {
-        return aValue.GetIntValue() == aSystem;
-      } else {
-        return aValue.GetPairValue().mXValue.GetIntValue() == aSystem;
-      }
-
-    case eCSSCounterDesc_Symbols:
-      switch (aSystem) {
-        case NS_STYLE_COUNTER_SYSTEM_NUMERIC:
-        case NS_STYLE_COUNTER_SYSTEM_ALPHABETIC:
-          // for these two system, the list must contain at least 2 elements
-          return aValue.GetListValue()->mNext;
-        case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
-          // for extends system, no symbols should be set
-          return false;
-        default:
-          return true;
-      }
-
-    case eCSSCounterDesc_AdditiveSymbols:
-      switch (aSystem) {
-        case NS_STYLE_COUNTER_SYSTEM_EXTENDS:
-          return false;
-        default:
-          return true;
-      }
-
-    default:
-      return true;
-  }
-}
-
-nsresult
-nsCSSCounterStyleRule::SetDescriptor(nsCSSCounterDesc aDescID,
-                                     const nsAString& aValue)
-{
-  nsCSSParser parser;
-  nsCSSValue value;
-  nsIURI* baseURL = nullptr;
-  nsIPrincipal* principal = nullptr;
-  if (StyleSheet* sheet = GetStyleSheet()) {
-    baseURL = sheet->GetBaseURI();
-    principal = sheet->Principal();
-  }
-  if (parser.ParseCounterDescriptor(aDescID, aValue, nullptr,
-                                    baseURL, principal, value)) {
-    if (CheckDescValue(GetSystem(), aDescID, value)) {
-      SetDesc(aDescID, value);
-    }
-  }
-  return NS_OK;
-}
-
-#define CSS_COUNTER_DESC_SETTER(name_)                        \
-NS_IMETHODIMP                                                 \
-nsCSSCounterStyleRule::Set##name_(const nsAString& a##name_)  \
-{                                                             \
-  return SetDescriptor(eCSSCounterDesc_##name_, a##name_);    \
-}
-CSS_COUNTER_DESC_SETTER(System)
-CSS_COUNTER_DESC_SETTER(Symbols)
-CSS_COUNTER_DESC_SETTER(AdditiveSymbols)
-CSS_COUNTER_DESC_SETTER(Negative)
-CSS_COUNTER_DESC_SETTER(Prefix)
-CSS_COUNTER_DESC_SETTER(Suffix)
-CSS_COUNTER_DESC_SETTER(Range)
-CSS_COUNTER_DESC_SETTER(Pad)
-CSS_COUNTER_DESC_SETTER(Fallback)
-CSS_COUNTER_DESC_SETTER(SpeakAs)
-#undef CSS_COUNTER_DESC_SETTER
-
-/* virtual */ size_t
-nsCSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-{
-  return aMallocSizeOf(this);
-}
-
-/* virtual */ JSObject*
-nsCSSCounterStyleRule::WrapObject(JSContext* aCx,
-                                  JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto);
-}