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 #include "AccAttributes.h"
8 #include "mozilla/ToString.h"
11 using namespace mozilla::a11y
;
13 bool AccAttributes::GetAttribute(nsAtom
* aAttrName
,
14 nsAString
& aAttrValue
) const {
15 if (auto value
= mData
.Lookup(aAttrName
)) {
16 StringFromValueAndName(aAttrName
, *value
, aAttrValue
);
23 void AccAttributes::StringFromValueAndName(nsAtom
* aAttrName
,
24 const AttrValueType
& aValue
,
25 nsAString
& aValueString
) {
26 aValueString
.Truncate();
29 [&aValueString
](const bool& val
) {
30 aValueString
.Assign(val
? u
"true" : u
"false");
32 [&aValueString
](const float& val
) {
33 aValueString
.AppendFloat(val
* 100);
34 aValueString
.Append(u
"%");
36 [&aValueString
](const double& val
) { aValueString
.AppendFloat(val
); },
37 [&aValueString
](const int32_t& val
) { aValueString
.AppendInt(val
); },
38 [&aValueString
](const RefPtr
<nsAtom
>& val
) {
39 val
->ToString(aValueString
);
41 [&aValueString
](const nsTArray
<int32_t>& val
) {
42 if (const size_t len
= val
.Length()) {
43 for (size_t i
= 0; i
< len
- 1; i
++) {
44 aValueString
.AppendInt(val
[i
]);
45 aValueString
.Append(u
", ");
47 aValueString
.AppendInt(val
[len
- 1]);
51 "Hmm, should we have used a DeleteEntry() for this instead?");
52 aValueString
.Append(u
"[ ]");
55 [&aValueString
](const CSSCoord
& val
) {
56 aValueString
.AppendFloat(val
);
57 aValueString
.Append(u
"px");
59 [&aValueString
](const FontSize
& val
) {
60 aValueString
.AppendInt(val
.mValue
);
61 aValueString
.Append(u
"pt");
63 [&aValueString
](const Color
& val
) {
64 StyleInfo::FormatColor(val
.mValue
, aValueString
);
66 [&aValueString
](const DeleteEntry
& val
) {
67 aValueString
.Append(u
"-delete-entry-");
69 [&aValueString
](const UniquePtr
<nsString
>& val
) {
70 aValueString
.Assign(*val
);
72 [&aValueString
](const RefPtr
<AccAttributes
>& val
) {
73 aValueString
.Assign(u
"AccAttributes{...}");
75 [&aValueString
](const uint64_t& val
) { aValueString
.AppendInt(val
); },
76 [&aValueString
](const UniquePtr
<AccGroupInfo
>& val
) {
77 aValueString
.Assign(u
"AccGroupInfo{...}");
79 [&aValueString
](const UniquePtr
<gfx::Matrix4x4
>& val
) {
80 aValueString
.AppendPrintf("Matrix4x4=%s", ToString(*val
).c_str());
82 [&aValueString
](const nsTArray
<uint64_t>& val
) {
83 if (const size_t len
= val
.Length()) {
84 for (size_t i
= 0; i
< len
- 1; i
++) {
85 aValueString
.AppendInt(val
[i
]);
86 aValueString
.Append(u
", ");
88 aValueString
.AppendInt(val
[len
- 1]);
92 "Hmm, should we have used a DeleteEntry() for this instead?");
93 aValueString
.Append(u
"[ ]");
98 void AccAttributes::Update(AccAttributes
* aOther
) {
99 for (auto iter
= aOther
->mData
.Iter(); !iter
.Done(); iter
.Next()) {
100 if (iter
.Data().is
<DeleteEntry
>()) {
101 mData
.Remove(iter
.Key());
103 mData
.InsertOrUpdate(iter
.Key(), std::move(iter
.Data()));
109 bool AccAttributes::Equal(const AccAttributes
* aOther
) const {
110 if (Count() != aOther
->Count()) {
113 for (auto iter
= mData
.ConstIter(); !iter
.Done(); iter
.Next()) {
114 const auto otherEntry
= aOther
->mData
.Lookup(iter
.Key());
118 if (iter
.Data().is
<UniquePtr
<nsString
>>()) {
119 // Because we store nsString in a UniquePtr, we must handle it specially
120 // so we compare the string and not the pointer.
121 if (!otherEntry
->is
<UniquePtr
<nsString
>>()) {
124 const auto& thisStr
= iter
.Data().as
<UniquePtr
<nsString
>>();
125 const auto& otherStr
= otherEntry
->as
<UniquePtr
<nsString
>>();
126 if (*thisStr
!= *otherStr
) {
129 } else if (iter
.Data() != otherEntry
.Data()) {
136 void AccAttributes::CopyTo(AccAttributes
* aDest
) const {
137 for (auto iter
= mData
.ConstIter(); !iter
.Done(); iter
.Next()) {
139 [&iter
, &aDest
](const bool& val
) {
140 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
142 [&iter
, &aDest
](const float& val
) {
143 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
145 [&iter
, &aDest
](const double& val
) {
146 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
148 [&iter
, &aDest
](const int32_t& val
) {
149 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
151 [&iter
, &aDest
](const RefPtr
<nsAtom
>& val
) {
152 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
154 [](const nsTArray
<int32_t>& val
) {
155 // We don't copy arrays.
156 MOZ_ASSERT_UNREACHABLE(
157 "Trying to copy an AccAttributes containing an array");
159 [&iter
, &aDest
](const CSSCoord
& val
) {
160 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
162 [&iter
, &aDest
](const FontSize
& val
) {
163 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
165 [&iter
, &aDest
](const Color
& val
) {
166 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
168 [](const DeleteEntry
& val
) {
169 // We don't copy DeleteEntry.
170 MOZ_ASSERT_UNREACHABLE(
171 "Trying to copy an AccAttributes containing a DeleteEntry");
173 [&iter
, &aDest
](const UniquePtr
<nsString
>& val
) {
174 aDest
->SetAttributeStringCopy(iter
.Key(), *val
);
176 [](const RefPtr
<AccAttributes
>& val
) {
177 // We don't copy nested AccAttributes.
178 MOZ_ASSERT_UNREACHABLE(
179 "Trying to copy an AccAttributes containing an AccAttributes");
181 [&iter
, &aDest
](const uint64_t& val
) {
182 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
184 [](const UniquePtr
<AccGroupInfo
>& val
) {
185 MOZ_ASSERT_UNREACHABLE(
186 "Trying to copy an AccAttributes containing an AccGroupInfo");
188 [](const UniquePtr
<gfx::Matrix4x4
>& val
) {
189 MOZ_ASSERT_UNREACHABLE(
190 "Trying to copy an AccAttributes containing a matrix");
192 [](const nsTArray
<uint64_t>& val
) {
193 // We don't copy arrays.
194 MOZ_ASSERT_UNREACHABLE(
195 "Trying to copy an AccAttributes containing an array");
201 void AccAttributes::DebugPrint(const char* aPrefix
,
202 const AccAttributes
& aAttributes
) {
203 nsAutoString prettyString
;
204 prettyString
.AssignLiteral("{\n");
205 for (const auto& iter
: aAttributes
) {
207 iter
.NameAsString(name
);
210 iter
.ValueAsString(value
);
211 prettyString
.AppendLiteral(" ");
212 prettyString
.Append(name
);
213 prettyString
.AppendLiteral(": ");
214 prettyString
.Append(value
);
215 prettyString
.AppendLiteral("\n");
218 prettyString
.AppendLiteral("}");
219 printf("%s %s\n", aPrefix
, NS_ConvertUTF16toUTF8(prettyString
).get());
223 size_t AccAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) {
225 aMallocSizeOf(this) + mData
.ShallowSizeOfExcludingThis(aMallocSizeOf
);
227 for (auto iter
: *this) {
228 size
+= iter
.SizeOfExcludingThis(aMallocSizeOf
);
234 size_t AccAttributes::Entry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) {
237 // We don't count the size of Name() since it's counted by the atoms table
240 if (mValue
->is
<nsTArray
<int32_t>>()) {
241 size
+= mValue
->as
<nsTArray
<int32_t>>().ShallowSizeOfExcludingThis(
243 } else if (mValue
->is
<UniquePtr
<nsString
>>()) {
244 // String data will never be shared.
245 size
+= mValue
->as
<UniquePtr
<nsString
>>()->SizeOfIncludingThisIfUnshared(
247 } else if (mValue
->is
<RefPtr
<AccAttributes
>>()) {
249 mValue
->as
<RefPtr
<AccAttributes
>>()->SizeOfIncludingThis(aMallocSizeOf
);
250 } else if (mValue
->is
<UniquePtr
<AccGroupInfo
>>()) {
251 size
+= mValue
->as
<UniquePtr
<AccGroupInfo
>>()->SizeOfIncludingThis(
253 } else if (mValue
->is
<UniquePtr
<gfx::Matrix4x4
>>()) {
254 size
+= aMallocSizeOf(mValue
->as
<UniquePtr
<gfx::Matrix4x4
>>().get());
255 } else if (mValue
->is
<nsTArray
<uint64_t>>()) {
256 size
+= mValue
->as
<nsTArray
<uint64_t>>().ShallowSizeOfExcludingThis(
259 // This type is stored directly and already counted or is an atom and
260 // stored and counted in the atoms table.
261 // Assert that we have exhausted all the remaining variant types.
262 MOZ_ASSERT(mValue
->is
<RefPtr
<nsAtom
>>() || mValue
->is
<bool>() ||
263 mValue
->is
<float>() || mValue
->is
<double>() ||
264 mValue
->is
<int32_t>() || mValue
->is
<uint64_t>() ||
265 mValue
->is
<CSSCoord
>() || mValue
->is
<FontSize
>() ||
266 mValue
->is
<Color
>() || mValue
->is
<DeleteEntry
>());