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"
14 #include "nsStringFwd.h"
15 #include "mozilla/gfx/Matrix.h"
35 bool operator==(const FontSize
& aOther
) const {
36 return mValue
== aOther
.mValue
;
39 bool operator!=(const FontSize
& aOther
) const {
40 return mValue
!= aOther
.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.
55 DeleteEntry() : mValue(true) {}
58 bool operator==(const DeleteEntry
& aOther
) const { return true; }
60 bool operator!=(const DeleteEntry
& aOther
) const { return false; }
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!
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
>;
78 ~AccAttributes() = default;
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
*>,
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());
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
>>());
138 if (value
->is
<T
>()) {
139 const T
& val
= value
->as
<T
>();
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
>>();
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
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.
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());
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
>>());
207 if (mValue
->is
<T
>()) {
208 const T
& val
= mValue
->as
<T
>();
215 void NameAsString(nsString
& aName
) {
216 mName
->ToString(aName
);
217 if (aName
.Find("aria-", false, 0, 1) == 0) {
219 aName
.ReplaceLiteral(0, 5, u
"");
223 void ValueAsString(nsAString
& aValueString
) {
224 StringFromValueAndName(mName
, *mValue
, aValueString
);
229 const AttrValueType
* mValue
;
231 friend class AccAttributes
;
236 explicit Iterator(AtomVariantMap::iterator aIter
) : mHashIterator(aIter
) {}
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++() {
254 auto& entry
= *mHashIterator
;
255 return Entry(entry
.GetKey(), &entry
.GetData());
259 AtomVariantMap::iterator mHashIterator
;
262 friend class Iterator
;
264 Iterator
begin() { return Iterator(mData
.begin()); }
265 Iterator
end() { return Iterator(mData
.end()); }
268 static void StringFromValueAndName(nsAtom
* aAttrName
,
269 const AttrValueType
& aValue
,
270 nsAString
& aValueString
);
272 AtomVariantMap mData
;
274 friend struct IPC::ParamTraits
<AccAttributes
*>;
278 } // namespace mozilla