Bug 1525955 - Include anon boxes in CSSPseudoElementType, to remove ComputedStyle::mPseudoTag. r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 19 Feb 2019 13:44:33 +0000
changeset 459880 1fc71d46c09a20908e6d016af6312ac1682d101f
parent 459879 e74ee65c18a6a836ed52088b1542e30a8ebf0955
child 459881 533f35feb9eb271cf4e9a41854f02f1725b81131
push id35577
push userbtara@mozilla.com
push dateTue, 19 Feb 2019 17:33:29 +0000
treeherdermozilla-central@510bae6520ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1525955
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525955 - Include anon boxes in CSSPseudoElementType, to remove ComputedStyle::mPseudoTag. r=heycam This is more consistent with what the Rust bits of the style system do, and removes a pointer from ComputedStyle which is always nice. This also aligns the Rust bits with the C++ bits re. not treating xul pseudos as anonymous boxes. See the comment in nsTreeStyleCache.cpp regarding those. Can't wait for XUL trees to die. Depends on D19001 Differential Revision: https://phabricator.services.mozilla.com/D19002
dom/animation/AnimationTarget.h
dom/animation/CSSPseudoElement.cpp
dom/animation/CSSPseudoElement.h
dom/animation/EffectCompositor.cpp
dom/animation/EffectCompositor.h
dom/animation/EffectSet.cpp
dom/animation/EffectSet.h
dom/animation/KeyframeEffect.cpp
dom/animation/KeyframeEffect.h
dom/animation/KeyframeUtils.cpp
dom/animation/KeyframeUtils.h
dom/animation/PseudoElementHashEntry.h
dom/base/Document.cpp
dom/base/Element.cpp
dom/base/Element.h
dom/base/nsDOMMutationObserver.cpp
dom/base/nsDOMWindowUtils.cpp
dom/smil/SMILAnimationController.cpp
dom/xml/nsXMLElement.cpp
layout/base/RestyleManager.cpp
layout/base/RestyleManager.h
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/base/nsGenConList.cpp
layout/base/nsGenConList.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresContext.cpp
layout/forms/nsButtonFrameRenderer.cpp
layout/forms/nsColorControlFrame.cpp
layout/forms/nsColorControlFrame.h
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFieldSetFrame.cpp
layout/forms/nsHTMLButtonControlFrame.cpp
layout/forms/nsMeterFrame.cpp
layout/forms/nsNumberControlFrame.cpp
layout/forms/nsNumberControlFrame.h
layout/forms/nsProgressFrame.cpp
layout/forms/nsProgressFrame.h
layout/forms/nsRangeFrame.cpp
layout/forms/nsRangeFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/ColumnSetWrapperFrame.cpp
layout/generic/ReflowInput.cpp
layout/generic/RubyUtils.h
layout/generic/TextOverflow.cpp
layout/generic/ViewportFrame.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsFirstLetterFrame.cpp
layout/generic/nsFlexContainerFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrame.h
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsIFrameInlines.h
layout/generic/nsImageFrame.cpp
layout/generic/nsInlineFrame.cpp
layout/generic/nsPlaceholderFrame.cpp
layout/generic/nsRubyContentFrame.cpp
layout/generic/nsTextFrame.cpp
layout/inspector/InspectorUtils.cpp
layout/mathml/nsMathMLFrame.cpp
layout/painting/nsCSSRendering.cpp
layout/style/AnimationCollection.cpp
layout/style/AnimationCollection.h
layout/style/AnimationCommon.h
layout/style/CSSStyleRule.cpp
layout/style/CachedInheritingStyles.cpp
layout/style/CachedInheritingStyles.h
layout/style/ComputedStyle.cpp
layout/style/ComputedStyle.h
layout/style/GeckoBindings.cpp
layout/style/GeckoBindings.h
layout/style/PseudoStyleType.h
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/StyleAnimationValue.h
layout/style/moz.build
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsCSSAnonBoxes.cpp
layout/style/nsCSSAnonBoxes.h
layout/style/nsCSSPseudoElements.cpp
layout/style/nsCSSPseudoElements.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsHTMLCSSStyleSheet.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableFrame.cpp
layout/xul/tree/nsTreeStyleCache.cpp
servo/components/style/gecko/pseudo_element.rs
servo/components/style/gecko/pseudo_element_definition.mako.rs
servo/components/style/gecko/regen_atoms.py
servo/components/style/properties/cascade.rs
servo/components/style/properties/gecko.mako.rs
servo/components/style/properties/properties.mako.rs
servo/ports/geckolib/glue.rs
servo/ports/geckolib/tests/size_of.rs
xpcom/ds/StaticAtoms.py
--- a/dom/animation/AnimationTarget.h
+++ b/dom/animation/AnimationTarget.h
@@ -14,48 +14,48 @@
 
 namespace mozilla {
 
 namespace dom {
 class Element;
 }  // namespace dom
 
 struct OwningAnimationTarget {
-  OwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
+  OwningAnimationTarget(dom::Element* aElement, PseudoStyleType aType)
       : mElement(aElement), mPseudoType(aType) {}
 
   explicit OwningAnimationTarget(dom::Element* aElement) : mElement(aElement) {}
 
   bool operator==(const OwningAnimationTarget& aOther) const {
     return mElement == aOther.mElement && mPseudoType == aOther.mPseudoType;
   }
 
   // mElement represents the parent element of a pseudo-element, not the
   // generated content element.
   RefPtr<dom::Element> mElement;
-  CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
+  PseudoStyleType mPseudoType = PseudoStyleType::NotPseudo;
 };
 
 struct NonOwningAnimationTarget {
   NonOwningAnimationTarget() = default;
 
-  NonOwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
+  NonOwningAnimationTarget(dom::Element* aElement, PseudoStyleType aType)
       : mElement(aElement), mPseudoType(aType) {}
 
   explicit NonOwningAnimationTarget(const OwningAnimationTarget& aOther)
       : mElement(aOther.mElement), mPseudoType(aOther.mPseudoType) {}
 
   bool operator==(const NonOwningAnimationTarget& aOther) const {
     return mElement == aOther.mElement && mPseudoType == aOther.mPseudoType;
   }
 
   // mElement represents the parent element of a pseudo-element, not the
   // generated content element.
   dom::Element* MOZ_NON_OWNING_REF mElement = nullptr;
-  CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
+  PseudoStyleType mPseudoType = PseudoStyleType::NotPseudo;
 };
 
 // Helper functions for cycle-collecting Maybe<OwningAnimationTarget>
 inline void ImplCycleCollectionTraverse(
     nsCycleCollectionTraversalCallback& aCallback,
     Maybe<OwningAnimationTarget>& aTarget, const char* aName,
     uint32_t aFlags = 0) {
   if (aTarget) {
--- a/dom/animation/CSSPseudoElement.cpp
+++ b/dom/animation/CSSPseudoElement.cpp
@@ -13,23 +13,22 @@
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CSSPseudoElement, mParentElement)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CSSPseudoElement, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CSSPseudoElement, Release)
 
-CSSPseudoElement::CSSPseudoElement(Element* aElement,
-                                   CSSPseudoElementType aType)
+CSSPseudoElement::CSSPseudoElement(Element* aElement, PseudoStyleType aType)
     : mParentElement(aElement), mPseudoType(aType) {
   MOZ_ASSERT(aElement);
-  MOZ_ASSERT(aType == CSSPseudoElementType::after ||
-                 aType == CSSPseudoElementType::before,
-             "Unexpected Pseudo Type");
+  MOZ_ASSERT(
+      aType == PseudoStyleType::after || aType == PseudoStyleType::before,
+      "Unexpected Pseudo Type");
 }
 
 CSSPseudoElement::~CSSPseudoElement() {
   // Element might have been unlinked already, so we have to do null check.
   if (mParentElement) {
     mParentElement->DeleteProperty(
         GetCSSPseudoElementPropertyAtom(mPseudoType));
   }
@@ -66,17 +65,17 @@ already_AddRefed<Animation> CSSPseudoEle
     ErrorResult& aError) {
   Nullable<ElementOrCSSPseudoElement> target;
   target.SetValue().SetAsCSSPseudoElement() = this;
   return Element::Animate(target, aContext, aKeyframes, aOptions, aError);
 }
 
 /* static */ already_AddRefed<CSSPseudoElement>
 CSSPseudoElement::GetCSSPseudoElement(Element* aElement,
-                                      CSSPseudoElementType aType) {
+                                      PseudoStyleType aType) {
   if (!aElement) {
     return nullptr;
   }
 
   nsAtom* propName = CSSPseudoElement::GetCSSPseudoElementPropertyAtom(aType);
   RefPtr<CSSPseudoElement> pseudo =
       static_cast<CSSPseudoElement*>(aElement->GetProperty(propName));
   if (pseudo) {
@@ -92,22 +91,22 @@ CSSPseudoElement::GetCSSPseudoElement(El
   if (NS_FAILED(rv)) {
     NS_WARNING("SetProperty failed");
     return nullptr;
   }
   return pseudo.forget();
 }
 
 /* static */ nsAtom* CSSPseudoElement::GetCSSPseudoElementPropertyAtom(
-    CSSPseudoElementType aType) {
+    PseudoStyleType aType) {
   switch (aType) {
-    case CSSPseudoElementType::before:
+    case PseudoStyleType::before:
       return nsGkAtoms::cssPseudoElementBeforeProperty;
 
-    case CSSPseudoElementType::after:
+    case PseudoStyleType::after:
       return nsGkAtoms::cssPseudoElementAfterProperty;
 
     default:
       MOZ_ASSERT_UNREACHABLE(
           "Should not try to get CSSPseudoElement "
           "other than ::before or ::after");
       return nullptr;
   }
--- a/dom/animation/CSSPseudoElement.h
+++ b/dom/animation/CSSPseudoElement.h
@@ -32,17 +32,17 @@ class CSSPseudoElement final : public ns
   virtual ~CSSPseudoElement();
 
  public:
   ParentObject GetParentObject() const;
 
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
-  CSSPseudoElementType GetType() const { return mPseudoType; }
+  PseudoStyleType GetType() const { return mPseudoType; }
   void GetType(nsString& aRetVal) const {
     MOZ_ASSERT(nsCSSPseudoElements::GetPseudoAtom(mPseudoType),
                "All pseudo-types allowed by this class should have a"
                " corresponding atom");
     // Our atoms use one colon and we would like to return two colons syntax
     // for the returned pseudo type string, so serialize this to the
     // non-deprecated two colon syntax.
     aRetVal.Assign(char16_t(':'));
@@ -61,27 +61,27 @@ class CSSPseudoElement final : public ns
       const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
       ErrorResult& aError);
 
   // Given an element:pseudoType pair, returns the CSSPseudoElement stored as a
   // property on |aElement|. If there is no CSSPseudoElement for the specified
   // pseudo-type on element, a new CSSPseudoElement will be created and stored
   // on the element.
   static already_AddRefed<CSSPseudoElement> GetCSSPseudoElement(
-      Element* aElement, CSSPseudoElementType aType);
+      Element* aElement, PseudoStyleType aType);
 
  private:
   // Only ::before and ::after are supported.
-  CSSPseudoElement(Element* aElement, CSSPseudoElementType aType);
+  CSSPseudoElement(Element* aElement, PseudoStyleType aType);
 
-  static nsAtom* GetCSSPseudoElementPropertyAtom(CSSPseudoElementType aType);
+  static nsAtom* GetCSSPseudoElementPropertyAtom(PseudoStyleType aType);
 
   // mParentElement needs to be an owning reference since if script is holding
   // on to the pseudo-element, it needs to continue to be able to refer to
   // the parent element.
   RefPtr<Element> mParentElement;
-  CSSPseudoElementType mPseudoType;
+  PseudoStyleType mPseudoType;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_CSSPseudoElement_h
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -205,17 +205,17 @@ bool FindAnimationsForCompositor(
   if (aMatches && foundRunningAnimations) {
     aMatches->Sort(AnimationPtrComparator<RefPtr<dom::Animation>>());
   }
 
   return foundRunningAnimations;
 }
 
 void EffectCompositor::RequestRestyle(dom::Element* aElement,
-                                      CSSPseudoElementType aPseudoType,
+                                      PseudoStyleType aPseudoType,
                                       RestyleType aRestyleType,
                                       CascadeLevel aCascadeLevel) {
   if (!mPresContext) {
     // Pres context will be null after the effect compositor is disconnected.
     return;
   }
 
   // Ignore animations on orphaned elements and elements in documents without
@@ -252,17 +252,17 @@ void EffectCompositor::RequestRestyle(do
     EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
     if (effectSet) {
       effectSet->UpdateAnimationGeneration(mPresContext);
     }
   }
 }
 
 void EffectCompositor::PostRestyleForAnimation(dom::Element* aElement,
-                                               CSSPseudoElementType aPseudoType,
+                                               PseudoStyleType aPseudoType,
                                                CascadeLevel aCascadeLevel) {
   if (!mPresContext) {
     return;
   }
 
   dom::Element* element = GetElementToRestyle(aElement, aPseudoType);
   if (!element) {
     return;
@@ -313,40 +313,40 @@ void EffectCompositor::PostRestyleForThr
   }
 }
 
 void EffectCompositor::ClearRestyleRequestsFor(Element* aElement) {
   MOZ_ASSERT(aElement);
 
   auto& elementsToRestyle = mElementsToRestyle[CascadeLevel::Animations];
 
-  CSSPseudoElementType pseudoType = aElement->GetPseudoElementType();
-  if (pseudoType == CSSPseudoElementType::NotPseudo) {
-    PseudoElementHashEntry::KeyType notPseudoKey = {
-        aElement, CSSPseudoElementType::NotPseudo};
-    PseudoElementHashEntry::KeyType beforePseudoKey = {
-        aElement, CSSPseudoElementType::before};
-    PseudoElementHashEntry::KeyType afterPseudoKey = {
-        aElement, CSSPseudoElementType::after};
+  PseudoStyleType pseudoType = aElement->GetPseudoElementType();
+  if (pseudoType == PseudoStyleType::NotPseudo) {
+    PseudoElementHashEntry::KeyType notPseudoKey = {aElement,
+                                                    PseudoStyleType::NotPseudo};
+    PseudoElementHashEntry::KeyType beforePseudoKey = {aElement,
+                                                       PseudoStyleType::before};
+    PseudoElementHashEntry::KeyType afterPseudoKey = {aElement,
+                                                      PseudoStyleType::after};
 
     elementsToRestyle.Remove(notPseudoKey);
     elementsToRestyle.Remove(beforePseudoKey);
     elementsToRestyle.Remove(afterPseudoKey);
-  } else if (pseudoType == CSSPseudoElementType::before ||
-             pseudoType == CSSPseudoElementType::after) {
+  } else if (pseudoType == PseudoStyleType::before ||
+             pseudoType == PseudoStyleType::after) {
     Element* parentElement = aElement->GetParentElement();
     MOZ_ASSERT(parentElement);
     PseudoElementHashEntry::KeyType key = {parentElement, pseudoType};
     elementsToRestyle.Remove(key);
   }
 }
 
-void EffectCompositor::UpdateEffectProperties(
-    const ComputedStyle* aStyle, Element* aElement,
-    CSSPseudoElementType aPseudoType) {
+void EffectCompositor::UpdateEffectProperties(const ComputedStyle* aStyle,
+                                              Element* aElement,
+                                              PseudoStyleType aPseudoType) {
   EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effectSet) {
     return;
   }
 
   // Style context (Gecko) or computed values (Stylo) change might cause CSS
   // cascade level, e.g removing !important, so we should update the cascading
   // result.
@@ -371,17 +371,17 @@ class EffectCompositeOrderComparator {
         a->GetAnimation()->HasLowerCompositeOrderThan(*b->GetAnimation()) !=
             b->GetAnimation()->HasLowerCompositeOrderThan(*a->GetAnimation()));
     return a->GetAnimation()->HasLowerCompositeOrderThan(*b->GetAnimation());
   }
 };
 }  // namespace
 
 bool EffectCompositor::GetServoAnimationRule(
-    const dom::Element* aElement, CSSPseudoElementType aPseudoType,
+    const dom::Element* aElement, PseudoStyleType aPseudoType,
     CascadeLevel aCascadeLevel,
     RawServoAnimationValueMapBorrowedMut aAnimationValues) {
   MOZ_ASSERT(aAnimationValues);
   MOZ_ASSERT(mPresContext && mPresContext->IsDynamic(),
              "Should not be in print preview");
   // Gecko_GetAnimationRule should have already checked this
   MOZ_ASSERT(nsContentUtils::GetPresShellForContent(aElement),
              "Should not be trying to run animations on elements in documents"
@@ -412,26 +412,26 @@ bool EffectCompositor::GetServoAnimation
 
   MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 
   return true;
 }
 
 /* static */ dom::Element* EffectCompositor::GetElementToRestyle(
-    dom::Element* aElement, CSSPseudoElementType aPseudoType) {
-  if (aPseudoType == CSSPseudoElementType::NotPseudo) {
+    dom::Element* aElement, PseudoStyleType aPseudoType) {
+  if (aPseudoType == PseudoStyleType::NotPseudo) {
     return aElement;
   }
 
-  if (aPseudoType == CSSPseudoElementType::before) {
+  if (aPseudoType == PseudoStyleType::before) {
     return nsLayoutUtils::GetBeforePseudo(aElement);
   }
 
-  if (aPseudoType == CSSPseudoElementType::after) {
+  if (aPseudoType == PseudoStyleType::after) {
     return nsLayoutUtils::GetAfterPseudo(aElement);
   }
 
   MOZ_ASSERT_UNREACHABLE(
       "Should not try to get the element to restyle for "
       "a pseudo other that :before or :after");
   return nullptr;
 }
@@ -474,65 +474,64 @@ EffectCompositor::GetAnimationsForCompos
   }
 
   for (KeyframeEffect* effect : *effects) {
     effect->SetIsRunningOnCompositor(aProperty, false);
   }
 }
 
 /* static */ void EffectCompositor::MaybeUpdateCascadeResults(
-    Element* aElement, CSSPseudoElementType aPseudoType) {
+    Element* aElement, PseudoStyleType aPseudoType) {
   EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effects || !effects->CascadeNeedsUpdate()) {
     return;
   }
 
   UpdateCascadeResults(*effects, aElement, aPseudoType);
 
   MOZ_ASSERT(!effects->CascadeNeedsUpdate(), "Failed to update cascade state");
 }
 
 /* static */ Maybe<NonOwningAnimationTarget>
 EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame) {
   // Always return the same object to benefit from return-value optimization.
   Maybe<NonOwningAnimationTarget> result;
 
-  CSSPseudoElementType pseudoType = aFrame->Style()->GetPseudoType();
+  PseudoStyleType pseudoType = aFrame->Style()->GetPseudoType();
 
-  if (pseudoType != CSSPseudoElementType::NotPseudo &&
-      pseudoType != CSSPseudoElementType::before &&
-      pseudoType != CSSPseudoElementType::after) {
+  if (pseudoType != PseudoStyleType::NotPseudo &&
+      pseudoType != PseudoStyleType::before &&
+      pseudoType != PseudoStyleType::after) {
     return result;
   }
 
   nsIContent* content = aFrame->GetContent();
   if (!content) {
     return result;
   }
 
-  if (pseudoType == CSSPseudoElementType::before ||
-      pseudoType == CSSPseudoElementType::after) {
+  if (pseudoType == PseudoStyleType::before ||
+      pseudoType == PseudoStyleType::after) {
     content = content->GetParent();
     if (!content) {
       return result;
     }
   }
 
   if (!content->IsElement()) {
     return result;
   }
 
   result.emplace(content->AsElement(), pseudoType);
 
   return result;
 }
 
 /* static */ nsCSSPropertyIDSet EffectCompositor::GetOverriddenProperties(
-    EffectSet& aEffectSet, Element* aElement,
-    CSSPseudoElementType aPseudoType) {
+    EffectSet& aEffectSet, Element* aElement, PseudoStyleType aPseudoType) {
   MOZ_ASSERT(aElement, "Should have an element to get style data from");
 
   nsCSSPropertyIDSet result;
 
   Element* elementToRestyle = GetElementToRestyle(aElement, aPseudoType);
   if (!elementToRestyle) {
     return result;
   }
@@ -564,18 +563,17 @@ EffectCompositor::GetAnimationElementAnd
   }
 
   Servo_GetProperties_Overriding_Animation(elementToRestyle, &propertiesToTrack,
                                            &result);
   return result;
 }
 
 /* static */ void EffectCompositor::UpdateCascadeResults(
-    EffectSet& aEffectSet, Element* aElement,
-    CSSPseudoElementType aPseudoType) {
+    EffectSet& aEffectSet, Element* aElement, PseudoStyleType aPseudoType) {
   MOZ_ASSERT(EffectSet::GetEffectSet(aElement, aPseudoType) == &aEffectSet,
              "Effect set should correspond to the specified (pseudo-)element");
   if (aEffectSet.IsEmpty()) {
     aEffectSet.MarkCascadeUpdated();
     return;
   }
 
   // Get a list of effects sorted by composite order.
@@ -823,30 +821,30 @@ bool EffectCompositor::PreTraverseInSubt
       elementSet.Clear();
     }
   }
 
   return foundElementsNeedingRestyle;
 }
 
 bool EffectCompositor::PreTraverse(dom::Element* aElement,
-                                   CSSPseudoElementType aPseudoType) {
+                                   PseudoStyleType aPseudoType) {
   MOZ_ASSERT(NS_IsMainThread());
 
   // If |aElement|'s document does not have a pres shell, e.g. it is document
   // without a browsing context such as we might get from an XMLHttpRequest, we
   // should not run animations on it.
   if (!nsContentUtils::GetPresShellForContent(aElement)) {
     return false;
   }
 
   bool found = false;
-  if (aPseudoType != CSSPseudoElementType::NotPseudo &&
-      aPseudoType != CSSPseudoElementType::before &&
-      aPseudoType != CSSPseudoElementType::after) {
+  if (aPseudoType != PseudoStyleType::NotPseudo &&
+      aPseudoType != PseudoStyleType::before &&
+      aPseudoType != PseudoStyleType::after) {
     return found;
   }
 
   AutoRestore<bool> guard(mIsInPreTraverse);
   mIsInPreTraverse = true;
 
   PseudoElementHashEntry::KeyType key = {aElement, aPseudoType};
 
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -82,25 +82,25 @@ class EffectCompositor {
     // configuration of the animation.
     Layer
   };
 
   // Notifies the compositor that the animation rule for the specified
   // (pseudo-)element at the specified cascade level needs to be updated.
   // The specified steps taken to update the animation rule depend on
   // |aRestyleType| whose values are described above.
-  void RequestRestyle(dom::Element* aElement, CSSPseudoElementType aPseudoType,
+  void RequestRestyle(dom::Element* aElement, PseudoStyleType aPseudoType,
                       RestyleType aRestyleType, CascadeLevel aCascadeLevel);
 
   // Schedule an animation restyle. This is called automatically by
   // RequestRestyle when necessary. However, it is exposed here since we also
   // need to perform this step when triggering transitions *without* also
   // invalidating the animation style rule (which RequestRestyle would do).
   void PostRestyleForAnimation(dom::Element* aElement,
-                               CSSPseudoElementType aPseudoType,
+                               PseudoStyleType aPseudoType,
                                CascadeLevel aCascadeLevel);
 
   // Posts an animation restyle for any elements whose animation style rule
   // is out of date but for which an animation restyle has not yet been
   // posted because updates on the main thread are throttled.
   void PostRestyleForThrottledAnimations();
 
   // Clear all pending restyle requests for the given (pseudo-) element (and its
@@ -108,25 +108,25 @@ class EffectCompositor {
   void ClearRestyleRequestsFor(dom::Element* aElement);
 
   // Called when computed style on the specified (pseudo-) element might
   // have changed so that any context-sensitive values stored within
   // animation effects (e.g. em-based endpoints used in keyframe effects)
   // can be re-resolved to computed values.
   void UpdateEffectProperties(const ComputedStyle* aStyle,
                               dom::Element* aElement,
-                              CSSPseudoElementType aPseudoType);
+                              PseudoStyleType aPseudoType);
 
   // Get animation rule for stylo. This is an equivalent of GetAnimationRule
   // and will be called from servo side.
   // The animation rule is stored in |RawServoAnimationValueMapBorrowed|.
   // We need to be careful while doing any modification because it may cause
   // some thread-safe issues.
   bool GetServoAnimationRule(
-      const dom::Element* aElement, CSSPseudoElementType aPseudoType,
+      const dom::Element* aElement, PseudoStyleType aPseudoType,
       CascadeLevel aCascadeLevel,
       RawServoAnimationValueMapBorrowedMut aAnimationValues);
 
   bool HasPendingStyleUpdates() const;
 
   static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
                                          nsCSSPropertyID aProperty);
 
@@ -139,33 +139,33 @@ class EffectCompositor {
   // Update animation cascade results for the specified (pseudo-)element
   // but only if we have marked the cascade as needing an update due a
   // the change in the set of effects or a change in one of the effects'
   // "in effect" state.
   //
   // This method does NOT detect if other styles that apply above the
   // animation level of the cascade have changed.
   static void MaybeUpdateCascadeResults(dom::Element* aElement,
-                                        CSSPseudoElementType aPseudoType);
+                                        PseudoStyleType aPseudoType);
 
   // Update the mPropertiesWithImportantRules and
   // mPropertiesForAnimationsLevel members of the given EffectSet, and also
   // request any restyles required by changes to the cascade result.
   //
   // NOTE: This can be expensive so we should only call it if styles that apply
   // above the animation level of the cascade might have changed. For all
   // other cases we should call MaybeUpdateCascadeResults.
   //
   // This is typically reserved for internal callers but is public here since
   // when we detect changes to the cascade on the Servo side we can't call
   // MarkCascadeNeedsUpdate during the traversal so instead we call this as part
   // of a follow-up sequential task.
   static void UpdateCascadeResults(EffectSet& aEffectSet,
                                    dom::Element* aElement,
-                                   CSSPseudoElementType aPseudoType);
+                                   PseudoStyleType aPseudoType);
 
   // Helper to fetch the corresponding element and pseudo-type from a frame.
   //
   // For frames corresponding to pseudo-elements, the returned element is the
   // element on which we store the animations (i.e. the EffectSet and/or
   // AnimationCollection), *not* the generated content.
   //
   // Returns an empty result when a suitable element cannot be found including
@@ -183,47 +183,47 @@ class EffectCompositor {
   // Do a bunch of stuff that we should avoid doing during the parallel
   // traversal (e.g. changing member variables) for all elements that we expect
   // to restyle on the next traversal.
   //
   // Returns true if there are elements needing a restyle for animation.
   bool PreTraverse(ServoTraversalFlags aFlags);
 
   // Similar to the above but only for the (pseudo-)element.
-  bool PreTraverse(dom::Element* aElement, CSSPseudoElementType aPseudoType);
+  bool PreTraverse(dom::Element* aElement, PseudoStyleType aPseudoType);
 
   // Similar to the above but for all elements in the subtree rooted
   // at aElement.
   bool PreTraverseInSubtree(ServoTraversalFlags aFlags, dom::Element* aRoot);
 
   // Returns the target element for restyling.
   //
   // If |aPseudoType| is ::after or ::before, returns the generated content
   // element of which |aElement| is the parent. If |aPseudoType| is any other
-  // pseudo type (other thant CSSPseudoElementType::NotPseudo) returns nullptr.
+  // pseudo type (other than PseudoStyleType::NotPseudo) returns nullptr.
   // Otherwise, returns |aElement|.
   static dom::Element* GetElementToRestyle(dom::Element* aElement,
-                                           CSSPseudoElementType aPseudoType);
+                                           PseudoStyleType aPseudoType);
 
   // Returns true if any type of compositor animations on |aFrame| allow
   // runnning on the compositor.
   // Sets the reason in |aWarning| if the result is false.
   static bool AllowCompositorAnimationsOnFrame(
       const nsIFrame* aFrame,
       AnimationPerformanceWarning::Type& aWarning /* out */);
 
  private:
   ~EffectCompositor() = default;
 
   // Get the properties in |aEffectSet| that we are able to animate on the
   // compositor but which are also specified at a higher level in the cascade
   // than the animations level.
   static nsCSSPropertyIDSet GetOverriddenProperties(
       EffectSet& aEffectSet, dom::Element* aElement,
-      CSSPseudoElementType aPseudoType);
+      PseudoStyleType aPseudoType);
 
   static nsPresContext* GetPresContext(dom::Element* aElement);
 
   nsPresContext* mPresContext;
 
   // Elements with a pending animation restyle. The associated bool value is
   // true if a pending animation restyle has also been dispatched. For
   // animations that can be throttled, we will add an entry to the hashtable to
--- a/dom/animation/EffectSet.cpp
+++ b/dom/animation/EffectSet.cpp
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #include "EffectSet.h"
 #include "mozilla/dom/Element.h"  // For Element
 #include "mozilla/RestyleManager.h"
-#include "nsCSSPseudoElements.h"         // For CSSPseudoElementType
+#include "nsCSSPseudoElements.h"         // For PseudoStyleType
 #include "nsCycleCollectionNoteChild.h"  // For CycleCollectionNoteChild
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 
 namespace mozilla {
 
 /* static */ void EffectSet::PropertyDtor(void* aObject, nsAtom* aPropertyName,
                                           void* aPropertyValue, void* aData) {
@@ -28,18 +28,18 @@ namespace mozilla {
 
 void EffectSet::Traverse(nsCycleCollectionTraversalCallback& aCallback) {
   for (auto iter = mEffects.Iter(); !iter.Done(); iter.Next()) {
     CycleCollectionNoteChild(aCallback, iter.Get()->GetKey(),
                              "EffectSet::mEffects[]", aCallback.Flags());
   }
 }
 
-/* static */ EffectSet* EffectSet::GetEffectSet(
-    const dom::Element* aElement, CSSPseudoElementType aPseudoType) {
+/* static */ EffectSet* EffectSet::GetEffectSet(const dom::Element* aElement,
+                                                PseudoStyleType aPseudoType) {
   if (!aElement->MayHaveAnimations()) {
     return nullptr;
   }
 
   nsAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
   return static_cast<EffectSet*>(aElement->GetProperty(propName));
 }
 
@@ -50,17 +50,17 @@ void EffectSet::Traverse(nsCycleCollecti
   if (!target) {
     return nullptr;
   }
 
   return GetEffectSet(target->mElement, target->mPseudoType);
 }
 
 /* static */ EffectSet* EffectSet::GetOrCreateEffectSet(
-    dom::Element* aElement, CSSPseudoElementType aPseudoType) {
+    dom::Element* aElement, PseudoStyleType aPseudoType) {
   EffectSet* effectSet = GetEffectSet(aElement, aPseudoType);
   if (effectSet) {
     return effectSet;
   }
 
   nsAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
   effectSet = new EffectSet();
 
@@ -74,18 +74,18 @@ void EffectSet::Traverse(nsCycleCollecti
     return nullptr;
   }
 
   aElement->SetMayHaveAnimations();
 
   return effectSet;
 }
 
-/* static */ void EffectSet::DestroyEffectSet(
-    dom::Element* aElement, CSSPseudoElementType aPseudoType) {
+/* static */ void EffectSet::DestroyEffectSet(dom::Element* aElement,
+                                              PseudoStyleType aPseudoType) {
   nsAtom* propName = GetEffectSetPropertyAtom(aPseudoType);
   EffectSet* effectSet =
       static_cast<EffectSet*>(aElement->GetProperty(propName));
   if (!effectSet) {
     return;
   }
 
   MOZ_ASSERT(!effectSet->IsBeingEnumerated(),
@@ -105,25 +105,25 @@ void EffectSet::UpdateAnimationGeneratio
       nsGkAtoms::animationEffectsProperty,
       nsGkAtoms::animationEffectsForBeforeProperty,
       nsGkAtoms::animationEffectsForAfterProperty, nullptr};
 
   return effectSetPropertyAtoms;
 }
 
 /* static */ nsAtom* EffectSet::GetEffectSetPropertyAtom(
-    CSSPseudoElementType aPseudoType) {
+    PseudoStyleType aPseudoType) {
   switch (aPseudoType) {
-    case CSSPseudoElementType::NotPseudo:
+    case PseudoStyleType::NotPseudo:
       return nsGkAtoms::animationEffectsProperty;
 
-    case CSSPseudoElementType::before:
+    case PseudoStyleType::before:
       return nsGkAtoms::animationEffectsForBeforeProperty;
 
-    case CSSPseudoElementType::after:
+    case PseudoStyleType::after:
       return nsGkAtoms::animationEffectsForAfterProperty;
 
     default:
       MOZ_ASSERT_UNREACHABLE(
           "Should not try to get animation effects for "
           "a pseudo other that :before or :after");
       return nullptr;
   }
--- a/dom/animation/EffectSet.h
+++ b/dom/animation/EffectSet.h
@@ -18,17 +18,17 @@
 class nsPresContext;
 
 namespace mozilla {
 
 namespace dom {
 class Element;
 }  // namespace dom
 
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 
 // A wrapper around a hashset of AnimationEffect objects to handle
 // storing the set as a property of an element.
 class EffectSet {
  public:
   EffectSet()
       : mCascadeNeedsUpdate(false),
         mAnimationGeneration(0)
@@ -53,22 +53,22 @@ class EffectSet {
   }
   static void PropertyDtor(void* aObject, nsAtom* aPropertyName,
                            void* aPropertyValue, void* aData);
 
   // Methods for supporting cycle-collection
   void Traverse(nsCycleCollectionTraversalCallback& aCallback);
 
   static EffectSet* GetEffectSet(const dom::Element* aElement,
-                                 CSSPseudoElementType aPseudoType);
+                                 PseudoStyleType aPseudoType);
   static EffectSet* GetEffectSet(const nsIFrame* aFrame);
   static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
-                                         CSSPseudoElementType aPseudoType);
+                                         PseudoStyleType aPseudoType);
   static void DestroyEffectSet(dom::Element* aElement,
-                               CSSPseudoElementType aPseudoType);
+                               PseudoStyleType aPseudoType);
 
   void AddEffect(dom::KeyframeEffect& aEffect);
   void RemoveEffect(dom::KeyframeEffect& aEffect);
 
   void SetMayHaveOpacityAnimation() { mMayHaveOpacityAnim = true; }
   bool MayHaveOpacityAnimation() const { return mMayHaveOpacityAnim; }
   void SetMayHaveTransformAnimation() { mMayHaveTransformAnim = true; }
   bool MayHaveTransformAnimation() const { return mMayHaveTransformAnim; }
@@ -184,17 +184,17 @@ class EffectSet {
   nsCSSPropertyIDSet& PropertiesForAnimationsLevel() {
     return mPropertiesForAnimationsLevel;
   }
   nsCSSPropertyIDSet PropertiesForAnimationsLevel() const {
     return mPropertiesForAnimationsLevel;
   }
 
  private:
-  static nsAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType);
+  static nsAtom* GetEffectSetPropertyAtom(PseudoStyleType aPseudoType);
 
   OwningEffectSet mEffects;
 
   // Refresh driver timestamp from the moment when the animations which produce
   // overflow change hints in this effect set were last updated.
 
   // This is used for animations whose main-thread restyling is throttled either
   // because they are running on the compositor or because they are not visible.
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -23,17 +23,17 @@
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/TypeTraits.h"
 #include "Layers.h"              // For Layer
 #include "nsComputedDOMStyle.h"  // nsComputedDOMStyle::GetComputedStyle
 #include "nsContentUtils.h"
 #include "nsCSSPropertyIDSet.h"
 #include "nsCSSProps.h"             // For nsCSSProps::PropHasFlags
-#include "nsCSSPseudoElements.h"    // For CSSPseudoElementType
+#include "nsCSSPseudoElements.h"    // For PseudoStyleType
 #include "nsDOMMutationObserver.h"  // For nsAutoAnimationMutationBatch
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsRefreshDriver.h"
 
 namespace mozilla {
 
@@ -776,17 +776,17 @@ already_AddRefed<ComputedStyle> Keyframe
   if (!GetRenderedDocument()) {
     return nullptr;
   }
 
   MOZ_ASSERT(mTarget,
              "Should only have a document when we have a target element");
 
   nsAtom* pseudo =
-      mTarget->mPseudoType < CSSPseudoElementType::Count
+      PseudoStyle::IsPseudoElement(mTarget->mPseudoType)
           ? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
           : nullptr;
 
   OwningAnimationTarget kungfuDeathGrip(mTarget->mElement,
                                         mTarget->mPseudoType);
 
   return aFlushType == Flush::Style
              ? nsComputedDOMStyle::GetComputedStyle(mTarget->mElement, pseudo)
@@ -861,24 +861,24 @@ void DumpAnimationProperties(
 void KeyframeEffect::GetTarget(
     Nullable<OwningElementOrCSSPseudoElement>& aRv) const {
   if (!mTarget) {
     aRv.SetNull();
     return;
   }
 
   switch (mTarget->mPseudoType) {
-    case CSSPseudoElementType::before:
-    case CSSPseudoElementType::after:
+    case PseudoStyleType::before:
+    case PseudoStyleType::after:
       aRv.SetValue().SetAsCSSPseudoElement() =
           CSSPseudoElement::GetCSSPseudoElement(mTarget->mElement,
                                                 mTarget->mPseudoType);
       break;
 
-    case CSSPseudoElementType::NotPseudo:
+    case PseudoStyleType::NotPseudo:
       aRv.SetValue().SetAsElement() = mTarget->mElement;
       break;
 
     default:
       MOZ_ASSERT_UNREACHABLE("Animation of unsupported pseudo-type");
       aRv.SetNull();
   }
 }
@@ -1308,23 +1308,23 @@ nsIFrame* KeyframeEffect::GetStyleFrame(
 }
 
 nsIFrame* KeyframeEffect::GetPrimaryFrame() const {
   nsIFrame* frame = nullptr;
   if (!mTarget) {
     return frame;
   }
 
-  if (mTarget->mPseudoType == CSSPseudoElementType::before) {
+  if (mTarget->mPseudoType == PseudoStyleType::before) {
     frame = nsLayoutUtils::GetBeforeFrame(mTarget->mElement);
-  } else if (mTarget->mPseudoType == CSSPseudoElementType::after) {
+  } else if (mTarget->mPseudoType == PseudoStyleType::after) {
     frame = nsLayoutUtils::GetAfterFrame(mTarget->mElement);
   } else {
     frame = mTarget->mElement->GetPrimaryFrame();
-    MOZ_ASSERT(mTarget->mPseudoType == CSSPseudoElementType::NotPseudo,
+    MOZ_ASSERT(mTarget->mPseudoType == PseudoStyleType::NotPseudo,
                "unknown mTarget->mPseudoType");
   }
 
   return frame;
 }
 
 Document* KeyframeEffect::GetRenderedDocument() const {
   if (!mTarget) {
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -34,17 +34,17 @@ struct JSContext;
 class JSObject;
 class nsIContent;
 class nsIFrame;
 class nsIPresShell;
 
 namespace mozilla {
 
 class AnimValuesStyleRule;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class ErrorResult;
 struct AnimationRule;
 struct TimingParams;
 class EffectSet;
 class ComputedStyle;
 
 namespace dom {
 class ElementOrCSSPseudoElement;
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -22,17 +22,17 @@
 #include "mozilla/dom/KeyframeEffectBinding.h"
 #include "mozilla/dom/KeyframeEffect.h"  // For PropertyValuesPair etc.
 #include "mozilla/dom/Nullable.h"
 #include "jsapi.h"  // For ForOfIterator etc.
 #include "nsClassHashtable.h"
 #include "nsContentUtils.h"  // For GetContextForContent
 #include "nsCSSPropertyIDSet.h"
 #include "nsCSSProps.h"
-#include "nsCSSPseudoElements.h"  // For CSSPseudoElementType
+#include "nsCSSPseudoElements.h"  // For PseudoStyleType
 #include "nsIScriptError.h"
 #include "nsTArray.h"
 #include <algorithm>  // For std::stable_sort, std::min
 
 using mozilla::dom::Nullable;
 
 namespace mozilla {
 
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -14,17 +14,17 @@
 
 struct JSContext;
 class JSObject;
 class ComputedStyle;
 struct RawServoDeclarationBlock;
 
 namespace mozilla {
 struct AnimationProperty;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class ErrorResult;
 struct Keyframe;
 struct PropertyStyleAnimationValuePair;
 
 namespace dom {
 class Document;
 class Element;
 }  // namespace dom
--- a/dom/animation/PseudoElementHashEntry.h
+++ b/dom/animation/PseudoElementHashEntry.h
@@ -9,17 +9,17 @@
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/HashFunctions.h"
 #include "PLDHashTable.h"
 
 namespace mozilla {
 
-// A hash entry that uses a RefPtr<dom::Element>, CSSPseudoElementType pair
+// A hash entry that uses a RefPtr<dom::Element>, PseudoStyleType pair
 class PseudoElementHashEntry : public PLDHashEntryHdr {
  public:
   typedef NonOwningAnimationTarget KeyType;
   typedef const NonOwningAnimationTarget* KeyTypePointer;
 
   explicit PseudoElementHashEntry(KeyTypePointer aKey)
       : mElement(aKey->mElement), mPseudoType(aKey->mPseudoType) {}
   PseudoElementHashEntry(PseudoElementHashEntry&& aOther) = default;
@@ -31,22 +31,21 @@ class PseudoElementHashEntry : public PL
     return mElement == aKey->mElement && mPseudoType == aKey->mPseudoType;
   }
 
   static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
   static PLDHashNumber HashKey(KeyTypePointer aKey) {
     if (!aKey) return 0;
 
     // Convert the scoped enum into an integer while adding it to hash.
-    // Note: CSSPseudoElementTypeBase is uint8_t, so we convert it into
-    //       uint8_t directly to avoid including the header.
+    static_assert(sizeof(PseudoStyleType) == sizeof(uint8_t), "");
     return mozilla::HashGeneric(aKey->mElement,
                                 static_cast<uint8_t>(aKey->mPseudoType));
   }
   enum { ALLOW_MEMMOVE = true };
 
   RefPtr<dom::Element> mElement;
-  CSSPseudoElementType mPseudoType;
+  PseudoStyleType mPseudoType;
 };
 
 }  // namespace mozilla
 
 #endif  // mozilla_PseudoElementHashEntry_h
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -5162,23 +5162,23 @@ bool IsLowercaseASCII(const nsAString& a
     if (!(0x0061 <= (c) && ((c) <= 0x007a))) {
       return false;
     }
   }
   return true;
 }
 
 // We only support pseudo-elements with two colons in this function.
-static CSSPseudoElementType GetPseudoElementType(const nsString& aString,
-                                                 ErrorResult& aRv) {
+static PseudoStyleType GetPseudoElementType(const nsString& aString,
+                                            ErrorResult& aRv) {
   MOZ_ASSERT(!aString.IsEmpty(),
              "GetPseudoElementType aString should be non-null");
   if (aString.Length() <= 2 || aString[0] != ':' || aString[1] != ':') {
     aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return CSSPseudoElementType::NotPseudo;
+    return PseudoStyleType::NotPseudo;
   }
   RefPtr<nsAtom> pseudo = NS_Atomize(Substring(aString, 1));
   return nsCSSPseudoElements::GetPseudoType(pseudo,
                                             CSSEnabledState::eInUASheets);
 }
 
 already_AddRefed<Element> Document::CreateElement(
     const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
@@ -5190,41 +5190,41 @@ already_AddRefed<Element> Document::Crea
 
   bool needsLowercase = IsHTMLDocument() && !IsLowercaseASCII(aTagName);
   nsAutoString lcTagName;
   if (needsLowercase) {
     nsContentUtils::ASCIIToLower(aTagName, lcTagName);
   }
 
   const nsString* is = nullptr;
-  CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
+  PseudoStyleType pseudoType = PseudoStyleType::NotPseudo;
   if (aOptions.IsElementCreationOptions()) {
     const ElementCreationOptions& options =
         aOptions.GetAsElementCreationOptions();
 
     if (options.mIs.WasPassed()) {
       is = &options.mIs.Value();
     }
 
     // Check 'pseudo' and throw an exception if it's not one allowed
     // with CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC.
     if (options.mPseudo.WasPassed()) {
       pseudoType = GetPseudoElementType(options.mPseudo.Value(), rv);
-      if (rv.Failed() || pseudoType == CSSPseudoElementType::NotPseudo ||
+      if (rv.Failed() || pseudoType == PseudoStyleType::NotPseudo ||
           !nsCSSPseudoElements::PseudoElementIsJSCreatedNAC(pseudoType)) {
         rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
         return nullptr;
       }
     }
   }
 
   RefPtr<Element> elem = CreateElem(needsLowercase ? lcTagName : aTagName,
                                     nullptr, mDefaultElementType, is);
 
-  if (pseudoType != CSSPseudoElementType::NotPseudo) {
+  if (pseudoType != PseudoStyleType::NotPseudo) {
     elem->SetPseudoElementType(pseudoType);
   }
 
   return elem.forget();
 }
 
 already_AddRefed<Element> Document::CreateElementNS(
     const nsAString& aNamespaceURI, const nsAString& aQualifiedName,
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1770,20 +1770,20 @@ nsresult Element::BindToTree(Document* a
   }
 
   // FIXME(emilio): Why is this needed? The element shouldn't even be styled in
   // the first place, we should style it properly eventually.
   //
   // Also, if this _is_ needed, then it's wrong and should use GetComposedDoc()
   // to account for Shadow DOM.
   if (aDocument && MayHaveAnimations()) {
-    CSSPseudoElementType pseudoType = GetPseudoElementType();
-    if ((pseudoType == CSSPseudoElementType::NotPseudo ||
-         pseudoType == CSSPseudoElementType::before ||
-         pseudoType == CSSPseudoElementType::after) &&
+    PseudoStyleType pseudoType = GetPseudoElementType();
+    if ((pseudoType == PseudoStyleType::NotPseudo ||
+         pseudoType == PseudoStyleType::before ||
+         pseudoType == PseudoStyleType::after) &&
         EffectSet::GetEffectSet(this, pseudoType)) {
       if (nsPresContext* presContext = aDocument->GetPresContext()) {
         presContext->EffectCompositor()->RequestRestyle(
             this, pseudoType, EffectCompositor::RestyleType::Standard,
             EffectCompositor::CascadeLevel::Animations);
       }
     }
   }
@@ -3479,57 +3479,57 @@ void Element::GetAnimations(const Animat
     // updating the animation style of elements will never affect the set of
     // running animations and it's only the set of running animations that is
     // important here.
     doc->FlushPendingNotifications(
         ChangesToFlush(FlushType::Style, false /* flush animations */));
   }
 
   Element* elem = this;
-  CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
+  PseudoStyleType pseudoType = PseudoStyleType::NotPseudo;
   // For animations on generated-content elements, the animations are stored
   // on the parent element.
   if (IsGeneratedContentContainerForBefore()) {
     elem = GetParentElement();
-    pseudoType = CSSPseudoElementType::before;
+    pseudoType = PseudoStyleType::before;
   } else if (IsGeneratedContentContainerForAfter()) {
     elem = GetParentElement();
-    pseudoType = CSSPseudoElementType::after;
+    pseudoType = PseudoStyleType::after;
   }
 
   if (!elem) {
     return;
   }
 
-  if (!filter.mSubtree || pseudoType == CSSPseudoElementType::before ||
-      pseudoType == CSSPseudoElementType::after) {
+  if (!filter.mSubtree || pseudoType == PseudoStyleType::before ||
+      pseudoType == PseudoStyleType::after) {
     GetAnimationsUnsorted(elem, pseudoType, aAnimations);
   } else {
     for (nsIContent* node = this; node; node = node->GetNextNode(this)) {
       if (!node->IsElement()) {
         continue;
       }
       Element* element = node->AsElement();
-      Element::GetAnimationsUnsorted(element, CSSPseudoElementType::NotPseudo,
+      Element::GetAnimationsUnsorted(element, PseudoStyleType::NotPseudo,
                                      aAnimations);
-      Element::GetAnimationsUnsorted(element, CSSPseudoElementType::before,
+      Element::GetAnimationsUnsorted(element, PseudoStyleType::before,
                                      aAnimations);
-      Element::GetAnimationsUnsorted(element, CSSPseudoElementType::after,
+      Element::GetAnimationsUnsorted(element, PseudoStyleType::after,
                                      aAnimations);
     }
   }
   aAnimations.Sort(AnimationPtrComparator<RefPtr<Animation>>());
 }
 
 /* static */ void Element::GetAnimationsUnsorted(
-    Element* aElement, CSSPseudoElementType aPseudoType,
+    Element* aElement, PseudoStyleType aPseudoType,
     nsTArray<RefPtr<Animation>>& aAnimations) {
-  MOZ_ASSERT(aPseudoType == CSSPseudoElementType::NotPseudo ||
-                 aPseudoType == CSSPseudoElementType::after ||
-                 aPseudoType == CSSPseudoElementType::before,
+  MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo ||
+                 aPseudoType == PseudoStyleType::after ||
+                 aPseudoType == PseudoStyleType::before,
              "Unsupported pseudo type");
   MOZ_ASSERT(aElement, "Null element");
 
   EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effects) {
     return;
   }
 
@@ -4112,17 +4112,17 @@ void Element::AddSizeOfExcludingThis(nsW
     // mServoData. This counts towards the relevant fields in |aSizes|.
     RefPtr<ComputedStyle> sc;
     if (Servo_Element_HasPrimaryComputedValues(this)) {
       sc = Servo_Element_GetPrimaryComputedValues(this).Consume();
       if (!aSizes.mState.HaveSeenPtr(sc.get())) {
         sc->AddSizeOfIncludingThis(aSizes, &aSizes.mLayoutComputedValuesDom);
       }
 
-      for (size_t i = 0; i < nsCSSPseudoElements::kEagerPseudoCount; i++) {
+      for (size_t i = 0; i < PseudoStyle::kEagerPseudoCount; i++) {
         if (Servo_Element_HasPseudoComputedValues(this, i)) {
           sc = Servo_Element_GetPseudoComputedValues(this, i).Consume();
           if (!aSizes.mState.HaveSeenPtr(sc.get())) {
             sc->AddSizeOfIncludingThis(aSizes,
                                        &aSizes.mLayoutComputedValuesDom);
           }
         }
       }
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -128,17 +128,17 @@ enum {
 };
 
 #undef ELEMENT_FLAG_BIT
 
 // Make sure we have space for our bits
 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class EventChainPostVisitor;
 class EventChainPreVisitor;
 class EventChainVisitor;
 class EventListenerManager;
 class EventStateManager;
 
 namespace dom {
 
@@ -1075,29 +1075,29 @@ class Element : public FragmentOrElement
   already_AddRefed<nsIHTMLCollection> GetElementsByTagName(
       const nsAString& aQualifiedName);
   already_AddRefed<nsIHTMLCollection> GetElementsByTagNameNS(
       const nsAString& aNamespaceURI, const nsAString& aLocalName,
       ErrorResult& aError);
   already_AddRefed<nsIHTMLCollection> GetElementsByClassName(
       const nsAString& aClassNames);
 
-  CSSPseudoElementType GetPseudoElementType() const {
+  PseudoStyleType GetPseudoElementType() const {
     nsresult rv = NS_OK;
     auto raw = GetProperty(nsGkAtoms::pseudoProperty, &rv);
     if (rv == NS_PROPTABLE_PROP_NOT_THERE) {
-      return CSSPseudoElementType::NotPseudo;
+      return PseudoStyleType::NotPseudo;
     }
-    return CSSPseudoElementType(reinterpret_cast<uintptr_t>(raw));
+    return PseudoStyleType(reinterpret_cast<uintptr_t>(raw));
   }
 
-  void SetPseudoElementType(CSSPseudoElementType aPseudo) {
-    static_assert(sizeof(CSSPseudoElementType) <= sizeof(uintptr_t),
+  void SetPseudoElementType(PseudoStyleType aPseudo) {
+    static_assert(sizeof(PseudoStyleType) <= sizeof(uintptr_t),
                   "Need to be able to store this in a void*");
-    MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo);
+    MOZ_ASSERT(PseudoStyle::IsPseudoElement(aPseudo));
     SetProperty(nsGkAtoms::pseudoProperty, reinterpret_cast<void*>(aPseudo));
   }
 
   /**
    * Return an array of all elements in the subtree rooted at this
    * element that have grid container frames. This does not include
    * pseudo-elements.
    */
@@ -1315,17 +1315,17 @@ class Element : public FragmentOrElement
       ErrorResult& aError);
 
   // Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
   // Callers must keep this element alive because flushing style may destroy
   // this element.
   void GetAnimations(const AnimationFilter& filter,
                      nsTArray<RefPtr<Animation>>& aAnimations);
   static void GetAnimationsUnsorted(Element* aElement,
-                                    CSSPseudoElementType aPseudoType,
+                                    PseudoStyleType aPseudoType,
                                     nsTArray<RefPtr<Animation>>& aAnimations);
 
   virtual void GetInnerHTML(nsAString& aInnerHTML, OOMReporter& aError);
   virtual void SetInnerHTML(const nsAString& aInnerHTML,
                             nsIPrincipal* aSubjectPrincipal,
                             ErrorResult& aError);
   void GetOuterHTML(nsAString& aOuterHTML);
   void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -360,18 +360,17 @@ void nsAnimationReceiver::RecordAnimatio
 
   Element* elem = animationTarget->mElement;
   if (!Animations() || !(Subtree() || elem == Target()) ||
       elem->ChromeOnlyAccess()) {
     return;
   }
 
   // Record animations targeting to a pseudo element only when subtree is true.
-  if (animationTarget->mPseudoType !=
-          mozilla::CSSPseudoElementType::NotPseudo &&
+  if (animationTarget->mPseudoType != PseudoStyleType::NotPseudo &&
       !Subtree()) {
     return;
   }
 
   if (nsAutoAnimationMutationBatch::IsBatching()) {
     switch (aMutationType) {
       case eAnimationMutation_Added:
         nsAutoAnimationMutationBatch::AnimationAdded(aAnimation, elem);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -94,17 +94,17 @@
 #include "nsROCSSPrimitiveValue.h"
 #include "nsIBaseWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "GeckoProfiler.h"
 #include "mozilla/Preferences.h"
 #include "nsIStyleSheetService.h"
 #include "nsContentPermissionHelper.h"
-#include "nsCSSPseudoElements.h"  // for CSSPseudoElementType
+#include "nsCSSPseudoElements.h"  // for PseudoStyleType
 #include "nsNetUtil.h"
 #include "HTMLImageElement.h"
 #include "HTMLCanvasElement.h"
 #include "mozilla/css/ImageLoader.h"
 #include "mozilla/layers/IAPZCTreeManager.h"  // for layers::ZoomToRectBehavior
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/ServoBindings.h"
--- a/dom/smil/SMILAnimationController.cpp
+++ b/dom/smil/SMILAnimationController.cpp
@@ -670,17 +670,17 @@ bool SMILAnimationController::PreTravers
     // Ignore restyles that aren't in the flattened tree subtree rooted at
     // aRoot.
     if (aRoot && !nsContentUtils::ContentIsFlattenedTreeDescendantOf(
                      key.mElement, aRoot)) {
       continue;
     }
 
     context->RestyleManager()->PostRestyleEventForAnimations(
-        key.mElement, CSSPseudoElementType::NotPseudo,
+        key.mElement, PseudoStyleType::NotPseudo,
         eRestyle_StyleAttribute_Animations);
 
     foundElementsNeedingRestyle = true;
   }
 
   // Only clear the mMightHavePendingStyleUpdates flag if we definitely posted
   // all restyles.
   if (!aRoot) {
--- a/dom/xml/nsXMLElement.cpp
+++ b/dom/xml/nsXMLElement.cpp
@@ -21,24 +21,24 @@ nsresult NS_NewXMLElement(
 }
 
 JSObject* nsXMLElement::WrapNode(JSContext* aCx,
                                  JS::Handle<JSObject*> aGivenProto) {
   return Element_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void nsXMLElement::UnbindFromTree(bool aDeep, bool aNullParent) {
-  CSSPseudoElementType pseudoType = GetPseudoElementType();
-  bool isBefore = pseudoType == CSSPseudoElementType::before;
+  PseudoStyleType pseudoType = GetPseudoElementType();
+  bool isBefore = pseudoType == PseudoStyleType::before;
   nsAtom* property = isBefore ? nsGkAtoms::beforePseudoProperty
                               : nsGkAtoms::afterPseudoProperty;
 
   switch (pseudoType) {
-    case CSSPseudoElementType::before:
-    case CSSPseudoElementType::after: {
+    case PseudoStyleType::before:
+    case PseudoStyleType::after: {
       MOZ_ASSERT(GetParent());
       MOZ_ASSERT(GetParent()->IsElement());
       GetParent()->DeleteProperty(property);
       break;
     }
     default:
       break;
   }
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1966,37 +1966,37 @@ RestyleManager::AnimationsWithDestroyedF
       mRestorePointer(mRestyleManager->mAnimationsWithDestroyedFrame) {
   MOZ_ASSERT(!mRestyleManager->mAnimationsWithDestroyedFrame,
              "shouldn't construct recursively");
   mRestyleManager->mAnimationsWithDestroyedFrame = this;
 }
 
 void RestyleManager::AnimationsWithDestroyedFrame ::
     StopAnimationsForElementsWithoutFrames() {
-  StopAnimationsWithoutFrame(mContents, CSSPseudoElementType::NotPseudo);
-  StopAnimationsWithoutFrame(mBeforeContents, CSSPseudoElementType::before);
-  StopAnimationsWithoutFrame(mAfterContents, CSSPseudoElementType::after);
+  StopAnimationsWithoutFrame(mContents, PseudoStyleType::NotPseudo);
+  StopAnimationsWithoutFrame(mBeforeContents, PseudoStyleType::before);
+  StopAnimationsWithoutFrame(mAfterContents, PseudoStyleType::after);
 }
 
 void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame(
-    nsTArray<RefPtr<nsIContent>>& aArray, CSSPseudoElementType aPseudoType) {
+    nsTArray<RefPtr<nsIContent>>& aArray, PseudoStyleType aPseudoType) {
   nsAnimationManager* animationManager =
       mRestyleManager->PresContext()->AnimationManager();
   nsTransitionManager* transitionManager =
       mRestyleManager->PresContext()->TransitionManager();
   for (nsIContent* content : aArray) {
-    if (aPseudoType == CSSPseudoElementType::NotPseudo) {
+    if (aPseudoType == PseudoStyleType::NotPseudo) {
       if (content->GetPrimaryFrame()) {
         continue;
       }
-    } else if (aPseudoType == CSSPseudoElementType::before) {
+    } else if (aPseudoType == PseudoStyleType::before) {
       if (nsLayoutUtils::GetBeforeFrame(content)) {
         continue;
       }
-    } else if (aPseudoType == CSSPseudoElementType::after) {
+    } else if (aPseudoType == PseudoStyleType::after) {
       if (nsLayoutUtils::GetAfterFrame(content)) {
         continue;
       }
     }
     dom::Element* element = content->AsElement();
 
     animationManager->StopAnimationsForElement(element, aPseudoType);
     transitionManager->StopAnimationsForElement(element, aPseudoType);
@@ -2071,18 +2071,18 @@ static const nsIFrame* ExpectedOwnerForC
   }
 
   parent = FirstContinuationOrPartOfIBSplit(parent);
 
   // We've handled already anon boxes and bullet frames, so now we're looking at
   // a frame of a DOM element or pseudo. Hop through anon and line-boxes
   // generated by our DOM parent, and go find the owner frame for it.
   while (parent && (IsAnonBox(parent) || parent->IsLineFrame())) {
-    auto* pseudo = parent->Style()->GetPseudo();
-    if (pseudo == nsCSSAnonBoxes::tableWrapper()) {
+    auto pseudo = parent->Style()->GetPseudoType();
+    if (pseudo == PseudoStyleType::tableWrapper) {
       const nsIFrame* tableFrame = parent->PrincipalChildList().FirstChild();
       MOZ_ASSERT(tableFrame->IsTableFrame());
       // Handle :-moz-table and :-moz-inline-table.
       parent = IsAnonBox(tableFrame) ? parent->GetParent() : tableFrame;
     } else {
       // We get the in-flow parent here so that we can handle the OOF anonymous
       // boxed to get the correct parent.
       parent = parent->GetInFlowParent();
@@ -2135,20 +2135,20 @@ nsChangeHint ServoRestyleState::ChangesH
 void ServoRestyleState::AddPendingWrapperRestyle(nsIFrame* aWrapperFrame) {
   MOZ_ASSERT(aWrapperFrame->Style()->IsWrapperAnonBox(),
              "All our wrappers are anon boxes, and why would we restyle "
              "non-inheriting ones?");
   MOZ_ASSERT(aWrapperFrame->Style()->IsInheritingAnonBox(),
              "All our wrappers are anon boxes, and why would we restyle "
              "non-inheriting ones?");
   MOZ_ASSERT(
-      aWrapperFrame->Style()->GetPseudo() != nsCSSAnonBoxes::cellContent(),
+      aWrapperFrame->Style()->GetPseudoType() != PseudoStyleType::cellContent,
       "Someone should be using TableAwareParentFor");
   MOZ_ASSERT(
-      aWrapperFrame->Style()->GetPseudo() != nsCSSAnonBoxes::tableWrapper(),
+      aWrapperFrame->Style()->GetPseudoType() != PseudoStyleType::tableWrapper,
       "Someone should be using TableAwareParentFor");
   // Make sure we only add first continuations.
   aWrapperFrame = aWrapperFrame->FirstContinuation();
   nsIFrame* last = mPendingWrapperRestyles.SafeLastElement(nullptr);
   if (last == aWrapperFrame) {
     // Already queued up, nothing to do.
     return;
   }
@@ -2260,17 +2260,17 @@ nsIFrame* ServoRestyleState::TableAwareP
   // its table wrapper.
   if (aChild->IsTableFrame()) {
     aChild = aChild->GetParent();
     MOZ_ASSERT(aChild->IsTableWrapperFrame());
   }
 
   nsIFrame* parent = aChild->GetParent();
   // Now if parent is a cell-content frame, we actually want the cellframe.
-  if (parent->Style()->GetPseudo() == nsCSSAnonBoxes::cellContent()) {
+  if (parent->Style()->GetPseudoType() == PseudoStyleType::cellContent) {
     parent = parent->GetParent();
   } else if (parent->IsTableWrapperFrame()) {
     // Must be a caption.  In that case we want the table here.
     MOZ_ASSERT(aChild->StyleDisplay()->mDisplay == StyleDisplay::TableCaption);
     parent = parent->PrincipalChildList().FirstChild();
   }
   return parent;
 }
@@ -2323,19 +2323,19 @@ void RestyleManager::PostRestyleEvent(El
     }
   }
 
   if (aRestyleHint || aMinChangeHint) {
     Servo_NoteExplicitHints(aElement, aRestyleHint, aMinChangeHint);
   }
 }
 
-void RestyleManager::PostRestyleEventForAnimations(
-    Element* aElement, CSSPseudoElementType aPseudoType,
-    nsRestyleHint aRestyleHint) {
+void RestyleManager::PostRestyleEventForAnimations(Element* aElement,
+                                                   PseudoStyleType aPseudoType,
+                                                   nsRestyleHint aRestyleHint) {
   Element* elementToRestyle =
       EffectCompositor::GetElementToRestyle(aElement, aPseudoType);
 
   if (!elementToRestyle) {
     // FIXME: Bug 1371107: When reframing happens,
     // EffectCompositor::mElementsToRestyle still has unbound old pseudo
     // element. We should drop it.
     return;
@@ -2436,24 +2436,24 @@ struct RestyleManager::TextPostTraversal
     }
     MOZ_ASSERT(mStyle);
     return *mStyle;
   }
 
   void ComputeHintIfNeeded(nsIContent* aContent, nsIFrame* aTextFrame,
                            ComputedStyle& aNewStyle) {
     MOZ_ASSERT(aTextFrame);
-    MOZ_ASSERT(aNewStyle.GetPseudo() == nsCSSAnonBoxes::mozText());
+    MOZ_ASSERT(aNewStyle.GetPseudoType() == PseudoStyleType::mozText);
 
     if (MOZ_LIKELY(!mShouldPostHints)) {
       return;
     }
 
     ComputedStyle* oldStyle = aTextFrame->Style();
-    MOZ_ASSERT(oldStyle->GetPseudo() == nsCSSAnonBoxes::mozText());
+    MOZ_ASSERT(oldStyle->GetPseudoType() == PseudoStyleType::mozText);
 
     // We rely on the fact that all the text children for the same element share
     // style to avoid recomputing style differences for all of them.
     //
     // TODO(emilio): The above may not be true for ::first-{line,letter}, but
     // we'll cross that bridge when we support those in stylo.
     if (mShouldComputeHints) {
       mShouldComputeHints = false;
@@ -2506,20 +2506,20 @@ static void UpdateBackdropIfNeeded(nsIFr
     return;
   }
 
   MOZ_ASSERT(backdropPlaceholder->IsPlaceholderFrame());
   nsIFrame* backdropFrame =
       nsPlaceholderFrame::GetRealFrameForPlaceholder(backdropPlaceholder);
   MOZ_ASSERT(backdropFrame->IsBackdropFrame());
   MOZ_ASSERT(backdropFrame->Style()->GetPseudoType() ==
-             CSSPseudoElementType::backdrop);
+             PseudoStyleType::backdrop);
 
   RefPtr<ComputedStyle> newStyle = aStyleSet.ResolvePseudoElementStyle(
-      aFrame->GetContent()->AsElement(), CSSPseudoElementType::backdrop,
+      aFrame->GetContent()->AsElement(), PseudoStyleType::backdrop,
       aFrame->Style(),
       /* aPseudoElement = */ nullptr);
 
   // NOTE(emilio): We can't use the changes handled for the owner of the
   // backdrop frame, since it's out of flow, and parented to the viewport or
   // canvas frame (depending on the `position` value).
   MOZ_ASSERT(backdropFrame->GetParent()->IsViewportFrame() ||
              backdropFrame->GetParent()->IsCanvasFrame());
@@ -2548,17 +2548,17 @@ static void UpdateFirstLetterIfNeeded(ns
   static_cast<nsBlockFrame*>(block->FirstContinuation())
       ->UpdateFirstLetterStyle(aRestyleState);
 }
 
 static void UpdateOneAdditionalComputedStyle(nsIFrame* aFrame, uint32_t aIndex,
                                              ComputedStyle& aOldContext,
                                              ServoRestyleState& aRestyleState) {
   auto pseudoType = aOldContext.GetPseudoType();
-  MOZ_ASSERT(pseudoType != CSSPseudoElementType::NotPseudo);
+  MOZ_ASSERT(pseudoType != PseudoStyleType::NotPseudo);
   MOZ_ASSERT(
       !nsCSSPseudoElements::PseudoElementSupportsUserActionState(pseudoType));
 
   RefPtr<ComputedStyle> newStyle =
       aRestyleState.StyleSet().ResolvePseudoElementStyle(
           aFrame->GetContent()->AsElement(), pseudoType, aFrame->Style(),
           /* aPseudoElement = */ nullptr);
 
@@ -3516,50 +3516,50 @@ void RestyleManager::DoReparentComputedS
   // Also see the comment at the start of
   // nsTransitionManager::ConsiderInitiatingTransition.
   //
   // We don't try to do the fancy copying from previous continuations that
   // GeckoRestyleManager does here, because that relies on knowing the parents
   // of ComputedStyles, and we don't know those.
   ComputedStyle* oldStyle = aFrame->Style();
   Element* ourElement =
-      oldStyle->GetPseudoType() == CSSPseudoElementType::NotPseudo && isElement
+      oldStyle->GetPseudoType() == PseudoStyleType::NotPseudo && isElement
           ? aFrame->GetContent()->AsElement()
           : nullptr;
   ComputedStyle* newParent = newParentStyle;
 
   ComputedStyle* newParentIgnoringFirstLine;
-  if (newParent->GetPseudoType() == CSSPseudoElementType::firstLine) {
+  if (newParent->GetPseudoType() == PseudoStyleType::firstLine) {
     MOZ_ASSERT(providerFrame && providerFrame->GetParent()->IsFrameOfType(
                                     nsIFrame::eBlockFrame),
                "How could we get a ::first-line parent style without having "
                "a ::first-line provider frame?");
     // If newParent is a ::first-line style, get the parent blockframe, and then
     // correct it for our pseudo as needed (e.g. stepping out of anon boxes).
     // Use the resulting style for the "parent style ignoring ::first-line".
     nsIFrame* blockFrame = providerFrame->GetParent();
     nsIFrame* correctedFrame =
-        nsFrame::CorrectStyleParentFrame(blockFrame, oldStyle->GetPseudo());
+        nsFrame::CorrectStyleParentFrame(blockFrame, oldStyle->GetPseudoType());
     newParentIgnoringFirstLine = correctedFrame->Style();
   } else {
     newParentIgnoringFirstLine = newParent;
   }
 
   if (!providerFrame) {
     // No providerFrame means we inherited from a display:contents thing.  Our
     // layout parent style is the style of our nearest ancestor frame.  But we
     // have to be careful to do that with our placeholder, not with us, if we're
     // out of flow.
     if (aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
       aFrame->FirstContinuation()
           ->GetPlaceholderFrame()
           ->GetLayoutParentStyleForOutOfFlow(&providerFrame);
     } else {
-      providerFrame = nsFrame::CorrectStyleParentFrame(aFrame->GetParent(),
-                                                       oldStyle->GetPseudo());
+      providerFrame = nsFrame::CorrectStyleParentFrame(
+          aFrame->GetParent(), oldStyle->GetPseudoType());
     }
   }
   ComputedStyle* layoutParent = providerFrame->Style();
 
   RefPtr<ComputedStyle> newStyle = aStyleSet.ReparentComputedStyle(
       oldStyle, newParent, newParentIgnoringFirstLine, layoutParent,
       ourElement);
   aFrame->SetComputedStyle(newStyle);
--- a/layout/base/RestyleManager.h
+++ b/layout/base/RestyleManager.h
@@ -249,35 +249,35 @@ class RestyleManager {
     // method of RestyleManager.)
     explicit AnimationsWithDestroyedFrame(RestyleManager* aRestyleManager);
 
     // This method takes the content node for the generated content for
     // animation/transition on ::before and ::after, rather than the
     // content node for the real element.
     void Put(nsIContent* aContent, ComputedStyle* aComputedStyle) {
       MOZ_ASSERT(aContent);
-      CSSPseudoElementType pseudoType = aComputedStyle->GetPseudoType();
-      if (pseudoType == CSSPseudoElementType::NotPseudo) {
+      PseudoStyleType pseudoType = aComputedStyle->GetPseudoType();
+      if (pseudoType == PseudoStyleType::NotPseudo) {
         mContents.AppendElement(aContent);
-      } else if (pseudoType == CSSPseudoElementType::before) {
+      } else if (pseudoType == PseudoStyleType::before) {
         MOZ_ASSERT(aContent->NodeInfo()->NameAtom() ==
                    nsGkAtoms::mozgeneratedcontentbefore);
         mBeforeContents.AppendElement(aContent->GetParent());
-      } else if (pseudoType == CSSPseudoElementType::after) {
+      } else if (pseudoType == PseudoStyleType::after) {
         MOZ_ASSERT(aContent->NodeInfo()->NameAtom() ==
                    nsGkAtoms::mozgeneratedcontentafter);
         mAfterContents.AppendElement(aContent->GetParent());
       }
     }
 
     void StopAnimationsForElementsWithoutFrames();
 
    private:
     void StopAnimationsWithoutFrame(nsTArray<RefPtr<nsIContent>>& aArray,
-                                    CSSPseudoElementType aPseudoType);
+                                    PseudoStyleType aPseudoType);
 
     RestyleManager* mRestyleManager;
     AutoRestore<AnimationsWithDestroyedFrame*> mRestorePointer;
 
     // Below three arrays might include elements that have already had their
     // animations or transitions stopped.
     //
     // mBeforeContents and mAfterContents hold the real element rather than
@@ -322,17 +322,17 @@ class RestyleManager {
    * Posts restyle hints for animations.
    * This is only called for the second traversal for CSS animations during
    * updating CSS animations in a SequentialTask.
    * This function does neither register a refresh observer nor flag that a
    * style flush is needed since this function is supposed to be called during
    * restyling process and this restyle event will be processed in the second
    * traversal of the same restyling process.
    */
-  void PostRestyleEventForAnimations(dom::Element*, CSSPseudoElementType,
+  void PostRestyleEventForAnimations(dom::Element*, PseudoStyleType,
                                      nsRestyleHint);
 
   void NextRestyleIsForCSSRuleChanges() { mRestyleForCSSRuleChanges = true; }
 
   void RebuildAllStyleData(nsChangeHint aExtraHint, nsRestyleHint aRestyleHint);
   void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
                                     nsRestyleHint aRestyleHint);
 
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -284,36 +284,36 @@ nsIFrame* NS_NewScrollbarButtonFrame(nsI
 
 nsIFrame* NS_NewImageFrameForContentProperty(nsIPresShell*, ComputedStyle*);
 
 nsIFrame* NS_NewImageFrameForGeneratedContentIndex(nsIPresShell*,
                                                    ComputedStyle*);
 
 // Returns true if aFrame is an anonymous flex/grid item.
 static inline bool IsAnonymousFlexOrGridItem(const nsIFrame* aFrame) {
-  const nsAtom* pseudoType = aFrame->Style()->GetPseudo();
-  return pseudoType == nsCSSAnonBoxes::anonymousFlexItem() ||
-         pseudoType == nsCSSAnonBoxes::anonymousGridItem();
+  auto pseudoType = aFrame->Style()->GetPseudoType();
+  return pseudoType == PseudoStyleType::anonymousFlexItem ||
+         pseudoType == PseudoStyleType::anonymousGridItem;
 }
 
 // Returns true IFF the given nsIFrame is a nsFlexContainerFrame and
 // represents a -webkit-{inline-}box or -moz-{inline-}box container.
 static inline bool IsFlexContainerForLegacyBox(const nsIFrame* aFrame) {
   return aFrame->IsFlexContainerFrame() &&
          aFrame->HasAnyStateBits(NS_STATE_FLEX_IS_EMULATING_LEGACY_BOX);
 }
 
 #if DEBUG
 static void AssertAnonymousFlexOrGridItemParent(const nsIFrame* aChild,
                                                 const nsIFrame* aParent) {
   MOZ_ASSERT(IsAnonymousFlexOrGridItem(aChild),
              "expected an anonymous flex or grid item child frame");
   MOZ_ASSERT(aParent, "expected a parent frame");
-  const nsAtom* pseudoType = aChild->Style()->GetPseudo();
-  if (pseudoType == nsCSSAnonBoxes::anonymousFlexItem()) {
+  auto pseudoType = aChild->Style()->GetPseudoType();
+  if (pseudoType == PseudoStyleType::anonymousFlexItem) {
     MOZ_ASSERT(aParent->IsFlexContainerFrame(),
                "anonymous flex items should only exist as children "
                "of flex container frames");
   } else {
     MOZ_ASSERT(aParent->IsGridContainerFrame(),
                "anonymous grid items should only exist as children "
                "of grid container frames");
   }
@@ -329,25 +329,25 @@ static inline nsContainerFrame* GetField
   nsIFrame* firstChild = aFieldsetFrame->PrincipalChildList().FirstChild();
   nsIFrame* inner = firstChild && firstChild->GetNextSibling()
                         ? firstChild->GetNextSibling()
                         : firstChild;
   return inner ? inner->GetContentInsertionFrame() : nullptr;
 }
 
 #define FCDATA_DECL(_flags, _func) \
-  { _flags, {(FrameCreationFunc)_func}, nullptr, nullptr }
+  { _flags, {(FrameCreationFunc)_func}, nullptr, PseudoStyleType::NotPseudo }
 #define FCDATA_WITH_WRAPPING_BLOCK(_flags, _func, _anon_box) \
   {                                                          \
     _flags | FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS,       \
         {(FrameCreationFunc)_func}, nullptr, _anon_box       \
   }
 
 #define UNREACHABLE_FCDATA() \
-  { 0, {(FrameCreationFunc) nullptr}, nullptr, nullptr }
+  { 0, {(FrameCreationFunc) nullptr}, nullptr, PseudoStyleType::NotPseudo }
 //----------------------------------------------------------------------
 
 /**
  * True if aFrame is an actual inline frame in the sense of non-replaced
  * display:inline CSS boxes.  In other words, it can be affected by {ib}
  * splitting and can contain first-letter frames.  Basically, this is either an
  * inline frame (positioned or otherwise) or an line frame (this last because
  * it can contain first-letter and because inserting blocks in the middle of it
@@ -374,17 +374,17 @@ static inline bool IsDisplayContents(con
  */
 static bool IsFrameForSVG(const nsIFrame* aFrame) {
   return aFrame->IsFrameOfType(nsIFrame::eSVG) ||
          nsSVGUtils::IsInSVGTextSubtree(aFrame);
 }
 
 static bool IsLastContinuationForColumnContent(const nsIFrame* aFrame) {
   MOZ_ASSERT(aFrame);
-  return aFrame->Style()->GetPseudo() == nsCSSAnonBoxes::columnContent() &&
+  return aFrame->Style()->GetPseudoType() == PseudoStyleType::columnContent &&
          !aFrame->GetNextContinuation();
 }
 
 /**
  * Returns true iff aFrame explicitly prevents its descendants from floating
  * (at least, down to the level of descendants which themselves are
  * float-containing blocks -- those will manage the floating status of any
  * lower-level descendents inside them, of course).
@@ -397,17 +397,17 @@ static bool ShouldSuppressFloatingOfDesc
 // Return true if column-span descendants should be suppressed under aFrame's
 // subtree (until a multi-column container re-establishing a block formatting
 // context). Basically, this is testing whether aFrame establishes a new block
 // formatting context or not.
 static bool ShouldSuppressColumnSpanDescendants(nsIFrame* aFrame) {
   MOZ_ASSERT(StaticPrefs::layout_css_column_span_enabled(),
              "Call this only when layout.css.column-span.enabled is true!");
 
-  if (aFrame->Style()->GetPseudo() == nsCSSAnonBoxes::columnContent()) {
+  if (aFrame->Style()->GetPseudoType() == PseudoStyleType::columnContent) {
     // Never suppress column-span under ::-moz-column-content frames.
     return false;
   }
 
   if (aFrame->IsInlineFrame()) {
     // Allow inline frames to have column-span block children.
     return false;
   }
@@ -549,17 +549,17 @@ static nsIFrame* GetIBContainingBlockFor
       NS_ERROR("no unsplit block frame in IB hierarchy");
       return aFrame;
     }
 
     // Note that we ignore non-ib-split frames which have a pseudo on their
     // ComputedStyle -- they're not the frames we're looking for!  In
     // particular, they may be hiding a real parent that _is_ in an ib-split.
     if (!IsFramePartOfIBSplit(parentFrame) &&
-        !parentFrame->Style()->GetPseudo())
+        !parentFrame->Style()->IsPseudoOrAnonBox())
       break;
 
     aFrame = parentFrame;
   } while (1);
 
   // post-conditions
   NS_ASSERTION(parentFrame,
                "no normal ancestor found for ib-split frame "
@@ -582,17 +582,17 @@ static nsContainerFrame* GetMultiColumnC
   MOZ_ASSERT(current, "No ColumnSetWrapperFrame in a valid column hierarchy?");
 
   return current;
 }
 
 // This is a bit slow, but sometimes we need it.
 static bool ParentIsWrapperAnonBox(nsIFrame* aParent) {
   nsIFrame* maybeAnonBox = aParent;
-  if (maybeAnonBox->Style()->GetPseudo() == nsCSSAnonBoxes::cellContent()) {
+  if (maybeAnonBox->Style()->GetPseudoType() == PseudoStyleType::cellContent) {
     // The thing that would maybe be a wrapper anon box is the cell.
     maybeAnonBox = maybeAnonBox->GetParent();
   }
   return maybeAnonBox->Style()->IsWrapperAnonBox();
 }
 
 //----------------------------------------------------------------------
 
@@ -1175,17 +1175,17 @@ void nsFrameConstructorState::ConstructB
   nsContainerFrame* frame = do_QueryFrame(aFrame);
   if (!frame) {
     NS_WARNING("Cannot create backdrop frame for non-container frame");
     return;
   }
 
   RefPtr<ComputedStyle> style =
       mPresShell->StyleSet()->ResolvePseudoElementStyle(
-          aContent->AsElement(), CSSPseudoElementType::backdrop,
+          aContent->AsElement(), PseudoStyleType::backdrop,
           /* aParentComputedStyle */ nullptr,
           /* aPseudoElement */ nullptr);
   MOZ_ASSERT(style->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_TOP);
   nsContainerFrame* parentFrame =
       GetGeometricParent(*style->StyleDisplay(), nullptr);
 
   nsBackdropFrame* backdropFrame =
       new (mPresShell) nsBackdropFrame(style, mPresShell->GetPresContext());
@@ -1704,19 +1704,19 @@ already_AddRefed<nsIContent> nsCSSFrameC
  * children of the XML element. Then we create a frame subtree for
  * the XML element as if it were a regular child of
  * aParentFrame/aParentContent, giving the XML element the ::before or
  * ::after style.
  */
 void nsCSSFrameConstructor::CreateGeneratedContentItem(
     nsFrameConstructorState& aState, nsContainerFrame* aParentFrame,
     Element& aOriginatingElement, ComputedStyle& aStyle,
-    CSSPseudoElementType aPseudoElement, FrameConstructionItemList& aItems) {
-  MOZ_ASSERT(aPseudoElement == CSSPseudoElementType::before ||
-                 aPseudoElement == CSSPseudoElementType::after,
+    PseudoStyleType aPseudoElement, FrameConstructionItemList& aItems) {
+  MOZ_ASSERT(aPseudoElement == PseudoStyleType::before ||
+                 aPseudoElement == PseudoStyleType::after,
              "unexpected aPseudoElement");
 
   if (aParentFrame && (aParentFrame->IsHTMLVideoFrame() ||
                        aParentFrame->IsDateTimeControlFrame())) {
     // Video frames and date time control frames may not be leafs when backed by
     // an UA widget, but we still don't want to expose generated content.
     return;
   }
@@ -1725,17 +1725,17 @@ void nsCSSFrameConstructor::CreateGenera
 
   // Probe for the existence of the pseudo-element
   RefPtr<ComputedStyle> pseudoStyle = styleSet->ProbePseudoElementStyle(
       aOriginatingElement, aPseudoElement, &aStyle);
   if (!pseudoStyle) {
     return;
   }
 
-  bool isBefore = aPseudoElement == CSSPseudoElementType::before;
+  bool isBefore = aPseudoElement == PseudoStyleType::before;
 
   // |ProbePseudoStyleFor| checked the 'display' property and the
   // |ContentCount()| of the 'content' property for us.
   nsAtom* elemName = isBefore ? nsGkAtoms::mozgeneratedcontentbefore
                               : nsGkAtoms::mozgeneratedcontentafter;
   RefPtr<NodeInfo> nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(
       elemName, nullptr, kNameSpaceID_None, nsINode::ELEMENT_NODE);
   RefPtr<Element> container;
@@ -1816,36 +1816,40 @@ void nsCSSFrameConstructor::CreateGenera
 // Return whether the given frame is a table pseudo-frame. Note that
 // cell-content and table-outer frames have pseudo-types, but are always
 // created, even for non-anonymous cells and tables respectively.  So for those
 // we have to examine the cell or table frame to see whether it's a pseudo
 // frame. In particular, a lone table caption will have a table wrapper as its
 // parent, but will also trigger construction of an empty inner table, which
 // will be the one we can examine to see whether the wrapper was a pseudo-frame.
 static bool IsTablePseudo(nsIFrame* aFrame) {
-  nsAtom* pseudoType = aFrame->Style()->GetPseudo();
-  return pseudoType &&
-         (pseudoType == nsCSSAnonBoxes::table() ||
-          pseudoType == nsCSSAnonBoxes::inlineTable() ||
-          pseudoType == nsCSSAnonBoxes::tableColGroup() ||
-          pseudoType == nsCSSAnonBoxes::tableRowGroup() ||
-          pseudoType == nsCSSAnonBoxes::tableRow() ||
-          pseudoType == nsCSSAnonBoxes::tableCell() ||
-          (pseudoType == nsCSSAnonBoxes::cellContent() &&
-           aFrame->GetParent()->Style()->GetPseudo() ==
-               nsCSSAnonBoxes::tableCell()) ||
-          (pseudoType == nsCSSAnonBoxes::tableWrapper() &&
-           (aFrame->PrincipalChildList().FirstChild()->Style()->GetPseudo() ==
-                nsCSSAnonBoxes::table() ||
-            aFrame->PrincipalChildList().FirstChild()->Style()->GetPseudo() ==
-                nsCSSAnonBoxes::inlineTable())));
+  auto pseudoType = aFrame->Style()->GetPseudoType();
+  return pseudoType != PseudoStyleType::NotPseudo &&
+         (pseudoType == PseudoStyleType::table ||
+          pseudoType == PseudoStyleType::inlineTable ||
+          pseudoType == PseudoStyleType::tableColGroup ||
+          pseudoType == PseudoStyleType::tableRowGroup ||
+          pseudoType == PseudoStyleType::tableRow ||
+          pseudoType == PseudoStyleType::tableCell ||
+          (pseudoType == PseudoStyleType::cellContent &&
+           aFrame->GetParent()->Style()->GetPseudoType() ==
+               PseudoStyleType::tableCell) ||
+          (pseudoType == PseudoStyleType::tableWrapper &&
+           (aFrame->PrincipalChildList()
+                    .FirstChild()
+                    ->Style()
+                    ->GetPseudoType() == PseudoStyleType::table ||
+            aFrame->PrincipalChildList()
+                    .FirstChild()
+                    ->Style()
+                    ->GetPseudoType() == PseudoStyleType::inlineTable)));
 }
 
 static bool IsRubyPseudo(nsIFrame* aFrame) {
-  return RubyUtils::IsRubyPseudo(aFrame->Style()->GetPseudo());
+  return RubyUtils::IsRubyPseudo(aFrame->Style()->GetPseudoType());
 }
 
 static bool IsTableOrRubyPseudo(nsIFrame* aFrame) {
   return IsTablePseudo(aFrame) || IsRubyPseudo(aFrame);
 }
 
 /* static */
 nsCSSFrameConstructor::ParentType nsCSSFrameConstructor::GetParentType(
@@ -1948,17 +1952,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
   nsIContent* const content = aItem.mContent;
   ComputedStyle* const computedStyle = aItem.mComputedStyle;
   const bool isMathMLContent = content->IsMathMLElement();
 
   // create the pseudo SC for the table wrapper as a child of the inner SC
   RefPtr<ComputedStyle> outerComputedStyle;
   outerComputedStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::tableWrapper(), computedStyle);
+          PseudoStyleType::tableWrapper, computedStyle);
 
   // Create the table wrapper frame which holds the caption and inner table
   // frame
   nsContainerFrame* newFrame;
   if (isMathMLContent)
     newFrame = NS_NewMathMLmtableOuterFrame(mPresShell, outerComputedStyle);
   else
     newFrame = NS_NewTableWrapperFrame(mPresShell, outerComputedStyle);
@@ -2147,17 +2151,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
 
   // Initialize the table cell frame
   InitAndRestoreFrame(aState, content, aParentFrame, newFrame);
   newFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
 
   // Resolve pseudo style and initialize the body cell frame
   RefPtr<ComputedStyle> innerPseudoStyle;
   innerPseudoStyle = mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::cellContent(), computedStyle);
+      PseudoStyleType::cellContent, computedStyle);
 
   // Create a block frame that will format the cell's content
   bool isBlock;
   nsContainerFrame* cellInnerFrame;
   if (isMathMLContent) {
     cellInnerFrame = NS_NewMathMLmtdInnerFrame(mPresShell, innerPseudoStyle);
     isBlock = false;
   } else {
@@ -2247,17 +2251,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
 
   // Resolve a new style for the viewport since it may be affected by a new root
   // element style (e.g. a propagated 'direction').
   //
   // @see ComputedStyle::ApplyStyleFixups
   {
     RefPtr<ComputedStyle> sc =
         mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::viewport(), nullptr);
+            PseudoStyleType::viewport, nullptr);
     GetRootFrame()->SetComputedStyleWithoutNotification(sc);
   }
 
   // Make sure to call UpdateViewportScrollStylesOverride before
   // SetUpDocElementContainingBlock, since it sets up our scrollbar state
   // properly.
   DebugOnly<nsIContent*> propagatedScrollFrom;
   if (nsPresContext* presContext = mPresShell->GetPresContext()) {
@@ -2511,17 +2515,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
   AUTO_PROFILER_LABEL("nsCSSFrameConstructor::ConstructRootFrame",
                       LAYOUT_FrameConstruction);
   AUTO_LAYOUT_PHASE_ENTRY_POINT(mPresShell->GetPresContext(), FrameC);
 
   ServoStyleSet* styleSet = mPresShell->StyleSet();
 
   // --------- BUILD VIEWPORT -----------
   RefPtr<ComputedStyle> viewportPseudoStyle =
-      styleSet->ResolveInheritingAnonymousBoxStyle(nsCSSAnonBoxes::viewport(),
+      styleSet->ResolveInheritingAnonymousBoxStyle(PseudoStyleType::viewport,
                                                    nullptr);
   ViewportFrame* viewportFrame =
       NS_NewViewportFrame(mPresShell, viewportPseudoStyle);
 
   // XXXbz do we _have_ to pass a null content pointer to that frame?
   // Would it really kill us to pass in the root element or something?
   // What would that break?
   viewportFrame->Init(nullptr, nullptr, nullptr);
@@ -2615,38 +2619,38 @@ void nsCSSFrameConstructor::SetUpDocElem
 
   nsPresContext* presContext = mPresShell->GetPresContext();
   bool isPaginated = presContext->IsRootPaginatedDocument();
   nsContainerFrame* viewportFrame =
       static_cast<nsContainerFrame*>(GetRootFrame());
   ComputedStyle* viewportPseudoStyle = viewportFrame->Style();
 
   nsContainerFrame* rootFrame = nullptr;
-  nsAtom* rootPseudo;
+  PseudoStyleType rootPseudo;
 
   if (!isPaginated) {
 #ifdef MOZ_XUL
     if (aDocElement->IsXULElement()) {
       // pass a temporary stylecontext, the correct one will be set later
       rootFrame = NS_NewRootBoxFrame(mPresShell, viewportPseudoStyle);
     } else
 #endif
     {
       // pass a temporary stylecontext, the correct one will be set later
       rootFrame = NS_NewCanvasFrame(mPresShell, viewportPseudoStyle);
       mHasRootAbsPosContainingBlock = true;
     }
 
-    rootPseudo = nsCSSAnonBoxes::canvas();
+    rootPseudo = PseudoStyleType::canvas;
     mDocElementContainingBlock = rootFrame;
   } else {
     // Create a page sequence frame
     rootFrame = NS_NewSimplePageSequenceFrame(mPresShell, viewportPseudoStyle);
     mPageSequenceFrame = rootFrame;
-    rootPseudo = nsCSSAnonBoxes::pageSequence();
+    rootPseudo = PseudoStyleType::pageSequence;
     rootFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
   }
 
   // --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------
 
   // If the device supports scrolling (e.g., in galley mode on the screen and
   // for print-preview, but not when printing), then create a scroll frame that
   // will act as the scrolling mechanism for the viewport.
@@ -2679,33 +2683,33 @@ void nsCSSFrameConstructor::SetUpDocElem
   nsContainerFrame* parentFrame = viewportFrame;
 
   ServoStyleSet* styleSet = mPresShell->StyleSet();
   // If paginated, make sure we don't put scrollbars in
   if (!isScrollable) {
     rootPseudoStyle = styleSet->ResolveInheritingAnonymousBoxStyle(
         rootPseudo, viewportPseudoStyle);
   } else {
-    if (rootPseudo == nsCSSAnonBoxes::canvas()) {
-      rootPseudo = nsCSSAnonBoxes::scrolledCanvas();
+    if (rootPseudo == PseudoStyleType::canvas) {
+      rootPseudo = PseudoStyleType::scrolledCanvas;
     } else {
-      NS_ASSERTION(rootPseudo == nsCSSAnonBoxes::pageSequence(),
+      NS_ASSERTION(rootPseudo == PseudoStyleType::pageSequence,
                    "Unknown root pseudo");
-      rootPseudo = nsCSSAnonBoxes::scrolledPageSequence();
+      rootPseudo = PseudoStyleType::scrolledPageSequence;
     }
 
     // Build the frame. We give it the content we are wrapping which is the
     // document element, the root frame, the parent view port frame, and we
     // should get back the new frame and the scrollable view if one was
     // created.
 
     // resolve a context for the scrollframe
     RefPtr<ComputedStyle> computedStyle =
         styleSet->ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::viewportScroll(), viewportPseudoStyle);
+            PseudoStyleType::viewportScroll, viewportPseudoStyle);
 
     // Note that the viewport scrollframe is always built with
     // overflow:auto style. This forces the scroll frame to create
     // anonymous content for both scrollbars. This is necessary even
     // if the HTML or BODY elements are overriding the viewport
     // scroll style to 'hidden' --- dynamic style changes might put
     // scrollbars back on the viewport and we don't want to have to
     // reframe the viewport to create the scrollbar content.
@@ -2772,27 +2776,27 @@ void nsCSSFrameConstructor::ConstructAno
 nsContainerFrame* nsCSSFrameConstructor::ConstructPageFrame(
     nsIPresShell* aPresShell, nsContainerFrame* aParentFrame,
     nsIFrame* aPrevPageFrame, nsContainerFrame*& aCanvasFrame) {
   ComputedStyle* parentComputedStyle = aParentFrame->Style();
   ServoStyleSet* styleSet = aPresShell->StyleSet();
 
   RefPtr<ComputedStyle> pagePseudoStyle;
   pagePseudoStyle = styleSet->ResolveInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::page(), parentComputedStyle);
+      PseudoStyleType::page, parentComputedStyle);
 
   nsContainerFrame* pageFrame = NS_NewPageFrame(aPresShell, pagePseudoStyle);
 
   // Initialize the page frame and force it to have a view. This makes printing
   // of the pages easier and faster.
   pageFrame->Init(nullptr, aParentFrame, aPrevPageFrame);
 
   RefPtr<ComputedStyle> pageContentPseudoStyle;
   pageContentPseudoStyle = styleSet->ResolveInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::pageContent(), pagePseudoStyle);
+      PseudoStyleType::pageContent, pagePseudoStyle);
 
   nsContainerFrame* pageContentFrame =
       NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle);
 
   // Initialize the page content frame and force it to have a view. Also make it
   // the containing block for fixed elements which are repeated on every page.
   nsIFrame* prevPageContentFrame = nullptr;
   if (aPrevPageFrame) {
@@ -2805,17 +2809,17 @@ nsContainerFrame* nsCSSFrameConstructor:
   }
   SetInitialSingleChild(pageFrame, pageContentFrame);
   // Make it an absolute container for fixed-pos elements
   pageContentFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
   pageContentFrame->MarkAsAbsoluteContainingBlock();
 
   RefPtr<ComputedStyle> canvasPseudoStyle;
   canvasPseudoStyle = styleSet->ResolveInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::canvas(), pageContentPseudoStyle);
+      PseudoStyleType::canvas, pageContentPseudoStyle);
 
   aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
 
   nsIFrame* prevCanvasFrame = nullptr;
   if (prevPageContentFrame) {
     prevCanvasFrame = prevPageContentFrame->PrincipalChildList().FirstChild();
     NS_ASSERTION(prevCanvasFrame, "missing canvas frame");
   }
@@ -2896,17 +2900,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
 
     comboboxFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
 
     aState.AddChild(comboboxFrame, aFrameItems, content, aParentFrame);
 
     // Resolve pseudo element style for the dropdown list
     RefPtr<ComputedStyle> listStyle;
     listStyle = mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-        nsCSSAnonBoxes::dropDownList(), computedStyle);
+        PseudoStyleType::dropDownList, computedStyle);
 
     // Create a listbox
     nsContainerFrame* listFrame = NS_NewListControlFrame(mPresShell, listStyle);
 
     // Notify the listbox that it is being used as a dropdown list.
     nsListControlFrame* listControlFrame = do_QueryFrame(listFrame);
     if (listControlFrame) {
       listControlFrame->SetComboboxFrame(comboboxFrame);
@@ -3055,26 +3059,26 @@ nsIFrame* nsCSSFrameConstructor::Constru
                       fieldsetFrame);
 
   fieldsetFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
 
   // Resolve style and initialize the frame
   RefPtr<ComputedStyle> fieldsetContentStyle;
   fieldsetContentStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::fieldsetContent(), computedStyle);
+          PseudoStyleType::fieldsetContent, computedStyle);
 
   const nsStyleDisplay* fieldsetContentDisplay =
       fieldsetContentStyle->StyleDisplay();
   bool isScrollable = fieldsetContentDisplay->IsScrollableOverflow();
   nsContainerFrame* scrollFrame = nullptr;
   if (isScrollable) {
     fieldsetContentStyle = BeginBuildingScrollFrame(
         aState, content, fieldsetContentStyle, fieldsetFrame,
-        nsCSSAnonBoxes::scrolledContent(), false, scrollFrame);
+        PseudoStyleType::scrolledContent, false, scrollFrame);
   }
 
   nsContainerFrame* absPosContainer = nullptr;
   if (fieldsetFrame->IsAbsPosContainingBlock()) {
     absPosContainer = fieldsetFrame;
   }
 
   // Create the inner ::-moz-fieldset-content frame.
@@ -3178,27 +3182,29 @@ nsIFrame* nsCSSFrameConstructor::Constru
                                                  aStyleDisplay, aFrameItems,
                                                  NS_NewDetailsFrame);
 }
 
 static nsIFrame* FindAncestorWithGeneratedContentPseudo(nsIFrame* aFrame) {
   for (nsIFrame* f = aFrame->GetParent(); f; f = f->GetParent()) {
     NS_ASSERTION(f->IsGeneratedContentFrame(),
                  "should not have exited generated content");
-    nsAtom* pseudo = f->Style()->GetPseudo();
-    if (pseudo == nsCSSPseudoElements::before() ||
-        pseudo == nsCSSPseudoElements::after())
+    auto pseudo = f->Style()->GetPseudoType();
+    if (pseudo == PseudoStyleType::before || pseudo == PseudoStyleType::after)
       return f;
   }
   return nullptr;
 }
 
 #define SIMPLE_FCDATA(_func) FCDATA_DECL(0, _func)
-#define FULL_CTOR_FCDATA(_flags, _func) \
-  { _flags | FCDATA_FUNC_IS_FULL_CTOR, {nullptr}, _func, nullptr }
+#define FULL_CTOR_FCDATA(_flags, _func)                  \
+  {                                                      \
+    _flags | FCDATA_FUNC_IS_FULL_CTOR, {nullptr}, _func, \
+        PseudoStyleType::NotPseudo                       \
+  }
 
 /* static */
 const nsCSSFrameConstructor::FrameConstructionData*
 nsCSSFrameConstructor::FindTextData(const Text& aTextContent,
                                     nsIFrame* aParentFrame) {
   if (aParentFrame && IsFrameForSVG(aParentFrame)) {
     nsIFrame* ancestorFrame =
         nsSVGUtils::GetFirstNonAAncestorFrame(aParentFrame);
@@ -3311,36 +3317,36 @@ nsCSSFrameConstructor::FindDataByTag(nsA
 #define SIMPLE_TAG_CREATE(_tag, _func) \
   { nsGkAtoms::_tag, SIMPLE_FCDATA(_func) }
 #define SIMPLE_TAG_CHAIN(_tag, _func) \
   { nsGkAtoms::_tag, FCDATA_DECL(FCDATA_FUNC_IS_DATA_GETTER, _func) }
 #define COMPLEX_TAG_CREATE(_tag, _func) \
   { nsGkAtoms::_tag, FULL_CTOR_FCDATA(0, _func) }
 
 static bool IsFrameForFieldSet(nsIFrame* aFrame) {
-  nsAtom* pseudo = aFrame->Style()->GetPseudo();
-  if (pseudo == nsCSSAnonBoxes::fieldsetContent() ||
-      pseudo == nsCSSAnonBoxes::scrolledContent() ||
-      pseudo == nsCSSAnonBoxes::columnContent()) {
+  auto pseudo = aFrame->Style()->GetPseudoType();
+  if (pseudo == PseudoStyleType::fieldsetContent ||
+      pseudo == PseudoStyleType::scrolledContent ||
+      pseudo == PseudoStyleType::columnContent) {
     return IsFrameForFieldSet(aFrame->GetParent());
   }
   return aFrame->IsFieldSetFrame();
 }
 
 /* static */
 const nsCSSFrameConstructor::FrameConstructionData*
 nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
                                     nsIFrame* aParentFrame,
                                     ComputedStyle& aStyle) {
   MOZ_ASSERT(aElement.IsHTMLElement());
 
   nsAtom* tag = aElement.NodeInfo()->NameAtom();
   NS_ASSERTION(!aParentFrame ||
-                   aParentFrame->Style()->GetPseudo() !=
-                       nsCSSAnonBoxes::fieldsetContent() ||
+                   aParentFrame->Style()->GetPseudoType() !=
+                       PseudoStyleType::fieldsetContent ||
                    aParentFrame->GetParent()->IsFieldSetFrame(),
                "Unexpected parent for fieldset content anon box");
   if (tag == nsGkAtoms::legend &&
       (!aParentFrame || !IsFrameForFieldSet(aParentFrame) ||
        aStyle.StyleDisplay()->IsFloatingStyle() ||
        aStyle.StyleDisplay()->IsAbsolutelyPositionedStyle())) {
     // <legend> is only special inside fieldset, we only check the frame tree
     // parent because the content tree parent may not be a <fieldset> due to
@@ -3369,17 +3375,17 @@ nsCSSFrameConstructor::FindHTMLData(cons
        FCDATA_DECL(FCDATA_ALLOW_BLOCK_STYLES | FCDATA_MAY_NEED_SCROLLFRAME |
                        FCDATA_MAY_NEED_BULLET,
                    NS_NewLegendFrame)},
       SIMPLE_TAG_CREATE(frameset, NS_NewHTMLFramesetFrame),
       SIMPLE_TAG_CREATE(iframe, NS_NewSubDocumentFrame),
       {nsGkAtoms::button,
        FCDATA_WITH_WRAPPING_BLOCK(
            FCDATA_ALLOW_BLOCK_STYLES | FCDATA_ALLOW_GRID_FLEX_COLUMNSET,
-           NS_NewHTMLButtonControlFrame, nsCSSAnonBoxes::buttonContent())},
+           NS_NewHTMLButtonControlFrame, PseudoStyleType::buttonContent)},
       SIMPLE_TAG_CHAIN(canvas, nsCSSFrameConstructor::FindCanvasData),
       SIMPLE_TAG_CREATE(video, NS_NewHTMLVideoFrame),
       SIMPLE_TAG_CREATE(audio, NS_NewHTMLVideoFrame),
       SIMPLE_TAG_CREATE(progress, NS_NewProgressFrame),
       SIMPLE_TAG_CREATE(meter, NS_NewMeterFrame),
       COMPLEX_TAG_CREATE(details,
                          &nsCSSFrameConstructor::ConstructDetailsFrame)};
 
@@ -3439,36 +3445,36 @@ nsCSSFrameConstructor::FindInputData(con
       SIMPLE_INT_CREATE(NS_FORM_INPUT_SEARCH, NS_NewTextControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_TEXT, NS_NewTextControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_TEL, NS_NewTextControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_RANGE, NS_NewRangeFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame),
       {NS_FORM_INPUT_COLOR,
        FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewColorControlFrame,
-                                  nsCSSAnonBoxes::buttonContent())},
+                                  PseudoStyleType::buttonContent)},
       // TODO: this is temporary until a frame is written: bug 635240.
       SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewNumberControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewDateTimeControlFrame),
       SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewDateTimeControlFrame),
       // TODO: this is temporary until a frame is written: bug 888320
       SIMPLE_INT_CREATE(NS_FORM_INPUT_MONTH, NS_NewTextControlFrame),
       // TODO: this is temporary until a frame is written: bug 888320
       SIMPLE_INT_CREATE(NS_FORM_INPUT_WEEK, NS_NewTextControlFrame),
       // TODO: this is temporary until a frame is written: bug 888320
       SIMPLE_INT_CREATE(NS_FORM_INPUT_DATETIME_LOCAL, NS_NewTextControlFrame),
       {NS_FORM_INPUT_SUBMIT,
        FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
-                                  nsCSSAnonBoxes::buttonContent())},
+                                  PseudoStyleType::buttonContent)},
       {NS_FORM_INPUT_RESET,
        FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
-                                  nsCSSAnonBoxes::buttonContent())},
+                                  PseudoStyleType::buttonContent)},
       {NS_FORM_INPUT_BUTTON,
        FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
-                                  nsCSSAnonBoxes::buttonContent())}
+                                  PseudoStyleType::buttonContent)}
       // Keeping hidden inputs out of here on purpose for so they get frames by
       // display (in practice, none).
   };
 
   auto controlType = HTMLInputElement::FromNode(aElement)->ControlType();
 
   // radio and checkbox inputs with appearance:none should be constructed
   // by display type.  (Note that we're not checking that appearance is
@@ -3535,17 +3541,17 @@ nsCSSFrameConstructor::FindCanvasData(co
   if (doc->IsStaticDocument()) {
     doc = doc->GetOriginalDocument();
   }
   if (!doc->IsScriptEnabled()) {
     return nullptr;
   }
 
   static const FrameConstructionData sCanvasData = FCDATA_WITH_WRAPPING_BLOCK(
-      0, NS_NewHTMLCanvasFrame, nsCSSAnonBoxes::htmlCanvasContent());
+      0, NS_NewHTMLCanvasFrame, PseudoStyleType::htmlCanvasContent);
   return &sCanvasData;
 }
 
 void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
     FrameConstructionItem& aItem, nsFrameConstructorState& aState,
     nsContainerFrame* aParentFrame, nsFrameItems& aFrameItems) {
   const FrameConstructionData* data = aItem.mFCData;
   NS_ASSERTION(data, "Must have frame construction data");
@@ -4125,17 +4131,18 @@ nsCSSFrameConstructor::FindXULDisplayDat
              "Did someone mess with the order?");
 
   return &data.mData;
 }
 
 already_AddRefed<ComputedStyle> nsCSSFrameConstructor::BeginBuildingScrollFrame(
     nsFrameConstructorState& aState, nsIContent* aContent,
     ComputedStyle* aContentStyle, nsContainerFrame* aParentFrame,
-    nsAtom* aScrolledPseudo, bool aIsRoot, nsContainerFrame*& aNewFrame) {
+    PseudoStyleType aScrolledPseudo, bool aIsRoot,
+    nsContainerFrame*& aNewFrame) {
   nsContainerFrame* gfxScrollFrame = aNewFrame;
 
   nsFrameItems anonymousItems;
 
   RefPtr<ComputedStyle> contentStyle = aContentStyle;
 
   if (!gfxScrollFrame) {
     // Build a XULScrollFrame when the child is a box, otherwise an
@@ -4235,17 +4242,17 @@ void nsCSSFrameConstructor::FinishBuildi
 void nsCSSFrameConstructor::BuildScrollFrame(nsFrameConstructorState& aState,
                                              nsIContent* aContent,
                                              ComputedStyle* aContentStyle,
                                              nsIFrame* aScrolledFrame,
                                              nsContainerFrame* aParentFrame,
                                              nsContainerFrame*& aNewFrame) {
   RefPtr<ComputedStyle> scrolledContentStyle = BeginBuildingScrollFrame(
       aState, aContent, aContentStyle, aParentFrame,
-      nsCSSAnonBoxes::scrolledContent(), false, aNewFrame);
+      PseudoStyleType::scrolledContent, false, aNewFrame);
 
   aScrolledFrame->SetComputedStyleWithoutNotification(scrolledContentStyle);
   InitAndRestoreFrame(aState, aContent, aNewFrame, aScrolledFrame);
 
   FinishBuildingScrollFrame(aNewFrame, aScrolledFrame);
 }
 
 const nsCSSFrameConstructor::FrameConstructionData*
@@ -4497,17 +4504,17 @@ nsIFrame* nsCSSFrameConstructor::Constru
     nsFrameItems& aFrameItems, BlockFrameCreationFunc aConstructor) {
   nsIContent* const content = aItem.mContent;
   ComputedStyle* const computedStyle = aItem.mComputedStyle;
 
   nsContainerFrame* newFrame = nullptr;
   RefPtr<ComputedStyle> scrolledContentStyle = BeginBuildingScrollFrame(
       aState, content, computedStyle,
       aState.GetGeometricParent(*aDisplay, aParentFrame),
-      nsCSSAnonBoxes::scrolledContent(), false, newFrame);
+      PseudoStyleType::scrolledContent, false, newFrame);
 
   // Create our block frame
   // pass a temporary stylecontext, the correct one will be set later
   nsContainerFrame* scrolledFrame = aConstructor(mPresShell, computedStyle);
 
   // Make sure to AddChild before we call ConstructBlock so that we
   // end up before our descendants in fixed-pos lists as needed.
   aState.AddChild(newFrame, aFrameItems, content, aParentFrame);
@@ -4623,17 +4630,17 @@ void nsCSSFrameConstructor::FlushAccumul
     nsFrameConstructorState& aState, nsIContent* aContent,
     nsContainerFrame* aParentFrame, nsFrameItems& aBlockItems,
     nsFrameItems& aNewItems) {
   if (aBlockItems.IsEmpty()) {
     // Nothing to do
     return;
   }
 
-  nsAtom* anonPseudo = nsCSSAnonBoxes::mozMathMLAnonymousBlock();
+  auto anonPseudo = PseudoStyleType::mozMathMLAnonymousBlock;
 
   ComputedStyle* parentContext =
       nsFrame::CorrectStyleParentFrame(aParentFrame, anonPseudo)->Style();
   ServoStyleSet* styleSet = mPresShell->StyleSet();
   RefPtr<ComputedStyle> blockContext;
   blockContext =
       styleSet->ResolveInheritingAnonymousBoxStyle(anonPseudo, parentContext);
 
@@ -4729,18 +4736,18 @@ nsCSSFrameConstructor::FindMathMLData(co
   return FindDataByTag(tag, aElement, aStyle, sMathMLData,
                        ArrayLength(sMathMLData));
 }
 
 nsContainerFrame* nsCSSFrameConstructor::ConstructFrameWithAnonymousChild(
     nsFrameConstructorState& aState, FrameConstructionItem& aItem,
     nsContainerFrame* aParentFrame, nsFrameItems& aFrameItems,
     ContainerFrameCreationFunc aConstructor,
-    ContainerFrameCreationFunc aInnerConstructor,
-    nsCSSAnonBoxPseudoStaticAtom* aInnerPseudo, bool aCandidateRootFrame) {
+    ContainerFrameCreationFunc aInnerConstructor, PseudoStyleType aInnerPseudo,
+    bool aCandidateRootFrame) {
   nsIContent* const content = aItem.mContent;
   ComputedStyle* const computedStyle = aItem.mComputedStyle;
 
   // Create the outer frame:
   nsContainerFrame* newFrame = aConstructor(mPresShell, computedStyle);
 
   InitAndRestoreFrame(aState, content,
                       aCandidateRootFrame
@@ -4791,27 +4798,27 @@ nsContainerFrame* nsCSSFrameConstructor:
 }
 
 nsIFrame* nsCSSFrameConstructor::ConstructOuterSVG(
     nsFrameConstructorState& aState, FrameConstructionItem& aItem,
     nsContainerFrame* aParentFrame, const nsStyleDisplay* aDisplay,
     nsFrameItems& aFrameItems) {
   return ConstructFrameWithAnonymousChild(
       aState, aItem, aParentFrame, aFrameItems, NS_NewSVGOuterSVGFrame,
-      NS_NewSVGOuterSVGAnonChildFrame,
-      nsCSSAnonBoxes::mozSVGOuterSVGAnonChild(), true);
+      NS_NewSVGOuterSVGAnonChildFrame, PseudoStyleType::mozSVGOuterSVGAnonChild,
+      true);
 }
 
 nsIFrame* nsCSSFrameConstructor::ConstructMarker(
     nsFrameConstructorState& aState, FrameConstructionItem& aItem,
     nsContainerFrame* aParentFrame, const nsStyleDisplay* aDisplay,
     nsFrameItems& aFrameItems) {
   return ConstructFrameWithAnonymousChild(
       aState, aItem, aParentFrame, aFrameItems, NS_NewSVGMarkerFrame,
-      NS_NewSVGMarkerAnonChildFrame, nsCSSAnonBoxes::mozSVGMarkerAnonChild(),
+      NS_NewSVGMarkerAnonChildFrame, PseudoStyleType::mozSVGMarkerAnonChild,
       false);
 }
 
 // Only outer <svg> elements can be floated or positioned.  All other SVG
 // should be in-flow.
 #define SIMPLE_SVG_FCDATA(_func)                                      \
   FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH | \
                   FCDATA_DISALLOW_GENERATED_CONTENT,                  \
@@ -4986,21 +4993,21 @@ nsCSSFrameConstructor::FindSVGData(const
       SIMPLE_SVG_CREATE(line, NS_NewSVGGeometryFrame),
       SIMPLE_SVG_CREATE(rect, NS_NewSVGGeometryFrame),
       SIMPLE_SVG_CREATE(path, NS_NewSVGGeometryFrame),
       SIMPLE_SVG_CREATE(defs, NS_NewSVGContainerFrame),
       SIMPLE_SVG_CREATE(generic_, NS_NewSVGGenericContainerFrame),
       {nsGkAtoms::text,
        FCDATA_WITH_WRAPPING_BLOCK(
            FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_ALLOW_BLOCK_STYLES,
-           NS_NewSVGTextFrame, nsCSSAnonBoxes::mozSVGText())},
+           NS_NewSVGTextFrame, PseudoStyleType::mozSVGText)},
       {nsGkAtoms::foreignObject,
        FCDATA_WITH_WRAPPING_BLOCK(FCDATA_DISALLOW_OUT_OF_FLOW,
                                   NS_NewSVGForeignObjectFrame,
-                                  nsCSSAnonBoxes::mozSVGForeignContent())},
+                                  PseudoStyleType::mozSVGForeignContent)},
       SIMPLE_SVG_CREATE(a, NS_NewSVGAFrame),
       SIMPLE_SVG_CREATE(linearGradient, NS_NewSVGLinearGradientFrame),
       SIMPLE_SVG_CREATE(radialGradient, NS_NewSVGRadialGradientFrame),
       SIMPLE_SVG_CREATE(stop, NS_NewSVGStopFrame),
       SIMPLE_SVG_CREATE(use, NS_NewSVGUseFrame),
       SIMPLE_SVG_CREATE(view, NS_NewSVGViewFrame),
       SIMPLE_SVG_CREATE(image, NS_NewSVGImageFrame),
       SIMPLE_SVG_CREATE(clipPath, NS_NewSVGClipPathFrame),
@@ -5042,17 +5049,17 @@ nsCSSFrameConstructor::FindSVGData(const
 
   return data;
 }
 
 void nsCSSFrameConstructor::AddPageBreakItem(
     nsIContent* aContent, FrameConstructionItemList& aItems) {
   RefPtr<ComputedStyle> pseudoStyle =
       mPresShell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::pageBreak());
+          PseudoStyleType::pageBreak);
 
   MOZ_ASSERT(pseudoStyle->StyleDisplay()->mDisplay == StyleDisplay::Block,
              "Unexpected display");
 
   static const FrameConstructionData sPageBreakData =
       FCDATA_DECL(FCDATA_SKIP_FRAMESET, NS_NewPageBreakFrame);
 
   aItems.AppendItem(this, &sPageBreakData, aContent, nullptr,
@@ -5355,17 +5362,17 @@ void nsCSSFrameConstructor::AddFrameCons
 
     style = xblInfo.mStyle.forget();
     aComputedStyle = style.get();
 
     tag = xblInfo.mTag;
   }
 
   const bool isGeneratedContent = !!(aFlags & ITEM_IS_GENERATED_CONTENT);
-  MOZ_ASSERT(!isGeneratedContent || style->GetPseudo(),
+  MOZ_ASSERT(!isGeneratedContent || style->IsPseudoElement(),
              "Generated content should be a pseudo-element");
 
   FrameConstructionItem* item = nullptr;
   auto cleanupGeneratedContent = mozilla::MakeScopeExit([&]() {
     if (isGeneratedContent && !item) {
       MOZ_ASSERT(!IsDisplayContents(aContent),
                  "This would need to change if we support display: contents "
                  "in generated content");
@@ -5378,29 +5385,29 @@ void nsCSSFrameConstructor::AddFrameCons
   // Pre-check for display "none" - if we find that, don't create
   // any frame at all
   if (display.mDisplay == StyleDisplay::None) {
     return;
   }
 
   if (display.mDisplay == StyleDisplay::Contents) {
     CreateGeneratedContentItem(aState, aParentFrame, *aContent->AsElement(),
-                               *style, CSSPseudoElementType::before, aItems);
+                               *style, PseudoStyleType::before, aItems);
 
     FlattenedChildIterator iter(aContent);
     InsertionPoint insertion(aParentFrame, aContent);
     for (nsIContent* child = iter.GetNextChild(); child;
          child = iter.GetNextChild()) {
       AddFrameConstructionItems(aState, child, aSuppressWhiteSpaceOptimizations,
                                 insertion, aItems);
     }
     aItems.SetParentHasNoXBLChildren(!iter.XBLInvolved());
 
     CreateGeneratedContentItem(aState, aParentFrame, *aContent->AsElement(),
-                               *style, CSSPseudoElementType::after, aItems);
+                               *style, PseudoStyleType::after, aItems);
     return;
   }
 
   nsIContent* parent = aParentFrame ? aParentFrame->GetContent() : nullptr;
   if (ShouldSuppressFrameInSelect(parent, *aContent)) {
     return;
   }
 
@@ -8330,17 +8337,17 @@ bool nsCSSFrameConstructor::MaybeRecreat
         inFlowFrame->GetProperty(nsIFrame::HasColumnSpanSiblings()) ||
         // 3. Removing the only child of a ::-moz-column-content, whose
         // ColumnSet grandparent has a previous column-span sibling, requires
         // reframing since we might connect the ColumnSet's next column-span
         // sibling (if there's one). Note that this isn't actually needed if
         // the ColumnSet is at the end of ColumnSetWrapper since we create
         // empty ones at the end anyway, but we're not worried about
         // optimizing that case.
-        (parent->Style()->GetPseudo() == nsCSSAnonBoxes::columnContent() &&
+        (parent->Style()->GetPseudoType() == PseudoStyleType::columnContent &&
          // The only child in ::-moz-column-content (might be tall enough to
          // split across columns)
          !inFlowFrame->GetPrevSibling() && !inFlowFrame->GetNextSibling() &&
          // That ::-moz-column-content is the first column.
          !parent->GetPrevInFlow() &&
          // The ColumnSet grandparent has a previous sibling that is a
          // column-span.
          grandparent->GetPrevSibling());
@@ -8694,52 +8701,52 @@ bool nsCSSFrameConstructor::DestroyFrame
 //////////////////////////////////////////////////////////////////////
 
 // Block frame construction code
 
 already_AddRefed<ComputedStyle> nsCSSFrameConstructor::GetFirstLetterStyle(
     nsIContent* aContent, ComputedStyle* aComputedStyle) {
   if (aContent) {
     return mPresShell->StyleSet()->ResolvePseudoElementStyle(
-        aContent->AsElement(), CSSPseudoElementType::firstLetter,
-        aComputedStyle, nullptr);
+        aContent->AsElement(), PseudoStyleType::firstLetter, aComputedStyle,
+        nullptr);
   }
   return nullptr;
 }
 
 already_AddRefed<ComputedStyle> nsCSSFrameConstructor::GetFirstLineStyle(
     nsIContent* aContent, ComputedStyle* aComputedStyle) {
   if (aContent) {
     return mPresShell->StyleSet()->ResolvePseudoElementStyle(
-        aContent->AsElement(), CSSPseudoElementType::firstLine, aComputedStyle,
+        aContent->AsElement(), PseudoStyleType::firstLine, aComputedStyle,
         nullptr);
   }
   return nullptr;
 }
 
 // Predicate to see if a given content (block element) has
 // first-letter style applied to it.
 bool nsCSSFrameConstructor::ShouldHaveFirstLetterStyle(
     nsIContent* aContent, ComputedStyle* aComputedStyle) {
   return nsLayoutUtils::HasPseudoStyle(aContent, aComputedStyle,
-                                       CSSPseudoElementType::firstLetter,
+                                       PseudoStyleType::firstLetter,
                                        mPresShell->GetPresContext());
 }
 
 bool nsCSSFrameConstructor::HasFirstLetterStyle(nsIFrame* aBlockFrame) {
   MOZ_ASSERT(aBlockFrame, "Need a frame");
   NS_ASSERTION(aBlockFrame->IsBlockFrameOrSubclass(), "Not a block frame?");
 
   return (aBlockFrame->GetStateBits() & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0;
 }
 
 bool nsCSSFrameConstructor::ShouldHaveFirstLineStyle(
     nsIContent* aContent, ComputedStyle* aComputedStyle) {
   bool hasFirstLine = nsLayoutUtils::HasPseudoStyle(
-      aContent, aComputedStyle, CSSPseudoElementType::firstLine,
+      aContent, aComputedStyle, PseudoStyleType::firstLine,
       mPresShell->GetPresContext());
   return hasFirstLine && !aContent->IsHTMLElement(nsGkAtoms::fieldset);
 }
 
 void nsCSSFrameConstructor::ShouldHaveSpecialBlockStyle(
     nsIContent* aContent, ComputedStyle* aComputedStyle,
     bool* aHaveFirstLetterStyle, bool* aHaveFirstLineStyle) {
   *aHaveFirstLetterStyle = ShouldHaveFirstLetterStyle(aContent, aComputedStyle);
@@ -8750,80 +8757,80 @@ void nsCSSFrameConstructor::ShouldHaveSp
 const nsCSSFrameConstructor::PseudoParentData
     nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
         // Cell
         {FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
                               FCDATA_USE_CHILD_ITEMS |
                               FCDATA_IS_WRAPPER_ANON_BOX |
                               FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
                           &nsCSSFrameConstructor::ConstructTableCell),
-         nsCSSAnonBoxes::tableCell()},
+         PseudoStyleType::tableCell},
         // Row
         {FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
                               FCDATA_USE_CHILD_ITEMS |
                               FCDATA_IS_WRAPPER_ANON_BOX |
                               FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
                           &nsCSSFrameConstructor::ConstructTableRowOrRowGroup),
-         nsCSSAnonBoxes::tableRow()},
+         PseudoStyleType::tableRow},
         // Row group
         {FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
                               FCDATA_USE_CHILD_ITEMS |
                               FCDATA_IS_WRAPPER_ANON_BOX |
                               FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
                           &nsCSSFrameConstructor::ConstructTableRowOrRowGroup),
-         nsCSSAnonBoxes::tableRowGroup()},
+         PseudoStyleType::tableRowGroup},
         // Column group
         {FCDATA_DECL(
              FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
                  FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_USE_CHILD_ITEMS |
                  FCDATA_SKIP_ABSPOS_PUSH |
                  // Not FCDATA_IS_WRAPPER_ANON_BOX, because we don't need to
                  // restyle these: they have non-inheriting styles.
                  FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
              NS_NewTableColGroupFrame),
-         nsCSSAnonBoxes::tableColGroup()},
+         PseudoStyleType::tableColGroup},
         // Table
         {FULL_CTOR_FCDATA(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS |
                               FCDATA_IS_WRAPPER_ANON_BOX,
                           &nsCSSFrameConstructor::ConstructTable),
-         nsCSSAnonBoxes::table()},
+         PseudoStyleType::table},
         // Ruby
         {FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT | FCDATA_USE_CHILD_ITEMS |
                          FCDATA_IS_WRAPPER_ANON_BOX | FCDATA_SKIP_FRAMESET,
                      NS_NewRubyFrame),
-         nsCSSAnonBoxes::ruby()},
+         PseudoStyleType::ruby},
         // Ruby Base
         {FCDATA_DECL(
              FCDATA_USE_CHILD_ITEMS | FCDATA_IS_LINE_PARTICIPANT |
                  FCDATA_IS_WRAPPER_ANON_BOX |
                  FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyBaseContainer) |
                  FCDATA_SKIP_FRAMESET,
              NS_NewRubyBaseFrame),
-         nsCSSAnonBoxes::rubyBase()},
+         PseudoStyleType::rubyBase},
         // Ruby Base Container
         {FCDATA_DECL(FCDATA_USE_CHILD_ITEMS | FCDATA_IS_LINE_PARTICIPANT |
                          FCDATA_IS_WRAPPER_ANON_BOX |
                          FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby) |
                          FCDATA_SKIP_FRAMESET,
                      NS_NewRubyBaseContainerFrame),
-         nsCSSAnonBoxes::rubyBaseContainer()},
+         PseudoStyleType::rubyBaseContainer},
         // Ruby Text
         {FCDATA_DECL(
              FCDATA_USE_CHILD_ITEMS | FCDATA_IS_LINE_PARTICIPANT |
                  FCDATA_IS_WRAPPER_ANON_BOX |
                  FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyTextContainer) |
                  FCDATA_SKIP_FRAMESET,
              NS_NewRubyTextFrame),
-         nsCSSAnonBoxes::rubyText()},
+         PseudoStyleType::rubyText},
         // Ruby Text Container
         {FCDATA_DECL(FCDATA_USE_CHILD_ITEMS | FCDATA_IS_WRAPPER_ANON_BOX |
                          FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby) |
                          FCDATA_SKIP_FRAMESET,
                      NS_NewRubyTextContainerFrame),
-         nsCSSAnonBoxes::rubyTextContainer()}};
+         PseudoStyleType::rubyTextContainer}};
 
 void nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
     nsFrameConstructorState& aState, FrameConstructionItemList& aItems,
     nsIFrame* aParentFrame) {
   if (aItems.IsEmpty() || !aParentFrame->IsFlexOrGridContainer()) {
     return;
   }
 
@@ -8880,19 +8887,19 @@ void nsCSSFrameConstructor::CreateNeeded
     FCItemIterator endIter(iter);  // iterator to find the end of the group
     endIter.SkipItemsThatNeedAnonFlexOrGridItem(aState, isLegacyBox);
 
     NS_ASSERTION(iter != endIter,
                  "Should've had at least one wrappable child to seek past");
 
     // Now, we create the anonymous flex or grid item to contain the children
     // between |iter| and |endIter|.
-    nsAtom* pseudoType = (aParentFrame->IsFlexContainerFrame())
-                             ? nsCSSAnonBoxes::anonymousFlexItem()
-                             : nsCSSAnonBoxes::anonymousGridItem();
+    auto pseudoType = aParentFrame->IsFlexContainerFrame()
+                          ? PseudoStyleType::anonymousFlexItem
+                          : PseudoStyleType::anonymousGridItem;
     ComputedStyle* parentStyle = aParentFrame->Style();
     nsIContent* parentContent = aParentFrame->GetContent();
     RefPtr<ComputedStyle> wrapperStyle =
         mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(pseudoType,
                                                                    parentStyle);
 
     static const FrameConstructionData sBlockFormattingContextFCData =
         FCDATA_DECL(FCDATA_SKIP_FRAMESET | FCDATA_USE_CHILD_ITEMS |
@@ -9352,24 +9359,24 @@ void nsCSSFrameConstructor::CreateNeeded
  * |aEndIter|. After it returns, aIter points to the first item
  * after the wrapper.
  */
 void nsCSSFrameConstructor::WrapItemsInPseudoParent(
     nsIContent* aParentContent, ComputedStyle* aParentStyle,
     ParentType aWrapperType, FCItemIterator& aIter,
     const FCItemIterator& aEndIter) {
   const PseudoParentData& pseudoData = sPseudoParentData[aWrapperType];
-  nsCSSAnonBoxPseudoStaticAtom* pseudoType = pseudoData.mPseudoType;
+  PseudoStyleType pseudoType = pseudoData.mPseudoType;
   StyleDisplay parentDisplay = aParentStyle->StyleDisplay()->mDisplay;
 
-  if (pseudoType == nsCSSAnonBoxes::table() &&
+  if (pseudoType == PseudoStyleType::table &&
       (parentDisplay == StyleDisplay::Inline ||
        parentDisplay == StyleDisplay::RubyBase ||
        parentDisplay == StyleDisplay::RubyText)) {
-    pseudoType = nsCSSAnonBoxes::inlineTable();
+    pseudoType = PseudoStyleType::inlineTable;
   }
 
   RefPtr<ComputedStyle> wrapperStyle;
   if (pseudoData.mFCData.mBits & FCDATA_IS_WRAPPER_ANON_BOX) {
     wrapperStyle = mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
         pseudoType, aParentStyle);
   } else {
     wrapperStyle =
@@ -9636,20 +9643,21 @@ void nsCSSFrameConstructor::ProcessChild
     //
     // Note that we don't use this style for looking up things like special
     // block styles because in some cases involving table pseudo-frames it has
     // nothing to do with the parent frame's desired behavior.
     ComputedStyle* computedStyle;
 
     if (aCanHaveGeneratedContent) {
       computedStyle =
-          nsFrame::CorrectStyleParentFrame(aFrame, nullptr)->Style();
+          nsFrame::CorrectStyleParentFrame(aFrame, PseudoStyleType::NotPseudo)
+              ->Style();
       // Probe for generated content before
       CreateGeneratedContentItem(aState, aFrame, *aContent->AsElement(),
-                                 *computedStyle, CSSPseudoElementType::before,
+                                 *computedStyle, PseudoStyleType::before,
                                  itemsToConstruct);
     }
 
     const bool addChildItems = MOZ_LIKELY(mCurrentDepth < kMaxDepth);
     if (!addChildItems) {
       NS_WARNING("ProcessChildren max depth exceeded");
     }
 
@@ -9666,17 +9674,17 @@ void nsCSSFrameConstructor::ProcessChild
         ClearLazyBits(child, child->GetNextSibling());
       }
     }
     itemsToConstruct.SetParentHasNoXBLChildren(!iter.XBLInvolved());
 
     if (aCanHaveGeneratedContent) {
       // Probe for generated content after
       CreateGeneratedContentItem(aState, aFrame, *aContent->AsElement(),
-                                 *computedStyle, CSSPseudoElementType::after,
+                                 *computedStyle, PseudoStyleType::after,
                                  itemsToConstruct);
     }
   } else {
     ClearLazyBits(aContent->GetFirstChild(), nullptr);
   }
 
   ConstructFramesFromItemList(aState, itemsToConstruct, aFrame,
                               /* aParentIsWrapperAnonBox = */ false,
@@ -9723,17 +9731,17 @@ void nsCSSFrameConstructor::ProcessChild
           nsIScriptError::warningFlag,
           NS_LITERAL_CSTRING("Layout: FrameConstructor"), mDocument,
           nsContentUtils::eXUL_PROPERTIES, message, params,
           ArrayLength(params));
     }
 
     RefPtr<ComputedStyle> blockSC =
         mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::mozXULAnonymousBlock(), frameComputedStyle);
+            PseudoStyleType::mozXULAnonymousBlock, frameComputedStyle);
     nsBlockFrame* blockFrame = NS_NewBlockFrame(mPresShell, blockSC);
     // We might, in theory, want to set NS_BLOCK_FLOAT_MGR and
     // NS_BLOCK_MARGIN_ROOT, but I think it's a bad idea given that
     // a real block placed here wouldn't get those set on it.
 
     InitAndRestoreFrame(aState, aContent, aFrame, blockFrame, false);
 
     NS_ASSERTION(!blockFrame->HasView(), "need to do view reparenting");
@@ -9775,20 +9783,19 @@ void nsCSSFrameConstructor::WrapFramesIn
 
   if (firstLineChildren.IsEmpty()) {
     // Nothing is supposed to go into the first-line; nothing to do
     return;
   }
 
   if (!aLineFrame) {
     // Create line frame
-    ComputedStyle* parentStyle =
-        nsFrame::CorrectStyleParentFrame(aBlockFrame,
-                                         nsCSSPseudoElements::firstLine())
-            ->Style();
+    ComputedStyle* parentStyle = nsFrame::CorrectStyleParentFrame(
+                                     aBlockFrame, PseudoStyleType::firstLine)
+                                     ->Style();
     RefPtr<ComputedStyle> firstLineStyle =
         GetFirstLineStyle(aBlockContent, parentStyle);
 
     aLineFrame = NS_NewFirstLineFrame(mPresShell, firstLineStyle);
 
     // Initialize the line frame
     InitAndRestoreFrame(aState, aBlockContent, aBlockFrame, aLineFrame);
 
@@ -10018,32 +10025,32 @@ void nsCSSFrameConstructor::CreateLetter
     nsFrameItems& aResult) {
   MOZ_ASSERT(aTextContent->IsText(), "aTextContent isn't text");
   NS_ASSERTION(aBlockFrame->IsBlockFrameOrSubclass(), "Not a block frame?");
 
   // Get a ComputedStyle for the first-letter-frame.
   //
   // Keep this in sync with nsBlockFrame::UpdatePseudoElementStyles.
   nsIFrame* parentFrame = nsFrame::CorrectStyleParentFrame(
-      aParentFrame, nsCSSPseudoElements::firstLetter());
+      aParentFrame, PseudoStyleType::firstLetter);
 
   ComputedStyle* parentComputedStyle = parentFrame->Style();
 
   // Use content from containing block so that we can actually
   // find a matching style rule.
   nsIContent* blockContent = aBlockFrame->GetContent();
 
   // Create first-letter style rule
   RefPtr<ComputedStyle> sc =
       GetFirstLetterStyle(blockContent, parentComputedStyle);
 
   if (sc) {
     if (parentFrame->IsLineFrame()) {
       nsIFrame* parentIgnoringFirstLine = nsFrame::CorrectStyleParentFrame(
-          aBlockFrame, nsCSSPseudoElements::firstLetter());
+          aBlockFrame, PseudoStyleType::firstLetter);
 
       sc = mPresShell->StyleSet()->ReparentComputedStyle(
           sc, parentComputedStyle, parentIgnoringFirstLine->Style(),
           parentComputedStyle, blockContent->AsElement());
     }
 
     RefPtr<ComputedStyle> textSC =
         mPresShell->StyleSet()->ResolveStyleForText(aTextContent, sc);
@@ -10442,17 +10449,17 @@ nsContainerFrame* nsCSSFrameConstructor:
   // Wrap the block frame in a ColumnSetFrame.
   nsContainerFrame* columnSetFrame = NS_NewColumnSetFrame(
       mPresShell, aComputedStyle, nsFrameState(NS_FRAME_OWNS_ANON_BOXES));
   InitAndRestoreFrame(aState, aContent, aParentFrame, columnSetFrame);
   SetInitialSingleChild(columnSetFrame, aBlockFrame);
 
   RefPtr<ComputedStyle> anonBlockStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::columnContent(), aComputedStyle);
+          PseudoStyleType::columnContent, aComputedStyle);
   aBlockFrame->SetComputedStyleWithoutNotification(anonBlockStyle);
   InitAndRestoreFrame(aState, aContent, columnSetFrame, aBlockFrame);
 
   return columnSetFrame;
 }
 
 void nsCSSFrameConstructor::ConstructBlock(
     nsFrameConstructorState& aState, nsIContent* aContent,
@@ -10692,17 +10699,17 @@ nsContainerFrame* nsCSSFrameConstructor:
     // Wrap the block frame in a ColumnSetFrame.
     nsContainerFrame* columnSetFrame = NS_NewColumnSetFrame(
         mPresShell, aComputedStyle, nsFrameState(NS_FRAME_OWNS_ANON_BOXES));
     InitAndRestoreFrame(aState, aContent, aParentFrame, columnSetFrame);
     SetInitialSingleChild(columnSetFrame, aColumnContent);
 
     RefPtr<ComputedStyle> anonBlockStyle =
         mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::columnContent(), aComputedStyle);
+            PseudoStyleType::columnContent, aComputedStyle);
     aColumnContent->SetComputedStyleWithoutNotification(anonBlockStyle);
     InitAndRestoreFrame(aState, aContent, columnSetFrame, aColumnContent);
 
     return columnSetFrame;
   }
 
   // The initial column hierarchy looks like this:
   //
@@ -10711,25 +10718,25 @@ nsContainerFrame* nsCSSFrameConstructor:
   //     Block (-moz-column-content)
   //
   nsBlockFrame* columnSetWrapper = NS_NewColumnSetWrapperFrame(
       mPresShell, aComputedStyle, nsFrameState(NS_FRAME_OWNS_ANON_BOXES));
   InitAndRestoreFrame(aState, aContent, aParentFrame, columnSetWrapper);
 
   RefPtr<ComputedStyle> columnSetStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::columnSet(), aComputedStyle);
+          PseudoStyleType::columnSet, aComputedStyle);
   nsContainerFrame* columnSet = NS_NewColumnSetFrame(
       mPresShell, columnSetStyle, nsFrameState(NS_FRAME_OWNS_ANON_BOXES));
   InitAndRestoreFrame(aState, aContent, columnSetWrapper, columnSet);
   columnSet->AddStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR);
 
   RefPtr<ComputedStyle> blockStyle =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::columnContent(), columnSetStyle);
+          PseudoStyleType::columnContent, columnSetStyle);
   aColumnContent->SetComputedStyleWithoutNotification(blockStyle);
   InitAndRestoreFrame(aState, aContent, columnSet, aColumnContent);
   aColumnContent->AddStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR);
 
   // Set up the parent-child chain.
   SetInitialSingleChild(columnSetWrapper, columnSet);
   SetInitialSingleChild(columnSet, aColumnContent);
 
@@ -10810,17 +10817,17 @@ nsFrameItems nsCSSFrameConstructor::Crea
     MOZ_ASSERT(aChildList.NotEmpty(), "Why call this if child list is empty?");
     MOZ_ASSERT(aChildList.FirstChild()->IsColumnSpan(),
                "Must have the child starting with column-span!");
 
     // Grab the consecutive column-span kids, and reparent them into a
     // block frame.
     RefPtr<ComputedStyle> columnSpanWrapperStyle =
         mPresShell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::columnSpanWrapper());
+            PseudoStyleType::columnSpanWrapper);
     nsBlockFrame* columnSpanWrapper =
         NS_NewBlockFrame(mPresShell, columnSpanWrapperStyle);
     InitAndRestoreFrame(aState, content, parentFrame, columnSpanWrapper, false);
     columnSpanWrapper->AddStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR |
                                     NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
 
     nsFrameList columnSpanKids =
         aChildList.Split([](nsIFrame* f) { return !f->IsColumnSpan(); });
@@ -11073,17 +11080,17 @@ void nsCSSFrameConstructor::CreateIBSibl
   // The distinction in styles is needed because of CSS 2.1, section
   // 9.2.1.1, which says:
   //
   //   When such an inline box is affected by relative positioning, any
   //   resulting translation also affects the block-level box contained
   //   in the inline box.
   RefPtr<ComputedStyle> blockSC =
       mPresShell->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::mozBlockInsideInlineWrapper(), computedStyle);
+          PseudoStyleType::mozBlockInsideInlineWrapper, computedStyle);
 
   nsContainerFrame* lastNewInline =
       static_cast<nsContainerFrame*>(aInitialInline->FirstContinuation());
   do {
     // On entry to this loop aChildItems is not empty and the first frame in it
     // is block-level.
     MOZ_ASSERT(aChildItems.NotEmpty(), "Should have child items");
     MOZ_ASSERT(aChildItems.FirstChild()->IsBlockOutside(),
@@ -11169,19 +11176,19 @@ void nsCSSFrameConstructor::BuildInlineC
   nsFrameConstructorState::PendingBindingAutoPusher pusher(
       aState, aParentItem.mPendingBinding);
 
   ComputedStyle* const parentComputedStyle = aParentItem.mComputedStyle;
   nsIContent* const parentContent = aParentItem.mContent;
 
   if (!aItemIsWithinSVGText) {
     // Probe for generated content before
-    CreateGeneratedContentItem(
-        aState, nullptr, *parentContent->AsElement(), *parentComputedStyle,
-        CSSPseudoElementType::before, aParentItem.mChildItems);
+    CreateGeneratedContentItem(aState, nullptr, *parentContent->AsElement(),
+                               *parentComputedStyle, PseudoStyleType::before,
+                               aParentItem.mChildItems);
   }
 
   uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK;
   if (aItemIsWithinSVGText) {
     flags |= ITEM_IS_WITHIN_SVG_TEXT;
   }
   if (aItemAllowsTextPathChild &&
       aParentItem.mContent->IsSVGElement(nsGkAtoms::a)) {
@@ -11202,19 +11209,19 @@ void nsCSSFrameConstructor::BuildInlineC
     RefPtr<ComputedStyle> childContext = ResolveComputedStyle(content);
     AddFrameConstructionItemsInternal(aState, content, nullptr,
                                       iter.XBLInvolved(), childContext, flags,
                                       aParentItem.mChildItems);
   }
 
   if (!aItemIsWithinSVGText) {
     // Probe for generated content after
-    CreateGeneratedContentItem(
-        aState, nullptr, *parentContent->AsElement(), *parentComputedStyle,
-        CSSPseudoElementType::after, aParentItem.mChildItems);
+    CreateGeneratedContentItem(aState, nullptr, *parentContent->AsElement(),
+                               *parentComputedStyle, PseudoStyleType::after,
+                               aParentItem.mChildItems);
   }
 
   aParentItem.mIsAllInline = aParentItem.mChildItems.AreAllItemsInline();
 }
 
 // return whether it's ok to append (in the AppendFrames sense) to
 // aParentFrame if our nextSibling is aNextSibling.  aParentFrame must
 // be an ib-split inline.
@@ -11536,17 +11543,18 @@ bool nsCSSFrameConstructor::WipeContaini
     }
 
     bool needsReframe =
         // 1. Insert / append any column-span children.
         anyColumnSpanItems ||
         // 2. GetInsertionPrevSibling() modifies insertion parent. If the prev
         // sibling is a column-span, aFrame ends up being the
         // column-span-wrapper.
-        aFrame->Style()->GetPseudo() == nsCSSAnonBoxes::columnSpanWrapper() ||
+        aFrame->Style()->GetPseudoType() ==
+            PseudoStyleType::columnSpanWrapper ||
         // 3. Append into {ib} split container. There might be room for
         // optimization, but let's reframe for correctness...
         IsFramePartOfIBSplit(aFrame);
 
     if (needsReframe) {
       TRACE("Multi-column");
       RecreateFramesForContent(
           GetMultiColumnContainingBlockFor(aFrame)->GetContent(),
@@ -11617,17 +11625,17 @@ bool nsCSSFrameConstructor::WipeContaini
   // enforces that the root is display:none, display:table, or display:block.
   // Note that walking up "too far" is OK in terms of correctness, even if it
   // might be a little inefficient.  This is why we walk out of all
   // pseudo-frames -- telling which ones are or are not OK to walk out of is
   // too hard (and I suspect that we do in fact need to walk out of all of
   // them).
   while (IsFramePartOfIBSplit(aContainingBlock) ||
          aContainingBlock->IsInlineOutside() ||
-         aContainingBlock->Style()->GetPseudo()) {
+         aContainingBlock->Style()->IsPseudoOrAnonBox()) {
     aContainingBlock = aContainingBlock->GetParent();
     NS_ASSERTION(aContainingBlock,
                  "Must have non-inline, non-ib-split, non-pseudo frame as "
                  "root (or child of root, for a table root)!");
   }
 
   // Tell parent of the containing block to reformulate the
   // entire block. This is painful and definitely not optimal
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -52,17 +52,17 @@ class Text;
 class FlattenedChildIterator;
 
 }  // namespace dom
 }  // namespace mozilla
 
 class nsCSSFrameConstructor final : public nsFrameManager {
  public:
   typedef mozilla::ComputedStyle ComputedStyle;
-  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
+  typedef mozilla::PseudoStyleType PseudoStyleType;
   typedef mozilla::dom::Element Element;
   typedef mozilla::dom::Text Text;
 
   // FIXME(emilio): Is this really needed?
   friend class mozilla::RestyleManager;
 
   nsCSSFrameConstructor(mozilla::dom::Document* aDocument,
                         nsIPresShell* aPresShell);
@@ -442,17 +442,17 @@ class nsCSSFrameConstructor final : publ
   already_AddRefed<nsIContent> CreateGeneratedContent(
       nsFrameConstructorState& aState, const Element& aOriginatingElement,
       ComputedStyle& aComputedStyle, uint32_t aContentIndex);
 
   // aParentFrame may be null; this method doesn't use it directly in any case.
   void CreateGeneratedContentItem(nsFrameConstructorState& aState,
                                   nsContainerFrame* aParentFrame,
                                   Element& aOriginatingElement, ComputedStyle&,
-                                  CSSPseudoElementType aPseudoElement,
+                                  PseudoStyleType aPseudoElement,
                                   FrameConstructionItemList& aItems);
 
   // This method is called by ContentAppended() and ContentRangeInserted() when
   // appending flowed frames to a parent's principal child list. It handles the
   // case where the parent is the trailing inline of an ib-split or is the last
   // continuation of a ::-moz-column-content in an nsColumnSetFrame.
   //
   // This method can change aFrameList: it can chop off the beginning and put it
@@ -716,17 +716,17 @@ class nsCSSFrameConstructor final : publ
     // FrameFullConstructor to see what the functions would do.
     union Func {
       FrameCreationFunc mCreationFunc;
       FrameConstructionDataGetter mDataGetter;
     } mFunc;
     FrameFullConstructor mFullConstructor;
     // For cases when FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, the
     // anonymous box type to use for that wrapper.
-    nsCSSAnonBoxPseudoStaticAtom* const mAnonBoxPseudo;
+    PseudoStyleType const mAnonBoxPseudo;
   };
 
   /* Structure representing a mapping of an atom to a FrameConstructionData.
      This can be used with non-static atoms, assuming that the nsAtom* is
      stored somewhere that this struct can point to (that is, a static
      nsAtom*) and that it's allocated before the struct is ever used. */
   struct FrameConstructionDataByTag {
     const nsStaticAtom* const mTag;
@@ -755,17 +755,17 @@ class nsCSSFrameConstructor final : publ
 #  define FCDATA_FOR_DISPLAY(_display, _fcdata) \
     { _fcdata }
 #endif
 
   /* Structure that has a FrameConstructionData and style pseudo-type
      for a table pseudo-frame */
   struct PseudoParentData {
     const FrameConstructionData mFCData;
-    nsCSSAnonBoxPseudoStaticAtom* const mPseudoType;
+    mozilla::PseudoStyleType const mPseudoType;
   };
   /* Array of such structures that we use to properly construct table
      pseudo-frames as needed */
   static const PseudoParentData sPseudoParentData[eParentTypeCount];
 
   // The information that concerns the frame constructor after loading an XBL
   // binding.
   //
@@ -1547,17 +1547,17 @@ class nsCSSFrameConstructor final : publ
    * ConstructOuterSVG and ConstructMarker, which both want an anonymous block
    * child for their children to go in to.
    */
   nsContainerFrame* ConstructFrameWithAnonymousChild(
       nsFrameConstructorState& aState, FrameConstructionItem& aItem,
       nsContainerFrame* aParentFrame, nsFrameItems& aFrameItems,
       ContainerFrameCreationFunc aConstructor,
       ContainerFrameCreationFunc aInnerConstructor,
-      nsCSSAnonBoxPseudoStaticAtom* aInnerPseudo, bool aCandidateRootFrame);
+      mozilla::PseudoStyleType aInnerPseudo, bool aCandidateRootFrame);
 
   /**
    * Construct an nsSVGOuterSVGFrame.
    */
   nsIFrame* ConstructOuterSVG(nsFrameConstructorState& aState,
                               FrameConstructionItem& aItem,
                               nsContainerFrame* aParentFrame,
                               const nsStyleDisplay* aDisplay,
@@ -1692,17 +1692,18 @@ class nsCSSFrameConstructor final : publ
                         ComputedStyle* aContentStyle, nsIFrame* aScrolledFrame,
                         nsContainerFrame* aParentFrame,
                         nsContainerFrame*& aNewFrame);
 
   // Builds the initial ScrollFrame
   already_AddRefed<ComputedStyle> BeginBuildingScrollFrame(
       nsFrameConstructorState& aState, nsIContent* aContent,
       ComputedStyle* aContentStyle, nsContainerFrame* aParentFrame,
-      nsAtom* aScrolledPseudo, bool aIsRoot, nsContainerFrame*& aNewFrame);
+      mozilla::PseudoStyleType aScrolledPseudo, bool aIsRoot,
+      nsContainerFrame*& aNewFrame);
 
   // Completes the building of the scrollframe:
   // Creates a view for the scrolledframe and makes it the child of the
   // scrollframe.
   void FinishBuildingScrollFrame(nsContainerFrame* aScrollFrame,
                                  nsIFrame* aScrolledFrame);
 
   // InitializeSelectFrame puts scrollFrame in aFrameItems if aBuildCombobox is
--- a/layout/base/nsGenConList.cpp
+++ b/layout/base/nsGenConList.cpp
@@ -48,22 +48,22 @@ bool nsGenConList::DestroyNodesFor(nsIFr
  * Compute the type of the pseudo and the content for the pseudo that
  * we'll use for comparison purposes.
  * @param aContent the content to use is stored here; it's the element
  * that generated the ::before or ::after content, or (if not for generated
  * content), the frame's own element
  * @return -1 for ::before, +1 for ::after, and 0 otherwise.
  */
 inline int32_t PseudoCompareType(nsIFrame* aFrame, nsIContent** aContent) {
-  nsAtom* pseudo = aFrame->Style()->GetPseudo();
-  if (pseudo == nsCSSPseudoElements::before()) {
+  auto pseudo = aFrame->Style()->GetPseudoType();
+  if (pseudo == mozilla::PseudoStyleType::before) {
     *aContent = aFrame->GetContent()->GetParent();
     return -1;
   }
-  if (pseudo == nsCSSPseudoElements::after()) {
+  if (pseudo == mozilla::PseudoStyleType::after) {
     *aContent = aFrame->GetContent()->GetParent();
     return 1;
   }
   *aContent = aFrame->GetContent();
   return 0;
 }
 
 /* static */ bool nsGenConList::NodeAfter(const nsGenConNode* aNode1,
--- a/layout/base/nsGenConList.h
+++ b/layout/base/nsGenConList.h
@@ -62,22 +62,22 @@ struct nsGenConNode : public mozilla::Li
  protected:
   void CheckFrameAssertions() {
     NS_ASSERTION(
         mContentIndex < int32_t(mPseudoFrame->StyleContent()->ContentCount()),
         "index out of range");
     // We allow negative values of mContentIndex for 'counter-reset' and
     // 'counter-increment'.
 
-    NS_ASSERTION(
-        mContentIndex < 0 ||
-            mPseudoFrame->Style()->GetPseudo() ==
-                nsCSSPseudoElements::before() ||
-            mPseudoFrame->Style()->GetPseudo() == nsCSSPseudoElements::after(),
-        "not :before/:after generated content and not counter change");
+    NS_ASSERTION(mContentIndex < 0 ||
+                     mPseudoFrame->Style()->GetPseudoType() ==
+                         mozilla::PseudoStyleType::before ||
+                     mPseudoFrame->Style()->GetPseudoType() ==
+                         mozilla::PseudoStyleType::after,
+                 "not :before/:after generated content and not counter change");
     NS_ASSERTION(mContentIndex < 0 ||
                      mPseudoFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT,
                  "not generated content and not counter change");
   }
 };
 
 class nsGenConList {
  protected:
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1923,17 +1923,17 @@ nsRect nsLayoutUtils::GetScrolledRect(ns
   }
 
   return nsRect(x1, y1, x2 - x1, y2 - y1);
 }
 
 // static
 bool nsLayoutUtils::HasPseudoStyle(nsIContent* aContent,
                                    ComputedStyle* aComputedStyle,
-                                   CSSPseudoElementType aPseudoElement,
+                                   PseudoStyleType aPseudoElement,
                                    nsPresContext* aPresContext) {
   MOZ_ASSERT(aPresContext, "Must have a prescontext");
 
   RefPtr<ComputedStyle> pseudoContext;
   if (aContent) {
     pseudoContext = aPresContext->StyleSet()->ProbePseudoElementStyle(
         *aContent->AsElement(), aPseudoElement, aComputedStyle);
   }
@@ -3965,29 +3965,29 @@ bool nsLayoutUtils::BinarySearchForPosit
       return true;
     }
   }
   return false;
 }
 
 void nsLayoutUtils::AddBoxesForFrame(nsIFrame* aFrame,
                                      nsLayoutUtils::BoxCallback* aCallback) {
-  nsAtom* pseudoType = aFrame->Style()->GetPseudo();
-
-  if (pseudoType == nsCSSAnonBoxes::tableWrapper()) {
+  auto pseudoType = aFrame->Style()->GetPseudoType();
+
+  if (pseudoType == PseudoStyleType::tableWrapper) {
     AddBoxesForFrame(aFrame->PrincipalChildList().FirstChild(), aCallback);
     if (aCallback->mIncludeCaptionBoxForTable) {
       nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild();
       if (kid) {
         AddBoxesForFrame(kid, aCallback);
       }
     }
-  } else if (pseudoType == nsCSSAnonBoxes::mozBlockInsideInlineWrapper() ||
-             pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock() ||
-             pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock()) {
+  } else if (pseudoType == PseudoStyleType::mozBlockInsideInlineWrapper ||
+             pseudoType == PseudoStyleType::mozMathMLAnonymousBlock ||
+             pseudoType == PseudoStyleType::mozXULAnonymousBlock) {
     for (nsIFrame* kid : aFrame->PrincipalChildList()) {
       AddBoxesForFrame(kid, aCallback);
     }
   } else {
     aCallback->AddBox(aFrame);
   }
 }
 
@@ -3996,34 +3996,34 @@ void nsLayoutUtils::GetAllInFlowBoxes(ns
   while (aFrame) {
     AddBoxesForFrame(aFrame, aCallback);
     aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
   }
 }
 
 nsIFrame* nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame) {
   while (aFrame) {
-    nsAtom* pseudoType = aFrame->Style()->GetPseudo();
-
-    if (pseudoType == nsCSSAnonBoxes::tableWrapper()) {
+    auto pseudoType = aFrame->Style()->GetPseudoType();
+
+    if (pseudoType == PseudoStyleType::tableWrapper) {
       nsIFrame* f =
           GetFirstNonAnonymousFrame(aFrame->PrincipalChildList().FirstChild());
       if (f) {
         return f;
       }
       nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild();
       if (kid) {
         f = GetFirstNonAnonymousFrame(kid);
         if (f) {
           return f;
         }
       }
-    } else if (pseudoType == nsCSSAnonBoxes::mozBlockInsideInlineWrapper() ||
-               pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock() ||
-               pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock()) {
+    } else if (pseudoType == PseudoStyleType::mozBlockInsideInlineWrapper ||
+               pseudoType == PseudoStyleType::mozMathMLAnonymousBlock ||
+               pseudoType == PseudoStyleType::mozXULAnonymousBlock) {
       for (nsIFrame* kid : aFrame->PrincipalChildList()) {
         nsIFrame* f = GetFirstNonAnonymousFrame(kid);
         if (f) {
           return f;
         }
       }
     } else {
       return aFrame;
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -58,17 +58,17 @@ class nsStyleCoord;
 class nsStyleCorners;
 class nsPIDOMWindowOuter;
 class imgIRequest;
 struct nsStyleFont;
 struct nsOverflowAreas;
 
 namespace mozilla {
 class ComputedStyle;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class EventListenerManager;
 enum class LayoutFrameType : uint8_t;
 struct IntrinsicSize;
 struct ContainerLayerParameters;
 class WritingMode;
 class DisplayItemClip;
 class EffectSet;
 struct ActiveScrolledRoot;
@@ -679,17 +679,17 @@ class nsLayoutUtils {
    * @param aContent the content node we're looking at
    * @param aComputedStyle aContent's ComputedStyle
    * @param aPseudoElement the id of the pseudo style we care about
    * @param aPresContext the presentation context
    * @return whether aContent has aPseudoElement style attached to it
    */
   static bool HasPseudoStyle(nsIContent* aContent,
                              ComputedStyle* aComputedStyle,
-                             mozilla::CSSPseudoElementType aPseudoElement,
+                             mozilla::PseudoStyleType aPseudoElement,
                              nsPresContext* aPresContext);
 
   /**
    * If this frame is a placeholder for a float, then return the float,
    * otherwise return nullptr.  aPlaceholder must be a placeholder frame.
    */
   static nsIFrame* GetFloatFromPlaceholder(nsIFrame* aPlaceholder);
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1825,34 +1825,32 @@ void nsPresContext::UpdateIsChrome() {
 }
 
 bool nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
                                             uint32_t aRuleTypeMask) const {
   Element* elem = aFrame->GetContent()->AsElement();
 
   // We need to handle non-generated content pseudos too, so we use
   // the parent of generated content pseudo to be consistent.
-  if (elem->GetPseudoElementType() != CSSPseudoElementType::NotPseudo) {
+  if (elem->GetPseudoElementType() != PseudoStyleType::NotPseudo) {
     MOZ_ASSERT(elem->GetParent(), "Pseudo element has no parent element?");
     elem = elem->GetParent()->AsElement();
   }
   if (MOZ_UNLIKELY(!elem->HasServoData())) {
     // Probably shouldn't happen, but does. See bug 1387953
     return false;
   }
 
-  ComputedStyle* computedStyle = aFrame->Style();
-  CSSPseudoElementType pseudoType = computedStyle->GetPseudoType();
   // Anonymous boxes are more complicated, and we just assume that they
   // cannot have any author-specified rules here.
-  if (pseudoType == CSSPseudoElementType::InheritingAnonBox ||
-      pseudoType == CSSPseudoElementType::NonInheritingAnonBox) {
+  if (aFrame->Style()->IsAnonBox()) {
     return false;
   }
-  return Servo_HasAuthorSpecifiedRules(computedStyle, elem, pseudoType,
+  return Servo_HasAuthorSpecifiedRules(aFrame->Style(), elem,
+                                       aFrame->Style()->GetPseudoType(),
                                        aRuleTypeMask, UseDocumentColors());
 }
 
 gfxUserFontSet* nsPresContext::GetUserFontSet() {
   return mDocument->GetUserFontSet();
 }
 
 void nsPresContext::UserFontSetUpdated(gfxUserFontEntry* aUpdatedFont) {
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -502,17 +502,17 @@ ImgDrawResult nsButtonFrameRenderer::Pai
  */
 void nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext) {
   // get all the styles
   ComputedStyle* context = mFrame->Style();
   ServoStyleSet* styleSet = aPresContext->StyleSet();
 
   // get styles assigned to -moz-focus-inner (ie dotted border on Windows)
   mInnerFocusStyle = styleSet->ProbePseudoElementStyle(
-      *mFrame->GetContent()->AsElement(), CSSPseudoElementType::mozFocusInner,
+      *mFrame->GetContent()->AsElement(), PseudoStyleType::mozFocusInner,
       context);
 }
 
 ComputedStyle* nsButtonFrameRenderer::GetComputedStyle(int32_t aIndex) const {
   switch (aIndex) {
     case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
       return mInnerFocusStyle;
     default:
--- a/layout/forms/nsColorControlFrame.cpp
+++ b/layout/forms/nsColorControlFrame.cpp
@@ -52,17 +52,17 @@ nsresult nsColorControlFrame::GetFrameNa
 #endif
 
 // Create the color area for the button.
 // The frame will be generated by the frame constructor.
 nsresult nsColorControlFrame::CreateAnonymousContent(
     nsTArray<ContentInfo>& aElements) {
   RefPtr<Document> doc = mContent->GetComposedDoc();
   mColorContent = doc->CreateHTMLElement(nsGkAtoms::div);
-  mColorContent->SetPseudoElementType(CSSPseudoElementType::mozColorSwatch);
+  mColorContent->SetPseudoElementType(PseudoStyleType::mozColorSwatch);
 
   // Mark the element to be native anonymous before setting any attributes.
   mColorContent->SetIsNativeAnonymousRoot();
 
   nsresult rv = UpdateColor();
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aElements.AppendElement(mColorContent)) {
--- a/layout/forms/nsColorControlFrame.h
+++ b/layout/forms/nsColorControlFrame.h
@@ -7,24 +7,24 @@
 #ifndef nsColorControlFrame_h___
 #define nsColorControlFrame_h___
 
 #include "nsCOMPtr.h"
 #include "nsHTMLButtonControlFrame.h"
 #include "nsIAnonymousContentCreator.h"
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 }  // namespace mozilla
 
 // Class which implements the input type=color
 
 class nsColorControlFrame final : public nsHTMLButtonControlFrame,
                                   public nsIAnonymousContentCreator {
-  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
+  typedef mozilla::PseudoStyleType PseudoStyleType;
   typedef mozilla::dom::Element Element;
 
  public:
   friend nsIFrame* NS_NewColorControlFrame(nsIPresShell* aPresShell,
                                            ComputedStyle* aStyle);
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot,
                            PostDestroyData& aPostDestroyData) override;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1268,17 +1268,17 @@ nsIFrame* nsComboboxControlFrame::Create
 
   // Get PresShell
   nsIPresShell* shell = PresShell();
   ServoStyleSet* styleSet = shell->StyleSet();
 
   // create the ComputedStyle for the anonymous block frame and text frame
   RefPtr<ComputedStyle> computedStyle;
   computedStyle = styleSet->ResolveInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::mozDisplayComboboxControlFrame(), mComputedStyle);
+      PseudoStyleType::mozDisplayComboboxControlFrame, mComputedStyle);
 
   RefPtr<ComputedStyle> textComputedStyle;
   textComputedStyle =
       styleSet->ResolveStyleForText(mDisplayContent, mComputedStyle);
 
   // Start by creating our anonymous block frame
   mDisplayFrame = new (shell) nsComboboxDisplayFrame(computedStyle, this);
   mDisplayFrame->Init(mContent, this, nullptr);
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -66,17 +66,18 @@ nsRect nsFieldSetFrame::VisualBorderRect
       }
     }
   }
   return r.GetPhysicalRect(wm, containerSize);
 }
 
 nsIFrame* nsFieldSetFrame::GetInner() const {
   nsIFrame* last = mFrames.LastChild();
-  if (last && last->Style()->GetPseudo() == nsCSSAnonBoxes::fieldsetContent()) {
+  if (last &&
+      last->Style()->GetPseudoType() == PseudoStyleType::fieldsetContent) {
     return last;
   }
   MOZ_ASSERT(mFrames.LastChild() == mFrames.FirstChild());
   return nullptr;
 }
 
 nsIFrame* nsFieldSetFrame::GetLegend() const {
   if (mFrames.FirstChild() == GetInner()) {
--- a/layout/forms/nsHTMLButtonControlFrame.cpp
+++ b/layout/forms/nsHTMLButtonControlFrame.cpp
@@ -165,18 +165,19 @@ void nsHTMLButtonControlFrame::Reflow(ns
   }
 
   // Reflow the child
   nsIFrame* firstKid = mFrames.FirstChild();
 
   MOZ_ASSERT(firstKid, "Button should have a child frame for its contents");
   MOZ_ASSERT(!firstKid->GetNextSibling(),
              "Button should have exactly one child frame");
-  MOZ_ASSERT(firstKid->Style()->GetPseudo() == nsCSSAnonBoxes::buttonContent(),
-             "Button's child frame has unexpected pseudo type!");
+  MOZ_ASSERT(
+      firstKid->Style()->GetPseudoType() == PseudoStyleType::buttonContent,
+      "Button's child frame has unexpected pseudo type!");
 
   // XXXbz Eventually we may want to check-and-bail if
   // !aReflowInput.ShouldReflowAllKids() &&
   // !NS_SUBTREE_DIRTY(firstKid).
   // We'd need to cache our ascent for that, of course.
 
   // Reflow the contents of the button.
   // (This populates our aDesiredSize, too.)
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -51,17 +51,17 @@ nsresult nsMeterFrame::CreateAnonymousCo
     nsTArray<ContentInfo>& aElements) {
   // Get the NodeInfoManager and tag necessary to create the meter bar div.
   nsCOMPtr<Document> doc = mContent->GetComposedDoc();
 
   // Create the div.
   mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div);
 
   // Associate ::-moz-meter-bar pseudo-element to the anonymous child.
-  mBarDiv->SetPseudoElementType(CSSPseudoElementType::mozMeterBar);
+  mBarDiv->SetPseudoElementType(PseudoStyleType::mozMeterBar);
 
   aElements.AppendElement(mBarDiv);
 
   return NS_OK;
 }
 
 void nsMeterFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                             uint32_t aFilter) {
--- a/layout/forms/nsNumberControlFrame.cpp
+++ b/layout/forms/nsNumberControlFrame.cpp
@@ -296,24 +296,24 @@ class FocusTextField : public Runnable {
   }
 
  private:
   nsCOMPtr<nsIContent> mNumber;
   nsCOMPtr<nsIContent> mTextField;
 };
 
 already_AddRefed<Element> nsNumberControlFrame::MakeAnonymousElement(
-    Element* aParent, nsAtom* aTagName, CSSPseudoElementType aPseudoType) {
+    Element* aParent, nsAtom* aTagName, PseudoStyleType aPseudoType) {
   // Get the NodeInfoManager and tag necessary to create the anonymous divs.
   Document* doc = mContent->GetComposedDoc();
   RefPtr<Element> resultElement = doc->CreateHTMLElement(aTagName);
   resultElement->SetPseudoElementType(aPseudoType);
 
-  if (aPseudoType == CSSPseudoElementType::mozNumberSpinDown ||
-      aPseudoType == CSSPseudoElementType::mozNumberSpinUp) {
+  if (aPseudoType == PseudoStyleType::mozNumberSpinDown ||
+      aPseudoType == PseudoStyleType::mozNumberSpinUp) {
     resultElement->SetAttr(kNameSpaceID_None, nsGkAtoms::role,
                            NS_LITERAL_STRING("button"), false);
   }
 
   if (aParent) {
     aParent->AppendChildTo(resultElement, false);
   }
 
@@ -332,23 +332,23 @@ nsresult nsNumberControlFrame::CreateAno
   //       div  - spin up (up arrow button)
   //       div  - spin down (down arrow button)
   //
   // If you change this, be careful to change the destruction order in
   // nsNumberControlFrame::DestroyFrom.
 
   // Create the anonymous outer wrapper:
   mOuterWrapper = MakeAnonymousElement(nullptr, nsGkAtoms::div,
-                                       CSSPseudoElementType::mozNumberWrapper);
+                                       PseudoStyleType::mozNumberWrapper);
 
   aElements.AppendElement(mOuterWrapper);
 
   // Create the ::-moz-number-text pseudo-element:
   mTextField = MakeAnonymousElement(mOuterWrapper, nsGkAtoms::input,
-                                    CSSPseudoElementType::mozNumberText);
+                                    PseudoStyleType::mozNumberText);
 
   mTextField->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                       NS_LITERAL_STRING("text"), false);
 
   HTMLInputElement* content = HTMLInputElement::FromNode(mContent);
   HTMLInputElement* textField = HTMLInputElement::FromNode(mTextField);
 
   // Initialize the text field value:
@@ -386,25 +386,25 @@ nsresult nsNumberControlFrame::CreateAno
   if (StyleDisplay()->mAppearance == StyleAppearance::Textfield) {
     // The author has elected to hide the spinner by setting this
     // -moz-appearance. We will reframe if it changes.
     return NS_OK;
   }
 
   // Create the ::-moz-number-spin-box pseudo-element:
   mSpinBox = MakeAnonymousElement(mOuterWrapper, nsGkAtoms::div,
-                                  CSSPseudoElementType::mozNumberSpinBox);
+                                  PseudoStyleType::mozNumberSpinBox);
 
   // Create the ::-moz-number-spin-up pseudo-element:
   mSpinUp = MakeAnonymousElement(mSpinBox, nsGkAtoms::div,
-                                 CSSPseudoElementType::mozNumberSpinUp);
+                                 PseudoStyleType::mozNumberSpinUp);
 
   // Create the ::-moz-number-spin-down pseudo-element:
   mSpinDown = MakeAnonymousElement(mSpinBox, nsGkAtoms::div,
-                                   CSSPseudoElementType::mozNumberSpinDown);
+                                   PseudoStyleType::mozNumberSpinDown);
 
   return NS_OK;
 }
 
 void nsNumberControlFrame::SetFocus(bool aOn, bool aRepaint) {
   GetTextFieldFrame()->SetFocus(aOn, aRepaint);
 }
 
--- a/layout/forms/nsNumberControlFrame.h
+++ b/layout/forms/nsNumberControlFrame.h
@@ -12,34 +12,34 @@
 #include "nsIFormControlFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsCOMPtr.h"
 
 class nsITextControlFrame;
 class nsPresContext;
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class WidgetEvent;
 class WidgetGUIEvent;
 namespace dom {
 class HTMLInputElement;
 }  // namespace dom
 }  // namespace mozilla
 
 /**
  * This frame type is used for <input type=number>.
  */
 class nsNumberControlFrame final : public nsContainerFrame,
                                    public nsIAnonymousContentCreator,
                                    public nsIFormControlFrame {
   friend nsIFrame* NS_NewNumberControlFrame(nsIPresShell* aPresShell,
                                             ComputedStyle* aStyle);
 
-  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
+  typedef mozilla::PseudoStyleType PseudoStyleType;
   typedef mozilla::dom::Element Element;
   typedef mozilla::dom::HTMLInputElement HTMLInputElement;
   typedef mozilla::WidgetEvent WidgetEvent;
   typedef mozilla::WidgetGUIEvent WidgetGUIEvent;
 
   explicit nsNumberControlFrame(ComputedStyle* aStyle,
                                 nsPresContext* aPresContext);
 
@@ -153,18 +153,19 @@ class nsNumberControlFrame final : publi
    * Our element had HTMLInputElement::Select() called on it.
    */
   void HandleSelectCall();
 
   bool ShouldUseNativeStyleForSpinner() const;
 
  private:
   nsITextControlFrame* GetTextFieldFrame();
-  already_AddRefed<Element> MakeAnonymousElement(
-      Element* aParent, nsAtom* aTagName, CSSPseudoElementType aPseudoType);
+  already_AddRefed<Element> MakeAnonymousElement(Element* aParent,
+                                                 nsAtom* aTagName,
+                                                 PseudoStyleType aPseudoType);
 
   class SyncDisabledStateEvent;
   friend class SyncDisabledStateEvent;
   class SyncDisabledStateEvent : public mozilla::Runnable {
    public:
     explicit SyncDisabledStateEvent(nsNumberControlFrame* aFrame)
         : mozilla::Runnable("nsNumberControlFrame::SyncDisabledStateEvent"),
           mFrame(aFrame) {}
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -49,17 +49,17 @@ void nsProgressFrame::DestroyFrom(nsIFra
 
 nsresult nsProgressFrame::CreateAnonymousContent(
     nsTArray<ContentInfo>& aElements) {
   // Create the progress bar div.
   nsCOMPtr<Document> doc = mContent->GetComposedDoc();
   mBarDiv = doc->CreateHTMLElement(nsGkAtoms::div);
 
   // Associate ::-moz-progress-bar pseudo-element to the anonymous child.
-  mBarDiv->SetPseudoElementType(CSSPseudoElementType::mozProgressBar);
+  mBarDiv->SetPseudoElementType(PseudoStyleType::mozProgressBar);
 
   if (!aElements.AppendElement(mBarDiv)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
--- a/layout/forms/nsProgressFrame.h
+++ b/layout/forms/nsProgressFrame.h
@@ -8,22 +8,22 @@
 #define nsProgressFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsCOMPtr.h"
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 }  // namespace mozilla
 
 class nsProgressFrame final : public nsContainerFrame,
                               public nsIAnonymousContentCreator {
-  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
+  typedef mozilla::PseudoStyleType PseudoStyleType;
   typedef mozilla::dom::Element Element;
 
  public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsProgressFrame)
 
   explicit nsProgressFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
   virtual ~nsProgressFrame();
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -69,17 +69,17 @@ void nsRangeFrame::Init(nsIContent* aCon
     mDummyTouchListener = new DummyTouchListener();
   }
   aContent->AddEventListener(NS_LITERAL_STRING("touchstart"),
                              mDummyTouchListener, false);
 
   ServoStyleSet* styleSet = PresContext()->StyleSet();
 
   mOuterFocusStyle = styleSet->ProbePseudoElementStyle(
-      *aContent->AsElement(), CSSPseudoElementType::mozFocusOuter, Style());
+      *aContent->AsElement(), PseudoStyleType::mozFocusOuter, Style());
 
   return nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 }
 
 void nsRangeFrame::DestroyFrom(nsIFrame* aDestructRoot,
                                PostDestroyData& aPostDestroyData) {
   NS_ASSERTION(!GetPrevContinuation() && !GetNextContinuation(),
                "nsRangeFrame should not have continuations; if it does we "
@@ -91,17 +91,17 @@ void nsRangeFrame::DestroyFrom(nsIFrame*
   nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
   aPostDestroyData.AddAnonymousContent(mTrackDiv.forget());
   aPostDestroyData.AddAnonymousContent(mProgressDiv.forget());
   aPostDestroyData.AddAnonymousContent(mThumbDiv.forget());
   nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
 }
 
 nsresult nsRangeFrame::MakeAnonymousDiv(Element** aResult,
-                                        CSSPseudoElementType aPseudoType,
+                                        PseudoStyleType aPseudoType,
                                         nsTArray<ContentInfo>& aElements) {
   nsCOMPtr<Document> doc = mContent->GetComposedDoc();
   RefPtr<Element> resultElement = doc->CreateHTMLElement(nsGkAtoms::div);
 
   // Associate the pseudo-element with the anonymous child.
   resultElement->SetPseudoElementType(aPseudoType);
 
   if (!aElements.AppendElement(resultElement)) {
@@ -111,29 +111,29 @@ nsresult nsRangeFrame::MakeAnonymousDiv(
   resultElement.forget(aResult);
   return NS_OK;
 }
 
 nsresult nsRangeFrame::CreateAnonymousContent(
     nsTArray<ContentInfo>& aElements) {
   nsresult rv;
 
-  // Create the ::-moz-range-track pseuto-element (a div):
+  // Create the ::-moz-range-track pseudo-element (a div):
   rv = MakeAnonymousDiv(getter_AddRefs(mTrackDiv),
-                        CSSPseudoElementType::mozRangeTrack, aElements);
+                        PseudoStyleType::mozRangeTrack, aElements);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the ::-moz-range-progress pseudo-element (a div):
   rv = MakeAnonymousDiv(getter_AddRefs(mProgressDiv),
-                        CSSPseudoElementType::mozRangeProgress, aElements);
+                        PseudoStyleType::mozRangeProgress, aElements);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the ::-moz-range-thumb pseudo-element (a div):
   rv = MakeAnonymousDiv(getter_AddRefs(mThumbDiv),
-                        CSSPseudoElementType::mozRangeThumb, aElements);
+                        PseudoStyleType::mozRangeThumb, aElements);
   return rv;
 }
 
 void nsRangeFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                             uint32_t aFilter) {
   if (mTrackDiv) {
     aElements.AppendElement(mTrackDiv);
   }
--- a/layout/forms/nsRangeFrame.h
+++ b/layout/forms/nsRangeFrame.h
@@ -28,17 +28,17 @@ class nsRangeFrame final : public nsCont
   friend nsIFrame* NS_NewRangeFrame(nsIPresShell* aPresShell,
                                     ComputedStyle* aStyle);
 
   friend class nsDisplayRangeFocusRing;
 
   explicit nsRangeFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
   virtual ~nsRangeFrame();
 
-  typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
+  typedef mozilla::PseudoStyleType PseudoStyleType;
   typedef mozilla::dom::Element Element;
 
  public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsRangeFrame)
 
   // nsIFrame overrides
   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
@@ -142,17 +142,17 @@ class nsRangeFrame final : public nsCont
    */
   void UpdateForValueChange();
 
  private:
   // Return our preferred size in the cross-axis (the axis perpendicular
   // to the direction of movement of the thumb).
   nscoord AutoCrossSize(nscoord aEm);
 
-  nsresult MakeAnonymousDiv(Element** aResult, CSSPseudoElementType aPseudoType,
+  nsresult MakeAnonymousDiv(Element** aResult, PseudoStyleType aPseudoType,
                             nsTArray<ContentInfo>& aElements);
 
   // Helper function which reflows the anonymous div frames.
   void ReflowAnonymousContent(nsPresContext* aPresContext,
                               ReflowOutput& aDesiredSize,
                               const ReflowInput& aReflowInput);
 
   void DoUpdateThumbPosition(nsIFrame* aThumbFrame, const nsSize& aRangeSize);
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -474,17 +474,17 @@ void nsTextControlFrame::CreatePlacehold
   }
 
   if (placeholderTxt.IsEmpty()) {
     return;
   }
 
   mPlaceholderDiv = CreateEmptyDivWithTextNode(*this);
   // Associate ::placeholder pseudo-element with the placeholder node.
-  mPlaceholderDiv->SetPseudoElementType(CSSPseudoElementType::placeholder);
+  mPlaceholderDiv->SetPseudoElementType(PseudoStyleType::placeholder);
   mPlaceholderDiv->GetFirstChild()->AsText()->SetText(placeholderTxt, false);
 }
 
 void nsTextControlFrame::CreatePreviewIfNeeded() {
   nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(GetContent());
   if (!txtCtrl->IsPreviewEnabled()) {
     return;
   }
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -16,17 +16,17 @@
 #include "nsITextControlElement.h"
 #include "nsIStatefulFrame.h"
 
 class nsISelectionController;
 class EditorInitializerEntryTracker;
 class nsTextEditorState;
 namespace mozilla {
 class TextEditor;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 namespace dom {
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
 class nsTextControlFrame final : public nsContainerFrame,
                                  public nsIAnonymousContentCreator,
                                  public nsITextControlFrame,
--- a/layout/generic/ColumnSetWrapperFrame.cpp
+++ b/layout/generic/ColumnSetWrapperFrame.cpp
@@ -157,17 +157,17 @@ void ColumnSetWrapperFrame::MarkIntrinsi
   if (!nsLayoutUtils::GetStyleFrame(const_cast<nsIFrame*>(aFrame))
            ->Style()
            ->IsAnonBox()) {
     // aFrame's style frame has "column-span: all". Traverse no further.
     return;
   }
 
   MOZ_ASSERT(
-      aFrame->Style()->GetPseudo() == nsCSSAnonBoxes::columnSpanWrapper(),
+      aFrame->Style()->GetPseudoType() == PseudoStyleType::columnSpanWrapper,
       "aFrame should be ::-moz-column-span-wrapper");
 
   MOZ_ASSERT(!aFrame->HasAnyStateBits(NS_FRAME_OWNS_ANON_BOXES),
              "::-moz-column-span-wrapper anonymous blocks cannot own "
              "other types of anonymous blocks!");
 
   for (const nsIFrame* child : aFrame->PrincipalChildList()) {
     AssertColumnSpanWrapperSubtreeIsSane(child);
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -2482,18 +2482,18 @@ void ReflowInput::InitConstraints(nsPres
                                               ComputeSizeFlags::eShrinkWrap);
         }
       } else {
         // Make sure legend frames with display:block and width:auto still
         // shrink-wrap.
         // Also shrink-wrap blocks that are orthogonal to their container.
         if (isBlock &&
             ((aFrameType == LayoutFrameType::Legend &&
-              mFrame->Style()->GetPseudo() !=
-                  nsCSSAnonBoxes::scrolledContent()) ||
+              mFrame->Style()->GetPseudoType() !=
+                  PseudoStyleType::scrolledContent) ||
              (aFrameType == LayoutFrameType::Scroll &&
               mFrame->GetContentInsertionFrame()->IsLegendFrame()) ||
              (mCBReflowInput &&
               mCBReflowInput->GetWritingMode().IsOrthogonalTo(mWritingMode)))) {
           computeSizeFlags = ComputeSizeFlags(computeSizeFlags |
                                               ComputeSizeFlags::eShrinkWrap);
         }
 
--- a/layout/generic/RubyUtils.h
+++ b/layout/generic/RubyUtils.h
@@ -69,22 +69,22 @@ class RubyUtils {
            IsRubyContentBox(aFrameType) || IsRubyContainerBox(aFrameType);
   }
 
   static inline bool IsExpandableRubyBox(nsIFrame* aFrame) {
     mozilla::LayoutFrameType type = aFrame->Type();
     return IsRubyContentBox(type) || IsRubyContainerBox(type);
   }
 
-  static inline bool IsRubyPseudo(nsAtom* aPseudo) {
-    return aPseudo == nsCSSAnonBoxes::ruby() ||
-           aPseudo == nsCSSAnonBoxes::rubyBase() ||
-           aPseudo == nsCSSAnonBoxes::rubyText() ||
-           aPseudo == nsCSSAnonBoxes::rubyBaseContainer() ||
-           aPseudo == nsCSSAnonBoxes::rubyTextContainer();
+  static inline bool IsRubyPseudo(PseudoStyleType aPseudo) {
+    return aPseudo == PseudoStyleType::ruby ||
+           aPseudo == PseudoStyleType::rubyBase ||
+           aPseudo == PseudoStyleType::rubyText ||
+           aPseudo == PseudoStyleType::rubyBaseContainer ||
+           aPseudo == PseudoStyleType::rubyTextContainer;
   }
 
   static void SetReservedISize(nsIFrame* aFrame, nscoord aISize);
   static void ClearReservedISize(nsIFrame* aFrame);
   static nscoord GetReservedISize(nsIFrame* aFrame);
 };
 
 /**
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -294,18 +294,18 @@ TextOverflow::TextOverflow(nsDisplayList
       mBuilder(aBuilder),
       mBlock(aBlockFrame),
       mScrollableFrame(nsLayoutUtils::GetScrollableFrameFor(aBlockFrame)),
       mBlockSize(aBlockFrame->GetSize()),
       mBlockWM(aBlockFrame->GetWritingMode()),
       mAdjustForPixelSnapping(false) {
 #ifdef MOZ_XUL
   if (!mScrollableFrame) {
-    nsAtom* pseudoType = aBlockFrame->Style()->GetPseudo();
-    if (pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock()) {
+    auto pseudoType = aBlockFrame->Style()->GetPseudoType();
+    if (pseudoType == PseudoStyleType::mozXULAnonymousBlock) {
       mScrollableFrame =
           nsLayoutUtils::GetScrollableFrameFor(aBlockFrame->GetParent());
       // nsXULScrollFrame::ClampAndSetBounds rounds to nearest pixels
       // for RTL blocks (also for overflow:hidden), so we need to move
       // the edges 1px outward in ExamineLineFrames to avoid triggering
       // a text-overflow marker in this case.
       mAdjustForPixelSnapping = !mBlockWM.IsBidiLTR();
     }
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -377,20 +377,19 @@ void ViewportFrame::Reflow(nsPresContext
   // so we don't need to change our overflow areas.
   FinishAndStoreOverflow(&aDesiredSize);
 
   NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
 }
 
 void ViewportFrame::UpdateStyle(ServoRestyleState& aRestyleState) {
-  nsAtom* pseudo = Style()->GetPseudo();
   RefPtr<ComputedStyle> newStyle =
-      aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(pseudo,
-                                                                  nullptr);
+      aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(
+          Style()->GetPseudoType(), nullptr);
 
   MOZ_ASSERT(!GetNextContinuation(), "Viewport has continuations?");
   SetComputedStyle(newStyle);
 
   UpdateStyleOfOwnedAnonBoxes(aRestyleState);
 }
 
 void ViewportFrame::AppendDirectlyOwnedAnonBoxes(
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1380,18 +1380,18 @@ void nsBlockFrame::Reflow(nsPresContext*
         // We're not going to reflow absolute frames; make sure to account for
         // their existing overflow areas, which is usually a side effect of this
         // reflow.
         //
         // TODO(emilio): nsAbsoluteContainingBlock::Reflow already checks for
         // interrupt, can we just rely on it and unconditionally take the else
         // branch below? That's a bit more subtle / risky, since I don't see
         // what would reflow them in that case if they depended on our size.
-        for (nsIFrame* kid = absoluteContainer->GetChildList().FirstChild(); kid;
-             kid = kid->GetNextSibling()) {
+        for (nsIFrame* kid = absoluteContainer->GetChildList().FirstChild();
+             kid; kid = kid->GetNextSibling()) {
           ConsiderChildOverflow(aMetrics.mOverflowAreas, kid);
         }
       }
     } else {
       LogicalSize containingBlockSize =
           CalculateContainingBlockSizeForAbsolutes(parentWM, *reflowInput,
                                                    aMetrics.Size(parentWM));
 
@@ -5440,22 +5440,22 @@ void nsBlockFrame::UpdateFirstLetterStyl
   }
 
   // Figure out what the right style parent is.  This needs to match
   // nsCSSFrameConstructor::CreateLetterFrame.
   nsIFrame* inFlowFrame = letterFrame;
   if (inFlowFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
     inFlowFrame = inFlowFrame->GetPlaceholderFrame();
   }
-  nsIFrame* styleParent = CorrectStyleParentFrame(
-      inFlowFrame->GetParent(), nsCSSPseudoElements::firstLetter());
+  nsIFrame* styleParent = CorrectStyleParentFrame(inFlowFrame->GetParent(),
+                                                  PseudoStyleType::firstLetter);
   ComputedStyle* parentStyle = styleParent->Style();
   RefPtr<ComputedStyle> firstLetterStyle =
       aRestyleState.StyleSet().ResolvePseudoElementStyle(
-          mContent->AsElement(), CSSPseudoElementType::firstLetter, parentStyle,
+          mContent->AsElement(), PseudoStyleType::firstLetter, parentStyle,
           nullptr);
   // Note that we don't need to worry about changehints for the continuation
   // styles: those will be handled by the styleParent already.
   RefPtr<ComputedStyle> continuationStyle =
       aRestyleState.StyleSet().ResolveStyleForFirstLetterContinuation(
           parentStyle);
   UpdateStyleOfOwnedChildFrame(letterFrame, firstLetterStyle, aRestyleState,
                                Some(continuationStyle.get()));
@@ -6755,27 +6755,27 @@ void nsBlockFrame::SetInitialChildList(C
 #ifdef DEBUG
     // The only times a block that is an anonymous box is allowed to have a
     // first-letter frame are when it's the block inside a non-anonymous cell,
     // the block inside a fieldset, button or column set, or a scrolled content
     // block, except for <select>.  Note that this means that blocks which are
     // the anonymous block in {ib} splits do NOT get first-letter frames.
     // Note that NS_BLOCK_HAS_FIRST_LETTER_STYLE gets set on all continuations
     // of the block.
-    nsAtom* pseudo = Style()->GetPseudo();
+    auto pseudo = Style()->GetPseudoType();
     bool haveFirstLetterStyle =
-        (!pseudo ||
-         (pseudo == nsCSSAnonBoxes::cellContent() &&
-          GetParent()->Style()->GetPseudo() == nullptr) ||
-         pseudo == nsCSSAnonBoxes::fieldsetContent() ||
-         pseudo == nsCSSAnonBoxes::buttonContent() ||
-         pseudo == nsCSSAnonBoxes::columnContent() ||
-         (pseudo == nsCSSAnonBoxes::scrolledContent() &&
+        (pseudo == PseudoStyleType::NotPseudo ||
+         (pseudo == PseudoStyleType::cellContent &&
+          !GetParent()->Style()->IsPseudoOrAnonBox()) ||
+         pseudo == PseudoStyleType::fieldsetContent ||
+         pseudo == PseudoStyleType::buttonContent ||
+         pseudo == PseudoStyleType::columnContent ||
+         (pseudo == PseudoStyleType::scrolledContent &&
           !GetParent()->IsListControlFrame()) ||
-         pseudo == nsCSSAnonBoxes::mozSVGText()) &&
+         pseudo == PseudoStyleType::mozSVGText) &&
         !IsComboboxControlFrame() && !IsFrameOfType(eMathML) &&
         RefPtr<ComputedStyle>(GetFirstLetterStyle(PresContext())) != nullptr;
     NS_ASSERTION(haveFirstLetterStyle ==
                      ((mState & NS_BLOCK_HAS_FIRST_LETTER_STYLE) != 0),
                  "NS_BLOCK_HAS_FIRST_LETTER_STYLE state out of sync");
 #endif
 
     AddFrames(aChildList, nullptr);
@@ -6790,19 +6790,19 @@ void nsBlockFrame::CreateBulletFrameForL
              "How can we have a bullet already?");
 
   nsPresContext* pc = PresContext();
   nsIPresShell* shell = pc->PresShell();
   const nsStyleList* styleList = StyleList();
   CounterStyle* style =
       pc->CounterStyleManager()->ResolveCounterStyle(styleList->mCounterStyle);
 
-  CSSPseudoElementType pseudoType = style->IsBullet()
-                                        ? CSSPseudoElementType::mozListBullet
-                                        : CSSPseudoElementType::mozListNumber;
+  PseudoStyleType pseudoType = style->IsBullet()
+                                   ? PseudoStyleType::mozListBullet
+                                   : PseudoStyleType::mozListNumber;
 
   RefPtr<ComputedStyle> kidSC =
       ResolveBulletStyle(pseudoType, shell->StyleSet());
 
   // Create bullet frame
   nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC, pc);
   bullet->Init(mContent, this, nullptr);
 
@@ -7204,57 +7204,54 @@ nsresult nsBlockFrame::ResolveBidi() {
 void nsBlockFrame::UpdatePseudoElementStyles(ServoRestyleState& aRestyleState) {
   // first-letter needs to be updated before first-line, because first-line can
   // change the style of the first-letter.
   if (HasFirstLetterChild()) {
     UpdateFirstLetterStyle(aRestyleState);
   }
 
   if (nsBulletFrame* bullet = GetBullet()) {
-    CSSPseudoElementType type = bullet->Style()->GetPseudoType();
+    PseudoStyleType type = bullet->Style()->GetPseudoType();
     RefPtr<ComputedStyle> newBulletStyle =
         ResolveBulletStyle(type, &aRestyleState.StyleSet());
     UpdateStyleOfOwnedChildFrame(bullet, newBulletStyle, aRestyleState);
   }
 
   if (nsIFrame* firstLineFrame = GetFirstLineFrame()) {
-    nsIFrame* styleParent = CorrectStyleParentFrame(
-        firstLineFrame->GetParent(), nsCSSPseudoElements::firstLine());
+    nsIFrame* styleParent = CorrectStyleParentFrame(firstLineFrame->GetParent(),
+                                                    PseudoStyleType::firstLine);
 
     ComputedStyle* parentStyle = styleParent->Style();
     RefPtr<ComputedStyle> firstLineStyle =
         aRestyleState.StyleSet().ResolvePseudoElementStyle(
-            mContent->AsElement(), CSSPseudoElementType::firstLine, parentStyle,
+            mContent->AsElement(), PseudoStyleType::firstLine, parentStyle,
             nullptr);
 
     // FIXME(bz): Can we make first-line continuations be non-inheriting anon
     // boxes?
     RefPtr<ComputedStyle> continuationStyle =
         aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::mozLineFrame(), parentStyle);
+            PseudoStyleType::mozLineFrame, parentStyle);
 
     UpdateStyleOfOwnedChildFrame(firstLineFrame, firstLineStyle, aRestyleState,
                                  Some(continuationStyle.get()));
 
     // We also want to update the styles of the first-line's descendants.  We
     // don't need to compute a changehint for this, though, since any changes to
     // them are handled by the first-line anyway.
     RestyleManager* manager = PresContext()->RestyleManager();
     for (nsIFrame* kid : firstLineFrame->PrincipalChildList()) {
       manager->ReparentComputedStyleForFirstLine(kid);
     }
   }
 }
 
 already_AddRefed<ComputedStyle> nsBlockFrame::ResolveBulletStyle(
-    CSSPseudoElementType aType, ServoStyleSet* aStyleSet) {
-  ComputedStyle* parentStyle =
-      CorrectStyleParentFrame(this, nsCSSPseudoElements::GetPseudoAtom(aType))
-          ->Style();
-
+    PseudoStyleType aType, ServoStyleSet* aStyleSet) {
+  ComputedStyle* parentStyle = CorrectStyleParentFrame(this, aType)->Style();
   return aStyleSet->ResolvePseudoElementStyle(mContent->AsElement(), aType,
                                               parentStyle, nullptr);
 }
 
 nsIFrame* nsBlockFrame::GetFirstLetter() const {
   if (!(GetStateBits() & NS_BLOCK_HAS_FIRST_LETTER_STYLE)) {
     // Certainly no first-letter frame.
     return nullptr;
@@ -7431,11 +7428,11 @@ int32_t nsBlockFrame::GetDepth() const {
     depth++;
   }
   return depth;
 }
 
 already_AddRefed<ComputedStyle> nsBlockFrame::GetFirstLetterStyle(
     nsPresContext* aPresContext) {
   return aPresContext->StyleSet()->ProbePseudoElementStyle(
-      *mContent->AsElement(), CSSPseudoElementType::firstLetter, Style());
+      *mContent->AsElement(), PseudoStyleType::firstLetter, Style());
 }
 #endif
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -903,17 +903,17 @@ class nsBlockFrame : public nsContainerF
   nsFrameList* EnsurePushedFloats();
   // Remove and return the pushed floats list.
   nsFrameList* RemovePushedFloats();
 
   // Resolve a ComputedStyle for our bullet frame.  aType should be
   // mozListBullet or mozListNumber.  Passing in the style set is an
   // optimization, because all callsites have it.
   already_AddRefed<ComputedStyle> ResolveBulletStyle(
-      mozilla::CSSPseudoElementType aType, mozilla::ServoStyleSet* aStyleSet);
+      mozilla::PseudoStyleType aType, mozilla::ServoStyleSet* aStyleSet);
 
 #ifdef DEBUG
   void VerifyLines(bool aFinalCheckOK);
   void VerifyOverflowSituation();
   int32_t GetDepth() const;
 #endif
 
   // FIXME The two variables should go through a renaming refactoring to reflect
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -1244,17 +1244,17 @@ void nsColumnSetFrame::AppendDirectlyOwn
   // Everything in mFrames is continuations of the first thing in mFrames.
   nsIFrame* column = mFrames.FirstChild();
 
   // We might not have any columns, apparently?
   if (!column) {
     return;
   }
 
-  MOZ_ASSERT(column->Style()->GetPseudo() == nsCSSAnonBoxes::columnContent(),
+  MOZ_ASSERT(column->Style()->GetPseudoType() == PseudoStyleType::columnContent,
              "What sort of child is this?");
   aResult.AppendElement(OwnedAnonBox(column));
 }
 
 #ifdef DEBUG
 void nsColumnSetFrame::SetInitialChildList(ChildListID aListID,
                                            nsFrameList& aChildList) {
   MOZ_ASSERT(aListID != kPrincipalList || aChildList.OnlyChild(),
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -47,17 +47,17 @@ void nsFirstLetterFrame::BuildDisplayLis
 void nsFirstLetterFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
                               nsIFrame* aPrevInFlow) {
   RefPtr<ComputedStyle> newSC;
   if (aPrevInFlow) {
     // Get proper ComputedStyle for ourselves.  We're creating the frame
     // that represents everything *except* the first letter, so just create
     // a ComputedStyle that inherits from our style parent, with no extra rules.
     nsIFrame* styleParent =
-        CorrectStyleParentFrame(aParent, nsCSSPseudoElements::firstLetter());
+        CorrectStyleParentFrame(aParent, PseudoStyleType::firstLetter);
     ComputedStyle* parentComputedStyle = styleParent->Style();
     newSC = PresContext()->StyleSet()->ResolveStyleForFirstLetterContinuation(
         parentComputedStyle);
     SetComputedStyleWithoutNotification(newSC);
   }
 
   nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 }
@@ -209,18 +209,18 @@ void nsFirstLetterFrame::Reflow(nsPresCo
     ConsiderChildOverflow(aMetrics.mOverflowAreas, kid);
 
     FinishAndStoreOverflow(&aMetrics, aReflowInput.mStyleDisplay);
   } else {
     // Pretend we are a span and reflow the child frame
     nsLineLayout* ll = aReflowInput.mLineLayout;
     bool pushedFrame;
 
-    ll->SetInFirstLetter(mComputedStyle->GetPseudo() ==
-                         nsCSSPseudoElements::firstLetter());
+    ll->SetInFirstLetter(Style()->GetPseudoType() ==
+                         PseudoStyleType::firstLetter);
     ll->BeginSpan(this, &aReflowInput, bp.IStart(wm), availSize.ISize(wm),
                   &mBaseline);
     ll->ReflowFrame(kid, aReflowStatus, &kidMetrics, pushedFrame);
     NS_ASSERTION(lineWM.IsVertical() == wm.IsVertical(),
                  "we're assuming we can mix sizes between lineWM and wm "
                  "since we shouldn't have orthogonal writing modes within "
                  "a line.");
     aMetrics.ISize(lineWM) = ll->EndSpan(this) + bp.IStartEnd(wm);
@@ -349,18 +349,18 @@ void nsFirstLetterFrame::DrainOverflowFr
   nsIFrame* kid = mFrames.FirstChild();
   if (kid) {
     nsIContent* kidContent = kid->GetContent();
     if (kidContent) {
       NS_ASSERTION(kidContent->IsText(), "should contain only text nodes");
       ComputedStyle* parentSC;
       if (prevInFlow) {
         // This is for the rest of the content not in the first-letter.
-        nsIFrame* styleParent = CorrectStyleParentFrame(
-            GetParent(), nsCSSPseudoElements::firstLetter());
+        nsIFrame* styleParent =
+            CorrectStyleParentFrame(GetParent(), PseudoStyleType::firstLetter);
         parentSC = styleParent->Style();
       } else {
         // And this for the first-letter style.
         parentSC = mComputedStyle;
       }
       RefPtr<ComputedStyle> sc =
           aPresContext->StyleSet()->ResolveStyleForText(kidContent, parentSC);
       kid->SetComputedStyle(sc);
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -151,22 +151,20 @@ static uint8_t ConvertLegacyStyleToJusti
   MOZ_ASSERT_UNREACHABLE("Unrecognized mBoxPack enum value");
   // Fall back to default value of "justify-content" property:
   return NS_STYLE_ALIGN_FLEX_START;
 }
 
 // Helper-function to find the first non-anonymous-box descendent of aFrame.
 static nsIFrame* GetFirstNonAnonBoxDescendant(nsIFrame* aFrame) {
   while (aFrame) {
-    nsAtom* pseudoTag = aFrame->Style()->GetPseudo();
-
-    // If aFrame isn't an anonymous container, then it'll do.
-    if (!pseudoTag ||                               // No pseudotag.
-        !nsCSSAnonBoxes::IsAnonBox(pseudoTag) ||    // Pseudotag isn't anon.
-        nsCSSAnonBoxes::IsNonElement(pseudoTag)) {  // Text, not a container.
+    // If aFrame isn't an anonymous container, or it's text or such, then it'll
+    // do.
+    if (!aFrame->Style()->IsAnonBox() ||
+        nsCSSAnonBoxes::IsNonElement(aFrame->Style()->GetPseudoType())) {
       break;
     }
 
     // Otherwise, descend to its first child and repeat.
 
     // SPECIAL CASE: if we're dealing with an anonymous table, then it might
     // be wrapping something non-anonymous in its caption or col-group lists
     // (instead of its principal child list), so we have to look there.
@@ -2346,19 +2344,18 @@ void nsFlexContainerFrame::Init(nsIConte
 
   // If this frame is for a scrollable element, then it will actually have
   // "display:block", and its *parent frame* will have the real
   // flex-flavored display value. So in that case, check the parent frame to
   // find out if we're legacy.
   if (!isLegacyBox && styleDisp->mDisplay == mozilla::StyleDisplay::Block) {
     ComputedStyle* parentComputedStyle = GetParent()->Style();
     NS_ASSERTION(
-        parentComputedStyle &&
-            (mComputedStyle->GetPseudo() == nsCSSAnonBoxes::buttonContent() ||
-             mComputedStyle->GetPseudo() == nsCSSAnonBoxes::scrolledContent()),
+        Style()->GetPseudoType() == PseudoStyleType::buttonContent ||
+            Style()->GetPseudoType() == PseudoStyleType::scrolledContent,
         "The only way a nsFlexContainerFrame can have 'display:block' "
         "should be if it's the inner part of a scrollable or button "
         "element");
     isLegacyBox = IsDisplayValueLegacyBox(parentComputedStyle->StyleDisplay());
   }
 
   if (isLegacyBox) {
     AddStateBits(NS_STATE_FLEX_IS_EMULATING_LEGACY_BOX);
@@ -3713,19 +3710,19 @@ bool nsFlexContainerFrame::ShouldUseMozB
   // Check our own display value:
   if (aThisStyleDisp->mDisplay == mozilla::StyleDisplay::MozBox ||
       aThisStyleDisp->mDisplay == mozilla::StyleDisplay::MozInlineBox) {
     return true;
   }
 
   // Check our parent's display value, if we're an anonymous box (with a
   // potentially-untrustworthy display value):
-  auto pseudoType = Style()->GetPseudo();
-  if (pseudoType == nsCSSAnonBoxes::scrolledContent() ||
-      pseudoType == nsCSSAnonBoxes::buttonContent()) {
+  auto pseudoType = Style()->GetPseudoType();
+  if (pseudoType == PseudoStyleType::scrolledContent ||
+      pseudoType == PseudoStyleType::buttonContent) {
     const nsStyleDisplay* disp = GetParent()->StyleDisplay();
     if (disp->mDisplay == mozilla::StyleDisplay::MozBox ||
         disp->mDisplay == mozilla::StyleDisplay::MozInlineBox) {
       return true;
     }
   }
 
   return false;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1195,29 +1195,29 @@ void nsIFrame::MarkNeedsDisplayItemRebui
   RemoveStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS | NS_FRAME_SIMPLE_DISPLAYLIST);
 
   mMayHaveRoundedCorners = true;
 }
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 void nsIFrame::AssertNewStyleIsSane(ComputedStyle& aNewStyle) {
   MOZ_DIAGNOSTIC_ASSERT(
-      aNewStyle.GetPseudo() == mComputedStyle->GetPseudo() ||
+      aNewStyle.GetPseudoType() == mComputedStyle->GetPseudoType() ||
       // ::first-line continuations are weird, this should probably be fixed via
       // bug 1465474.
-      (mComputedStyle->GetPseudo() == nsCSSPseudoElements::firstLine() &&
-       aNewStyle.GetPseudo() == nsCSSAnonBoxes::mozLineFrame()) ||
+      (mComputedStyle->GetPseudoType() == PseudoStyleType::firstLine &&
+       aNewStyle.GetPseudoType() == PseudoStyleType::mozLineFrame) ||
       // ::first-letter continuations are broken, in particular floating ones,
       // see bug 1490281. The construction code tries to fix this up after the
       // fact, then restyling undoes it...
-      (mComputedStyle->GetPseudo() == nsCSSAnonBoxes::mozText() &&
-       aNewStyle.GetPseudo() == nsCSSAnonBoxes::firstLetterContinuation()) ||
-      (mComputedStyle->GetPseudo() ==
-           nsCSSAnonBoxes::firstLetterContinuation() &&
-       aNewStyle.GetPseudo() == nsCSSAnonBoxes::mozText()));
+      (mComputedStyle->GetPseudoType() == PseudoStyleType::mozText &&
+       aNewStyle.GetPseudoType() == PseudoStyleType::firstLetterContinuation) ||
+      (mComputedStyle->GetPseudoType() ==
+           PseudoStyleType::firstLetterContinuation &&
+       aNewStyle.GetPseudoType() == PseudoStyleType::mozText));
 }
 #endif
 
 void nsIFrame::ReparentFrameViewTo(nsViewManager* aViewManager,
                                    nsView* aNewParentView,
                                    nsView* aOldParentView) {
   if (HasView()) {
 #ifdef MOZ_XUL
@@ -2187,17 +2187,17 @@ static Element* FindElementAncestorForMo
 }
 
 already_AddRefed<ComputedStyle> nsIFrame::ComputeSelectionStyle() const {
   Element* element = FindElementAncestorForMozSelection(GetContent());
   if (!element) {
     return nullptr;
   }
   RefPtr<ComputedStyle> sc = PresContext()->StyleSet()->ProbePseudoElementStyle(
-      *element, CSSPseudoElementType::selection, Style());
+      *element, PseudoStyleType::selection, Style());
   return sc.forget();
 }
 
 /********************************************************
  * Refreshes each content's frame
  *********************************************************/
 
 void nsFrame::DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
@@ -7242,20 +7242,20 @@ bool nsFrame::IsFrameTreeTooDeep(const R
 
     return true;
   }
   RemoveStateBits(NS_FRAME_TOO_DEEP_IN_FRAME_TREE);
   return false;
 }
 
 bool nsIFrame::IsBlockWrapper() const {
-  nsAtom* pseudoType = Style()->GetPseudo();
-  return (pseudoType == nsCSSAnonBoxes::mozBlockInsideInlineWrapper() ||
-          pseudoType == nsCSSAnonBoxes::buttonContent() ||
-          pseudoType == nsCSSAnonBoxes::cellContent());
+  auto pseudoType = Style()->GetPseudoType();
+  return pseudoType == PseudoStyleType::mozBlockInsideInlineWrapper ||
+         pseudoType == PseudoStyleType::buttonContent ||
+         pseudoType == PseudoStyleType::cellContent;
 }
 
 bool nsIFrame::IsBlockFrameOrSubclass() const {
   const nsBlockFrame* thisAsBlock = do_QueryFrame(this);
   return !!thisAsBlock;
 }
 
 static nsIFrame* GetNearestBlockContainer(nsIFrame* frame) {
@@ -7293,17 +7293,17 @@ nsIFrame* nsIFrame::GetContainingBlock(
   if (IsAbsolutelyPositioned(aStyleDisplay) &&
       (GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
     f = GetParent();  // the parent is always the containing block
   } else {
     f = GetNearestBlockContainer(GetParent());
   }
 
   if (aFlags & SKIP_SCROLLED_FRAME && f &&
-      f->Style()->GetPseudo() == nsCSSAnonBoxes::scrolledContent()) {
+      f->Style()->GetPseudoType() == PseudoStyleType::scrolledContent) {
     f = f->GetParent();
   }
   return f;
 }
 
 #ifdef DEBUG_FRAME_DUMP
 
 int32_t nsFrame::ContentIndexInContainer(const nsIFrame* aFrame) {
@@ -7422,22 +7422,20 @@ void nsIFrame::ListGeneric(nsACString& a
   if (Combines3DTransformWithAncestors()) {
     aTo += nsPrintfCString(" combines-3d-transform-with-ancestors");
   }
   if (mContent) {
     aTo += nsPrintfCString(" [content=%p]", static_cast<void*>(mContent));
   }
   aTo += nsPrintfCString(" [cs=%p", static_cast<void*>(mComputedStyle));
   if (mComputedStyle) {
-    nsAtom* pseudoTag = mComputedStyle->GetPseudo();
-    if (pseudoTag) {
-      nsAutoString atomString;
-      pseudoTag->ToString(atomString);
-      aTo +=
-          nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
+    auto pseudoType = mComputedStyle->GetPseudoType();
+    if (pseudoType != PseudoStyleType::NotPseudo) {
+      // FIXME(emilio): It'd be nice to get the string from here.
+      aTo += nsPrintfCString("pseudo: %d", static_cast<int>(pseudoType));
     }
   }
   aTo += "]";
 }
 
 void nsIFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const {
   nsCString str;
   ListGeneric(str, aPrefix, aFlags);
@@ -8864,18 +8862,18 @@ static void ComputeAndIncludeOutlineArea
 
   // When the outline property is set on a :-moz-block-inside-inline-wrapper
   // pseudo-element, it inherited that outline from the inline that was broken
   // because it contained a block.  In that case, we don't want a really wide
   // outline if the block inside the inline is narrow, so union the actual
   // contents of the anonymous blocks.
   nsIFrame* frameForArea = aFrame;
   do {
-    nsAtom* pseudoType = frameForArea->Style()->GetPseudo();
-    if (pseudoType != nsCSSAnonBoxes::mozBlockInsideInlineWrapper()) break;
+    PseudoStyleType pseudoType = frameForArea->Style()->GetPseudoType();
+    if (pseudoType != PseudoStyleType::mozBlockInsideInlineWrapper) break;
     // If we're done, we really want it and all its later siblings.
     frameForArea = frameForArea->PrincipalChildList().FirstChild();
     NS_ASSERTION(frameForArea, "anonymous block with no children?");
   } while (frameForArea);
 
   // Find the union of the border boxes of all descendants, or in
   // the block-in-inline case, all descendants we care about.
   //
@@ -9278,18 +9276,18 @@ bool nsFrame::ShouldAvoidBreakInside(con
  *
  * If aFrame is not an anonymous block, null is returned.
  */
 static nsIFrame* GetIBSplitSiblingForAnonymousBlock(const nsIFrame* aFrame) {
   MOZ_ASSERT(aFrame, "Must have a non-null frame!");
   NS_ASSERTION(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT,
                "GetIBSplitSibling should only be called on ib-split frames");
 
-  nsAtom* type = aFrame->Style()->GetPseudo();
-  if (type != nsCSSAnonBoxes::mozBlockInsideInlineWrapper()) {
+  if (aFrame->Style()->GetPseudoType() !=
+      PseudoStyleType::mozBlockInsideInlineWrapper) {
     // it's not an anonymous block
     return nullptr;
   }
 
   // Find the first continuation of the frame.  (Ugh.  This ends up
   // being O(N^2) when it is called O(N) times.)
   aFrame = aFrame->FirstContinuation();
 
@@ -9320,32 +9318,33 @@ static nsIFrame* GetCorrectedParent(cons
   if (!parent) {
     return nullptr;
   }
 
   // For a table caption we want the _inner_ table frame (unless it's anonymous)
   // as the style parent.
   if (aFrame->IsTableCaption()) {
     nsIFrame* innerTable = parent->PrincipalChildList().FirstChild();
-    if (!innerTable->Style()->GetPseudo()) {
+    if (!innerTable->Style()->IsAnonBox()) {
       return innerTable;
     }
   }
 
   // Table wrappers are always anon boxes; if we're in here for an outer
   // table, that actually means its the _inner_ table that wants to
   // know its parent. So get the pseudo of the inner in that case.
-  nsAtom* pseudo = aFrame->Style()->GetPseudo();
-  if (pseudo == nsCSSAnonBoxes::tableWrapper()) {
-    pseudo = aFrame->PrincipalChildList().FirstChild()->Style()->GetPseudo();
+  auto pseudo = aFrame->Style()->GetPseudoType();
+  if (pseudo == PseudoStyleType::tableWrapper) {
+    pseudo =
+        aFrame->PrincipalChildList().FirstChild()->Style()->GetPseudoType();
   }
 
   // Prevent a NAC pseudo-element from inheriting from its NAC parent, and
   // inherit from the NAC generator element instead.
-  if (pseudo) {
+  if (pseudo != PseudoStyleType::NotPseudo) {
     MOZ_ASSERT(aFrame->GetContent());
     Element* element = Element::FromNode(aFrame->GetContent());
     // Make sure to avoid doing the fixup for non-element-backed pseudos like
     // ::first-line and such.
     if (element && !element->IsRootOfNativeAnonymousSubtree() &&
         element->GetPseudoElementType() == aFrame->Style()->GetPseudoType()) {
       while (parent->GetContent() &&
              !parent->GetContent()->IsRootOfAnonymousSubtree()) {
@@ -9355,33 +9354,32 @@ static nsIFrame* GetCorrectedParent(cons
     }
   }
 
   return nsFrame::CorrectStyleParentFrame(parent, pseudo);
 }
 
 /* static */
 nsIFrame* nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
-                                           nsAtom* aChildPseudo) {
+                                           PseudoStyleType aChildPseudo) {
   MOZ_ASSERT(aProspectiveParent, "Must have a prospective parent");
 
-  if (aChildPseudo) {
+  if (aChildPseudo != PseudoStyleType::NotPseudo) {
     // Non-inheriting anon boxes have no style parent frame at all.
-    if (nsCSSAnonBoxes::IsNonInheritingAnonBox(aChildPseudo)) {
+    if (PseudoStyle::IsNonInheritingAnonBox(aChildPseudo)) {
       return nullptr;
     }
 
     // Other anon boxes are parented to their actual parent already, except
     // for non-elements.  Those should not be treated as an anon box.
-    if (!nsCSSAnonBoxes::IsNonElement(aChildPseudo) &&
-        nsCSSAnonBoxes::IsAnonBox(aChildPseudo)) {
-      NS_ASSERTION(
-          aChildPseudo != nsCSSAnonBoxes::mozBlockInsideInlineWrapper(),
-          "Should have dealt with kids that have "
-          "NS_FRAME_PART_OF_IBSPLIT elsewhere");
+    if (PseudoStyle::IsAnonBox(aChildPseudo) &&
+        !nsCSSAnonBoxes::IsNonElement(aChildPseudo)) {
+      NS_ASSERTION(aChildPseudo != PseudoStyleType::mozBlockInsideInlineWrapper,
+                   "Should have dealt with kids that have "
+                   "NS_FRAME_PART_OF_IBSPLIT elsewhere");
       return aProspectiveParent;
     }
   }
 
   // Otherwise, walk up out of all anon boxes.  For placeholder frames, walk out
   // of all pseudo-elements as well.  Otherwise ReparentComputedStyle could
   // cause style data to be out of sync with the frame tree.
   nsIFrame* parent = aProspectiveParent;
@@ -9391,32 +9389,33 @@ nsIFrame* nsFrame::CorrectStyleParentFra
 
       if (sibling) {
         // |parent| was a block in an {ib} split; use the inline as
         // |the style parent.
         parent = sibling;
       }
     }
 
-    nsAtom* parentPseudo = parent->Style()->GetPseudo();
-    if (!parentPseudo ||
-        (!nsCSSAnonBoxes::IsAnonBox(parentPseudo) &&
-         // nsPlaceholderFrame pases in nsGkAtoms::placeholderFrame for
-         // aChildPseudo (even though that's not a valid pseudo-type) just to
-         // trigger this behavior of walking up to the nearest non-pseudo
-         // ancestor.
-         aChildPseudo != nsGkAtoms::placeholderFrame)) {
+    if (!parent->Style()->IsPseudoOrAnonBox()) {
+      return parent;
+    }
+
+    if (!parent->Style()->IsAnonBox() && aChildPseudo != PseudoStyleType::MAX) {
+      // nsPlaceholderFrame passes in PseudoStyleType::MAX for
+      // aChildPseudo (even though that's not a valid pseudo-type) just to
+      // trigger this behavior of walking up to the nearest non-pseudo
+      // ancestor.
       return parent;
     }
 
     parent = parent->GetInFlowParent();
   } while (parent);
 
-  if (aProspectiveParent->Style()->GetPseudo() ==
-      nsCSSAnonBoxes::viewportScroll()) {
+  if (aProspectiveParent->Style()->GetPseudoType() ==
+      PseudoStyleType::viewportScroll) {
     // aProspectiveParent is the scrollframe for a viewport
     // and the kids are the anonymous scrollbars
     return aProspectiveParent;
   }
 
   // We can get here if the root element is absolutely positioned.
   // We can't test for this very accurately, but it can only happen
   // when the prospective parent is a canvas frame.
@@ -9429,39 +9428,39 @@ ComputedStyle* nsFrame::DoGetParentCompu
     nsIFrame** aProviderFrame) const {
   *aProviderFrame = nullptr;
 
   // Handle display:contents and the root frame, when there's no parent frame
   // to inherit from.
   if (MOZ_LIKELY(mContent)) {
     Element* parentElement = mContent->GetFlattenedTreeParentElement();
     if (MOZ_LIKELY(parentElement)) {
-      nsAtom* pseudo = Style()->GetPseudo();
-      if (!pseudo || !mContent->IsElement() ||
-          (!nsCSSAnonBoxes::IsAnonBox(pseudo) &&
+      auto pseudo = Style()->GetPseudoType();
+      if (pseudo == PseudoStyleType::NotPseudo || !mContent->IsElement() ||
+          (!PseudoStyle::IsAnonBox(pseudo) &&
            // Ensure that we don't return the display:contents style
            // of the parent content for pseudos that have the same content
            // as their primary frame (like -moz-list-bullets do):
            IsPrimaryFrame()) ||
           /* if next is true then it's really a request for the table frame's
              parent context, see nsTable[Outer]Frame::GetParentComputedStyle. */
-          pseudo == nsCSSAnonBoxes::tableWrapper()) {
+          pseudo == PseudoStyleType::tableWrapper) {
         if (Servo_Element_IsDisplayContents(parentElement)) {
           RefPtr<ComputedStyle> style =
               PresShell()->StyleSet()->ResolveServoStyle(*parentElement);
           // NOTE(emilio): we return a weak reference because the element also
           // holds the style context alive. This is a bit silly (we could've
           // returned a weak ref directly), but it's probably not worth
           // optimizing, given this function has just one caller which is rare,
           // and this path is rare itself.
           return style;
         }
       }
     } else {
-      if (!Style()->GetPseudo()) {
+      if (Style()->GetPseudoType() == PseudoStyleType::NotPseudo) {
         // We're a frame for the root.  We have no style parent.
         return nullptr;
       }
     }
   }
 
   if (!(mState & NS_FRAME_OUT_OF_FLOW)) {
     /*
@@ -9527,18 +9526,18 @@ void nsFrame::GetFirstLeaf(nsPresContext
 /* virtual */ bool nsIFrame::IsFocusable(int32_t* aTabIndex, bool aWithMouse) {
   int32_t tabIndex = -1;
   if (aTabIndex) {
     *aTabIndex = -1;  // Default for early return is not focusable
   }
   bool isFocusable = false;
 
   if (mContent && mContent->IsElement() && IsVisibleConsideringAncestors() &&
-      Style()->GetPseudo() != nsCSSAnonBoxes::anonymousFlexItem() &&
-      Style()->GetPseudo() != nsCSSAnonBoxes::anonymousGridItem()) {
+      Style()->GetPseudoType() != PseudoStyleType::anonymousFlexItem &&
+      Style()->GetPseudoType() != PseudoStyleType::anonymousGridItem) {
     const nsStyleUI* ui = StyleUI();
     if (ui->mUserFocus != StyleUserFocus::Ignore &&
         ui->mUserFocus != StyleUserFocus::None) {
       // Pass in default tabindex of -1 for nonfocusable and 0 for focusable
       tabIndex = 0;
     }
     isFocusable = mContent->IsFocusable(&tabIndex, aWithMouse);
     if (!isFocusable && !aWithMouse && IsScrollFrame() &&
@@ -10206,19 +10205,19 @@ void nsIFrame::UpdateStyleOfChildAnonBox
   MOZ_ASSERT(!GetContent() || !aChildFrame->GetContent() ||
                  aChildFrame->GetContent() == GetContent(),
              "What content node is it a frame for?");
   MOZ_ASSERT(!aChildFrame->GetPrevContinuation(),
              "Only first continuations should end up here");
 
   // We could force the caller to pass in the pseudo, since some callers know it
   // statically...  But this API is a bit nicer.
-  nsAtom* pseudo = aChildFrame->Style()->GetPseudo();
-  MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(pseudo), "Child is not an anon box?");
-  MOZ_ASSERT(!nsCSSAnonBoxes::IsNonInheritingAnonBox(pseudo),
+  auto pseudo = aChildFrame->Style()->GetPseudoType();
+  MOZ_ASSERT(PseudoStyle::IsAnonBox(pseudo), "Child is not an anon box?");
+  MOZ_ASSERT(!PseudoStyle::IsNonInheritingAnonBox(pseudo),
              "Why did the caller bother calling us?");
 
   // Anon boxes inherit from their parent; that's us.
   RefPtr<ComputedStyle> newContext =
       aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(pseudo,
                                                                   Style());
 
   nsChangeHint childHint =
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -531,18 +531,18 @@ class nsFrame : public nsBox {
    * Adjust the given parent frame to the right ComputedStyle parent frame for
    * the child, given the pseudo-type of the prospective child.  This handles
    * things like walking out of table pseudos and so forth.
    *
    * @param aProspectiveParent what GetParent() on the child returns.
    *                           Must not be null.
    * @param aChildPseudo the child's pseudo type, if any.
    */
-  static nsIFrame* CorrectStyleParentFrame(nsIFrame* aProspectiveParent,
-                                           nsAtom* aChildPseudo);
+  static nsIFrame* CorrectStyleParentFrame(
+      nsIFrame* aProspectiveParent, mozilla::PseudoStyleType aChildPseudo);
 
  protected:
   // Protected constructor and destructor
   nsFrame(ComputedStyle* aStyle, nsPresContext* aPresContext, ClassID aID);
   explicit nsFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
       : nsFrame(aStyle, aPresContext, ClassID::nsFrame_id) {}
   virtual ~nsFrame();
 
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -312,17 +312,17 @@ void nsHTMLFramesetFrame::Init(nsIConten
   }
 
   mNonBlankChildCount = mChildCount;
   // add blank frames for frameset cells that had no content provided
   for (int blankX = mChildCount; blankX < numCells; blankX++) {
     RefPtr<ComputedStyle> pseudoComputedStyle;
     pseudoComputedStyle =
         shell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::framesetBlank());
+            PseudoStyleType::framesetBlank);
 
     // XXX the blank frame is using the content of its parent - at some point it
     // should just have null content, if we support that
     nsHTMLFramesetBlankFrame* blankFrame = new (shell)
         nsHTMLFramesetBlankFrame(pseudoComputedStyle, PresContext());
 
     blankFrame->Init(mContent, this, nullptr);
 
@@ -870,17 +870,17 @@ void nsHTMLFramesetFrame::Reflow(nsPresC
 
     if (lastRow != cellIndex.y) {  // changed to next row
       offset.x = 0;
       offset.y += lastSize.height;
       if (firstTime) {  // create horizontal border
 
         RefPtr<ComputedStyle> pseudoComputedStyle;
         pseudoComputedStyle = styleSet->ResolveNonInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::horizontalFramesetBorder());
+            PseudoStyleType::horizontalFramesetBorder);
 
         borderFrame = new (shell) nsHTMLFramesetBorderFrame(
             pseudoComputedStyle, PresContext(), borderWidth, false, false);
         borderFrame->Init(mContent, this, nullptr);
         mChildCount++;
         mFrames.AppendFrame(nullptr, borderFrame);
         mHorBorders[cellIndex.y - 1] = borderFrame;
         // set the neighbors for determining drag boundaries
@@ -899,17 +899,17 @@ void nsHTMLFramesetFrame::Reflow(nsPresC
     } else {
       if (cellIndex.x > 0) {     // moved to next col in same row
         if (0 == cellIndex.y) {  // in 1st row
           if (firstTime) {       // create vertical border
 
             RefPtr<ComputedStyle> pseudoComputedStyle;
             pseudoComputedStyle =
                 styleSet->ResolveNonInheritingAnonymousBoxStyle(
-                    nsCSSAnonBoxes::verticalFramesetBorder());
+                    PseudoStyleType::verticalFramesetBorder);
 
             borderFrame = new (shell) nsHTMLFramesetBorderFrame(
                 pseudoComputedStyle, PresContext(), borderWidth, true, false);
             borderFrame->Init(mContent, this, nullptr);
             mChildCount++;
             mFrames.AppendFrame(nullptr, borderFrame);
             mVerBorders[cellIndex.x - 1] = borderFrame;
             // set the neighbors for determining drag boundaries
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -123,17 +123,17 @@ struct nsPeekOffsetStruct;
 struct nsPoint;
 struct nsRect;
 struct nsSize;
 struct nsMargin;
 struct CharacterDataChangeInfo;
 
 namespace mozilla {
 
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 class EventStates;
 struct ReflowInput;
 class ReflowOutput;
 class ServoRestyleState;
 class DisplayItemData;
 class EffectSet;
 
 namespace layers {
--- a/layout/generic/nsIFrameInlines.h
+++ b/layout/generic/nsIFrameInlines.h
@@ -25,17 +25,18 @@ bool nsIFrame::IsFlexOrGridContainer() c
 
 bool nsIFrame::IsFlexOrGridItem() const {
   return !(GetStateBits() & NS_FRAME_OUT_OF_FLOW) && GetParent() &&
          GetParent()->IsFlexOrGridContainer();
 }
 
 bool nsIFrame::IsTableCaption() const {
   return StyleDisplay()->mDisplay == mozilla::StyleDisplay::TableCaption &&
-         GetParent()->Style()->GetPseudo() == nsCSSAnonBoxes::tableWrapper();
+         GetParent()->Style()->GetPseudoType() ==
+             mozilla::PseudoStyleType::tableWrapper;
 }
 
 bool nsIFrame::IsFloating() const { return StyleDisplay()->IsFloating(this); }
 
 bool nsIFrame::IsAbsPosContainingBlock() const {
   return StyleDisplay()->IsAbsPosContainingBlock(this);
 }
 
@@ -73,18 +74,18 @@ bool nsIFrame::IsColumnSpan() const {
   return IsBlockOutside() && StyleColumn()->IsColumnSpanStyle();
 }
 
 bool nsIFrame::IsColumnSpanInMulticolSubtree() const {
   return IsColumnSpan() &&
          (HasAnyStateBits(NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR) ||
           // A frame other than inline and block won't have
           // NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR. We instead test its parent.
-          (GetParent() && GetParent()->Style()->GetPseudo() ==
-                              nsCSSAnonBoxes::columnSpanWrapper()));
+          (GetParent() && GetParent()->Style()->GetPseudoType() ==
+                              mozilla::PseudoStyleType::columnSpanWrapper));
 }
 
 mozilla::StyleDisplay nsIFrame::GetDisplay() const {
   return StyleDisplay()->GetDisplay(this);
 }
 
 nscoord nsIFrame::SynthesizeBaselineBOffsetFromMarginBox(
     mozilla::WritingMode aWM, BaselineSharingGroup aGroup) const {
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2614,17 +2614,17 @@ nsImageListener::Notify(imgIRequest* aRe
   return mFrame->Notify(aRequest, aType, aData);
 }
 
 static bool IsInAutoWidthTableCellForQuirk(nsIFrame* aFrame) {
   if (eCompatibility_NavQuirks != aFrame->PresContext()->CompatibilityMode())
     return false;
   // Check if the parent of the closest nsBlockFrame has auto width.
   nsBlockFrame* ancestor = nsLayoutUtils::FindNearestBlockAncestor(aFrame);
-  if (ancestor->Style()->GetPseudo() == nsCSSAnonBoxes::cellContent()) {
+  if (ancestor->Style()->GetPseudoType() == PseudoStyleType::cellContent) {
     // Assume direct parent is a table cell frame.
     nsFrame* grandAncestor = static_cast<nsFrame*>(ancestor->GetParent());
     return grandAncestor && grandAncestor->StylePosition()->mWidth.IsAuto();
   }
   return false;
 }
 
 /* virtual */ void nsImageFrame::AddInlineMinISize(
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -879,30 +879,30 @@ void nsInlineFrame::UpdateStyleOfOwnedAn
 
   // The later inlines need to get our style.
   ComputedStyle* ourStyle = Style();
 
   // The anonymous block's style inherits from ours, and we already have our new
   // ComputedStyle.
   RefPtr<ComputedStyle> newContext =
       aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::mozBlockInsideInlineWrapper(), ourStyle);
+          PseudoStyleType::mozBlockInsideInlineWrapper, ourStyle);
 
   // We're guaranteed that newContext only differs from the old ComputedStyle on
   // the block in things they might inherit from us.  And changehint processing
   // guarantees walking the continuation and ib-sibling chains, so our existing
   // changehint being in aChangeList is good enough.  So we don't need to touch
   // aChangeList at all here.
 
   while (blockFrame) {
     MOZ_ASSERT(!blockFrame->GetPrevContinuation(),
                "Must be first continuation");
 
-    MOZ_ASSERT(blockFrame->Style()->GetPseudo() ==
-                   nsCSSAnonBoxes::mozBlockInsideInlineWrapper(),
+    MOZ_ASSERT(blockFrame->Style()->GetPseudoType() ==
+                   PseudoStyleType::mozBlockInsideInlineWrapper,
                "Unexpected kind of ComputedStyle");
 
     for (nsIFrame* cont = blockFrame; cont;
          cont = cont->GetNextContinuation()) {
       cont->SetComputedStyle(newContext);
     }
 
     nsIFrame* nextInline = blockFrame->GetProperty(nsIFrame::IBSplitSibling());
@@ -934,37 +934,37 @@ nsFirstLineFrame* NS_NewFirstLineFrame(n
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsFirstLineFrame)
 
 void nsFirstLineFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
                             nsIFrame* aPrevInFlow) {
   nsInlineFrame::Init(aContent, aParent, aPrevInFlow);
   if (!aPrevInFlow) {
-    MOZ_ASSERT(Style()->GetPseudo() == nsCSSPseudoElements::firstLine());
+    MOZ_ASSERT(Style()->GetPseudoType() == PseudoStyleType::firstLine);
     return;
   }
 
   // This frame is a continuation - fixup the computed style if aPrevInFlow
   // is the first-in-flow (the only one with a ::first-line pseudo).
-  if (aPrevInFlow->Style()->GetPseudo() == nsCSSPseudoElements::firstLine()) {
+  if (aPrevInFlow->Style()->GetPseudoType() == PseudoStyleType::firstLine) {
     MOZ_ASSERT(FirstInFlow() == aPrevInFlow);
     // Create a new ComputedStyle that is a child of the parent
     // ComputedStyle thus removing the ::first-line style. This way
     // we behave as if an anonymous (unstyled) span was the child
     // of the parent frame.
     ComputedStyle* parentContext = aParent->Style();
     RefPtr<ComputedStyle> newSC =
         PresContext()->StyleSet()->ResolveInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::mozLineFrame(), parentContext);
+            PseudoStyleType::mozLineFrame, parentContext);
     SetComputedStyle(newSC);
   } else {
     MOZ_ASSERT(FirstInFlow() != aPrevInFlow);
-    MOZ_ASSERT(aPrevInFlow->Style()->GetPseudo() ==
-               nsCSSAnonBoxes::mozLineFrame());
+    MOZ_ASSERT(aPrevInFlow->Style()->GetPseudoType() ==
+               PseudoStyleType::mozLineFrame);
   }
 }
 
 #ifdef DEBUG_FRAME_DUMP
 nsresult nsFirstLineFrame::GetFrameName(nsAString& aResult) const {
   return MakeFrameName(NS_LITERAL_STRING("Line"), aResult);
 }
 #endif
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -212,18 +212,19 @@ ComputedStyle* nsPlaceholderFrame::GetPa
   return GetLayoutParentStyleForOutOfFlow(aProviderFrame);
 }
 
 ComputedStyle* nsPlaceholderFrame::GetLayoutParentStyleForOutOfFlow(
     nsIFrame** aProviderFrame) const {
   // Lie about our pseudo so we can step out of all anon boxes and
   // pseudo-elements.  The other option would be to reimplement the
   // {ib} split gunk here.
-  *aProviderFrame =
-      CorrectStyleParentFrame(GetParent(), nsGkAtoms::placeholderFrame);
+  //
+  // See the hack in CorrectStyleParentFrame for why we pass `MAX`.
+  *aProviderFrame = CorrectStyleParentFrame(GetParent(), PseudoStyleType::MAX);
   return *aProviderFrame ? (*aProviderFrame)->Style() : nullptr;
 }
 
 #ifdef DEBUG
 static void PaintDebugPlaceholder(nsIFrame* aFrame, DrawTarget* aDrawTarget,
                                   const nsRect& aDirtyRect, nsPoint aPt) {
   ColorPattern cyan(ToDeviceColor(Color(0.f, 1.f, 1.f, 1.f)));
   int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
--- a/layout/generic/nsRubyContentFrame.cpp
+++ b/layout/generic/nsRubyContentFrame.cpp
@@ -22,17 +22,17 @@ using namespace mozilla;
 /* virtual */ bool nsRubyContentFrame::IsFrameOfType(uint32_t aFlags) const {
   if (aFlags & eBidiInlineContainer) {
     return false;
   }
   return nsInlineFrame::IsFrameOfType(aFlags);
 }
 
 bool nsRubyContentFrame::IsIntraLevelWhitespace() const {
-  nsAtom* pseudoType = Style()->GetPseudo();
-  if (pseudoType != nsCSSAnonBoxes::rubyBase() &&
-      pseudoType != nsCSSAnonBoxes::rubyText()) {
+  auto pseudoType = Style()->GetPseudoType();
+  if (pseudoType != PseudoStyleType::rubyBase &&
+      pseudoType != PseudoStyleType::rubyText) {
     return false;
   }
 
   nsIFrame* child = mFrames.OnlyChild();
   return child && child->GetContent()->TextIsOnlyWhitespace();
 }
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5146,17 +5146,17 @@ void nsTextFrame::BuildDisplayList(nsDis
 
   aLists.Content()->AppendToTop(
       MakeDisplayItem<nsDisplayText>(aBuilder, this, isSelected));
 }
 
 static nsIFrame* GetGeneratedContentOwner(nsIFrame* aFrame, bool* aIsBefore) {
   *aIsBefore = false;
   while (aFrame && (aFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT)) {
-    if (aFrame->Style()->GetPseudo() == nsCSSPseudoElements::before()) {
+    if (aFrame->Style()->GetPseudoType() == PseudoStyleType::before) {
       *aIsBefore = true;
     }
     aFrame = aFrame->GetParent();
   }
   return aFrame;
 }
 
 UniquePtr<SelectionDetails> nsTextFrame::GetSelectionDetails() {
--- a/layout/inspector/InspectorUtils.cpp
+++ b/layout/inspector/InspectorUtils.cpp
@@ -586,20 +586,20 @@ static EventStates GetStatesForPseudoCla
     return EventStates();
   }
   NS_ConvertUTF16toUTF8 statePseudo(Substring(aStatePseudo, 1));
   return EventStates(Servo_PseudoClass_GetStates(&statePseudo));
 }
 
 /* static */ void InspectorUtils::GetCSSPseudoElementNames(
     GlobalObject& aGlobalObject, nsTArray<nsString>& aResult) {
-  const CSSPseudoElementTypeBase pseudoCount =
-      static_cast<CSSPseudoElementTypeBase>(CSSPseudoElementType::Count);
-  for (CSSPseudoElementTypeBase i = 0; i < pseudoCount; ++i) {
-    CSSPseudoElementType type = static_cast<CSSPseudoElementType>(i);
+  const auto kPseudoCount =
+      static_cast<size_t>(PseudoStyleType::CSSPseudoElementsEnd);
+  for (size_t i = 0; i < kPseudoCount; ++i) {
+    PseudoStyleType type = static_cast<PseudoStyleType>(i);
     if (nsCSSPseudoElements::IsEnabled(type, CSSEnabledState::eForAllContent)) {
       nsAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type);
       aResult.AppendElement(nsDependentAtomString(atom));
     }
   }
 }
 
 /* static */ void InspectorUtils::AddPseudoClassLock(
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -87,18 +87,17 @@ nsMathMLFrame::UpdatePresentationData(ui
 
 // Helper to give a ComputedStyle suitable for doing the stretching of
 // a MathMLChar. Frame classes that use this should ensure that the
 // extra leaf ComputedStyle given to the MathMLChars are accessible to
 // the Style System via the Get/Set AdditionalComputedStyle() APIs.
 /* static */ void nsMathMLFrame::ResolveMathMLCharStyle(
     nsPresContext* aPresContext, nsIContent* aContent,
     ComputedStyle* aParentComputedStyle, nsMathMLChar* aMathMLChar) {
-  CSSPseudoElementType pseudoType =
-      CSSPseudoElementType::mozMathAnonymous;  // savings
+  PseudoStyleType pseudoType = PseudoStyleType::mozMathAnonymous;  // savings
   RefPtr<ComputedStyle> newComputedStyle;
   newComputedStyle = aPresContext->StyleSet()->ResolvePseudoElementStyle(
       aContent->AsElement(), pseudoType, aParentComputedStyle, nullptr);
 
   aMathMLChar->SetComputedStyle(newComputedStyle);
 }
 
 /* static */ void nsMathMLFrame::GetEmbellishDataFrom(
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -964,17 +964,17 @@ Maybe<nsCSSBorderRenderer> nsCSSRenderin
   if (!ourOutline->ShouldPaintOutline()) {
     // Empty outline
     return Nothing();
   }
 
   nsRect innerRect;
   if (
 #ifdef MOZ_XUL
-      aComputedStyle->GetPseudoType() == CSSPseudoElementType::XULTree
+      aComputedStyle->GetPseudoType() == PseudoStyleType::XULTree
 #else
       false
 #endif
   ) {
     innerRect = aBorderArea;
   } else {
     innerRect = GetOutlineInnerRect(aForFrame) + aBorderArea.TopLeft();
   }
@@ -1279,17 +1279,19 @@ inline bool FindElementBackground(nsIFra
   // was propagated to the viewport.
 
   nsIContent* content = aForFrame->GetContent();
   if (!content || content->NodeInfo()->NameAtom() != nsGkAtoms::body)
     return true;  // not frame for a "body" element
   // It could be a non-HTML "body" element but that's OK, we'd fail the
   // bodyContent check below
 
-  if (aForFrame->Style()->GetPseudo()) return true;  // A pseudo-element frame.
+  if (aForFrame->Style()->GetPseudoType() != PseudoStyleType::NotPseudo) {
+    return true;  // A pseudo-element frame.
+  }
 
   // We should only look at the <html> background if we're in an HTML document
   Document* document = content->OwnerDoc();
 
   dom::Element* bodyContent = document->GetBodyElement();
   if (bodyContent != content)
     return true;  // this wasn't the background that was propagated
 
--- a/layout/style/AnimationCollection.cpp
+++ b/layout/style/AnimationCollection.cpp
@@ -30,17 +30,17 @@ template <class AnimationType>
     }
   }
   delete collection;
 }
 
 template <class AnimationType>
 /* static */ AnimationCollection<AnimationType>*
 AnimationCollection<AnimationType>::GetAnimationCollection(
-    const dom::Element* aElement, CSSPseudoElementType aPseudoType) {
+    const dom::Element* aElement, PseudoStyleType aPseudoType) {
   if (!aElement->MayHaveAnimations()) {
     // Early return for the most common case.
     return nullptr;
   }
 
   nsAtom* propName = GetPropertyAtomForPseudoType(aPseudoType);
   if (!propName) {
     return nullptr;
@@ -66,17 +66,17 @@ AnimationCollection<AnimationType>::GetA
 
   return GetAnimationCollection(pseudoElement->mElement,
                                 pseudoElement->mPseudoType);
 }
 
 template <class AnimationType>
 /* static */ AnimationCollection<AnimationType>*
 AnimationCollection<AnimationType>::GetOrCreateAnimationCollection(
-    dom::Element* aElement, CSSPseudoElementType aPseudoType,
+    dom::Element* aElement, PseudoStyleType aPseudoType,
     bool* aCreatedCollection) {
   MOZ_ASSERT(aCreatedCollection);
   *aCreatedCollection = false;
 
   nsAtom* propName = GetPropertyAtomForPseudoType(aPseudoType);
   MOZ_ASSERT(propName,
              "Should only try to create animations for one of the"
              " recognized pseudo types");
@@ -103,24 +103,24 @@ AnimationCollection<AnimationType>::GetO
   }
 
   return collection;
 }
 
 template <class AnimationType>
 /*static*/ nsAtom*
 AnimationCollection<AnimationType>::GetPropertyAtomForPseudoType(
-    CSSPseudoElementType aPseudoType) {
+    PseudoStyleType aPseudoType) {
   nsAtom* propName = nullptr;
 
-  if (aPseudoType == CSSPseudoElementType::NotPseudo) {
+  if (aPseudoType == PseudoStyleType::NotPseudo) {
     propName = TraitsType::ElementPropertyAtom();
-  } else if (aPseudoType == CSSPseudoElementType::before) {
+  } else if (aPseudoType == PseudoStyleType::before) {
     propName = TraitsType::BeforePropertyAtom();
-  } else if (aPseudoType == CSSPseudoElementType::after) {
+  } else if (aPseudoType == PseudoStyleType::after) {
     propName = TraitsType::AfterPropertyAtom();
   }
 
   return propName;
 }
 
 // Explicit class instantiations
 
--- a/layout/style/AnimationCollection.h
+++ b/layout/style/AnimationCollection.h
@@ -60,45 +60,45 @@ class AnimationCollection
   }
 
   static void PropertyDtor(void* aObject, nsAtom* aPropertyName,
                            void* aPropertyValue, void* aData);
 
   // Get the collection of animations for the given |aElement| and
   // |aPseudoType|.
   static AnimationCollection<AnimationType>* GetAnimationCollection(
-      const dom::Element* aElement, CSSPseudoElementType aPseudoType);
+      const dom::Element* aElement, PseudoStyleType aPseudoType);
 
   // Given the frame |aFrame| with possibly animated content, finds its
   // associated collection of animations. If |aFrame| is a generated content
   // frame, this function may examine the parent frame to search for such
   // animations.
   static AnimationCollection<AnimationType>* GetAnimationCollection(
       const nsIFrame* aFrame);
 
   // Get the collection of animations for the given |aElement| and
   // |aPseudoType| or create it if it does not already exist.
   //
   // We'll set the outparam |aCreatedCollection| to true if we have
   // to create the collection and we successfully do so. Otherwise,
   // we'll set it to false.
   static AnimationCollection<AnimationType>* GetOrCreateAnimationCollection(
-      dom::Element* aElement, CSSPseudoElementType aPseudoType,
+      dom::Element* aElement, PseudoStyleType aPseudoType,
       bool* aCreatedCollection);
 
   dom::Element* mElement;
 
   // the atom we use in mElement's prop table (must be a static atom,
   // i.e., in an atom list)
   nsAtom* mElementProperty;
 
   InfallibleTArray<RefPtr<AnimationType>> mAnimations;
 
  private:
-  static nsAtom* GetPropertyAtomForPseudoType(CSSPseudoElementType aPseudoType);
+  static nsAtom* GetPropertyAtomForPseudoType(PseudoStyleType aPseudoType);
 
 #ifdef DEBUG
   bool mCalledPropertyDtor;
 #endif
 };
 
 }  // namespace mozilla
 
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -14,17 +14,17 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/TimingParams.h"
 #include "mozilla/dom/Nullable.h"
 #include "nsContentUtils.h"
 
 class nsPresContext;
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 
 namespace dom {
 class Element;
 }
 
 template <class AnimationType>
 class CommonAnimationManager {
  public:
@@ -45,17 +45,17 @@ class CommonAnimationManager {
   }
 
   /**
    * Stop animations on the element. This method takes the real element
    * rather than the element for the generated content for animations on
    * ::before and ::after.
    */
   void StopAnimationsForElement(dom::Element* aElement,
-                                CSSPseudoElementType aPseudoType) {
+                                PseudoStyleType aPseudoType) {
     MOZ_ASSERT(aElement);
     AnimationCollection<AnimationType>* collection =
         AnimationCollection<AnimationType>::GetAnimationCollection(aElement,
                                                                    aPseudoType);
     if (!collection) {
       return;
     }
 
@@ -98,17 +98,17 @@ class CommonAnimationManager {
  */
 class OwningElementRef final {
  public:
   OwningElementRef() = default;
 
   explicit OwningElementRef(const NonOwningAnimationTarget& aTarget)
       : mTarget(aTarget) {}
 
-  OwningElementRef(dom::Element& aElement, CSSPseudoElementType aPseudoType)
+  OwningElementRef(dom::Element& aElement, PseudoStyleType aPseudoType)
       : mTarget(&aElement, aPseudoType) {}
 
   bool Equals(const OwningElementRef& aOther) const {
     return mTarget == aOther.mTarget;
   }
 
   bool LessThan(int32_t& aChildIndex, const OwningElementRef& aOther,
                 int32_t& aOtherChildIndex) const {
@@ -116,25 +116,24 @@ class OwningElementRef final {
                "Elements to compare should not be null");
 
     if (mTarget.mElement != aOther.mTarget.mElement) {
       return nsContentUtils::PositionIsBefore(mTarget.mElement,
                                               aOther.mTarget.mElement,
                                               &aChildIndex, &aOtherChildIndex);
     }
 
-    return mTarget.mPseudoType == CSSPseudoElementType::NotPseudo ||
-           (mTarget.mPseudoType == CSSPseudoElementType::before &&
-            aOther.mTarget.mPseudoType == CSSPseudoElementType::after);
+    return mTarget.mPseudoType == PseudoStyleType::NotPseudo ||
+           (mTarget.mPseudoType == PseudoStyleType::before &&
+            aOther.mTarget.mPseudoType == PseudoStyleType::after);
   }
 
   bool IsSet() const { return !!mTarget.mElement; }
 
-  void GetElement(dom::Element*& aElement,
-                  CSSPseudoElementType& aPseudoType) const {
+  void GetElement(dom::Element*& aElement, PseudoStyleType& aPseudoType) const {
     aElement = mTarget.mElement;
     aPseudoType = mTarget.mPseudoType;
   }
 
   const NonOwningAnimationTarget& Target() const { return mTarget; }
 
   nsPresContext* GetPresContext() const {
     return nsContentUtils::GetContextForContent(mTarget.mElement);
--- a/layout/style/CSSStyleRule.cpp
+++ b/layout/style/CSSStyleRule.cpp
@@ -188,23 +188,23 @@ nsresult CSSStyleRule::GetSpecificity(ui
   Servo_StyleRule_GetSpecificityAtIndex(mRawRule, aSelectorIndex, aSpecificity);
   return NS_OK;
 }
 
 nsresult CSSStyleRule::SelectorMatchesElement(Element* aElement,
                                               uint32_t aSelectorIndex,
                                               const nsAString& aPseudo,
                                               bool* aMatches) {
-  CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
+  PseudoStyleType pseudoType = PseudoStyleType::NotPseudo;
   if (!aPseudo.IsEmpty()) {
     RefPtr<nsAtom> pseudoElt = NS_Atomize(aPseudo);
     pseudoType = nsCSSPseudoElements::GetPseudoType(
         pseudoElt, CSSEnabledState::eIgnoreEnabledState);
 
-    if (pseudoType == CSSPseudoElementType::NotPseudo) {
+    if (pseudoType == PseudoStyleType::NotPseudo) {
       *aMatches = false;
       return NS_OK;
     }
   }
 
   *aMatches = Servo_StyleRule_SelectorMatchesElement(
       mRawRule, aElement, aSelectorIndex, pseudoType);
 
--- a/layout/style/CachedInheritingStyles.cpp
+++ b/layout/style/CachedInheritingStyles.cpp
@@ -28,31 +28,31 @@ void CachedInheritingStyles::Insert(Comp
     IndirectCache* cache = new IndirectCache();
     cache->AppendElement(dont_AddRef(AsDirect()));
     cache->AppendElement(aStyle);
     mBits = reinterpret_cast<uintptr_t>(cache) | 1;
     MOZ_ASSERT(IsIndirect());
   }
 }
 
-ComputedStyle* CachedInheritingStyles::Lookup(nsAtom* aPseudoTag) const {
-  MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aPseudoTag) ||
-             nsCSSPseudoElements::IsPseudoElement(aPseudoTag));
+ComputedStyle* CachedInheritingStyles::Lookup(PseudoStyleType aType) const {
+  MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType) ||
+             PseudoStyle::IsInheritingAnonBox(aType));
   if (IsIndirect()) {
     for (auto& style : *AsIndirect()) {
-      if (style->GetPseudo() == aPseudoTag) {
+      if (style->GetPseudoType() == aType) {
         return style;
       }
     }
 
     return nullptr;
   }
 
   ComputedStyle* direct = AsDirect();
-  return direct && direct->GetPseudo() == aPseudoTag ? direct : nullptr;
+  return direct && direct->GetPseudoType() == aType ? direct : nullptr;
 }
 
 void CachedInheritingStyles::AddSizeOfIncludingThis(nsWindowSizes& aSizes,
                                                     size_t* aCVsSize) const {
   if (IsIndirect()) {
     for (auto& style : *AsIndirect()) {
       if (!aSizes.mState.HaveSeenPtr(style)) {
         style->AddSizeOfIncludingThis(aSizes, aCVsSize);
--- a/layout/style/CachedInheritingStyles.h
+++ b/layout/style/CachedInheritingStyles.h
@@ -10,29 +10,30 @@
 #include "nsAtom.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 
 class nsWindowSizes;
 
 namespace mozilla {
 
+enum class PseudoStyleType : uint8_t;
 class ComputedStyle;
 
 // Cache of anonymous box and lazy pseudo styles that inherit from a given
 // style.
 //
 // To minimize memory footprint, the cache is word-sized with a tagged pointer
 // If there is only one entry, it's stored inline. If there are more, they're
 // stored in an out-of-line buffer. See bug 1429126 comment 0 and comment 1 for
 // the measurements and rationale that influenced the design.
 class CachedInheritingStyles {
  public:
   void Insert(ComputedStyle* aStyle);
-  ComputedStyle* Lookup(nsAtom* aPseudoTag) const;
+  ComputedStyle* Lookup(PseudoStyleType) const;
 
   CachedInheritingStyles() : mBits(0) {}
   ~CachedInheritingStyles() {
     if (IsIndirect()) {
       delete AsIndirect();
     } else if (!IsEmpty()) {
       RefPtr<ComputedStyle> ref = dont_AddRef(AsDirect());
     }
--- a/layout/style/ComputedStyle.cpp
+++ b/layout/style/ComputedStyle.cpp
@@ -37,21 +37,19 @@
 // Ensure the binding function declarations in ComputedStyle.h matches
 // those in ServoBindings.h.
 #include "mozilla/ServoBindings.h"
 
 namespace mozilla {
 
 //----------------------------------------------------------------------
 
-ComputedStyle::ComputedStyle(nsAtom* aPseudoTag,
-                             CSSPseudoElementType aPseudoType,
+ComputedStyle::ComputedStyle(PseudoStyleType aPseudoType,
                              ServoComputedDataForgotten aComputedValues)
     : mSource(aComputedValues),
-      mPseudoTag(aPseudoTag),
       mBits(static_cast<Bit>(Servo_ComputedValues_GetStyleBits(this))),
       mPseudoType(aPseudoType) {}
 
 nsChangeHint ComputedStyle::CalcStyleDifference(const ComputedStyle& aNewStyle,
                                                 uint32_t* aEqualStructs) const {
   AUTO_PROFILER_LABEL("ComputedStyle::CalcStyleDifference", LAYOUT);
   static_assert(StyleStructConstants::kStyleStructCount <= 32,
                 "aEqualStructs is not big enough");
@@ -255,21 +253,18 @@ nsChangeHint ComputedStyle::CalcStyleDif
 void ComputedStyle::List(FILE* out, int32_t aIndent) {
   nsAutoCString str;
   // Indent
   int32_t ix;
   for (ix = aIndent; --ix >= 0;) {
     str.AppendLiteral("  ");
   }
   str.Append(nsPrintfCString("%p(%d) parent=%p ", (void*)this, 0, nullptr));
-  if (mPseudoTag) {
-    nsAutoString buffer;
-    mPseudoTag->ToString(buffer);
-    AppendUTF16toUTF8(buffer, str);
-    str.Append(' ');
+  if (mPseudoType != PseudoStyleType::NotPseudo) {
+    str.Append(nsPrintfCString("pseudo-%d ", static_cast<int>(mPseudoType)));
   }
 
   fprintf_stderr(out, "%s{ServoComputedData}\n", str.get());
 }
 #endif
 
 template <typename Func>
 static nscolor GetVisitedDependentColorInternal(ComputedStyle* aSc,
@@ -362,29 +357,26 @@ static const ColorIndexSet gVisitedIndic
     if (aName.EqualsLiteral(#name_)) return Some(StyleStructID::name_);
 #  include "nsStyleStructList.h"
 #  undef STYLE_STRUCT
   return Nothing();
 }
 #endif  // DEBUG
 
 ComputedStyle* ComputedStyle::GetCachedLazyPseudoStyle(
-    CSSPseudoElementType aPseudo) const {
-  MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo &&
-             aPseudo != CSSPseudoElementType::InheritingAnonBox &&
-             aPseudo != CSSPseudoElementType::NonInheritingAnonBox);
+    PseudoStyleType aPseudo) const {
+  MOZ_ASSERT(PseudoStyle::IsPseudoElement(aPseudo));
   MOZ_ASSERT(!IsLazilyCascadedPseudoElement(),
              "Lazy pseudos can't inherit lazy pseudos");
 
   if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aPseudo)) {
     return nullptr;
   }
 
-  return mCachedInheritingStyles.Lookup(
-      nsCSSPseudoElements::GetPseudoAtom(aPseudo));
+  return mCachedInheritingStyles.Lookup(aPseudo);
 }
 
 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoComputedValuesMallocEnclosingSizeOf)
 
 void ComputedStyle::AddSizeOfIncludingThis(nsWindowSizes& aSizes,
                                            size_t* aCVsSize) const {
   // Note: |this| sits within a servo_arc::Arc, i.e. it is preceded by a
   // refcount. So we need to measure it with a function that can handle an
--- a/layout/style/ComputedStyle.h
+++ b/layout/style/ComputedStyle.h
@@ -9,26 +9,26 @@
 #ifndef _ComputedStyle_h_
 #define _ComputedStyle_h_
 
 #include "nsIMemoryReporter.h"
 #include <algorithm>
 #include "mozilla/Assertions.h"
 #include "mozilla/CachedInheritingStyles.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/PseudoStyleType.h"
 #include "mozilla/ServoComputedData.h"
 #include "mozilla/ServoTypes.h"
 #include "mozilla/ServoUtils.h"
 #include "mozilla/StyleComplexColor.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSPseudoElements.h"
 
 #include "nsStyleStructFwd.h"
 
-class nsAtom;
 enum nsChangeHint : uint32_t;
 class nsIPresShell;
 class nsPresContext;
 class nsWindowSizes;
 
 #define STYLE_STRUCT(name_) struct nsStyle##name_;
 #include "nsStyleStructList.h"
 #undef STYLE_STRUCT
@@ -40,17 +40,16 @@ void Gecko_ComputedStyle_Destroy(mozilla
 }
 
 namespace mozilla {
 
 namespace dom {
 class Document;
 }
 
-enum class CSSPseudoElementType : uint8_t;
 class ComputedStyle;
 
 /**
  * A ComputedStyle represents the computed style data for an element.
  *
  * The computed style data are stored in a set of reference counted structs
  * (see nsStyleStruct.h) that are stored directly on the ComputedStyle.
  *
@@ -74,17 +73,17 @@ enum class ComputedStyleBit : uint8_t {
 };
 
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ComputedStyleBit)
 
 class ComputedStyle {
   using Bit = ComputedStyleBit;
 
  public:
-  ComputedStyle(nsAtom* aPseudoTag, CSSPseudoElementType aPseudoType,
+  ComputedStyle(PseudoStyleType aPseudoType,
                 ServoComputedDataForgotten aComputedValues);
 
   void AddRef() { Servo_ComputedStyle_AddRef(this); }
   void Release() { Servo_ComputedStyle_Release(this); }
 
   // Return the ComputedStyle whose style data should be used for the R,
   // G, and B components of color, background-color, and border-*-color
   // if RelevantLinkIsVisited().
@@ -103,42 +102,40 @@ class ComputedStyle {
     return mSource.visited_style.mPtr;
   }
 
   bool IsLazilyCascadedPseudoElement() const {
     return IsPseudoElement() &&
            !nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType());
   }
 
-  nsAtom* GetPseudo() const { return mPseudoTag; }
-  mozilla::CSSPseudoElementType GetPseudoType() const { return mPseudoType; }
+  PseudoStyleType GetPseudoType() const { return mPseudoType; }
+
+  bool IsPseudoElement() const {
+    return PseudoStyle::IsPseudoElement(mPseudoType);
+  }
 
   bool IsInheritingAnonBox() const {
-    return GetPseudoType() == mozilla::CSSPseudoElementType::InheritingAnonBox;
+    return PseudoStyle::IsInheritingAnonBox(mPseudoType);
   }
 
   bool IsNonInheritingAnonBox() const {
-    return GetPseudoType() ==
-           mozilla::CSSPseudoElementType::NonInheritingAnonBox;
+    return PseudoStyle::IsNonInheritingAnonBox(mPseudoType);
   }
 
-  // This function is rather slow; you probably don't want to use it outside
-  // asserts unless you have to.  We _could_ add a new CSSPseudoElementType for
-  // wrapper anon boxes, but that adds a bunch of complexity everywhere we
-  // resolve anonymous box styles...
   bool IsWrapperAnonBox() const {
-    return nsCSSAnonBoxes::IsWrapperAnonBox(GetPseudo());
+    return PseudoStyle::IsWrapperAnonBox(mPseudoType);
   }
 
-  bool IsAnonBox() const {
-    return IsInheritingAnonBox() || IsNonInheritingAnonBox();
+  bool IsAnonBox() const { return PseudoStyle::IsAnonBox(mPseudoType); }
+
+  bool IsPseudoOrAnonBox() const {
+    return mPseudoType != PseudoStyleType::NotPseudo;
   }
 
-  bool IsPseudoElement() const { return mPseudoTag && !IsAnonBox(); }
-
   // Does this ComputedStyle or any of its ancestors have text
   // decoration lines?
   // Differs from nsStyleTextReset::HasTextDecorationLines, which tests
   // only the data for a single context.
   bool HasTextDecorationLines() const {
     return bool(mBits & Bit::HasTextDecorationLines);
   }
 
@@ -167,30 +164,30 @@ class ComputedStyle {
 
   // Is the only link whose visitedness is allowed to influence the
   // style of the node this ComputedStyle is for (which is that element
   // or its nearest ancestor that is a link) visited?
   bool RelevantLinkVisited() const {
     return bool(mBits & Bit::RelevantLinkVisited);
   }
 
-  ComputedStyle* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const {
-    MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
-    return mCachedInheritingStyles.Lookup(aAnonBox);
+  ComputedStyle* GetCachedInheritingAnonBoxStyle(
+      PseudoStyleType aPseudoType) const {
+    MOZ_ASSERT(PseudoStyle::IsInheritingAnonBox(aPseudoType));
+    return mCachedInheritingStyles.Lookup(aPseudoType);
   }
 
-  void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox, ComputedStyle* aStyle) {
-    MOZ_ASSERT(!GetCachedInheritingAnonBoxStyle(aAnonBox));
+  void SetCachedInheritedAnonBoxStyle(ComputedStyle* aStyle) {
     mCachedInheritingStyles.Insert(aStyle);
   }
 
-  ComputedStyle* GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const;
+  ComputedStyle* GetCachedLazyPseudoStyle(PseudoStyleType aPseudo) const;
 
   void SetCachedLazyPseudoStyle(ComputedStyle* aStyle) {
-    MOZ_ASSERT(aStyle->GetPseudo() && !aStyle->IsAnonBox());
+    MOZ_ASSERT(aStyle->IsPseudoElement());
     MOZ_ASSERT(!GetCachedLazyPseudoStyle(aStyle->GetPseudoType()));
     MOZ_ASSERT(!IsLazilyCascadedPseudoElement(),
                "lazy pseudos can't inherit lazy pseudos");
     MOZ_ASSERT(aStyle->IsLazilyCascadedPseudoElement());
 
     // Since we're caching lazy pseudo styles on the ComputedValues of the
     // originating element, we can assume that we either have the same
     // originating element, or that they were at least similar enough to share
@@ -283,19 +280,15 @@ class ComputedStyle {
 
   ~ComputedStyle() = default;
 
   ServoComputedData mSource;
 
   // A cache of anonymous box and lazy pseudo styles inheriting from this style.
   CachedInheritingStyles mCachedInheritingStyles;
 
-  // If this ComputedStyle is for a pseudo-element or anonymous box,
-  // the relevant atom.
-  const RefPtr<nsAtom> mPseudoTag;
-
   const Bit mBits;
-  const CSSPseudoElementType mPseudoType;
+  const PseudoStyleType mPseudoType;
 };
 
 }  // namespace mozilla
 
 #endif
--- a/layout/style/GeckoBindings.cpp
+++ b/layout/style/GeckoBindings.cpp
@@ -180,20 +180,19 @@ void Gecko_DestroyAnonymousContentList(n
 const nsTArray<RefPtr<nsINode>>* Gecko_GetAssignedNodes(
     RawGeckoElementBorrowed aElement) {
   MOZ_ASSERT(HTMLSlotElement::FromNode(aElement));
   return &static_cast<const HTMLSlotElement*>(aElement)->AssignedNodes();
 }
 
 void Gecko_ComputedStyle_Init(ComputedStyle* aStyle,
                               const ServoComputedData* aValues,
-                              CSSPseudoElementType aPseudoType,
-                              nsAtom* aPseudoTag) {
-  new (KnownNotNull, aStyle) ComputedStyle(aPseudoTag, aPseudoType,
-                                           ServoComputedDataForgotten(aValues));
+                              PseudoStyleType aPseudoType) {
+  new (KnownNotNull, aStyle)
+      ComputedStyle(aPseudoType, ServoComputedDataForgotten(aValues));
 }
 
 ServoComputedData::ServoComputedData(const ServoComputedDataForgotten aValue) {
   PodAssign(this, aValue.mPtr);
 }
 
 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoStyleStructsMallocEnclosingSizeOf)
 
@@ -305,18 +304,17 @@ void Gecko_NoteAnimationOnlyDirtyElement
 }
 
 bool Gecko_AnimationNameMayBeReferencedFromStyle(
     RawGeckoPresContextBorrowed aPresContext, nsAtom* aName) {
   MOZ_ASSERT(aPresContext);
   return aPresContext->AnimationManager()->AnimationMayBeReferenced(aName);
 }
 
-CSSPseudoElementType Gecko_GetImplementedPseudo(
-    RawGeckoElementBorrowed aElement) {
+PseudoStyleType Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement) {
   return aElement->GetPseudoElementType();
 }
 
 uint32_t Gecko_CalcStyleDifference(ComputedStyleBorrowed aOldStyle,
                                    ComputedStyleBorrowed aNewStyle,
                                    bool* aAnyStyleStructChanged,
                                    bool* aOnlyResetStructsChanged) {
   MOZ_ASSERT(aOldStyle);
@@ -464,29 +462,29 @@ Gecko_GetActiveLinkAttrDeclarationBlock(
   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
   if (!sheet) {
     return nullptr;
   }
 
   return AsRefRawStrong(sheet->GetServoActiveLinkDecl());
 }
 
-static CSSPseudoElementType GetPseudoTypeFromElementForAnimation(
+static PseudoStyleType GetPseudoTypeFromElementForAnimation(
     const Element*& aElementOrPseudo) {
   if (aElementOrPseudo->IsGeneratedContentContainerForBefore()) {
     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
-    return CSSPseudoElementType::before;
+    return PseudoStyleType::before;
   }
 
   if (aElementOrPseudo->IsGeneratedContentContainerForAfter()) {
     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
-    return CSSPseudoElementType::after;
+    return PseudoStyleType::after;
   }
 
-  return CSSPseudoElementType::NotPseudo;
+  return PseudoStyleType::NotPseudo;
 }
 
 bool Gecko_GetAnimationRule(
     RawGeckoElementBorrowed aElement,
     EffectCompositor::CascadeLevel aCascadeLevel,
     RawServoAnimationValueMapBorrowedMut aAnimationValues) {
   MOZ_ASSERT(aElement);
 
@@ -495,18 +493,17 @@ bool Gecko_GetAnimationRule(
     return false;
   }
   nsPresContext* presContext = doc->GetPresContext();
   if (!presContext || !presContext->IsDynamic()) {
     // For print or print preview, ignore animations.
     return false;
   }
 
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
 
   return presContext->EffectCompositor()->GetServoAnimationRule(
       aElement, pseudoType, aCascadeLevel, aAnimationValues);
 }
 
 bool Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
                                  RawGeckoStyleAnimationListBorrowed aB) {
   return *aA == *aB;
@@ -541,18 +538,17 @@ void Gecko_UpdateAnimations(RawGeckoElem
 
   nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
   if (!presContext || !presContext->IsDynamic()) {
     return;
   }
 
   nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
 
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
 
   if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
     presContext->AnimationManager()->UpdateAnimations(
         const_cast<dom::Element*>(aElement), pseudoType, aComputedData);
   }
 
   // aComputedData might be nullptr if the target element is now in a
   // display:none subtree. We still call Gecko_UpdateAnimations in this case
@@ -596,64 +592,59 @@ void Gecko_UpdateAnimations(RawGeckoElem
     presContext->EffectCompositor()->RequestRestyle(
         const_cast<Element*>(aElement), pseudoType,
         EffectCompositor::RestyleType::Standard,
         EffectCompositor::CascadeLevel::Animations);
   }
 }
 
 size_t Gecko_GetAnimationEffectCount(RawGeckoElementBorrowed aElementOrPseudo) {
-  CSSPseudoElementType pseudoType =
+  PseudoStyleType pseudoType =
       GetPseudoTypeFromElementForAnimation(aElementOrPseudo);
 
   EffectSet* effectSet = EffectSet::GetEffectSet(aElementOrPseudo, pseudoType);
   return effectSet ? effectSet->Count() : 0;
 }
 
 bool Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElement) {
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
 
   return !!EffectSet::GetEffectSet(aElement, pseudoType);
 }
 
 bool Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElement) {
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
   nsAnimationManager::CSSAnimationCollection* collection =
       nsAnimationManager::CSSAnimationCollection ::GetAnimationCollection(
           aElement, pseudoType);
 
   return collection && !collection->mAnimations.IsEmpty();
 }
 
 bool Gecko_ElementHasCSSTransitions(RawGeckoElementBorrowed aElement) {
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
   nsTransitionManager::CSSTransitionCollection* collection =
       nsTransitionManager::CSSTransitionCollection ::GetAnimationCollection(
           aElement, pseudoType);
 
   return collection && !collection->mAnimations.IsEmpty();
 }
 
 size_t Gecko_ElementTransitions_Length(RawGeckoElementBorrowed aElement) {
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
   nsTransitionManager::CSSTransitionCollection* collection =
       nsTransitionManager::CSSTransitionCollection ::GetAnimationCollection(
           aElement, pseudoType);
 
   return collection ? collection->mAnimations.Length() : 0;
 }
 
 static CSSTransition* GetCurrentTransitionAt(RawGeckoElementBorrowed aElement,
                                              size_t aIndex) {
-  CSSPseudoElementType pseudoType =
-      GetPseudoTypeFromElementForAnimation(aElement);
+  PseudoStyleType pseudoType = GetPseudoTypeFromElementForAnimation(aElement);
   nsTransitionManager::CSSTransitionCollection* collection =
       nsTransitionManager::CSSTransitionCollection ::GetAnimationCollection(
           aElement, pseudoType);
   if (!collection) {
     return nullptr;
   }
   nsTArray<RefPtr<CSSTransition>>& transitions = collection->mAnimations;
   return aIndex < transitions.Length() ? transitions[aIndex].get() : nullptr;
--- a/layout/style/GeckoBindings.h
+++ b/layout/style/GeckoBindings.h
@@ -27,17 +27,17 @@ struct nsFont;
 
 namespace mozilla {
 class ComputedStyle;
 class SeenPtrs;
 class ServoElementSnapshot;
 class ServoElementSnapshotTable;
 class SharedFontList;
 class StyleSheet;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 enum class PointerCapabilities : uint8_t;
 enum class UpdateAnimationsTasks : uint8_t;
 struct FontFamilyName;
 struct Keyframe;
 
 namespace css {
 class LoaderReusableStyleSheets;
 }
@@ -84,18 +84,17 @@ nsTArray<nsIContent*>* Gecko_GetAnonymou
 
 const nsTArray<RefPtr<nsINode>>* Gecko_GetAssignedNodes(
     RawGeckoElementBorrowed element);
 
 void Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* anon_content);
 
 void Gecko_ComputedStyle_Init(mozilla::ComputedStyle* context,
                               ServoComputedDataBorrowed values,
-                              mozilla::CSSPseudoElementType pseudo_type,
-                              nsAtom* pseudo_tag);
+                              mozilla::PseudoStyleType pseudo_type);
 
 void Gecko_ComputedStyle_Destroy(mozilla::ComputedStyle* context);
 
 // By default, Servo walks the DOM by traversing the siblings of the DOM-view
 // first child. This generally works, but misses anonymous children, which we
 // want to traverse during styling. To support these cases, we create an
 // optional stack-allocated iterator in aIterator for nodes that need it.
 void Gecko_ConstructStyleChildrenIterator(
@@ -380,17 +379,17 @@ void Gecko_UnsetNodeFlags(RawGeckoNodeBo
 void Gecko_NoteDirtyElement(RawGeckoElementBorrowed element);
 void Gecko_NoteDirtySubtreeForInvalidation(RawGeckoElementBorrowed element);
 void Gecko_NoteAnimationOnlyDirtyElement(RawGeckoElementBorrowed element);
 
 bool Gecko_AnimationNameMayBeReferencedFromStyle(
     RawGeckoPresContextBorrowed pres_context, nsAtom* name);
 
 // Incremental restyle.
-mozilla::CSSPseudoElementType Gecko_GetImplementedPseudo(
+mozilla::PseudoStyleType Gecko_GetImplementedPseudo(
     RawGeckoElementBorrowed element);
 
 // We'd like to return `nsChangeHint` here, but bindgen bitfield enums don't
 // work as return values with the Linux 32-bit ABI at the moment because
 // they wrap the value in a struct.
 uint32_t Gecko_CalcStyleDifference(ComputedStyleBorrowed old_style,
                                    ComputedStyleBorrowed new_style,
                                    bool* any_style_struct_changed,
new file mode 100644
--- /dev/null
+++ b/layout/style/PseudoStyleType.h
@@ -0,0 +1,108 @@
+/* -*- 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/. */
+
+#ifndef mozilla_PseudoStyleType_h
+#define mozilla_PseudoStyleType_h
+
+#include <cstdint>
+
+namespace mozilla {
+
+// The kind of pseudo-style that we have. This can be:
+//
+//  * CSS pseudo-elements (see nsCSSPseudoElements.h).
+//  * Anonymous boxes (see nsCSSAnonBoxes.h).
+//  * XUL tree pseudo-element stuff.
+//
+// This roughly corresponds to the `PseudoElement` enum in Rust code.
+enum class PseudoStyleType : uint8_t {
+// If CSS pseudo-elements stop being first here, change GetPseudoType.
+#define CSS_PSEUDO_ELEMENT(_name, _value, _flags) _name,
+#include "nsCSSPseudoElementList.h"
+#undef CSS_PSEUDO_ELEMENT
+  CSSPseudoElementsEnd,
+  AnonBoxesStart = CSSPseudoElementsEnd,
+  InheritingAnonBoxesStart = CSSPseudoElementsEnd,
+
+  // Dummy variant so the next variant also has the same discriminant as
+  // AnonBoxesStart.
+  __reset_1 = AnonBoxesStart - 1,
+
+#define CSS_ANON_BOX(_name, _str) _name,
+#define CSS_NON_INHERITING_ANON_BOX(_name, _str)
+#define CSS_WRAPPER_ANON_BOX(_name, _str)
+#include "nsCSSAnonBoxList.h"
+#undef CSS_ANON_BOX
+#undef CSS_WRAPPER_ANON_BOX
+#undef CSS_NON_INHERITING_ANON_BOX
+
+  // Wrapper anon boxes are inheriting anon boxes.
+  WrapperAnonBoxesStart,
+
+  // Dummy variant so the next variant also has the same discriminant as
+  // WrapperAnonBoxesStart.
+  __reset_2 = WrapperAnonBoxesStart - 1,
+
+
+#define CSS_ANON_BOX(_name, _str)
+#define CSS_NON_INHERITING_ANON_BOX(_name, _str)
+#define CSS_WRAPPER_ANON_BOX(_name, _str) _name,
+#include "nsCSSAnonBoxList.h"
+#undef CSS_ANON_BOX
+#undef CSS_WRAPPER_ANON_BOX
+#undef CSS_NON_INHERITING_ANON_BOX
+
+  WrapperAnonBoxesEnd,
+  InheritingAnonBoxesEnd = WrapperAnonBoxesEnd,
+  NonInheritingAnonBoxesStart = WrapperAnonBoxesEnd,
+
+  __reset_3 = NonInheritingAnonBoxesStart - 1,
+
+#define CSS_ANON_BOX(_name, _str)
+#define CSS_NON_INHERITING_ANON_BOX(_name, _str) _name,
+#include "nsCSSAnonBoxList.h"
+#undef CSS_ANON_BOX
+#undef CSS_NON_INHERITING_ANON_BOX
+
+  NonInheritingAnonBoxesEnd,
+  AnonBoxesEnd = NonInheritingAnonBoxesEnd,
+
+  XULTree = AnonBoxesEnd,
+  NotPseudo,
+  MAX
+};
+
+class PseudoStyle final {
+public:
+  using Type = PseudoStyleType;
+
+  // This must match EAGER_PSEUDO_COUNT in Rust code.
+  static const size_t kEagerPseudoCount = 4;
+
+  static bool IsPseudoElement(Type aType) {
+    return aType < Type::CSSPseudoElementsEnd;
+  }
+
+  static bool IsAnonBox(Type aType) {
+    return aType >= Type::AnonBoxesStart && aType < Type::AnonBoxesEnd;
+  }
+
+  static bool IsInheritingAnonBox(Type aType) {
+    return aType >= Type::InheritingAnonBoxesStart && aType < Type::InheritingAnonBoxesEnd;
+  }
+
+  static bool IsNonInheritingAnonBox(Type aType) {
+    return aType >= Type::NonInheritingAnonBoxesStart && aType < Type::NonInheritingAnonBoxesEnd;
+  }
+
+  static bool IsWrapperAnonBox(Type aType) {
+    return aType >= Type::WrapperAnonBoxesStart && aType < Type::WrapperAnonBoxesEnd;
+  }
+};
+
+}
+
+#endif
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -24,17 +24,17 @@ class nsAtom;
 class nsSimpleContentList;
 struct gfxFontFeature;
 
 namespace mozilla {
 class SeenPtrs;
 class ServoElementSnapshotTable;
 class SharedFontList;
 class StyleSheet;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 enum class OriginFlags : uint8_t;
 struct Keyframe;
 
 namespace css {
 class LoaderReusableStyleSheets;
 }
 
 namespace gfx {
@@ -327,17 +327,17 @@ void Servo_StyleRule_GetSpecificityAtInd
                                            uint32_t index,
                                            uint64_t* specificity);
 
 void Servo_StyleRule_GetSelectorCount(RawServoStyleRuleBorrowed rule,
                                       uint32_t* count);
 
 bool Servo_StyleRule_SelectorMatchesElement(
     RawServoStyleRuleBorrowed, RawGeckoElementBorrowed, uint32_t index,
-    mozilla::CSSPseudoElementType pseudo_type);
+    mozilla::PseudoStyleType pseudo_type);
 
 bool Servo_StyleRule_SetSelectorText(RawServoStyleSheetContentsBorrowed sheet,
                                      RawServoStyleRuleBorrowed rule,
                                      const nsAString* text);
 
 void Servo_ImportRule_GetHref(RawServoImportRuleBorrowed rule,
                               nsAString* result);
 
@@ -775,22 +775,22 @@ size_t Servo_MediaList_SizeOfIncludingTh
 // CSS supports();
 
 bool Servo_CSSSupports2(const nsACString* name, const nsACString* value);
 bool Servo_CSSSupports(const nsACString* cond);
 
 // Computed style data
 
 ComputedStyleStrong Servo_ComputedValues_GetForAnonymousBox(
-    ComputedStyleBorrowedOrNull parent_style_or_null, nsAtom* pseudo_tag,
+    ComputedStyleBorrowedOrNull parent_style_or_null, mozilla::PseudoStyleType,
     RawServoStyleSetBorrowed set);
 
 ComputedStyleStrong Servo_ComputedValues_Inherit(
-    RawServoStyleSetBorrowed set, nsAtom* pseudo_tag,
-    ComputedStyleBorrowedOrNull parent_style, mozilla::InheritTarget target);
+    RawServoStyleSetBorrowed, mozilla::PseudoStyleType,
+    ComputedStyleBorrowedOrNull parent_style, mozilla::InheritTarget);
 
 uint8_t Servo_ComputedValues_GetStyleBits(ComputedStyleBorrowed values);
 
 bool Servo_ComputedValues_EqualCustomProperties(
     ServoComputedDataBorrowed first, ServoComputedDataBorrowed second);
 
 // Gets the source style rules for the computed values. This returns
 // the result via rules, which would include a list of unowned pointers
@@ -817,45 +817,45 @@ void Servo_NoteExplicitHints(RawGeckoEle
 // they wrap the value in a struct.
 uint32_t Servo_TakeChangeHint(RawGeckoElementBorrowed element,
                               bool* was_restyled);
 
 ComputedStyleStrong Servo_ResolveStyle(RawGeckoElementBorrowed element,
                                        RawServoStyleSetBorrowed set);
 
 ComputedStyleStrong Servo_ResolvePseudoStyle(
-    RawGeckoElementBorrowed element, mozilla::CSSPseudoElementType pseudo_type,
+    RawGeckoElementBorrowed element, mozilla::PseudoStyleType pseudo_type,
     bool is_probe, ComputedStyleBorrowedOrNull inherited_style,
     RawServoStyleSetBorrowed set);
 
 ComputedStyleStrong Servo_ComputedValues_ResolveXULTreePseudoStyle(
     RawGeckoElementBorrowed element, nsAtom* pseudo_tag,
     ComputedStyleBorrowed inherited_style, const mozilla::AtomArray* input_word,
     RawServoStyleSetBorrowed set);
 
 void Servo_SetExplicitStyle(RawGeckoElementBorrowed element,
                             ComputedStyleBorrowed primary_style);
 
 bool Servo_HasAuthorSpecifiedRules(ComputedStyleBorrowed style,
                                    RawGeckoElementBorrowed element,
-                                   mozilla::CSSPseudoElementType pseudo_type,
+                                   mozilla::PseudoStyleType pseudo_type,
                                    uint32_t rule_type_mask,
                                    bool author_colors_allowed);
 
 // Resolves style for an element or pseudo-element without processing pending
 // restyles first. The Element and its ancestors may be unstyled, have pending
 // restyles, or be in a display:none subtree. Styles are cached when possible,
 // though caching is not possible within display:none subtrees, and the styles
 // may be invalidated by already-scheduled restyles.
 //
 // The tree must be in a consistent state such that a normal traversal could be
 // performed, and this function maintains that invariant.
 
 ComputedStyleStrong Servo_ResolveStyleLazily(
-    RawGeckoElementBorrowed element, mozilla::CSSPseudoElementType pseudo_type,
+    RawGeckoElementBorrowed element, mozilla::PseudoStyleType pseudo_type,
     mozilla::StyleRuleInclusion rule_inclusion,
     const mozilla::ServoElementSnapshotTable* snapshots,
     RawServoStyleSetBorrowed set);
 
 // Reparents style to the new parents.
 ComputedStyleStrong Servo_ReparentStyle(
     ComputedStyleBorrowed style_to_reparent, ComputedStyleBorrowed parent_style,
     ComputedStyleBorrowed parent_style_ignoring_first_line,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -133,17 +133,17 @@ rusty-enums = [
     "mozilla::StyleScrollbarWidth",
     "mozilla::StyleWhiteSpace",
     "mozilla::StyleTextRendering",
     "mozilla::StyleColorAdjust",
     "nsStyleImageType",
     "nsStyleSVGPaintType",
     "nsStyleSVGFallbackType",
     "nsINode_BooleanFlag",
-    "mozilla::CSSPseudoElementType",
+    "mozilla::PseudoStyleType",
     "mozilla::LookAndFeel_ColorID",
     "mozilla::LookAndFeel_FontID",
     "nsStyleTransformMatrix::MatrixTransformOperator",
     "mozilla::StyleGeometryBox",
     "mozilla::SystemColor",
 ]
 whitelist-vars = [
     "NS_AUTHOR_SPECIFIED_.*",
@@ -531,17 +531,17 @@ structs-types = [
     "RawGeckoStyleChildrenIterator",
     "RawGeckoServoStyleRuleList",
     "RawGeckoURLExtraData",
     "RawGeckoXBLBinding",
     "RawServoSelectorList",
     "RawServoSourceSizeList",
     "RefPtr",
     "StyleUseCounters",
-    "CSSPseudoElementType",
+    "PseudoStyleType",
     "ServoTraversalFlags",
     "ComputedTimingFunction_BeforeFlag",
     "CounterStylePtr",
     "FontFamilyType",
     "mozilla::FontSizePrefs",
     "GeckoFontMetrics",
     "IterationCompositeOperation",
     "Keyframe",
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -346,17 +346,17 @@ void ServoStyleSet::SetAuthorStyleDisabl
   // to rebuild stylist for this change. But we have bug around this, and we
   // may want to rethink how things should work. See bug 1437785.
   SetStylistStyleSheetsDirty();
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleFor(
     Element* aElement, LazyComputeBehavior aMayCompute) {
   if (aMayCompute == LazyComputeBehavior::Allow) {
-    return ResolveStyleLazily(aElement, CSSPseudoElementType::NotPseudo);
+    return ResolveStyleLazily(aElement, PseudoStyleType::NotPseudo);
   }
 
   return ResolveServoStyle(*aElement);
 }
 
 const ServoElementSnapshotTable& ServoStyleSet::Snapshots() {
   MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?");
   return GetPresContext()->RestyleManager()->Snapshots();
@@ -428,210 +428,196 @@ void ServoStyleSet::PreTraverse(ServoTra
       smilController->PreTraverse();
     }
   }
 }
 
 static inline already_AddRefed<ComputedStyle>
 ResolveStyleForTextOrFirstLetterContinuation(RawServoStyleSetBorrowed aStyleSet,
                                              ComputedStyle& aParent,
-                                             nsAtom* aAnonBox) {
-  MOZ_ASSERT(aAnonBox == nsCSSAnonBoxes::mozText() ||
-             aAnonBox == nsCSSAnonBoxes::firstLetterContinuation());
-  auto inheritTarget = aAnonBox == nsCSSAnonBoxes::mozText()
+                                             PseudoStyleType aType) {
+  MOZ_ASSERT(aType == PseudoStyleType::mozText ||
+             aType == PseudoStyleType::firstLetterContinuation);
+  auto inheritTarget = aType == PseudoStyleType::mozText
                            ? InheritTarget::Text
                            : InheritTarget::FirstLetterContinuation;
 
-  RefPtr<ComputedStyle> style =
-      aParent.GetCachedInheritingAnonBoxStyle(aAnonBox);
+  RefPtr<ComputedStyle> style = aParent.GetCachedInheritingAnonBoxStyle(aType);
   if (!style) {
-    style = Servo_ComputedValues_Inherit(aStyleSet, aAnonBox, &aParent,
-                                         inheritTarget)
-                .Consume();
+    style =
+        Servo_ComputedValues_Inherit(aStyleSet, aType, &aParent, inheritTarget)
+            .Consume();
     MOZ_ASSERT(style);
-    aParent.SetCachedInheritedAnonBoxStyle(aAnonBox, style);
+    aParent.SetCachedInheritedAnonBoxStyle(style);
   }
 
   return style.forget();
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleForText(
-    nsIContent* aTextNode, ComputedStyle* aParentContext) {
+    nsIContent* aTextNode, ComputedStyle* aParentStyle) {
   MOZ_ASSERT(aTextNode && aTextNode->IsText());
   MOZ_ASSERT(aTextNode->GetParent());
-  MOZ_ASSERT(aParentContext);
+  MOZ_ASSERT(aParentStyle);
 
   return ResolveStyleForTextOrFirstLetterContinuation(
-      mRawSet.get(), *aParentContext, nsCSSAnonBoxes::mozText());
+      mRawSet.get(), *aParentStyle, PseudoStyleType::mozText);
 }
 
 already_AddRefed<ComputedStyle>
 ServoStyleSet::ResolveStyleForFirstLetterContinuation(
-    ComputedStyle* aParentContext) {
-  MOZ_ASSERT(aParentContext);
+    ComputedStyle* aParentStyle) {
+  MOZ_ASSERT(aParentStyle);
 
   return ResolveStyleForTextOrFirstLetterContinuation(
-      mRawSet.get(), *aParentContext,
-      nsCSSAnonBoxes::firstLetterContinuation());
+      mRawSet.get(), *aParentStyle, PseudoStyleType::firstLetterContinuation);
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleForPlaceholder() {
   RefPtr<ComputedStyle>& cache = mNonInheritingComputedStyles
       [nsCSSAnonBoxes::NonInheriting::oofPlaceholder];
   if (cache) {
     RefPtr<ComputedStyle> retval = cache;
     return retval.forget();
   }
 
   RefPtr<ComputedStyle> computedValues =
       Servo_ComputedValues_Inherit(mRawSet.get(),
-                                   nsCSSAnonBoxes::oofPlaceholder(), nullptr,
+                                   PseudoStyleType::oofPlaceholder, nullptr,
                                    InheritTarget::PlaceholderFrame)
           .Consume();
   MOZ_ASSERT(computedValues);
 
   cache = computedValues;
   return computedValues.forget();
 }
 
-static inline bool LazyPseudoIsCacheable(CSSPseudoElementType aType,
+static inline bool LazyPseudoIsCacheable(PseudoStyleType aType,
                                          const Element& aOriginatingElement,
-                                         ComputedStyle* aParentContext) {
-  return aParentContext &&
+                                         ComputedStyle* aParentStyle) {
+  return aParentStyle &&
          !nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) &&
          aOriginatingElement.HasServoData() &&
          !Servo_Element_IsPrimaryStyleReusedViaRuleNode(&aOriginatingElement);
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolvePseudoElementStyle(
-    Element* aOriginatingElement, CSSPseudoElementType aType,
-    ComputedStyle* aParentContext, Element* aPseudoElement) {
+    Element* aOriginatingElement, PseudoStyleType aType,
+    ComputedStyle* aParentStyle, Element* aPseudoElement) {
   // Runs from frame construction, this should have clean styles already, except
   // with non-lazy FC...
   UpdateStylistIfNeeded();
-  MOZ_ASSERT(aType < CSSPseudoElementType::Count);
+  MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType));
 
   RefPtr<ComputedStyle> computedValues;
 
   if (aPseudoElement) {
     MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
     computedValues =
         Servo_ResolveStyle(aPseudoElement, mRawSet.get()).Consume();
   } else {
     bool cacheable =
-        LazyPseudoIsCacheable(aType, *aOriginatingElement, aParentContext);
+        LazyPseudoIsCacheable(aType, *aOriginatingElement, aParentStyle);
     computedValues =
-        cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr;
+        cacheable ? aParentStyle->GetCachedLazyPseudoStyle(aType) : nullptr;
 
     if (!computedValues) {
       computedValues = Servo_ResolvePseudoStyle(aOriginatingElement, aType,
                                                 /* is_probe = */ false,
-                                                aParentContext, mRawSet.get())
+                                                aParentStyle, mRawSet.get())
                            .Consume();
       if (cacheable) {
-        aParentContext->SetCachedLazyPseudoStyle(computedValues);
+        aParentStyle->SetCachedLazyPseudoStyle(computedValues);
       }
     }
   }
 
   MOZ_ASSERT(computedValues);
   return computedValues.forget();
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleLazily(
-    Element* aElement, CSSPseudoElementType aPseudoType,
+    Element* aElement, PseudoStyleType aPseudoType,
     StyleRuleInclusion aRuleInclusion) {
   PreTraverseSync();
   return ResolveStyleLazilyInternal(aElement, aPseudoType, aRuleInclusion);
 }
 
 already_AddRefed<ComputedStyle>
-ServoStyleSet::ResolveInheritingAnonymousBoxStyle(
-    nsAtom* aPseudoTag, ComputedStyle* aParentContext) {
-  MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
-             !nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
-  MOZ_ASSERT_IF(aParentContext, !StylistNeedsUpdate());
+ServoStyleSet::ResolveInheritingAnonymousBoxStyle(PseudoStyleType aType,
+                                                  ComputedStyle* aParentStyle) {
+  MOZ_ASSERT(PseudoStyle::IsInheritingAnonBox(aType));
+  MOZ_ASSERT_IF(aParentStyle, !StylistNeedsUpdate());
 
   UpdateStylistIfNeeded();
 
   RefPtr<ComputedStyle> style = nullptr;
 
-  if (aParentContext) {
-    style = aParentContext->GetCachedInheritingAnonBoxStyle(aPseudoTag);
+  if (aParentStyle) {
+    style = aParentStyle->GetCachedInheritingAnonBoxStyle(aType);
   }
 
   if (!style) {
-    style = Servo_ComputedValues_GetForAnonymousBox(aParentContext, aPseudoTag,
+    style = Servo_ComputedValues_GetForAnonymousBox(aParentStyle, aType,
                                                     mRawSet.get())
                 .Consume();
     MOZ_ASSERT(style);
-    if (aParentContext) {
-      aParentContext->SetCachedInheritedAnonBoxStyle(aPseudoTag, style);
+    if (aParentStyle) {
+      aParentStyle->SetCachedInheritedAnonBoxStyle(style);
     }
   }
 
   return style.forget();
 }
 
 already_AddRefed<ComputedStyle>
-ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(nsAtom* aPseudoTag) {
-  MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
-             nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
-  MOZ_ASSERT(aPseudoTag != nsCSSAnonBoxes::pageContent(),
-             "If nsCSSAnonBoxes::pageContent() ends up non-inheriting, check "
+ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType) {
+  MOZ_ASSERT(PseudoStyle::IsNonInheritingAnonBox(aType));
+  MOZ_ASSERT(aType != PseudoStyleType::pageContent,
+             "If pageContent ends up non-inheriting, check "
              "whether we need to do anything to move the "
              "@page handling from ResolveInheritingAnonymousBoxStyle to "
              "ResolveNonInheritingAnonymousBoxStyle");
 
   nsCSSAnonBoxes::NonInheriting type =
-      nsCSSAnonBoxes::NonInheritingTypeForPseudoTag(aPseudoTag);
+      nsCSSAnonBoxes::NonInheritingTypeForPseudoType(aType);
   RefPtr<ComputedStyle>& cache = mNonInheritingComputedStyles[type];
   if (cache) {
     RefPtr<ComputedStyle> retval = cache;
     return retval.forget();
   }
 
   UpdateStylistIfNeeded();
 
   // We always want to skip parent-based display fixup here.  It never makes
   // sense for non-inheriting anonymous boxes.  (Static assertions in
   // nsCSSAnonBoxes.cpp ensure that all non-inheriting non-anonymous boxes
   // are indeed annotated as skipping this fixup.)
-  MOZ_ASSERT(
-      !nsCSSAnonBoxes::IsNonInheritingAnonBox(nsCSSAnonBoxes::viewport()),
-      "viewport needs fixup to handle blockifying it");
+  MOZ_ASSERT(!PseudoStyle::IsNonInheritingAnonBox(PseudoStyleType::viewport),
+             "viewport needs fixup to handle blockifying it");
+
   RefPtr<ComputedStyle> computedValues =
-      Servo_ComputedValues_GetForAnonymousBox(nullptr, aPseudoTag,
-                                              mRawSet.get())
+      Servo_ComputedValues_GetForAnonymousBox(nullptr, aType, mRawSet.get())
           .Consume();
-#ifdef DEBUG
-  if (!computedValues) {
-    nsString pseudo;
-    aPseudoTag->ToString(pseudo);
-    NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
-                             NS_ConvertUTF16toUTF8(pseudo).get())
-                 .get());
-    MOZ_CRASH();
-  }
-#endif
+  MOZ_ASSERT(computedValues);
 
   cache = computedValues;
   return computedValues.forget();
 }
 
 #ifdef MOZ_XUL
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveXULTreePseudoStyle(
     dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag,
-    ComputedStyle* aParentContext, const AtomArray& aInputWord) {
+    ComputedStyle* aParentStyle, const AtomArray& aInputWord) {
   MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag));
-  MOZ_ASSERT(aParentContext);
+  MOZ_ASSERT(aParentStyle);
   MOZ_ASSERT(!StylistNeedsUpdate());
 
   return Servo_ComputedValues_ResolveXULTreePseudoStyle(
-             aParentElement, aPseudoTag, aParentContext, &aInputWord,
+             aParentElement, aPseudoTag, aParentStyle, &aInputWord,
              mRawSet.get())
       .Consume();
 }
 #endif
 
 // manage the set of style sheets in the style set
 nsresult ServoStyleSet::AppendStyleSheet(SheetType aType, StyleSheet* aSheet) {
   MOZ_ASSERT(aSheet);
@@ -804,54 +790,54 @@ nsresult ServoStyleSet::AddDocStyleSheet
   if (mStyleRuleMap) {
     mStyleRuleMap->SheetAdded(*aSheet);
   }
 
   return NS_OK;
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ProbePseudoElementStyle(
-    const Element& aOriginatingElement, CSSPseudoElementType aType,
-    ComputedStyle* aParentContext) {
+    const Element& aOriginatingElement, PseudoStyleType aType,
+    ComputedStyle* aParentStyle) {
   // Runs from frame construction, this should have clean styles already, except
   // with non-lazy FC...
   UpdateStylistIfNeeded();
 
-  // NB: We ignore aParentContext, because in some cases
+  // NB: We ignore aParentStyle, because in some cases
   // (first-line/first-letter on anonymous box blocks) Gecko passes something
   // nonsensical there.  In all other cases we want to inherit directly from
   // aOriginatingElement's styles anyway.
-  MOZ_ASSERT(aType < CSSPseudoElementType::Count);
+  MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType));
 
   bool cacheable =
-      LazyPseudoIsCacheable(aType, aOriginatingElement, aParentContext);
+      LazyPseudoIsCacheable(aType, aOriginatingElement, aParentStyle);
 
   RefPtr<ComputedStyle> computedValues =
-      cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr;
+      cacheable ? aParentStyle->GetCachedLazyPseudoStyle(aType) : nullptr;
   if (!computedValues) {
     computedValues =
         Servo_ResolvePseudoStyle(&aOriginatingElement, aType,
                                  /* is_probe = */ true, nullptr, mRawSet.get())
             .Consume();
     if (!computedValues) {
       return nullptr;
     }
 
     if (cacheable) {
       // NB: We don't need to worry about the before/after handling below
       // because those are eager and thus not |cacheable| anyway.
-      aParentContext->SetCachedLazyPseudoStyle(computedValues);
+      aParentStyle->SetCachedLazyPseudoStyle(computedValues);
     }
   }
 
   // For :before and :after pseudo-elements, having display: none or no
   // 'content' property is equivalent to not having the pseudo-element
   // at all.
-  bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
-                         aType == CSSPseudoElementType::after;
+  bool isBeforeOrAfter =
+      aType == PseudoStyleType::before || aType == PseudoStyleType::after;
   if (isBeforeOrAfter) {
     const nsStyleDisplay* display = computedValues->StyleDisplay();
     const nsStyleContent* content = computedValues->StyleContent();
     if (display->mDisplay == StyleDisplay::None ||
         content->ContentCount() == 0) {
       return nullptr;
     }
   }
@@ -1194,17 +1180,17 @@ void ServoStyleSet::CompatibilityModeCha
 
 void ServoStyleSet::ClearNonInheritingComputedStyles() {
   for (RefPtr<ComputedStyle>& ptr : mNonInheritingComputedStyles) {
     ptr = nullptr;
   }
 }
 
 already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleLazilyInternal(
-    Element* aElement, CSSPseudoElementType aPseudoType,
+    Element* aElement, PseudoStyleType aPseudoType,
     StyleRuleInclusion aRuleInclusion) {
   MOZ_ASSERT(GetPresContext(),
              "For now, no style resolution without a pres context");
   GetPresContext()->EffectCompositor()->PreTraverse(aElement, aPseudoType);
   MOZ_ASSERT(!StylistNeedsUpdate());
 
   AutoSetInServoTraversal guard(this);
 
@@ -1215,26 +1201,26 @@ already_AddRefed<ComputedStyle> ServoSty
    * That means that that style doesn't account for animations, and we can't do
    * that easily from the traversal without doing wasted work.
    *
    * As such, we just lie here a bit, which is the entrypoint of
    * getComputedStyle, the only API where this can be observed, to look at the
    * style of the pseudo-element if it exists instead.
    */
   Element* elementForStyleResolution = aElement;
-  CSSPseudoElementType pseudoTypeForStyleResolution = aPseudoType;
-  if (aPseudoType == CSSPseudoElementType::before) {
+  PseudoStyleType pseudoTypeForStyleResolution = aPseudoType;
+  if (aPseudoType == PseudoStyleType::before) {
     if (Element* pseudo = nsLayoutUtils::GetBeforePseudo(aElement)) {
       elementForStyleResolution = pseudo;
-      pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
+      pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
     }
-  } else if (aPseudoType == CSSPseudoElementType::after) {
+  } else if (aPseudoType == PseudoStyleType::after) {
     if (Element* pseudo = nsLayoutUtils::GetAfterPseudo(aElement)) {
       elementForStyleResolution = pseudo;
-      pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
+      pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
     }
   }
 
   RefPtr<ComputedStyle> computedValues =
       Servo_ResolveStyleLazily(elementForStyleResolution,
                                pseudoTypeForStyleResolution, aRuleInclusion,
                                &Snapshots(), mRawSet.get())
           .Consume();
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -141,74 +141,72 @@ class ServoStyleSet {
   //
   // The returned ComputedStyle will have nsCSSAnonBoxes::mozText() as its
   // pseudo.
   //
   // (Perhaps mozText should go away and we shouldn't even create style
   // contexts for such content nodes, when text-combine-upright is not
   // present.  However, not doing any rule matching for them is a first step.)
   already_AddRefed<ComputedStyle> ResolveStyleForText(
-      nsIContent* aTextNode, ComputedStyle* aParentContext);
+      nsIContent* aTextNode, ComputedStyle* aParentStyle);
 
   // Get a ComputedStyle for a first-letter continuation (which no rules will
   // match).
   //
   // The returned ComputedStyle will have
   // nsCSSAnonBoxes::firstLetterContinuation() as its pseudo.
   //
   // (Perhaps nsCSSAnonBoxes::firstLetterContinuation() should go away and we
   // shouldn't even create ComputedStyles for such frames.  However, not doing
   // any rule matching for them is a first step.  And right now we do use this
   // ComputedStyle for some things)
   already_AddRefed<ComputedStyle> ResolveStyleForFirstLetterContinuation(
-      ComputedStyle* aParentContext);
+      ComputedStyle* aParentStyle);
 
   // Get a ComputedStyle for a placeholder frame (which no rules will match).
   //
   // The returned ComputedStyle will have nsCSSAnonBoxes::oofPlaceholder() as
   // its pseudo.
   //
   // (Perhaps nsCSSAnonBoxes::oofPaceholder() should go away and we shouldn't
   // even create ComputedStyle for placeholders.  However, not doing any rule
   // matching for them is a first step.)
   already_AddRefed<ComputedStyle> ResolveStyleForPlaceholder();
 
   // Get a ComputedStyle for a pseudo-element.  aParentElement must be
-  // non-null.  aPseudoID is the CSSPseudoElementType for the
+  // non-null.  aPseudoID is the PseudoStyleType for the
   // pseudo-element.  aPseudoElement must be non-null if the pseudo-element
   // type is one that allows user action pseudo-classes after it or allows
   // style attributes; otherwise, it is ignored.
   already_AddRefed<ComputedStyle> ResolvePseudoElementStyle(
-      dom::Element* aOriginatingElement, CSSPseudoElementType aType,
-      ComputedStyle* aParentContext, dom::Element* aPseudoElement);
+      dom::Element* aOriginatingElement, PseudoStyleType aType,
+      ComputedStyle* aParentStyle, dom::Element* aPseudoElement);
 
   // Resolves style for a (possibly-pseudo) Element without assuming that the
   // style has been resolved. If the element was unstyled and a new style
   // context was resolved, it is not stored in the DOM. (That is, the element
   // remains unstyled.)
   already_AddRefed<ComputedStyle> ResolveStyleLazily(
-      dom::Element* aElement, CSSPseudoElementType aPseudoType,
+      dom::Element* aElement, PseudoStyleType,
       StyleRuleInclusion aRules = StyleRuleInclusion::All);
 
-  // Get a ComputedStyle for an anonymous box.  aPseudoTag is the pseudo-tag to
-  // use and must be non-null.  It must be an anon box, and must be one that
-  // inherits style from the given aParentContext.
+  // Get a ComputedStyle for an anonymous box. The pseudo type must be an
+  // inheriting anon box.
   already_AddRefed<ComputedStyle> ResolveInheritingAnonymousBoxStyle(
-      nsAtom* aPseudoTag, ComputedStyle* aParentContext);
+      PseudoStyleType, ComputedStyle* aParentStyle);
 
-  // Get a ComputedStyle for an anonymous box that does not inherit style from
-  // anything.  aPseudoTag is the pseudo-tag to use and must be non-null.  It
-  // must be an anon box, and must be a non-inheriting one.
+  // Get a ComputedStyle for an anonymous box. The pseudo type must be
+  // a non-inheriting anon box.
   already_AddRefed<ComputedStyle> ResolveNonInheritingAnonymousBoxStyle(
-      nsAtom* aPseudoTag);
+      PseudoStyleType);
 
 #ifdef MOZ_XUL
   already_AddRefed<ComputedStyle> ResolveXULTreePseudoStyle(
       dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag,
-      ComputedStyle* aParentContext, const AtomArray& aInputWord);
+      ComputedStyle* aParentStyle, const AtomArray& aInputWord);
 #endif
 
   // manage the set of style sheets in the style set
   nsresult AppendStyleSheet(SheetType aType, StyleSheet* aSheet);
   nsresult RemoveStyleSheet(SheetType aType, StyleSheet* aSheet);
   nsresult ReplaceSheets(SheetType aType,
                          const nsTArray<RefPtr<StyleSheet>>& aNewSheets);
   nsresult InsertStyleSheetBefore(SheetType aType, StyleSheet* aNewSheet,
@@ -226,17 +224,17 @@ class ServoStyleSet {
     }
   }
 
   nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
   nsresult AddDocStyleSheet(StyleSheet* aSheet, dom::Document* aDocument);
 
   // check whether there is ::before/::after style for an element
   already_AddRefed<ComputedStyle> ProbePseudoElementStyle(
-      const dom::Element& aOriginatingElement, CSSPseudoElementType aType,
+      const dom::Element& aOriginatingElement, PseudoStyleType aType,
       ComputedStyle* aParentStyle);
 
   /**
    * Performs a Servo traversal to compute style for all dirty nodes in the
    * document.
    *
    * This will traverse all of the document's style roots (that is, its document
    * element, and the roots of the document-level native anonymous content).
@@ -489,17 +487,17 @@ class ServoStyleSet {
   /**
    * Update the stylist as needed to ensure style data is up-to-date.
    *
    * This should only be called if StylistNeedsUpdate returns true.
    */
   void UpdateStylist();
 
   already_AddRefed<ComputedStyle> ResolveStyleLazilyInternal(
-      dom::Element* aElement, CSSPseudoElementType aPseudoType,
+      dom::Element* aElement, PseudoStyleType aPseudoType,
       StyleRuleInclusion aRules = StyleRuleInclusion::All);
 
   void RunPostTraversalTasks();
 
   void PrependSheetOfType(SheetType aType, StyleSheet* aSheet);
 
   void AppendSheetOfType(SheetType aType, StyleSheet* aSheet);
 
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -32,17 +32,17 @@ class ComputedStyle;
 namespace css {
 class StyleRule;
 }  // namespace css
 
 namespace dom {
 class Element;
 }  // namespace dom
 
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 struct PropertyStyleAnimationValuePair;
 
 struct AnimationValue {
   explicit AnimationValue(const RefPtr<RawServoAnimationValue>& aValue)
       : mServo(aValue) {}
   AnimationValue() = default;
 
   AnimationValue(const AnimationValue& aOther) : mServo(aOther.mServo) {}
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -83,16 +83,17 @@ EXPORTS.mozilla += [
     'DeclarationBlock.h',
     'DocumentStyleRootIterator.h',
     'GeckoBindings.h',
     'LayerAnimationInfo.h',
     'MappedDeclarations.h',
     'MediaFeatureChange.h',
     'PostTraversalTask.h',
     'PreloadedStyleSheet.h',
+    'PseudoStyleType.h',
     'RustCell.h',
     'ServoArcTypeList.h',
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoBoxedTypeList.h',
     'ServoComputedData.h',
     'ServoComputedDataInlines.h',
     'ServoCSSParser.h',
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -524,17 +524,17 @@ static nsAnimationManager::OwningCSSAnim
 
     dest->SetAnimationIndex(static_cast<uint64_t>(animIdx));
     result.AppendElement(dest);
   }
   return result;
 }
 
 void nsAnimationManager::UpdateAnimations(dom::Element* aElement,
-                                          CSSPseudoElementType aPseudoType,
+                                          PseudoStyleType aPseudoType,
                                           const ComputedStyle* aComputedStyle) {
   MOZ_ASSERT(mPresContext->IsDynamic(),
              "Should not update animations for print or print preview");
   MOZ_ASSERT(aElement->IsInComposedDoc(),
              "Should not update animations that are not attached to the "
              "document tree");
 
   const nsStyleDisplay* disp =
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -25,17 +25,17 @@ namespace mozilla {
 class ComputedStyle;
 namespace css {
 class Declaration;
 } /* namespace css */
 namespace dom {
 class Promise;
 } /* namespace dom */
 
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 struct NonOwningAnimationTarget;
 
 namespace dom {
 
 class CSSAnimation final : public Animation {
  public:
   explicit CSSAnimation(nsIGlobalObject* aGlobal, nsAtom* aAnimationName)
       : dom::Animation(aGlobal),
@@ -273,17 +273,17 @@ class nsAnimationManager final
 
   ~nsAnimationManager() override = default;
 
   /**
    * This function does the same thing as the above UpdateAnimations()
    * but with servo's computed values.
    */
   void UpdateAnimations(mozilla::dom::Element* aElement,
-                        mozilla::CSSPseudoElementType aPseudoType,
+                        mozilla::PseudoStyleType aPseudoType,
                         const mozilla::ComputedStyle* aComputedValues);
 
   // Utility function to walk through |aIter| to find the Keyframe with
   // matching offset and timing function but stopping as soon as the offset
   // differs from |aOffset| (i.e. it assumes a sorted iterator).
   //
   // If a matching Keyframe is found,
   //   Returns true and sets |aIndex| to the index of the matching Keyframe
--- a/layout/style/nsCSSAnonBoxes.cpp
+++ b/layout/style/nsCSSAnonBoxes.cpp
@@ -9,44 +9,29 @@
 #include "mozilla/ArrayUtils.h"
 
 #include "nsCSSAnonBoxes.h"
 #include "nsGkAtomConsts.h"
 #include "nsStaticAtomUtils.h"
 
 using namespace mozilla;
 
+#ifdef MOZ_XUL
+/* static */ bool nsCSSAnonBoxes::IsTreePseudoElement(nsAtom* aPseudo) {
+  return StringBeginsWith(nsDependentAtomString(aPseudo),
+                          NS_LITERAL_STRING(":-moz-tree-"));
+}
+#endif
+
+#ifdef DEBUG
 static nsStaticAtom* GetAtomBase() {
   return const_cast<nsStaticAtom*>(
       nsGkAtoms::GetAtomByIndex(kAtomIndex_AnonBoxes));
 }
 
-bool nsCSSAnonBoxes::IsAnonBox(nsAtom* aAtom) {
-  return nsStaticAtomUtils::IsMember(aAtom, GetAtomBase(),
-                                     kAtomCount_AnonBoxes);
-}
-
-#ifdef MOZ_XUL
-/* static */ bool nsCSSAnonBoxes::IsTreePseudoElement(nsAtom* aPseudo) {
-  MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudo));
-  return StringBeginsWith(nsDependentAtomString(aPseudo),
-                          NS_LITERAL_STRING(":-moz-tree-"));
-}
-#endif
-
-/* static*/ nsCSSAnonBoxes::NonInheriting
-nsCSSAnonBoxes::NonInheritingTypeForPseudoTag(nsAtom* aPseudo) {
-  MOZ_ASSERT(IsNonInheritingAnonBox(aPseudo));
-  Maybe<uint32_t> index =
-      nsStaticAtomUtils::Lookup(aPseudo, GetAtomBase(), kAtomCount_AnonBoxes);
-  MOZ_RELEASE_ASSERT(index.isSome());
-  return static_cast<NonInheriting>(*index);
-}
-
-#ifdef DEBUG
 /* static */ void nsCSSAnonBoxes::AssertAtoms() {
   nsStaticAtom* base = GetAtomBase();
   size_t index = 0;
 #  define CSS_ANON_BOX(name_, value_)                                 \
     {                                                                 \
       RefPtr<nsAtom> atom = NS_Atomize(value_);                       \
       MOZ_ASSERT(atom == nsGkAtoms::AnonBox_##name_,                  \
                  "Static atom for " #name_ " has incorrect value");   \
--- a/layout/style/nsCSSAnonBoxes.h
+++ b/layout/style/nsCSSAnonBoxes.h
@@ -6,94 +6,50 @@
 
 /* atom list for CSS anonymous boxes */
 
 #ifndef nsCSSAnonBoxes_h___
 #define nsCSSAnonBoxes_h___
 
 #include "nsAtom.h"
 #include "nsGkAtoms.h"
+#include "mozilla/PseudoStyleType.h"
 
 class nsCSSAnonBoxes {
+  using PseudoStyleType = mozilla::PseudoStyleType;
+  using PseudoStyle = mozilla::PseudoStyle;
+
  public:
-  static bool IsAnonBox(nsAtom* aAtom);
 #ifdef MOZ_XUL
   static bool IsTreePseudoElement(nsAtom* aPseudo);
 #endif
-  static bool IsNonElement(nsAtom* aPseudo) {
-    return aPseudo == nsCSSAnonBoxes::mozText() ||
-           aPseudo == nsCSSAnonBoxes::oofPlaceholder() ||
-           aPseudo == nsCSSAnonBoxes::firstLetterContinuation();
+  static bool IsNonElement(PseudoStyleType aPseudo) {
+    return aPseudo == PseudoStyleType::mozText ||
+           aPseudo == PseudoStyleType::oofPlaceholder ||
+           aPseudo == PseudoStyleType::firstLetterContinuation;
   }
 
-  typedef uint8_t NonInheritingBase;
-  enum class NonInheriting : NonInheritingBase {
+  enum class NonInheriting : uint8_t {
 #define CSS_ANON_BOX(_name, _value) /* nothing */
 #define CSS_NON_INHERITING_ANON_BOX(_name, _value) _name,
 #include "nsCSSAnonBoxList.h"
 #undef CSS_NON_INHERITING_ANON_BOX
 #undef CSS_ANON_BOX
     _Count
   };
 
-  // Be careful using this: if we have a lot of non-inheriting anon box types it
-  // might not be very fast.  We may want to think of ways to handle that
-  // (e.g. by moving to an enum instead of an atom, like we did for
-  // pseudo-elements, or by adding a new value of the pseudo-element enum for
-  // non-inheriting anon boxes or something).
-  static bool IsNonInheritingAnonBox(nsAtom* aPseudo) {
-    return
-#define CSS_ANON_BOX(_name, _value) /* nothing */
-#define CSS_NON_INHERITING_ANON_BOX(_name, _value) \
-  nsGkAtoms::AnonBox_##_name == aPseudo ||
-#include "nsCSSAnonBoxList.h"
-#undef CSS_NON_INHERITING_ANON_BOX
-#undef CSS_ANON_BOX
-        false;
-  }
-
-#ifdef DEBUG
-  // NOTE(emilio): DEBUG only because this does a pretty slow linear search. Try
-  // to use IsNonInheritingAnonBox if you know the atom is an anon box already
-  // or, even better, nothing like this.  Note that this function returns true
-  // for wrapper anon boxes as well, since they're all inheriting.
-  static bool IsInheritingAnonBox(nsAtom* aPseudo) {
-    return
-#  define CSS_ANON_BOX(_name, _value) nsGkAtoms::AnonBox_##_name == aPseudo ||
-#  define CSS_NON_INHERITING_ANON_BOX(_name, _value) /* nothing */
-#  include "nsCSSAnonBoxList.h"
-#  undef CSS_NON_INHERITING_ANON_BOX
-#  undef CSS_ANON_BOX
-        false;
-  }
-#endif  // DEBUG
-
-  // This function is rather slow; you probably don't want to use it outside
-  // asserts unless you have to.
-  static bool IsWrapperAnonBox(nsAtom* aPseudo) {
-    // We commonly get null passed here, and want to quickly return false for
-    // it.
-    if (!aPseudo) {
-      return false;
-    }
-    return
-#define CSS_ANON_BOX(_name, _value) /* nothing */
-#define CSS_WRAPPER_ANON_BOX(_name, _value) \
-  nsGkAtoms::AnonBox_##_name == aPseudo ||
-#define CSS_NON_INHERITING_ANON_BOX(_name, _value) /* nothing */
-#include "nsCSSAnonBoxList.h"
-#undef CSS_NON_INHERITING_ANON_BOX
-#undef CSS_WRAPPER_ANON_BOX
-#undef CSS_ANON_BOX
-        false;
-  }
-
   // Get the NonInheriting type for a given pseudo tag.  The pseudo tag must
   // test true for IsNonInheritingAnonBox.
-  static NonInheriting NonInheritingTypeForPseudoTag(nsAtom* aPseudo);
+  static NonInheriting NonInheritingTypeForPseudoType(PseudoStyleType aType) {
+    MOZ_ASSERT(PseudoStyle::IsNonInheritingAnonBox(aType));
+    static_assert(sizeof(PseudoStyleType) == sizeof(uint8_t), "");
+    return static_cast<NonInheriting>(
+        static_cast<uint8_t>(aType) -
+        static_cast<uint8_t>(PseudoStyleType::NonInheritingAnonBoxesStart));
+  }
 
 #ifdef DEBUG
   static void AssertAtoms();
 #endif
 
 // Alias nsCSSAnonBoxes::foo() to nsGkAtoms::AnonBox_foo.
 #define CSS_ANON_BOX(name_, value_)                       \
   static nsCSSAnonBoxPseudoStaticAtom* name_() {          \
--- a/layout/style/nsCSSPseudoElements.cpp
+++ b/layout/style/nsCSSPseudoElements.cpp
@@ -32,60 +32,43 @@ static nsStaticAtom* GetAtomBase() {
 bool nsCSSPseudoElements::IsPseudoElement(nsAtom* aAtom) {
   return nsStaticAtomUtils::IsMember(aAtom, GetAtomBase(),
                                      kAtomCount_PseudoElements);
 }
 
 /* static */ bool nsCSSPseudoElements::IsCSS2PseudoElement(nsAtom* aAtom) {
   // We don't implement this using PseudoElementHasFlags because callers
   // want to pass things that could be anon boxes.
-  NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aAtom) ||
-                   nsCSSAnonBoxes::IsAnonBox(aAtom),
-               "must be pseudo element or anon box");
+  MOZ_ASSERT(IsPseudoElement(aAtom), "must be pseudo element");
   bool result = aAtom == nsCSSPseudoElements::after() ||
                 aAtom == nsCSSPseudoElements::before() ||
                 aAtom == nsCSSPseudoElements::firstLetter() ||
                 aAtom == nsCSSPseudoElements::firstLine();
   NS_ASSERTION(
-      nsCSSAnonBoxes::IsAnonBox(aAtom) ||
-          result == PseudoElementHasFlags(
-                        GetPseudoType(aAtom, EnabledState::eIgnoreEnabledState),
-                        CSS_PSEUDO_ELEMENT_IS_CSS2),
+      result == PseudoElementHasFlags(
+                    GetPseudoType(aAtom, EnabledState::eIgnoreEnabledState),
+                    CSS_PSEUDO_ELEMENT_IS_CSS2),
       "result doesn't match flags");
   return result;
 }
 
-/* static */ CSSPseudoElementType nsCSSPseudoElements::GetPseudoType(
+/* static */ PseudoStyleType nsCSSPseudoElements::GetPseudoType(
     nsAtom* aAtom, EnabledState aEnabledState) {
   Maybe<uint32_t> index = nsStaticAtomUtils::Lookup(aAtom, GetAtomBase(),
                                                     kAtomCount_PseudoElements);
   if (index.isSome()) {
     auto type = static_cast<Type>(*index);
     return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
   }
 
-  if (nsCSSAnonBoxes::IsAnonBox(aAtom)) {
-#ifdef MOZ_XUL
-    if (nsCSSAnonBoxes::IsTreePseudoElement(aAtom)) {
-      return Type::XULTree;
-    }
-#endif
-
-    if (nsCSSAnonBoxes::IsNonInheritingAnonBox(aAtom)) {
-      return Type::NonInheritingAnonBox;
-    }
-
-    return Type::InheritingAnonBox;
-  }
-
   return Type::NotPseudo;
 }
 
 /* static */ nsAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) {
-  MOZ_ASSERT(aType < Type::Count, "Unexpected type");
+  MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType), "Unexpected type");
   size_t index = kAtomIndex_PseudoElements + static_cast<size_t>(aType);
   return nsGkAtoms::GetAtomByIndex(index);
 }
 
 /* static */ already_AddRefed<nsAtom> nsCSSPseudoElements::GetPseudoAtom(
     const nsAString& aPseudoElement) {
   if (DOMStringIsNull(aPseudoElement) || aPseudoElement.IsEmpty() ||
       aPseudoElement.First() != char16_t(':')) {
@@ -121,35 +104,35 @@ bool nsCSSPseudoElements::IsPseudoElemen
     const Type aType) {
   return PseudoElementHasFlags(aType,
                                CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE);
 }
 
 /* static */ nsString nsCSSPseudoElements::PseudoTypeAsString(
     Type aPseudoType) {
   switch (aPseudoType) {
-    case CSSPseudoElementType::before:
+    case PseudoStyleType::before:
       return NS_LITERAL_STRING("::before");
-    case CSSPseudoElementType::after:
+    case PseudoStyleType::after:
       return NS_LITERAL_STRING("::after");
     default:
-      MOZ_ASSERT(aPseudoType == CSSPseudoElementType::NotPseudo,
+      MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo,
                  "Unexpected pseudo type");
       return EmptyString();
   }
 }
 
 #ifdef DEBUG
 /* static */ void nsCSSPseudoElements::AssertAtoms() {
   nsStaticAtom* base = GetAtomBase();
-#  define CSS_PSEUDO_ELEMENT(name_, value_, flags_)                    \
-    {                                                                  \
-      RefPtr<nsAtom> atom = NS_Atomize(value_);                        \
-      size_t index = static_cast<size_t>(CSSPseudoElementType::name_); \
-      MOZ_ASSERT(atom == nsGkAtoms::PseudoElement_##name_,             \
-                 "Static atom for " #name_ " has incorrect value");    \
-      MOZ_ASSERT(atom == &base[index],                                 \
-                 "Static atom for " #name_ " not at expected index");  \
+#  define CSS_PSEUDO_ELEMENT(name_, value_, flags_)                   \
+    {                                                                 \
+      RefPtr<nsAtom> atom = NS_Atomize(value_);                       \
+      size_t index = static_cast<size_t>(PseudoStyleType::name_);     \
+      MOZ_ASSERT(atom == nsGkAtoms::PseudoElement_##name_,            \
+                 "Static atom for " #name_ " has incorrect value");   \
+      MOZ_ASSERT(atom == &base[index],                                \
+                 "Static atom for " #name_ " not at expected index"); \
     }
 #  include "nsCSSPseudoElementList.h"
 #  undef CSS_PSEUDO_ELEMENT
 }
 #endif
--- a/layout/style/nsCSSPseudoElements.h
+++ b/layout/style/nsCSSPseudoElements.h
@@ -7,16 +7,17 @@
 /* atom list for CSS pseudo-elements */
 
 #ifndef nsCSSPseudoElements_h___
 #define nsCSSPseudoElements_h___
 
 #include "nsGkAtoms.h"
 #include "mozilla/CSSEnabledState.h"
 #include "mozilla/Compiler.h"
+#include "mozilla/PseudoStyleType.h"
 
 // Is this pseudo-element a CSS2 pseudo-element that can be specified
 // with the single colon syntax (in addition to the double-colon syntax,
 // which can be used for all pseudo-elements)?
 //
 // Note: We also rely on this for IsEagerlyCascadedInServo.
 #define CSS_PSEUDO_ELEMENT_IS_CSS2 (1 << 0)
 // Is this pseudo-element a pseudo-element that can contain other
@@ -50,52 +51,25 @@
 // Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" })
 // API for creating pseudo-implementing native anonymous content in JS with this
 // pseudo-element?
 #define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1 << 6)
 // Does this pseudo-element act like an item for containers (such as flex and
 // grid containers) and thus needs parent display-based style fixup?
 #define CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM (1 << 7)
 
-namespace mozilla {
-
-// The total count of CSSPseudoElement is less than 256,
-// so use uint8_t as its underlying type.
-typedef uint8_t CSSPseudoElementTypeBase;
-enum class CSSPseudoElementType : CSSPseudoElementTypeBase {
-// If the actual pseudo-elements stop being first here, change
-// GetPseudoType.
-#define CSS_PSEUDO_ELEMENT(_name, _value, _flags) _name,
-#include "nsCSSPseudoElementList.h"
-#undef CSS_PSEUDO_ELEMENT
-  Count,
-  InheritingAnonBox = Count,  // pseudo from nsCSSAnonBoxes,
-                              // IsNonInheritingAnonBox false.
-  NonInheritingAnonBox,  // from nsCSSAnonBoxes, IsNonInheritingAnonBox true.
-#ifdef MOZ_XUL
-  XULTree,
-#endif
-  NotPseudo,
-  MAX
-};
-
-}  // namespace mozilla
-
 class nsCSSPseudoElements {
-  typedef mozilla::CSSPseudoElementType Type;
+  typedef mozilla::PseudoStyleType Type;
   typedef mozilla::CSSEnabledState EnabledState;
 
  public:
   static bool IsPseudoElement(nsAtom* aAtom);
 
   static bool IsCSS2PseudoElement(nsAtom* aAtom);
 
-  // This must match EAGER_PSEUDO_COUNT in Rust code.
-  static const size_t kEagerPseudoCount = 4;
-
   static bool IsEagerlyCascadedInServo(const Type aType) {
     return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_CSS2);
   }
 
  public:
 #ifdef DEBUG
   static void AssertAtoms();
 #endif
@@ -107,31 +81,32 @@ class nsCSSPseudoElements {
         static_cast<const nsCSSPseudoElementStaticAtom*>( \
             nsGkAtoms::PseudoElement_##name_));           \
   }
 #include "nsCSSPseudoElementList.h"
 #undef CSS_PSEUDO_ELEMENT
 
   static Type GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState);
 
-  // Get the atom for a given Type. aType must be < CSSPseudoElementType::Count.
+  // Get the atom for a given Type. aType must be <
+  // PseudoType::CSSPseudoElementsEnd.
   // This only ever returns static atoms, so it's fine to return a raw pointer.
   static nsAtom* GetPseudoAtom(Type aType);
 
   // Get the atom for a given pseudo-element string (e.g. "::before").  This can
   // return dynamic atoms, for unrecognized pseudo-elements.
   static already_AddRefed<nsAtom> GetPseudoAtom(
       const nsAString& aPseudoElement);
 
   static bool PseudoElementContainsElements(const Type aType) {
     return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS);
   }
 
   static bool PseudoElementSupportsStyleAttribute(const Type aType) {
-    MOZ_ASSERT(aType < Type::Count);
+    MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
     return PseudoElementHasFlags(aType,
                                  CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE);
   }
 
   static bool PseudoElementSupportsUserActionState(const Type aType);
 
   static bool PseudoElementIsJSCreatedNAC(Type aType) {
     return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC);
@@ -161,21 +136,21 @@ class nsCSSPseudoElements {
     return false;
   }
 
   static nsString PseudoTypeAsString(Type aPseudoType);
 
  private:
   // Does the given pseudo-element have all of the flags given?
   static bool PseudoElementHasFlags(const Type aType, uint32_t aFlags) {
-    MOZ_ASSERT(aType < Type::Count);
+    MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
     return (kPseudoElementFlags[size_t(aType)] & aFlags) == aFlags;
   }
 
   static bool PseudoElementHasAnyFlag(const Type aType, uint32_t aFlags) {
-    MOZ_ASSERT(aType < Type::Count);
+    MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
     return (kPseudoElementFlags[size_t(aType)] & aFlags) != 0;
   }
 
-  static const uint32_t kPseudoElementFlags[size_t(Type::Count)];
+  static const uint32_t kPseudoElementFlags[size_t(Type::CSSPseudoElementsEnd)];
 };
 
 #endif /* nsCSSPseudoElements_h___ */
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -123,21 +123,21 @@ static bool DocumentNeedsRestyle(const D
   if (presContext->HasPendingMediaQueryUpdates()) {
     // So gotta flush.
     return true;
   }
 
   // If the pseudo-element is animating, make sure to flush.
   if (aElement->MayHaveAnimations() && aPseudo) {
     if (aPseudo == nsCSSPseudoElements::before()) {
-      if (EffectSet::GetEffectSet(aElement, CSSPseudoElementType::before)) {
+      if (EffectSet::GetEffectSet(aElement, PseudoStyleType::before)) {
         return true;
       }
     } else if (aPseudo == nsCSSPseudoElements::after()) {
-      if (EffectSet::GetEffectSet(aElement, CSSPseudoElementType::after)) {
+      if (EffectSet::GetEffectSet(aElement, PseudoStyleType::after)) {
         return true;
       }
     }
   }
 
   // For Servo, we need to process the restyle-hint-invalidations first, to
   // expand LaterSiblings hint, so that we can look whether ancestors need
   // restyling.
@@ -466,22 +466,22 @@ already_AddRefed<ComputedStyle> nsComput
  * ::first-letter frame, in which case we can't return the frame style, and we
  * need to resolve it. See bug 505515.
  */
 static bool MustReresolveStyle(const mozilla::ComputedStyle* aStyle) {
   MOZ_ASSERT(aStyle);
 
   // TODO(emilio): We may want to avoid re-resolving pseudo-element styles
   // more often.
-  return aStyle->HasPseudoElementData() && !aStyle->GetPseudo();
+  return aStyle->HasPseudoElementData() && !aStyle->IsPseudoElement();
 }
 
-static inline CSSPseudoElementType GetPseudoType(nsAtom* aPseudo) {
+static inline PseudoStyleType GetPseudoType(nsAtom* aPseudo) {
   if (!aPseudo) {
-    return CSSPseudoElementType::NotPseudo;
+    return PseudoStyleType::NotPseudo;
   }
   return nsCSSPseudoElements::GetPseudoType(aPseudo,
                                             CSSEnabledState::eForAllContent);
 }
 
 already_AddRefed<ComputedStyle> nsComputedDOMStyle::DoGetComputedStyleNoFlush(
     Element* aElement, nsAtom* aPseudo, nsIPresShell* aPresShell,
     StyleType aStyleType) {
@@ -497,18 +497,18 @@ already_AddRefed<ComputedStyle> nsComput
   if (!presShell) {
     inDocWithShell = false;
     presShell = aPresShell;
     if (!presShell) {
       return nullptr;
     }
   }
 
-  CSSPseudoElementType pseudoType = GetPseudoType(aPseudo);
-  if (aPseudo && pseudoType >= CSSPseudoElementType::Count) {
+  PseudoStyleType pseudoType = GetPseudoType(aPseudo);
+  if (aPseudo && !PseudoStyle::IsPseudoElement(pseudoType)) {
     return nullptr;
   }
 
   if (!aElement->IsInComposedDoc()) {
     // Don't return styles for disconnected elements, that makes no sense. This
     // can only happen with a non-null presShell for cross-document calls.
     //
     // FIXME(emilio, bug 1483798): This should also not return styles for
@@ -558,17 +558,17 @@ already_AddRefed<ComputedStyle> nsComput
 already_AddRefed<ComputedStyle>
 nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(Element* aElement,
                                                       nsAtom* aPseudo) {
   RefPtr<ComputedStyle> style = GetComputedStyleNoFlush(aElement, aPseudo);
   if (!style) {
     return nullptr;
   }
 
-  CSSPseudoElementType pseudoType = GetPseudoType(aPseudo);
+  PseudoStyleType pseudoType = GetPseudoType(aPseudo);
   nsIPresShell* shell = aElement->OwnerDoc()->GetShell();
   MOZ_ASSERT(shell, "How in the world did we get a style a few lines above?");
 
   Element* elementOrPseudoElement =
       EffectCompositor::GetElementToRestyle(aElement, pseudoType);
   if (!elementOrPseudoElement) {
     return nullptr;
   }
--- a/layout/style/nsHTMLCSSStyleSheet.h
+++ b/layout/style/nsHTMLCSSStyleSheet.h
@@ -15,17 +15,17 @@
 #include "mozilla/MemoryReporting.h"
 
 #include "nsDataHashtable.h"
 
 class nsRuleWalker;
 struct MiscContainer;
 
 namespace mozilla {
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 namespace dom {
 class Element;
 }  // namespace dom
 }  // namespace mozilla
 
 class nsHTMLCSSStyleSheet final {
  public:
   nsHTMLCSSStyleSheet();
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -377,34 +377,33 @@ static inline bool ExtractNonDiscreteCom
 
   aAnimationValue.mServo =
       Servo_ComputedValues_ExtractAnimationValue(&aComputedStyle, aProperty)
           .Consume();
   return !!aAnimationValue.mServo;
 }
 
 bool nsTransitionManager::UpdateTransitions(dom::Element* aElement,
-                                            CSSPseudoElementType aPseudoType,
+                                            PseudoStyleType aPseudoType,
                                             const ComputedStyle& aOldStyle,
                                             const ComputedStyle& aNewStyle) {
   if (!mPresContext->IsDynamic()) {
     // For print or print preview, ignore transitions.
     return false;
   }
 
   CSSTransitionCollection* collection =
       CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
   return DoUpdateTransitions(*aNewStyle.StyleDisplay(), aElement, aPseudoType,
                              collection, aOldStyle, aNewStyle);
 }
 
 bool nsTransitionManager::DoUpdateTransitions(
     const nsStyleDisplay& aDisp, dom::Element* aElement,
-    CSSPseudoElementType aPseudoType,
-    CSSTransitionCollection*& aElementTransitions,
+    PseudoStyleType aPseudoType, CSSTransitionCollection*& aElementTransitions,
     const ComputedStyle& aOldStyle, const ComputedStyle& aNewStyle) {
   MOZ_ASSERT(!aElementTransitions || aElementTransitions->mElement == aElement,
              "Element mismatch");
 
   // Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
   // I'll consider only the transitions from the number of items in
   // 'transition-property' on down, and later ones will override earlier
   // ones (tracked using |propertiesChecked|).
@@ -566,18 +565,17 @@ static nsTArray<Keyframe> GetTransitionK
 }
 
 static bool IsTransitionable(nsCSSPropertyID aProperty) {
   return Servo_Property_IsTransitionable(aProperty);
 }
 
 bool nsTransitionManager::ConsiderInitiatingTransition(
     nsCSSPropertyID aProperty, const nsStyleDisplay& aStyleDisplay,
-    uint32_t transitionIdx, dom::Element* aElement,
-    CSSPseudoElementType aPseudoType,
+    uint32_t transitionIdx, dom::Element* aElement, PseudoStyleType aPseudoType,
     CSSTransitionCollection*& aElementTransitions,
     const ComputedStyle& aOldStyle, const ComputedStyle& aNewStyle,
     nsCSSPropertyIDSet& aPropertiesChecked) {
   // IsShorthand itself will assert if aProperty is not a property.
   MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty), "property out of range");
   NS_ASSERTION(
       !aElementTransitions || aElementTransitions->mElement == aElement,
       "Element mismatch");
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -17,17 +17,17 @@
 #include "nsISupportsImpl.h"
 
 class nsIGlobalObject;
 class nsPresContext;
 class nsCSSPropertyIDSet;
 
 namespace mozilla {
 class ComputedStyle;
-enum class CSSPseudoElementType : uint8_t;
+enum class PseudoStyleType : uint8_t;
 struct Keyframe;
 struct StyleTransition;
 }  // namespace mozilla
 
 /*****************************************************************************
  * Per-Element data                                                          *
  *****************************************************************************/
 
@@ -291,40 +291,40 @@ class nsTransitionManager final
 
   typedef mozilla::AnimationCollection<mozilla::dom::CSSTransition>
       CSSTransitionCollection;
 
   /**
    * Update transitions for stylo.
    */
   bool UpdateTransitions(mozilla::dom::Element* aElement,
-                         mozilla::CSSPseudoElementType aPseudoType,
+                         mozilla::PseudoStyleType aPseudoType,
                          const mozilla::ComputedStyle& aOldStyle,
                          const mozilla::ComputedStyle& aNewStyle);
 
  protected:
   typedef nsTArray<RefPtr<mozilla::dom::CSSTransition>>
       OwningCSSTransitionPtrArray;
 
   // Update transitions. This will start new transitions,
   // replace existing transitions, and stop existing transitions
   // as needed. aDisp and aElement must be non-null.
   // aElementTransitions is the collection of current transitions, and it
   // could be a nullptr if we don't have any transitions.
   bool DoUpdateTransitions(const nsStyleDisplay& aDisp,
                            mozilla::dom::Element* aElement,
-                           mozilla::CSSPseudoElementType aPseudoType,
+                           mozilla::PseudoStyleType aPseudoType,
                            CSSTransitionCollection*& aElementTransitions,
                            const mozilla::ComputedStyle& aOldStyle,
                            const mozilla::ComputedStyle& aNewStyle);
 
   // Returns whether the transition actually started.
   bool ConsiderInitiatingTransition(
       nsCSSPropertyID aProperty, const nsStyleDisplay& aStyleDisplay,
       uint32_t transitionIdx, mozilla::dom::Element* aElement,
-      mozilla::CSSPseudoElementType aPseudoType,
+      mozilla::PseudoStyleType aPseudoType,
       CSSTransitionCollection*& aElementTransitions,
       const mozilla::ComputedStyle& aOldStyle,
       const mozilla::ComputedStyle& aNewStyle,
       nsCSSPropertyIDSet& aPropertiesChecked);
 };
 
 #endif /* !defined(nsTransitionManager_h_) */
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -648,34 +648,34 @@ nscoord nsTableCellFrame::GetCellBaselin
     return result + borderPadding;
   return inner->GetContentRectRelativeToSelf().YMost() + borderPadding;
 }
 
 int32_t nsTableCellFrame::GetRowSpan() {
   int32_t rowSpan = 1;
 
   // Don't look at the content's rowspan if we're a pseudo cell
-  if (!Style()->GetPseudo()) {
+  if (!Style()->IsPseudoOrAnonBox()) {
     dom::Element* elem = mContent->AsElement();
     const nsAttrValue* attr = elem->GetParsedAttr(nsGkAtoms::rowspan);
     // Note that we don't need to check the tag name, because only table cells
     // (including MathML <mtd>) and table headers parse the "rowspan" attribute
     // into an integer.
     if (attr && attr->Type() == nsAttrValue::eInteger) {
       rowSpan = attr->GetIntegerValue();
     }
   }
   return rowSpan;
 }
 
 int32_t nsTableCellFrame::GetColSpan() {
   int32_t colSpan = 1;
 
   // Don't look at the content's colspan if we're a pseudo cell
-  if (!Style()->GetPseudo()) {
+  if (!Style()->IsPseudoOrAnonBox()) {
     dom::Element* elem = mContent->AsElement();
     const nsAttrValue* attr = elem->GetParsedAttr(
         MOZ_UNLIKELY(elem->IsMathMLElement()) ? nsGkAtoms::columnspan_
                                               : nsGkAtoms::colspan);
     // Note that we don't need to check the tag name, because only table cells
     // (including MathML <mtd>) and table headers parse the "colspan" attribute
     // into an integer.
     if (attr && attr->Type() == nsAttrValue::eInteger) {
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -136,17 +136,17 @@ struct BCPropertyData {
 };
 
 ComputedStyle* nsTableFrame::GetParentComputedStyle(
     nsIFrame** aProviderFrame) const {
   // Since our parent, the table wrapper frame, returned this frame, we
   // must return whatever our parent would normally have returned.
 
   MOZ_ASSERT(GetParent(), "table constructed without table wrapper");
-  if (!mContent->GetParent() && !Style()->GetPseudo()) {
+  if (!mContent->GetParent() && !Style()->IsPseudoOrAnonBox()) {
     // We're the root.  We have no ComputedStyle parent.
     *aProviderFrame = nullptr;
     return nullptr;
   }
 
   return GetParent()->DoGetParentComputedStyle(aProviderFrame);
 }
 
@@ -636,17 +636,17 @@ nsTableCellMap* nsTableFrame::GetCellMap
 
 nsTableColGroupFrame* nsTableFrame::CreateSyntheticColGroupFrame() {
   nsIContent* colGroupContent = GetContent();
   nsPresContext* presContext = PresContext();
   nsIPresShell* shell = presContext->PresShell();
 
   RefPtr<ComputedStyle> colGroupStyle;
   colGroupStyle = shell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle(
-      nsCSSAnonBoxes::tableColGroup());
+      PseudoStyleType::tableColGroup);
   // Create a col group frame
   nsTableColGroupFrame* newFrame =
       NS_NewTableColGroupFrame(shell, colGroupStyle);
   newFrame->SetIsSynthetic();
   newFrame->Init(colGroupContent, this, nullptr);
   return newFrame;
 }
 
@@ -690,17 +690,17 @@ void nsTableFrame::AppendAnonymousColFra
   int32_t lastIndex = startIndex + aNumColsToAdd - 1;
 
   for (int32_t childX = startIndex; childX <= lastIndex; childX++) {
     // all anonymous cols that we create here use a pseudo ComputedStyle of the
     // col group
     nsIContent* iContent = aColGroupFrame->GetContent();
     RefPtr<ComputedStyle> computedStyle =
         shell->StyleSet()->ResolveNonInheritingAnonymousBoxStyle(
-            nsCSSAnonBoxes::tableCol());
+            PseudoStyleType::tableCol);
     // ASSERTION to check for bug 54454 sneaking back in...
     NS_ASSERTION(iContent, "null content in CreateAnonymousColFrames");
 
     // create the new col frame
     nsIFrame* colFrame = NS_NewTableColFrame(shell, computedStyle);
     ((nsTableColFrame*)colFrame)->SetColType(aColType);
     colFrame->Init(iContent, aColGroupFrame, nullptr);
 
@@ -7663,32 +7663,32 @@ void nsTableFrame::InvalidateTableFrame(
     aFrame->InvalidateFrameWithRect(aOrigVisualOverflow);
     aFrame->InvalidateFrame();
   }
 }
 
 void nsTableFrame::AppendDirectlyOwnedAnonBoxes(
     nsTArray<OwnedAnonBox>& aResult) {
   nsIFrame* wrapper = GetParent();
-  MOZ_ASSERT(wrapper->Style()->GetPseudo() == nsCSSAnonBoxes::tableWrapper(),
+  MOZ_ASSERT(wrapper->Style()->GetPseudoType() == PseudoStyleType::tableWrapper,
              "What happened to our parent?");
   aResult.AppendElement(
       OwnedAnonBox(wrapper, &UpdateStyleOfOwnedAnonBoxesForTableWrapper));
 }
 
 /* static */ void nsTableFrame::UpdateStyleOfOwnedAnonBoxesForTableWrapper(
     nsIFrame* aOwningFrame, nsIFrame* aWrapperFrame,
     ServoRestyleState& aRestyleState) {
   MOZ_ASSERT(
-      aWrapperFrame->Style()->GetPseudo() == nsCSSAnonBoxes::tableWrapper(),
+      aWrapperFrame->Style()->GetPseudoType() == PseudoStyleType::tableWrapper,
       "What happened to our parent?");
 
   RefPtr<ComputedStyle> newStyle =
       aRestyleState.StyleSet().ResolveInheritingAnonymousBoxStyle(
-          nsCSSAnonBoxes::tableWrapper(), aOwningFrame->Style());
+          PseudoStyleType::tableWrapper, aOwningFrame->Style());
 
   // Figure out whether we have an actual change.  It's important that we do
   // this, even though all the wrapper's changes are due to properties it
   // inherits from us, because it's possible that no one ever asked us for those
   // style structs and hence changes to them aren't reflected in
   // the handled changes at all.
   //
   // Also note that extensions can add/remove stylesheets that change the styles
--- a/layout/xul/tree/nsTreeStyleCache.cpp
+++ b/layout/xul/tree/nsTreeStyleCache.cpp
@@ -74,16 +74,25 @@ ComputedStyle* nsTreeStyleCache::GetComp
         aPresContext->StyleSet()->ResolveXULTreePseudoStyle(
             aContent->AsElement(), aPseudoElement, aStyle, aInputWord);
 
     // Normally we rely on nsFrame::Init / RestyleManager to call this, but
     // these are weird and don't use a frame, yet ::-moz-tree-twisty definitely
     // pokes at list-style-image.
     newResult->StartImageLoads(*aPresContext->Document());
 
+    // Even though xul-tree pseudos are defined in nsCSSAnonBoxList, nothing has
+    // ever treated them as an anon box, and they don't ever get boxes anyway.
+    //
+    // This is really weird, and probably nothing really relies on the result of
+    // these assert, but it's here just to avoid changing them accidentally.
+    MOZ_ASSERT(newResult->GetPseudoType() == PseudoStyleType::XULTree);
+    MOZ_ASSERT(!newResult->IsAnonBox());
+    MOZ_ASSERT(!newResult->IsPseudoElement());
+
     // Put the ComputedStyle in our table, transferring the owning reference to
     // the table.
     if (!mCache) {
       mCache = new ComputedStyleCache();
     }
     result = newResult.get();
     mCache->Put(currState, newResult.forget());
   }
--- a/servo/components/style/gecko/pseudo_element.rs
+++ b/servo/components/style/gecko/pseudo_element.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 //! Gecko's definition of a pseudo-element.
 //!
 //! Note that a few autogenerated bits of this live in
 //! `pseudo_element_definition.mako.rs`. If you touch that file, you probably
 //! need to update the checked-in files for Servo.
 
-use crate::gecko_bindings::structs::{self, CSSPseudoElementType};
+use crate::gecko_bindings::structs::{self, PseudoStyleType};
 use crate::properties::longhands::display::computed_value::T as Display;
 use crate::properties::{ComputedValues, PropertyFlags};
 use crate::selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl};
 use crate::str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase};
 use crate::string_cache::Atom;
 use crate::values::serialize_atom_identifier;
 use cssparser::ToCss;
 use std::fmt;
--- a/servo/components/style/gecko/pseudo_element_definition.mako.rs
+++ b/servo/components/style/gecko/pseudo_element_definition.mako.rs
@@ -43,27 +43,16 @@ pub const EAGER_PSEUDOS: [PseudoElement;
     % endfor
 ];
 
 <%def name="pseudo_element_variant(pseudo, tree_arg='..')">\
 PseudoElement::${pseudo.capitalized_pseudo()}${"({})".format(tree_arg) if pseudo.is_tree_pseudo_element() else ""}\
 </%def>
 
 impl PseudoElement {
-    /// Get the pseudo-element as an atom.
-    #[inline]
-    fn atom(&self) -> Atom {
-        match *self {
-            % for pseudo in PSEUDOS:
-                ${pseudo_element_variant(pseudo)} => atom!("${pseudo.value}"),
-            % endfor
-            PseudoElement::UnknownWebkit(..) => unreachable!(),
-        }
-    }
-
     /// Returns an index of the pseudo-element.
     #[inline]
     pub fn index(&self) -> usize {
         match *self {
             % for i, pseudo in enumerate(PSEUDOS):
             ${pseudo_element_variant(pseudo)} => ${i},
             % endfor
             PseudoElement::UnknownWebkit(..) => unreachable!(),
@@ -133,105 +122,66 @@ impl PseudoElement {
                 % else:
                     structs::SERVO_CSS_PSEUDO_ELEMENT_FLAGS_${pseudo.pseudo_ident},
                 % endif
             % endfor
             PseudoElement::UnknownWebkit(..) => 0,
         }
     }
 
-    /// Construct a pseudo-element from a `CSSPseudoElementType`.
+    /// Construct a pseudo-element from a `PseudoStyleType`.
     #[inline]
-    pub fn from_pseudo_type(type_: CSSPseudoElementType) -> Option<Self> {
+    pub fn from_pseudo_type(type_: PseudoStyleType) -> Option<Self> {
         match type_ {
             % for pseudo in PSEUDOS:
-                % if not pseudo.is_anon_box():
-                    CSSPseudoElementType::${pseudo.pseudo_ident} => {
-                        Some(${pseudo_element_variant(pseudo)})
-                    },
-                % endif
+            % if not pseudo.is_tree_pseudo_element():
+                PseudoStyleType::${pseudo.pseudo_ident} => {
+                    Some(${pseudo_element_variant(pseudo)})
+                },
+            % endif
             % endfor
             _ => None,
         }
     }
 
-    /// Construct a `CSSPseudoElementType` from a pseudo-element
+    /// Construct a `PseudoStyleType` from a pseudo-element
     #[inline]
-    fn pseudo_type(&self) -> CSSPseudoElementType {
+    pub fn pseudo_type(&self) -> PseudoStyleType {
         match *self {
             % for pseudo in PSEUDOS:
-                % if not pseudo.is_anon_box():
-                    PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::${pseudo.pseudo_ident},
-                % elif pseudo.is_tree_pseudo_element():
-                    PseudoElement::${pseudo.capitalized_pseudo()}(..) => CSSPseudoElementType::XULTree,
-                % elif pseudo.is_inheriting_anon_box():
-                    PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::InheritingAnonBox,
-                % else:
-                    PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox,
-                % endif
+            % if pseudo.is_tree_pseudo_element():
+                PseudoElement::${pseudo.capitalized_pseudo()}(..) => PseudoStyleType::XULTree,
+            % else:
+                PseudoElement::${pseudo.capitalized_pseudo()} => PseudoStyleType::${pseudo.pseudo_ident},
+            % endif
             % endfor
             PseudoElement::UnknownWebkit(..) => unreachable!(),
         }
     }
 
-    /// Get a PseudoInfo for a pseudo
-    pub fn pseudo_info(&self) -> (*mut structs::nsAtom, CSSPseudoElementType) {
-        (self.atom().as_ptr(), self.pseudo_type())
-    }
-
     /// Get the argument list of a tree pseudo-element.
     #[inline]
     pub fn tree_pseudo_args(&self) -> Option<<&[Atom]> {
         match *self {
             % for pseudo in TREE_PSEUDOS:
             PseudoElement::${pseudo.capitalized_pseudo()}(ref args) => Some(args),
             % endfor
             _ => None,
         }
     }
 
-    /// Construct a pseudo-element from an `Atom`.
-    #[inline]
-    pub fn from_atom(atom: &Atom) -> Option<Self> {
-        % for pseudo in PSEUDOS:
-            % if pseudo.is_tree_pseudo_element():
-                // We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
-            % else:
-                if atom == &atom!("${pseudo.value}") {
-                    return Some(${pseudo_element_variant(pseudo)});
-                }
-            % endif
-        % endfor
-        None
-    }
-
-    /// Construct a pseudo-element from an anonymous box `Atom`.
-    #[inline]
-    pub fn from_anon_box_atom(atom: &Atom) -> Option<Self> {
-        % for pseudo in PSEUDOS:
-            % if pseudo.is_tree_pseudo_element():
-                // We cannot generate ${pseudo_element_variant(pseudo)} from just an atom.
-            % elif pseudo.is_anon_box():
-                if atom == &atom!("${pseudo.value}") {
-                    return Some(${pseudo_element_variant(pseudo)});
-                }
-            % endif
-        % endfor
-        None
-    }
-
     /// Construct a tree pseudo-element from atom and args.
     #[inline]
     pub fn from_tree_pseudo_atom(atom: &Atom, args: Box<[Atom]>) -> Option<Self> {
         % for pseudo in PSEUDOS:
-            % if pseudo.is_tree_pseudo_element():
-                if atom == &atom!("${pseudo.value}") {
-                    return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
-                }
-            % endif
+        % if pseudo.is_tree_pseudo_element():
+            if atom == &atom!("${pseudo.value}") {
+                return Some(PseudoElement::${pseudo.capitalized_pseudo()}(args.into()));
+            }
+        % endif
         % endfor
         None
     }
 
     /// Constructs a pseudo-element from a string of text.
     ///
     /// Returns `None` if the pseudo-element is not recognised.
     #[inline]
--- a/servo/components/style/gecko/regen_atoms.py
+++ b/servo/components/style/gecko/regen_atoms.py
@@ -36,37 +36,44 @@ class Atom:
         self.value = value
         self.hash = hash
         # The Gecko type: "nsStaticAtom", "nsCSSPseudoElementStaticAtom", or
         # "nsAnonBoxPseudoStaticAtom".
         self.ty = ty
         # The type of atom: "Atom", "PseudoElement", "NonInheritingAnonBox",
         # or "InheritingAnonBox".
         self.atom_type = atom_type
-        if self.is_pseudo() or self.is_anon_box():
+
+        if self.is_pseudo_element() or self.is_anon_box() or self.is_tree_pseudo_element():
             self.pseudo_ident = (ident.split("_", 1))[1]
+
         if self.is_anon_box():
             assert self.is_inheriting_anon_box() or self.is_non_inheriting_anon_box()
 
     def type(self):
         return self.ty
 
     def capitalized_pseudo(self):
         return self.pseudo_ident[0].upper() + self.pseudo_ident[1:]
 
-    def is_pseudo(self):
+    def is_pseudo_element(self):
         return self.atom_type == "PseudoElementAtom"
 
     def is_anon_box(self):
+        if self.is_tree_pseudo_element():
+            return False
         return self.is_non_inheriting_anon_box() or self.is_inheriting_anon_box()
 
     def is_non_inheriting_anon_box(self):
+        assert not self.is_tree_pseudo_element()
         return self.atom_type == "NonInheritingAnonBoxAtom"
 
     def is_inheriting_anon_box(self):
+        if self.is_tree_pseudo_element():
+            return False
         return self.atom_type == "InheritingAnonBoxAtom"
 
     def is_tree_pseudo_element(self):
         return self.value.startswith(":-moz-tree-")
 
 
 def collect_atoms(objdir):
     atoms = []
--- a/servo/components/style/properties/cascade.rs
+++ b/servo/components/style/properties/cascade.rs
@@ -231,17 +231,17 @@ where
     );
     #[cfg(feature = "gecko")]
     debug_assert!(
         parent_style.is_none() ||
             ::std::ptr::eq(
                 parent_style.unwrap(),
                 parent_style_ignoring_first_line.unwrap()
             ) ||
-            parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine)
+            parent_style.unwrap().is_first_line_style()
     );
 
     let inherited_style = parent_style.unwrap_or(device.default_computed_values());
 
     let mut declarations = SmallVec::<[(&_, CascadeLevel); 32]>::new();
     let custom_properties = {
         let mut builder = CustomPropertiesBuilder::new(
             inherited_style.custom_properties(),
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -33,17 +33,17 @@ use crate::gecko_bindings::bindings::Gec
 use crate::gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom;
 use crate::gecko_bindings::bindings::Gecko_SetListStyleImageNone;
 use crate::gecko_bindings::bindings::Gecko_SetListStyleImageImageValue;
 use crate::gecko_bindings::bindings::Gecko_SetNullImageValue;
 use crate::gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
 use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed;
 use crate::gecko_bindings::structs;
 use crate::gecko_bindings::structs::nsCSSPropertyID;
-use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType;
+use crate::gecko_bindings::structs::mozilla::PseudoStyleType;
 use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
 use crate::gecko_bindings::sugar::refptr::RefPtr;
 use crate::gecko::values::convert_nscolor_to_rgba;
 use crate::gecko::values::convert_rgba_to_nscolor;
 use crate::gecko::values::GeckoStyleCoordConvertible;
 use crate::gecko::values::round_border_to_device_pixels;
 use crate::logical_geometry::WritingMode;
 use crate::media_queries::Device;
@@ -110,36 +110,27 @@ impl ComputedValues {
             /* rules = */ None,
             /* visited_style = */ None,
             % for style_struct in data.style_structs:
             style_structs::${style_struct.name}::default(pres_context),
             % endfor
         ).to_outer(None)
     }
 
+    #[inline]
     pub fn pseudo(&self) -> Option<PseudoElement> {
-        let atom = (self.0).mPseudoTag.mRawPtr;
-        if atom.is_null() {
+        if self.0.mPseudoType == PseudoStyleType::NotPseudo {
             return None;
         }
-
-        let atom = unsafe { Atom::from_raw(atom) };
-        PseudoElement::from_atom(&atom)
+        PseudoElement::from_pseudo_type(self.0.mPseudoType)
     }
 
     #[inline]
-    fn get_pseudo_type(&self) -> CSSPseudoElementType {
-        self.0.mPseudoType
-    }
-
-    #[inline]
-    pub fn is_anon_box(&self) -> bool {
-        let our_type = self.get_pseudo_type();
-        return our_type == CSSPseudoElementType::InheritingAnonBox ||
-               our_type == CSSPseudoElementType::NonInheritingAnonBox;
+    pub fn is_first_line_style(&self) -> bool {
+        self.pseudo() == Some(PseudoElement::FirstLine)
     }
 
     /// Returns true if the display property is changed from 'none' to others.
     pub fn is_display_property_changed_from_none(
         &self,
         old_values: Option<<&ComputedValues>
     ) -> bool {
         use crate::properties::longhands::display::computed_value::T as Display;
@@ -208,27 +199,26 @@ impl ComputedValuesInner {
             % endfor
         }
     }
 
     fn to_outer(
         self,
         pseudo: Option<<&PseudoElement>,
     ) -> Arc<ComputedValues> {
-        let (pseudo_tag, pseudo_ty) = match pseudo {
-            Some(p) => p.pseudo_info(),
-            None => (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo),
+        let pseudo_ty = match pseudo {
+            Some(p) => p.pseudo_type(),
+            None => structs::PseudoStyleType::NotPseudo,
         };
         let arc = unsafe {
             let arc: Arc<ComputedValues> = Arc::new(uninitialized());
             bindings::Gecko_ComputedStyle_Init(
                 &arc.0 as *const _ as *mut _,
                 &self,
                 pseudo_ty,
-                pseudo_tag
             );
             // We're simulating a move by having C++ do a memcpy and then forgetting
             // it on this end.
             forget(self);
             arc
         };
         arc
     }
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -3353,17 +3353,17 @@ impl<'a> StyleBuilder<'a> {
         rules: Option<StrongRuleNode>,
         custom_properties: Option<Arc<crate::custom_properties::CustomPropertiesMap>>,
     ) -> Self {
         debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
         #[cfg(feature = "gecko")]
         debug_assert!(parent_style.is_none() ||
                       std::ptr::eq(parent_style.unwrap(),
                                      parent_style_ignoring_first_line.unwrap()) ||
-                      parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine));
+                      parent_style.unwrap().is_first_line_style());
         let reset_style = device.default_computed_values();
         let inherited_style = parent_style.unwrap_or(reset_style);
         let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style);
 
         let flags = inherited_style.flags.inherited();
 
         StyleBuilder {
             device,
@@ -3397,17 +3397,17 @@ impl<'a> StyleBuilder<'a> {
         device: &'a Device,
         style_to_derive_from: &'a ComputedValues,
         parent_style: Option<<&'a ComputedValues>,
     ) -> Self {
         let reset_style = device.default_computed_values();
         let inherited_style = parent_style.unwrap_or(reset_style);
         #[cfg(feature = "gecko")]
         debug_assert!(parent_style.is_none() ||
-                      parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine));
+                      !parent_style.unwrap().is_first_line_style());
         StyleBuilder {
             device,
             inherited_style,
             // None of our callers pass in ::first-line parent styles.
             inherited_style_ignoring_first_line: inherited_style,
             reset_style,
             pseudo: None,
             modified_reset: false,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -131,17 +131,17 @@ use style::gecko_bindings::structs::nsCS
 use style::gecko_bindings::structs::nsChangeHint;
 use style::gecko_bindings::structs::nsCompatibility;
 use style::gecko_bindings::structs::nsRestyleHint;
 use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
 use style::gecko_bindings::structs::nsTArray;
 use style::gecko_bindings::structs::nsTimingFunction;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::structs::AtomArray;
-use style::gecko_bindings::structs::CSSPseudoElementType;
+use style::gecko_bindings::structs::PseudoStyleType;
 use style::gecko_bindings::structs::CallerType;
 use style::gecko_bindings::structs::CompositeOperation;
 use style::gecko_bindings::structs::ComputedStyleStrong;
 use style::gecko_bindings::structs::DeclarationBlockMutationClosure;
 use style::gecko_bindings::structs::IterationCompositeOperation;
 use style::gecko_bindings::structs::Loader;
 use style::gecko_bindings::structs::LoaderReusableStyleSheets;
 use style::gecko_bindings::structs::MallocSizeOf as GeckoMallocSizeOf;
@@ -2126,17 +2126,17 @@ pub extern "C" fn Servo_StyleRule_GetSpe
     })
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(
     rule: RawServoStyleRuleBorrowed,
     element: RawGeckoElementBorrowed,
     index: u32,
-    pseudo_type: CSSPseudoElementType,
+    pseudo_type: PseudoStyleType,
 ) -> bool {
     read_locked_arc(rule, |rule: &StyleRule| {
         let index = index as usize;
         if index >= rule.selectors.0.len() {
             return false;
         }
 
         let selector = &rule.selectors.0[index];
@@ -3123,25 +3123,25 @@ counter_style_descriptors! {
         eCSSCounterDesc_UNKNOWN,
         eCSSCounterDesc_COUNT,
     ]
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn Servo_ComputedValues_GetForAnonymousBox(
     parent_style_or_null: ComputedStyleBorrowedOrNull,
-    pseudo_tag: *mut nsAtom,
+    pseudo: PseudoStyleType,
     raw_data: RawServoStyleSetBorrowed,
 ) -> ComputedStyleStrong {
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let guards = StylesheetGuards::same(&guard);
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
-    let atom = Atom::from_raw(pseudo_tag);
-    let pseudo = PseudoElement::from_anon_box_atom(&atom).expect("Not an anon box pseudo?");
+    let pseudo = PseudoElement::from_pseudo_type(pseudo).unwrap();
+    debug_assert!(pseudo.is_anon_box());
 
     let metrics = get_metrics_provider_for_product();
 
     // If the pseudo element is PageContent, we should append the precomputed
     // pseudo element declerations with specified page rules.
     let page_decls = match pseudo {
         PseudoElement::PageContent => {
             let mut declarations = vec![];
@@ -3177,17 +3177,17 @@ pub unsafe extern "C" fn Servo_ComputedV
             rule_node,
         )
         .into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ResolvePseudoStyle(
     element: RawGeckoElementBorrowed,
-    pseudo_type: CSSPseudoElementType,
+    pseudo_type: PseudoStyleType,
     is_probe: bool,
     inherited_style: ComputedStyleBorrowedOrNull,
     raw_data: RawServoStyleSetBorrowed,
 ) -> ComputedStyleStrong {
     let element = GeckoElement(element);
     let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
 
     debug!(
@@ -3326,17 +3326,17 @@ pub extern "C" fn Servo_SetExplicitStyle
     let mut data = unsafe { element.ensure_data() };
     data.styles.primary = Some(unsafe { ArcBorrow::from_ref(style) }.clone_arc());
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_HasAuthorSpecifiedRules(
     style: ComputedStyleBorrowed,
     element: RawGeckoElementBorrowed,
-    pseudo_type: CSSPseudoElementType,
+    pseudo_type: PseudoStyleType,
     rule_type_mask: u32,
     author_colors_allowed: bool,
 ) -> bool {
     let element = GeckoElement(element);
     let pseudo = PseudoElement::from_pseudo_type(pseudo_type);
 
     let guard = (*GLOBAL_STYLE_DATA).shared_lock.read();
     let guards = StylesheetGuards::same(&guard);
@@ -3449,25 +3449,25 @@ fn get_pseudo_style(
         )
         .build()
     }))
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn Servo_ComputedValues_Inherit(
     raw_data: RawServoStyleSetBorrowed,
-    pseudo_tag: *mut nsAtom,
+    pseudo: PseudoStyleType,
     parent_style_context: ComputedStyleBorrowedOrNull,
     target: structs::InheritTarget,
 ) -> ComputedStyleStrong {
     let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
 
     let for_text = target == structs::InheritTarget::Text;
-    let atom = Atom::from_raw(pseudo_tag);
-    let pseudo = PseudoElement::from_anon_box_atom(&atom).expect("Not an anon-box? Gah!");
+    let pseudo = PseudoElement::from_pseudo_type(pseudo).unwrap();
+    debug_assert!(pseudo.is_anon_box());
 
     let mut style =
         StyleBuilder::for_inheritance(data.stylist.device(), parent_style_context, Some(&pseudo));
 
     if for_text {
         StyleAdjuster::new(&mut style).adjust_for_text();
     }
 
@@ -4835,17 +4835,17 @@ pub extern "C" fn Servo_ResolveStyle(
         data
     );
     data.styles.primary().clone().into()
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ResolveStyleLazily(
     element: RawGeckoElementBorrowed,
-    pseudo_type: CSSPseudoElementType,
+    pseudo_type: PseudoStyleType,
     rule_inclusion: StyleRuleInclusion,
     snapshots: *const ServoElementSnapshotTable,
     raw_data: RawServoStyleSetBorrowed,
 ) -> ComputedStyleStrong {
     debug_assert!(!snapshots.is_null());
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
     let element = GeckoElement(element);
--- a/servo/ports/geckolib/tests/size_of.rs
+++ b/servo/ports/geckolib/tests/size_of.rs
@@ -28,17 +28,17 @@ size_of_test!(
 size_of_test!(size_of_pseudo_class, selector_parser::NonTSPseudoClass, 16);
 
 // The size of this is critical to performance on the bloom-basic microbenchmark.
 // When iterating over a large Rule array, we want to be able to fast-reject
 // selectors (with the inline hashes) with as few cache misses as possible.
 size_of_test!(test_size_of_rule, style::stylist::Rule, 32);
 
 // Large pages generate tens of thousands of ComputedValues.
-size_of_test!(test_size_of_cv, ComputedValues, 240);
+size_of_test!(test_size_of_cv, ComputedValues, 232);
 
 size_of_test!(test_size_of_option_arc_cv, Option<Arc<ComputedValues>>, 8);
 size_of_test!(test_size_of_option_rule_node, Option<StrongRuleNode>, 8);
 
 size_of_test!(test_size_of_element_styles, ElementStyles, 16);
 size_of_test!(test_size_of_element_data, ElementData, 24);
 
 size_of_test!(
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -2058,17 +2058,17 @@ STATIC_ATOMS = [
     Atom("transitionsOfAfterProperty", "TransitionsOfAfterProperty"),  # FrameTransitions*
     Atom("genConInitializerProperty", "QuoteNodeProperty"),
     Atom("labelMouseDownPtProperty", "LabelMouseDownPtProperty"),
     Atom("lockedStyleStates", "lockedStyleStates"),
     Atom("apzCallbackTransform", "apzCallbackTransform"),
     Atom("restylableAnonymousNode", "restylableAnonymousNode"),  # bool
     Atom("docLevelNativeAnonymousContent", "docLevelNativeAnonymousContent"),  # bool
     Atom("paintRequestTime", "PaintRequestTime"),
-    Atom("pseudoProperty", "PseudoProperty"),  # CSSPseudoElementType
+    Atom("pseudoProperty", "PseudoProperty"),  # PseudoStyleType
     Atom("manualNACProperty", "ManualNACProperty"),  # ManualNAC*
 
     # Languages for lang-specific transforms
     Atom("Japanese", "ja"),
     Atom("Chinese", "zh-CN"),
     Atom("Taiwanese", "zh-TW"),
     Atom("HongKongChinese", "zh-HK"),
     Atom("Unicode", "x-unicode"),