Bug 1700051: part 48) Slightly simplify `mozInlineSpellWordUtil::FindRealWordContaini...
[gecko.git] / layout / style / nsCSSPseudoElements.cpp
blob5b67f25faa663cbdf0bc5dd734628a44da3a45e5
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* atom list for CSS pseudo-elements */
9 #include "nsCSSPseudoElements.h"
11 #include "mozilla/ArrayUtils.h"
13 #include "nsCSSAnonBoxes.h"
14 #include "nsDOMString.h"
15 #include "nsGkAtomConsts.h"
16 #include "nsStaticAtomUtils.h"
18 using namespace mozilla;
20 // Flags data for each of the pseudo-elements.
21 /* static */ const uint32_t nsCSSPseudoElements::kPseudoElementFlags[] = {
22 #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) flags_,
23 #include "nsCSSPseudoElementList.h"
24 #undef CSS_PSEUDO_ELEMENT
27 /* static */
28 nsStaticAtom* nsCSSPseudoElements::GetAtomBase() {
29 return const_cast<nsStaticAtom*>(
30 nsGkAtoms::GetAtomByIndex(kAtomIndex_PseudoElements));
33 bool nsCSSPseudoElements::IsPseudoElement(nsAtom* aAtom) {
34 return nsStaticAtomUtils::IsMember(aAtom, GetAtomBase(),
35 kAtomCount_PseudoElements);
38 /* static */
39 bool nsCSSPseudoElements::IsCSS2PseudoElement(nsAtom* aAtom) {
40 // We don't implement this using PseudoElementHasFlags because callers
41 // want to pass things that could be anon boxes.
42 MOZ_ASSERT(IsPseudoElement(aAtom), "must be pseudo element");
43 bool result = aAtom == nsCSSPseudoElements::after() ||
44 aAtom == nsCSSPseudoElements::before() ||
45 aAtom == nsCSSPseudoElements::firstLetter() ||
46 aAtom == nsCSSPseudoElements::firstLine();
47 NS_ASSERTION(
48 result == PseudoElementHasFlags(
49 GetPseudoType(aAtom, EnabledState::IgnoreEnabledState),
50 CSS_PSEUDO_ELEMENT_IS_CSS2),
51 "result doesn't match flags");
52 return result;
55 /* static */
56 PseudoStyleType nsCSSPseudoElements::GetPseudoType(nsAtom* aAtom,
57 EnabledState aEnabledState) {
58 Maybe<uint32_t> index = nsStaticAtomUtils::Lookup(aAtom, GetAtomBase(),
59 kAtomCount_PseudoElements);
60 if (index.isSome()) {
61 auto type = static_cast<Type>(*index);
62 return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
65 return Type::NotPseudo;
68 /* static */
69 nsAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) {
70 MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType), "Unexpected type");
71 size_t index = kAtomIndex_PseudoElements + static_cast<size_t>(aType);
72 return nsGkAtoms::GetAtomByIndex(index);
75 /* static */
76 already_AddRefed<nsAtom> nsCSSPseudoElements::GetPseudoAtom(
77 const nsAString& aPseudoElement) {
78 if (DOMStringIsNull(aPseudoElement) || aPseudoElement.IsEmpty() ||
79 aPseudoElement.First() != char16_t(':')) {
80 return nullptr;
83 // deal with two-colon forms of aPseudoElt
84 nsAString::const_iterator start, end;
85 aPseudoElement.BeginReading(start);
86 aPseudoElement.EndReading(end);
87 NS_ASSERTION(start != end, "aPseudoElement is not empty!");
88 ++start;
89 bool haveTwoColons = true;
90 if (start == end || *start != char16_t(':')) {
91 --start;
92 haveTwoColons = false;
94 RefPtr<nsAtom> pseudo = NS_Atomize(Substring(start, end));
95 MOZ_ASSERT(pseudo);
97 // There aren't any non-CSS2 pseudo-elements with a single ':'
98 if (!haveTwoColons &&
99 (!IsPseudoElement(pseudo) || !IsCSS2PseudoElement(pseudo))) {
100 // XXXbz I'd really rather we threw an exception or something, but
101 // the DOM spec sucks.
102 return nullptr;
105 return pseudo.forget();
108 /* static */
109 bool nsCSSPseudoElements::PseudoElementSupportsUserActionState(
110 const Type aType) {
111 return PseudoElementHasFlags(aType,
112 CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE);
115 /* static */
116 nsString nsCSSPseudoElements::PseudoTypeAsString(Type aPseudoType) {
117 switch (aPseudoType) {
118 case PseudoStyleType::before:
119 return u"::before"_ns;
120 case PseudoStyleType::after:
121 return u"::after"_ns;
122 case PseudoStyleType::marker:
123 return u"::marker"_ns;
124 default:
125 MOZ_ASSERT(aPseudoType == PseudoStyleType::NotPseudo,
126 "Unexpected pseudo type");
127 return u""_ns;
131 #ifdef DEBUG
132 /* static */
133 void nsCSSPseudoElements::AssertAtoms() {
134 nsStaticAtom* base = GetAtomBase();
135 # define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
137 RefPtr<nsAtom> atom = NS_Atomize(value_); \
138 size_t index = static_cast<size_t>(PseudoStyleType::name_); \
139 MOZ_ASSERT(atom == nsGkAtoms::PseudoElement_##name_, \
140 "Static atom for " #name_ " has incorrect value"); \
141 MOZ_ASSERT(atom == &base[index], \
142 "Static atom for " #name_ " not at expected index"); \
144 # include "nsCSSPseudoElementList.h"
145 # undef CSS_PSEUDO_ELEMENT
147 #endif