Bug 1631735 Part 1: Make nsCocoaWindow animated transitions asynchronous and atomic...
[gecko.git] / accessible / base / AccAttributes.h
blob6ee78aaaa0e7decabcf193736c5159420ee280ae
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(const AccAttributes&) = delete;
83 AccAttributes& operator=(const AccAttributes&) = delete;
85 NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::AccAttributes)
87 template <typename T>
88 void SetAttribute(nsAtom* aAttrName, T&& aAttrValue) {
89 using ValType =
90 std::remove_const_t<std::remove_reference_t<decltype(aAttrValue)>>;
91 if constexpr (std::is_convertible_v<ValType, nsString>) {
92 static_assert(std::is_rvalue_reference_v<decltype(aAttrValue)>,
93 "Please only move strings into this function. To make a "
94 "copy, use SetAttributeStringCopy.");
95 UniquePtr<nsString> value = MakeUnique<nsString>(std::move(aAttrValue));
96 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
97 } else if constexpr (std::is_same_v<ValType, gfx::Matrix4x4>) {
98 UniquePtr<gfx::Matrix4x4> value = MakeUnique<gfx::Matrix4x4>(aAttrValue);
99 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
100 } else if constexpr (std::is_same_v<ValType, AccGroupInfo*>) {
101 UniquePtr<AccGroupInfo> value(aAttrValue);
102 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
103 } else if constexpr (std::is_convertible_v<ValType, nsAtom*>) {
104 mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr<nsAtom>(aAttrValue)));
105 } else {
106 mData.InsertOrUpdate(aAttrName, AsVariant(std::forward<T>(aAttrValue)));
110 void SetAttributeStringCopy(nsAtom* aAttrName, nsString aAttrValue) {
111 SetAttribute(aAttrName, std::move(aAttrValue));
114 template <typename T>
115 Maybe<const T&> GetAttribute(nsAtom* aAttrName) const {
116 if (auto value = mData.Lookup(aAttrName)) {
117 if constexpr (std::is_same_v<nsString, T>) {
118 if (value->is<UniquePtr<nsString>>()) {
119 const T& val = *(value->as<UniquePtr<nsString>>().get());
120 return SomeRef(val);
122 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
123 if (value->is<UniquePtr<gfx::Matrix4x4>>()) {
124 const T& val = *(value->as<UniquePtr<gfx::Matrix4x4>>());
125 return SomeRef(val);
127 } else {
128 if (value->is<T>()) {
129 const T& val = value->as<T>();
130 return SomeRef(val);
134 return Nothing();
137 template <typename T>
138 RefPtr<const T> GetAttributeRefPtr(nsAtom* aAttrName) const {
139 if (auto value = mData.Lookup(aAttrName)) {
140 if (value->is<RefPtr<T>>()) {
141 RefPtr<const T> ref = value->as<RefPtr<T>>();
142 return ref;
145 return nullptr;
148 template <typename T>
149 Maybe<T&> GetMutableAttribute(nsAtom* aAttrName) const {
150 static_assert(std::is_same_v<nsTArray<int32_t>, T> ||
151 std::is_same_v<nsTArray<uint64_t>, T>,
152 "Only arrays should be mutable attributes");
153 if (auto value = mData.Lookup(aAttrName)) {
154 if (value->is<T>()) {
155 T& val = value->as<T>();
156 return SomeRef(val);
159 return Nothing();
162 // Get stringified value
163 bool GetAttribute(nsAtom* aAttrName, nsAString& aAttrValue) const;
165 bool HasAttribute(nsAtom* aAttrName) const {
166 return mData.Contains(aAttrName);
169 bool Remove(nsAtom* aAttrName) { return mData.Remove(aAttrName); }
171 uint32_t Count() const { return mData.Count(); }
173 // Update one instance with the entries in another. The supplied AccAttributes
174 // will be emptied.
175 void Update(AccAttributes* aOther);
178 * Return true if all the attributes in this instance are equal to all the
179 * attributes in another instance.
181 bool Equal(const AccAttributes* aOther) const;
184 * Copy attributes from this instance to another instance.
185 * This should only be used in very specific cases; e.g. merging two sets of
186 * cached attributes without modifying the cache. It can only copy simple
187 * value types; e.g. it can't copy array values. Attempting to copy an
188 * AccAttributes with uncopyable values will cause an assertion.
190 void CopyTo(AccAttributes* aDest) const;
192 // An entry class for our iterator.
193 class Entry {
194 public:
195 Entry(nsAtom* aAttrName, const AttrValueType* aAttrValue)
196 : mName(aAttrName), mValue(aAttrValue) {}
198 nsAtom* Name() const { return mName; }
200 template <typename T>
201 Maybe<const T&> Value() const {
202 if constexpr (std::is_same_v<nsString, T>) {
203 if (mValue->is<UniquePtr<nsString>>()) {
204 const T& val = *(mValue->as<UniquePtr<nsString>>().get());
205 return SomeRef(val);
207 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
208 if (mValue->is<UniquePtr<gfx::Matrix4x4>>()) {
209 const T& val = *(mValue->as<UniquePtr<gfx::Matrix4x4>>());
210 return SomeRef(val);
212 } else {
213 if (mValue->is<T>()) {
214 const T& val = mValue->as<T>();
215 return SomeRef(val);
218 return Nothing();
221 void NameAsString(nsString& aName) const {
222 mName->ToString(aName);
223 if (StringBeginsWith(aName, u"aria-"_ns)) {
224 // Found 'aria-'
225 aName.ReplaceLiteral(0, 5, u"");
229 void ValueAsString(nsAString& aValueString) const {
230 StringFromValueAndName(mName, *mValue, aValueString);
233 // Size of the pair in the hash table.
234 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf);
236 private:
237 nsAtom* mName;
238 const AttrValueType* mValue;
240 friend class AccAttributes;
243 class Iterator {
244 public:
245 explicit Iterator(AtomVariantMap::const_iterator aIter)
246 : mHashIterator(aIter) {}
248 Iterator() = delete;
249 Iterator(const Iterator&) = delete;
250 Iterator& operator=(const Iterator&) = delete;
252 bool operator!=(const Iterator& aOther) const {
253 return mHashIterator != aOther.mHashIterator;
256 Iterator& operator++() {
257 mHashIterator++;
258 return *this;
261 Entry operator*() const {
262 auto& entry = *mHashIterator;
263 return Entry(entry.GetKey(), &entry.GetData());
266 private:
267 AtomVariantMap::const_iterator mHashIterator;
270 friend class Iterator;
272 Iterator begin() const { return Iterator(mData.begin()); }
273 Iterator end() const { return Iterator(mData.end()); }
275 #ifdef A11Y_LOG
276 static void DebugPrint(const char* aPrefix, const AccAttributes& aAttributes);
277 #endif
279 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf);
281 private:
282 static void StringFromValueAndName(nsAtom* aAttrName,
283 const AttrValueType& aValue,
284 nsAString& aValueString);
286 AtomVariantMap mData;
288 friend struct IPC::ParamTraits<AccAttributes*>;
291 } // namespace a11y
292 } // namespace mozilla
294 #endif