Bug 1769547 - Do not MOZ_CRASH() on missing process r=nika
[gecko.git] / accessible / base / AccAttributes.h
blob2d651ff0bd564261be3efd4c49c485b61e9ec604
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef AccAttributes_h_
7 #define AccAttributes_h_
9 #include "mozilla/ServoStyleConsts.h"
10 #include "mozilla/a11y/AccGroupInfo.h"
11 #include "mozilla/Variant.h"
12 #include "nsTHashMap.h"
13 #include "nsAtom.h"
14 #include "nsStringFwd.h"
15 #include "mozilla/gfx/Matrix.h"
17 class nsVariant;
19 namespace IPC {
20 template <typename T>
21 struct ParamTraits;
22 } // namespace IPC
24 namespace mozilla {
26 namespace dom {
27 class Element;
30 namespace a11y {
32 struct FontSize {
33 int32_t mValue;
35 bool operator==(const FontSize& aOther) const {
36 return mValue == aOther.mValue;
39 bool operator!=(const FontSize& aOther) const {
40 return mValue != aOther.mValue;
44 struct Color {
45 nscolor mValue;
47 bool operator==(const Color& aOther) const { return mValue == aOther.mValue; }
49 bool operator!=(const Color& aOther) const { return mValue != aOther.mValue; }
52 // A special type. If an entry has a value of this type, it instructs the
53 // target instance of an Update to remove the entry with the same key value.
54 struct DeleteEntry {
55 DeleteEntry() : mValue(true) {}
56 bool mValue;
58 bool operator==(const DeleteEntry& aOther) const { return true; }
60 bool operator!=(const DeleteEntry& aOther) const { return false; }
63 class AccAttributes {
64 // Warning! An AccAttributes can contain another AccAttributes. This is
65 // intended for object and text attributes. However, the nested
66 // AccAttributes should never itself contain another AccAttributes, nor
67 // should it create a cycle. We don't do cycle collection here for
68 // performance reasons, so violating this rule will cause leaks!
69 using AttrValueType =
70 Variant<bool, float, double, int32_t, RefPtr<nsAtom>, nsTArray<int32_t>,
71 CSSCoord, FontSize, Color, DeleteEntry, UniquePtr<nsString>,
72 RefPtr<AccAttributes>, uint64_t, UniquePtr<AccGroupInfo>,
73 UniquePtr<gfx::Matrix4x4>, nsTArray<uint64_t>>;
74 static_assert(sizeof(AttrValueType) <= 16);
75 using AtomVariantMap = nsTHashMap<nsRefPtrHashKey<nsAtom>, AttrValueType>;
77 protected:
78 ~AccAttributes() = default;
80 public:
81 AccAttributes() = default;
82 AccAttributes(AccAttributes&&) = delete;
83 AccAttributes& operator=(AccAttributes&&) = delete;
84 AccAttributes(const AccAttributes&) = delete;
85 AccAttributes& operator=(const AccAttributes&) = delete;
87 NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::AccAttributes)
89 template <typename T, typename std::enable_if<
90 !std::is_convertible_v<T, nsString> &&
91 !std::is_convertible_v<T, AccGroupInfo*> &&
92 !std::is_convertible_v<T, gfx::Matrix4x4> &&
93 !std::is_convertible_v<T, nsAtom*>,
94 bool>::type = true>
95 void SetAttribute(nsAtom* aAttrName, T&& aAttrValue) {
96 mData.InsertOrUpdate(aAttrName, AsVariant(std::forward<T>(aAttrValue)));
99 void SetAttribute(nsAtom* aAttrName, nsString&& aAttrValue) {
100 UniquePtr<nsString> value = MakeUnique<nsString>();
101 *value = std::forward<nsString>(aAttrValue);
102 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
105 void SetAttribute(nsAtom* aAttrName, AccGroupInfo* aAttrValue) {
106 UniquePtr<AccGroupInfo> value(aAttrValue);
107 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
110 void SetAttribute(nsAtom* aAttrName, gfx::Matrix4x4&& aAttrValue) {
111 UniquePtr<gfx::Matrix4x4> value = MakeUnique<gfx::Matrix4x4>();
112 *value = std::forward<gfx::Matrix4x4>(aAttrValue);
113 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
116 void SetAttributeStringCopy(nsAtom* aAttrName, nsString aAttrValue) {
117 SetAttribute(aAttrName, std::move(aAttrValue));
120 void SetAttribute(nsAtom* aAttrName, nsAtom* aAttrValue) {
121 mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr<nsAtom>(aAttrValue)));
124 template <typename T>
125 Maybe<const T&> GetAttribute(nsAtom* aAttrName) {
126 if (auto value = mData.Lookup(aAttrName)) {
127 if constexpr (std::is_same_v<nsString, T>) {
128 if (value->is<UniquePtr<nsString>>()) {
129 const T& val = *(value->as<UniquePtr<nsString>>().get());
130 return SomeRef(val);
132 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
133 if (value->is<UniquePtr<gfx::Matrix4x4>>()) {
134 const T& val = *(value->as<UniquePtr<gfx::Matrix4x4>>());
135 return SomeRef(val);
137 } else {
138 if (value->is<T>()) {
139 const T& val = value->as<T>();
140 return SomeRef(val);
144 return Nothing();
147 template <typename T>
148 RefPtr<const T> GetAttributeRefPtr(nsAtom* aAttrName) {
149 if (auto value = mData.Lookup(aAttrName)) {
150 if (value->is<RefPtr<T>>()) {
151 RefPtr<const T> ref = value->as<RefPtr<T>>();
152 return ref;
155 return nullptr;
158 // Get stringified value
159 bool GetAttribute(nsAtom* aAttrName, nsAString& aAttrValue);
161 bool HasAttribute(nsAtom* aAttrName) { return mData.Contains(aAttrName); }
163 bool Remove(nsAtom* aAttrName) { return mData.Remove(aAttrName); }
165 uint32_t Count() const { return mData.Count(); }
167 // Update one instance with the entries in another. The supplied AccAttributes
168 // will be emptied.
169 void Update(AccAttributes* aOther);
172 * Return true if all the attributes in this instance are equal to all the
173 * attributes in another instance.
175 bool Equal(const AccAttributes* aOther) const;
178 * Copy attributes from this instance to another instance.
179 * This should only be used in very specific cases; e.g. merging two sets of
180 * cached attributes without modifying the cache. It can only copy simple
181 * value types; e.g. it can't copy array values. Attempting to copy an
182 * AccAttributes with uncopyable values will cause an assertion.
184 void CopyTo(AccAttributes* aDest) const;
186 // An entry class for our iterator.
187 class Entry {
188 public:
189 Entry(nsAtom* aAttrName, const AttrValueType* aAttrValue)
190 : mName(aAttrName), mValue(aAttrValue) {}
192 nsAtom* Name() { return mName; }
194 template <typename T>
195 Maybe<const T&> Value() {
196 if constexpr (std::is_same_v<nsString, T>) {
197 if (mValue->is<UniquePtr<nsString>>()) {
198 const T& val = *(mValue->as<UniquePtr<nsString>>().get());
199 return SomeRef(val);
201 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
202 if (mValue->is<UniquePtr<gfx::Matrix4x4>>()) {
203 const T& val = *(mValue->as<UniquePtr<gfx::Matrix4x4>>());
204 return SomeRef(val);
206 } else {
207 if (mValue->is<T>()) {
208 const T& val = mValue->as<T>();
209 return SomeRef(val);
212 return Nothing();
215 void NameAsString(nsString& aName) {
216 mName->ToString(aName);
217 if (aName.Find("aria-", false, 0, 1) == 0) {
218 // Found 'aria-'
219 aName.ReplaceLiteral(0, 5, u"");
223 void ValueAsString(nsAString& aValueString) {
224 StringFromValueAndName(mName, *mValue, aValueString);
227 private:
228 nsAtom* mName;
229 const AttrValueType* mValue;
231 friend class AccAttributes;
234 class Iterator {
235 public:
236 explicit Iterator(AtomVariantMap::iterator aIter) : mHashIterator(aIter) {}
238 Iterator() = delete;
239 Iterator(const Iterator&) = delete;
240 Iterator(Iterator&&) = delete;
241 Iterator& operator=(const Iterator&) = delete;
242 Iterator& operator=(Iterator&&) = delete;
244 bool operator!=(const Iterator& aOther) const {
245 return mHashIterator != aOther.mHashIterator;
248 Iterator& operator++() {
249 mHashIterator++;
250 return *this;
253 Entry operator*() {
254 auto& entry = *mHashIterator;
255 return Entry(entry.GetKey(), &entry.GetData());
258 private:
259 AtomVariantMap::iterator mHashIterator;
262 friend class Iterator;
264 Iterator begin() { return Iterator(mData.begin()); }
265 Iterator end() { return Iterator(mData.end()); }
267 private:
268 static void StringFromValueAndName(nsAtom* aAttrName,
269 const AttrValueType& aValue,
270 nsAString& aValueString);
272 AtomVariantMap mData;
274 friend struct IPC::ParamTraits<AccAttributes*>;
277 } // namespace a11y
278 } // namespace mozilla
280 #endif