PseudoStyleType.h (6446B)
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/. */ 6 7 #ifndef mozilla_PseudoStyleType_h 8 #define mozilla_PseudoStyleType_h 9 10 #include <cstddef> 11 #include <cstdint> 12 #include <iosfwd> 13 14 #include "PLDHashTable.h" 15 #include "mozilla/RefPtr.h" 16 #include "nsAtom.h" 17 18 namespace mozilla { 19 namespace dom { 20 class Element; 21 } // namespace dom 22 23 // The kind of pseudo-style that we have. This can be: 24 // 25 // * CSS pseudo-elements (see nsCSSPseudoElements.h). 26 // * Anonymous boxes (see nsCSSAnonBoxes.h). 27 // * XUL tree pseudo-element stuff. 28 // 29 // This roughly corresponds to the `PseudoElement` enum in Rust code. 30 enum class PseudoStyleType : uint8_t { 31 // If CSS pseudo-elements stop being first here, change GetPseudoType. 32 #define CSS_PSEUDO_ELEMENT(_name, _value, _flags) _name, 33 #include "nsCSSPseudoElementList.h" 34 #undef CSS_PSEUDO_ELEMENT 35 CSSPseudoElementsEnd, 36 AnonBoxesStart = CSSPseudoElementsEnd, 37 InheritingAnonBoxesStart = CSSPseudoElementsEnd, 38 39 // Dummy variant so the next variant also has the same discriminant as 40 // AnonBoxesStart. 41 __reset_1 = AnonBoxesStart - 1, 42 43 #define CSS_ANON_BOX(_name, _str) _name, 44 #define CSS_NON_INHERITING_ANON_BOX(_name, _str) 45 #define CSS_WRAPPER_ANON_BOX(_name, _str) 46 #include "nsCSSAnonBoxList.h" 47 #undef CSS_ANON_BOX 48 #undef CSS_WRAPPER_ANON_BOX 49 #undef CSS_NON_INHERITING_ANON_BOX 50 51 // Wrapper anon boxes are inheriting anon boxes. 52 WrapperAnonBoxesStart, 53 54 // Dummy variant so the next variant also has the same discriminant as 55 // WrapperAnonBoxesStart. 56 __reset_2 = WrapperAnonBoxesStart - 1, 57 58 #define CSS_ANON_BOX(_name, _str) 59 #define CSS_NON_INHERITING_ANON_BOX(_name, _str) 60 #define CSS_WRAPPER_ANON_BOX(_name, _str) _name, 61 #include "nsCSSAnonBoxList.h" 62 #undef CSS_ANON_BOX 63 #undef CSS_WRAPPER_ANON_BOX 64 #undef CSS_NON_INHERITING_ANON_BOX 65 66 WrapperAnonBoxesEnd, 67 InheritingAnonBoxesEnd = WrapperAnonBoxesEnd, 68 NonInheritingAnonBoxesStart = WrapperAnonBoxesEnd, 69 70 __reset_3 = NonInheritingAnonBoxesStart - 1, 71 72 #define CSS_ANON_BOX(_name, _str) 73 #define CSS_NON_INHERITING_ANON_BOX(_name, _str) _name, 74 #include "nsCSSAnonBoxList.h" 75 #undef CSS_ANON_BOX 76 #undef CSS_NON_INHERITING_ANON_BOX 77 78 NonInheritingAnonBoxesEnd, 79 AnonBoxesEnd = NonInheritingAnonBoxesEnd, 80 81 XULTree = AnonBoxesEnd, 82 NotPseudo, 83 MAX 84 }; 85 86 std::ostream& operator<<(std::ostream&, PseudoStyleType); 87 88 class PseudoStyle final { 89 public: 90 using Type = PseudoStyleType; 91 92 // This must match EAGER_PSEUDO_COUNT in Rust code. 93 static const size_t kEagerPseudoCount = 4; 94 95 static bool IsPseudoElement(Type aType) { 96 return aType < Type::CSSPseudoElementsEnd; 97 } 98 99 static bool IsAnonBox(Type aType) { 100 return aType >= Type::AnonBoxesStart && aType < Type::AnonBoxesEnd; 101 } 102 103 static bool IsInheritingAnonBox(Type aType) { 104 return aType >= Type::InheritingAnonBoxesStart && 105 aType < Type::InheritingAnonBoxesEnd; 106 } 107 108 static bool IsNonInheritingAnonBox(Type aType) { 109 return aType >= Type::NonInheritingAnonBoxesStart && 110 aType < Type::NonInheritingAnonBoxesEnd; 111 } 112 113 static bool IsWrapperAnonBox(Type aType) { 114 return aType >= Type::WrapperAnonBoxesStart && 115 aType < Type::WrapperAnonBoxesEnd; 116 } 117 118 static bool IsNamedViewTransitionPseudoElement(Type aType) { 119 return aType == Type::viewTransitionGroup || 120 aType == Type::viewTransitionImagePair || 121 aType == Type::viewTransitionOld || aType == Type::viewTransitionNew; 122 } 123 124 static bool IsViewTransitionPseudoElement(Type aType) { 125 return aType == Type::viewTransition || 126 IsNamedViewTransitionPseudoElement(aType); 127 } 128 129 static bool IsElementBackedPseudo(Type aType) { 130 return aType == Type::detailsContent || 131 IsNamedViewTransitionPseudoElement(aType); 132 } 133 }; 134 135 /* 136 * The pseudo style request is used to get the pseudo style of an element. This 137 * include a pseudo style type and an identifier which is used for functional 138 * pseudo style. 139 */ 140 struct PseudoStyleRequest { 141 PseudoStyleRequest() = default; 142 PseudoStyleRequest(PseudoStyleRequest&&) = default; 143 PseudoStyleRequest(const PseudoStyleRequest&) = default; 144 PseudoStyleRequest& operator=(PseudoStyleRequest&&) = default; 145 PseudoStyleRequest& operator=(const PseudoStyleRequest&) = default; 146 147 explicit PseudoStyleRequest(PseudoStyleType aType) : mType(aType) {} 148 PseudoStyleRequest(PseudoStyleType aType, nsAtom* aIdentifier) 149 : mType(aType), mIdentifier(aIdentifier) {} 150 151 bool operator==(const PseudoStyleRequest&) const = default; 152 153 bool IsNotPseudo() const { return mType == PseudoStyleType::NotPseudo; } 154 bool IsPseudoElementOrNotPseudo() const { 155 return IsNotPseudo() || PseudoStyle::IsPseudoElement(mType); 156 } 157 bool IsViewTransition() const { 158 return PseudoStyle::IsViewTransitionPseudoElement(mType); 159 } 160 161 static PseudoStyleRequest NotPseudo() { return PseudoStyleRequest(); } 162 static PseudoStyleRequest Before() { 163 return PseudoStyleRequest(PseudoStyleType::before); 164 } 165 static PseudoStyleRequest After() { 166 return PseudoStyleRequest(PseudoStyleType::after); 167 } 168 static PseudoStyleRequest Marker() { 169 return PseudoStyleRequest(PseudoStyleType::marker); 170 } 171 static PseudoStyleRequest Backdrop() { 172 return PseudoStyleRequest(PseudoStyleType::backdrop); 173 } 174 175 PseudoStyleType mType = PseudoStyleType::NotPseudo; 176 RefPtr<nsAtom> mIdentifier; 177 }; 178 179 class PseudoStyleRequestHashKey : public PLDHashEntryHdr { 180 public: 181 using KeyType = PseudoStyleRequest; 182 using KeyTypePointer = const PseudoStyleRequest*; 183 184 explicit PseudoStyleRequestHashKey(KeyTypePointer aKey) : mRequest(*aKey) {} 185 PseudoStyleRequestHashKey(PseudoStyleRequestHashKey&& aOther) = default; 186 ~PseudoStyleRequestHashKey() = default; 187 188 KeyType GetKey() const { return mRequest; } 189 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mRequest; } 190 191 static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; } 192 static PLDHashNumber HashKey(KeyTypePointer aKey) { 193 return mozilla::HashGeneric( 194 static_cast<uint8_t>(aKey->mType), 195 aKey->mIdentifier ? aKey->mIdentifier->hash() : 0); 196 } 197 enum { ALLOW_MEMMOVE = true }; 198 199 private: 200 PseudoStyleRequest mRequest; 201 }; 202 203 } // namespace mozilla 204 205 #endif