no bug - Correct some typos in the comments. a=typo-fix
[gecko.git] / accessible / base / AccAttributes.h
blob0d7610b3582e7ca8e6c6de83194a50a66c219a19
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 "nsStringFwd.h"
14 #include "mozilla/gfx/Matrix.h"
16 class nsVariant;
18 namespace IPC {
19 template <typename T>
20 struct ParamTraits;
21 } // namespace IPC
23 namespace mozilla {
25 namespace dom {
26 class Element;
29 namespace a11y {
31 struct FontSize {
32 int32_t mValue;
34 bool operator==(const FontSize& aOther) const {
35 return mValue == aOther.mValue;
38 bool operator!=(const FontSize& aOther) const {
39 return mValue != aOther.mValue;
43 struct Color {
44 nscolor mValue;
46 bool operator==(const Color& aOther) const { return mValue == aOther.mValue; }
48 bool operator!=(const Color& aOther) const { return mValue != aOther.mValue; }
51 // A special type. If an entry has a value of this type, it instructs the
52 // target instance of an Update to remove the entry with the same key value.
53 struct DeleteEntry {
54 DeleteEntry() : mValue(true) {}
55 bool mValue;
57 bool operator==(const DeleteEntry& aOther) const { return true; }
59 bool operator!=(const DeleteEntry& aOther) const { return false; }
62 class AccAttributes {
63 // Warning! An AccAttributes can contain another AccAttributes. This is
64 // intended for object and text attributes. However, the nested
65 // AccAttributes should never itself contain another AccAttributes, nor
66 // should it create a cycle. We don't do cycle collection here for
67 // performance reasons, so violating this rule will cause leaks!
68 using AttrValueType =
69 Variant<bool, float, double, int32_t, RefPtr<nsAtom>, nsTArray<int32_t>,
70 CSSCoord, FontSize, Color, DeleteEntry, UniquePtr<nsString>,
71 RefPtr<AccAttributes>, uint64_t, UniquePtr<AccGroupInfo>,
72 UniquePtr<gfx::Matrix4x4>, nsTArray<uint64_t>>;
73 static_assert(sizeof(AttrValueType) <= 16);
74 using AtomVariantMap = nsTHashMap<RefPtr<nsAtom>, AttrValueType>;
76 protected:
77 ~AccAttributes() = default;
79 public:
80 AccAttributes() = default;
81 AccAttributes(const AccAttributes&) = delete;
82 AccAttributes& operator=(const AccAttributes&) = delete;
84 NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::AccAttributes)
86 template <typename T>
87 void SetAttribute(nsAtom* aAttrName, T&& aAttrValue) {
88 using ValType =
89 std::remove_const_t<std::remove_reference_t<decltype(aAttrValue)>>;
90 if constexpr (std::is_convertible_v<ValType, nsString>) {
91 static_assert(std::is_rvalue_reference_v<decltype(aAttrValue)>,
92 "Please only move strings into this function. To make a "
93 "copy, use SetAttributeStringCopy.");
94 UniquePtr<nsString> value = MakeUnique<nsString>(std::move(aAttrValue));
95 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
96 } else if constexpr (std::is_same_v<ValType, gfx::Matrix4x4>) {
97 UniquePtr<gfx::Matrix4x4> value = MakeUnique<gfx::Matrix4x4>(aAttrValue);
98 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
99 } else if constexpr (std::is_same_v<ValType, AccGroupInfo*>) {
100 UniquePtr<AccGroupInfo> value(aAttrValue);
101 mData.InsertOrUpdate(aAttrName, AsVariant(std::move(value)));
102 } else if constexpr (std::is_convertible_v<ValType, nsAtom*>) {
103 mData.InsertOrUpdate(aAttrName, AsVariant(RefPtr<nsAtom>(aAttrValue)));
104 } else {
105 mData.InsertOrUpdate(aAttrName, AsVariant(std::forward<T>(aAttrValue)));
109 void SetAttributeStringCopy(nsAtom* aAttrName, nsString aAttrValue) {
110 SetAttribute(aAttrName, std::move(aAttrValue));
113 template <typename T>
114 Maybe<const T&> GetAttribute(nsAtom* aAttrName) const {
115 if (auto value = mData.Lookup(aAttrName)) {
116 if constexpr (std::is_same_v<nsString, T>) {
117 if (value->is<UniquePtr<nsString>>()) {
118 const T& val = *(value->as<UniquePtr<nsString>>().get());
119 return SomeRef(val);
121 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
122 if (value->is<UniquePtr<gfx::Matrix4x4>>()) {
123 const T& val = *(value->as<UniquePtr<gfx::Matrix4x4>>());
124 return SomeRef(val);
126 } else {
127 if (value->is<T>()) {
128 const T& val = value->as<T>();
129 return SomeRef(val);
133 return Nothing();
136 template <typename T>
137 RefPtr<const T> GetAttributeRefPtr(nsAtom* aAttrName) const {
138 if (auto value = mData.Lookup(aAttrName)) {
139 if (value->is<RefPtr<T>>()) {
140 RefPtr<const T> ref = value->as<RefPtr<T>>();
141 return ref;
144 return nullptr;
147 template <typename T>
148 Maybe<T&> GetMutableAttribute(nsAtom* aAttrName) const {
149 static_assert(std::is_same_v<nsTArray<int32_t>, T> ||
150 std::is_same_v<nsTArray<uint64_t>, T>,
151 "Only arrays should be mutable attributes");
152 if (auto value = mData.Lookup(aAttrName)) {
153 if (value->is<T>()) {
154 T& val = value->as<T>();
155 return SomeRef(val);
158 return Nothing();
161 // Get stringified value
162 bool GetAttribute(nsAtom* aAttrName, nsAString& aAttrValue) const;
164 bool HasAttribute(nsAtom* aAttrName) const {
165 return mData.Contains(aAttrName);
168 bool Remove(nsAtom* aAttrName) { return mData.Remove(aAttrName); }
170 uint32_t Count() const { return mData.Count(); }
172 // Update one instance with the entries in another. The supplied AccAttributes
173 // will be emptied.
174 void Update(AccAttributes* aOther);
177 * Return true if all the attributes in this instance are equal to all the
178 * attributes in another instance.
180 bool Equal(const AccAttributes* aOther) const;
183 * Copy attributes from this instance to another instance.
184 * This should only be used in very specific cases; e.g. merging two sets of
185 * cached attributes without modifying the cache. It can only copy simple
186 * value types; e.g. it can't copy array values. Attempting to copy an
187 * AccAttributes with uncopyable values will cause an assertion.
189 void CopyTo(AccAttributes* aDest) const;
191 // An entry class for our iterator.
192 class Entry {
193 public:
194 Entry(nsAtom* aAttrName, const AttrValueType* aAttrValue)
195 : mName(aAttrName), mValue(aAttrValue) {}
197 nsAtom* Name() const { return mName; }
199 template <typename T>
200 Maybe<const T&> Value() const {
201 if constexpr (std::is_same_v<nsString, T>) {
202 if (mValue->is<UniquePtr<nsString>>()) {
203 const T& val = *(mValue->as<UniquePtr<nsString>>().get());
204 return SomeRef(val);
206 } else if constexpr (std::is_same_v<gfx::Matrix4x4, T>) {
207 if (mValue->is<UniquePtr<gfx::Matrix4x4>>()) {
208 const T& val = *(mValue->as<UniquePtr<gfx::Matrix4x4>>());
209 return SomeRef(val);
211 } else {
212 if (mValue->is<T>()) {
213 const T& val = mValue->as<T>();
214 return SomeRef(val);
217 return Nothing();
220 void NameAsString(nsString& aName) const {
221 mName->ToString(aName);
222 if (StringBeginsWith(aName, u"aria-"_ns)) {
223 // Found 'aria-'
224 aName.ReplaceLiteral(0, 5, u"");
228 void ValueAsString(nsAString& aValueString) const {
229 StringFromValueAndName(mName, *mValue, aValueString);
232 // Size of the pair in the hash table.
233 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf);
235 private:
236 nsAtom* mName;
237 const AttrValueType* mValue;
239 friend class AccAttributes;
242 class Iterator {
243 public:
244 explicit Iterator(AtomVariantMap::const_iterator aIter)
245 : mHashIterator(aIter) {}
247 Iterator() = delete;
248 Iterator(const Iterator&) = delete;
249 Iterator& operator=(const Iterator&) = delete;
251 bool operator!=(const Iterator& aOther) const {
252 return mHashIterator != aOther.mHashIterator;
255 Iterator& operator++() {
256 mHashIterator++;
257 return *this;
260 Entry operator*() const {
261 auto& entry = *mHashIterator;
262 return Entry(entry.GetKey(), &entry.GetData());
265 private:
266 AtomVariantMap::const_iterator mHashIterator;
269 friend class Iterator;
271 Iterator begin() const { return Iterator(mData.begin()); }
272 Iterator end() const { return Iterator(mData.end()); }
274 #ifdef A11Y_LOG
275 static void DebugPrint(const char* aPrefix, const AccAttributes& aAttributes);
276 #endif
278 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf);
280 private:
281 static void StringFromValueAndName(nsAtom* aAttrName,
282 const AttrValueType& aValue,
283 nsAString& aValueString);
285 AtomVariantMap mData;
287 friend struct IPC::ParamTraits<AccAttributes*>;
290 } // namespace a11y
291 } // namespace mozilla
293 #endif