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/Maybe.h"
9 #include "mozilla/ToString.h"
12 using namespace mozilla::a11y
;
14 bool AccAttributes::GetAttribute(nsAtom
* aAttrName
,
15 nsAString
& aAttrValue
) const {
16 if (auto value
= mData
.Lookup(aAttrName
)) {
17 StringFromValueAndName(aAttrName
, *value
, aAttrValue
);
24 void AccAttributes::StringFromValueAndName(nsAtom
* aAttrName
,
25 const AttrValueType
& aValue
,
26 nsAString
& aValueString
) {
27 aValueString
.Truncate();
30 [&aValueString
](const bool& val
) {
31 aValueString
.Assign(val
? u
"true" : u
"false");
33 [&aValueString
](const float& val
) {
34 aValueString
.AppendFloat(val
* 100);
35 aValueString
.Append(u
"%");
37 [&aValueString
](const double& val
) { aValueString
.AppendFloat(val
); },
38 [&aValueString
](const int32_t& val
) { aValueString
.AppendInt(val
); },
39 [&aValueString
](const RefPtr
<nsAtom
>& val
) {
40 val
->ToString(aValueString
);
42 [&aValueString
](const nsTArray
<int32_t>& val
) {
43 if (const size_t len
= val
.Length()) {
44 for (size_t i
= 0; i
< len
- 1; i
++) {
45 aValueString
.AppendInt(val
[i
]);
46 aValueString
.Append(u
", ");
48 aValueString
.AppendInt(val
[len
- 1]);
52 "Hmm, should we have used a DeleteEntry() for this instead?");
53 aValueString
.Append(u
"[ ]");
56 [&aValueString
](const CSSCoord
& val
) {
57 aValueString
.AppendFloat(val
);
58 aValueString
.Append(u
"px");
60 [&aValueString
](const FontSize
& val
) {
61 aValueString
.AppendInt(val
.mValue
);
62 aValueString
.Append(u
"pt");
64 [&aValueString
](const Color
& val
) {
65 StyleInfo::FormatColor(val
.mValue
, aValueString
);
67 [&aValueString
](const DeleteEntry
& val
) {
68 aValueString
.Append(u
"-delete-entry-");
70 [&aValueString
](const UniquePtr
<nsString
>& val
) {
71 aValueString
.Assign(*val
);
73 [&aValueString
](const RefPtr
<AccAttributes
>& val
) {
74 aValueString
.Assign(u
"AccAttributes{...}");
76 [&aValueString
](const uint64_t& val
) { aValueString
.AppendInt(val
); },
77 [&aValueString
](const UniquePtr
<AccGroupInfo
>& val
) {
78 aValueString
.Assign(u
"AccGroupInfo{...}");
80 [&aValueString
](const UniquePtr
<gfx::Matrix4x4
>& val
) {
81 aValueString
.AppendPrintf("Matrix4x4=%s", ToString(*val
).c_str());
83 [&aValueString
](const nsTArray
<uint64_t>& val
) {
84 if (const size_t len
= val
.Length()) {
85 for (size_t i
= 0; i
< len
- 1; i
++) {
86 aValueString
.AppendInt(val
[i
]);
87 aValueString
.Append(u
", ");
89 aValueString
.AppendInt(val
[len
- 1]);
93 "Hmm, should we have used a DeleteEntry() for this instead?");
94 aValueString
.Append(u
"[ ]");
99 void AccAttributes::Update(AccAttributes
* aOther
) {
100 for (auto iter
= aOther
->mData
.Iter(); !iter
.Done(); iter
.Next()) {
101 if (iter
.Data().is
<DeleteEntry
>()) {
102 mData
.Remove(iter
.Key());
104 mData
.InsertOrUpdate(iter
.Key(), std::move(iter
.Data()));
110 bool AccAttributes::Equal(const AccAttributes
* aOther
) const {
111 if (Count() != aOther
->Count()) {
114 for (auto iter
= mData
.ConstIter(); !iter
.Done(); iter
.Next()) {
115 const auto otherEntry
= aOther
->mData
.Lookup(iter
.Key());
119 if (iter
.Data().is
<UniquePtr
<nsString
>>()) {
120 // Because we store nsString in a UniquePtr, we must handle it specially
121 // so we compare the string and not the pointer.
122 if (!otherEntry
->is
<UniquePtr
<nsString
>>()) {
125 const auto& thisStr
= iter
.Data().as
<UniquePtr
<nsString
>>();
126 const auto& otherStr
= otherEntry
->as
<UniquePtr
<nsString
>>();
127 if (*thisStr
!= *otherStr
) {
130 } else if (iter
.Data() != otherEntry
.Data()) {
137 void AccAttributes::CopyTo(AccAttributes
* aDest
) const {
138 for (auto iter
= mData
.ConstIter(); !iter
.Done(); iter
.Next()) {
140 [&iter
, &aDest
](const bool& val
) {
141 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
143 [&iter
, &aDest
](const float& val
) {
144 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
146 [&iter
, &aDest
](const double& val
) {
147 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
149 [&iter
, &aDest
](const int32_t& val
) {
150 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
152 [&iter
, &aDest
](const RefPtr
<nsAtom
>& val
) {
153 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
155 [](const nsTArray
<int32_t>& val
) {
156 // We don't copy arrays.
157 MOZ_ASSERT_UNREACHABLE(
158 "Trying to copy an AccAttributes containing an array");
160 [&iter
, &aDest
](const CSSCoord
& val
) {
161 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
163 [&iter
, &aDest
](const FontSize
& val
) {
164 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
166 [&iter
, &aDest
](const Color
& val
) {
167 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
169 [](const DeleteEntry
& val
) {
170 // We don't copy DeleteEntry.
171 MOZ_ASSERT_UNREACHABLE(
172 "Trying to copy an AccAttributes containing a DeleteEntry");
174 [&iter
, &aDest
](const UniquePtr
<nsString
>& val
) {
175 aDest
->SetAttributeStringCopy(iter
.Key(), *val
);
177 [](const RefPtr
<AccAttributes
>& val
) {
178 // We don't copy nested AccAttributes.
179 MOZ_ASSERT_UNREACHABLE(
180 "Trying to copy an AccAttributes containing an AccAttributes");
182 [&iter
, &aDest
](const uint64_t& val
) {
183 aDest
->mData
.InsertOrUpdate(iter
.Key(), AsVariant(val
));
185 [](const UniquePtr
<AccGroupInfo
>& val
) {
186 MOZ_ASSERT_UNREACHABLE(
187 "Trying to copy an AccAttributes containing an AccGroupInfo");
189 [](const UniquePtr
<gfx::Matrix4x4
>& val
) {
190 MOZ_ASSERT_UNREACHABLE(
191 "Trying to copy an AccAttributes containing a matrix");
193 [](const nsTArray
<uint64_t>& val
) {
194 // We don't copy arrays.
195 MOZ_ASSERT_UNREACHABLE(
196 "Trying to copy an AccAttributes containing an array");
202 void AccAttributes::DebugPrint(const char* aPrefix
,
203 const AccAttributes
& aAttributes
) {
204 nsAutoString prettyString
;
205 prettyString
.AssignLiteral("{\n");
206 for (const auto& iter
: aAttributes
) {
208 iter
.NameAsString(name
);
211 iter
.ValueAsString(value
);
212 prettyString
.AppendLiteral(" ");
213 prettyString
.Append(name
);
214 prettyString
.AppendLiteral(": ");
215 prettyString
.Append(value
);
216 prettyString
.AppendLiteral("\n");
219 prettyString
.AppendLiteral("}");
220 printf("%s %s\n", aPrefix
, NS_ConvertUTF16toUTF8(prettyString
).get());
224 size_t AccAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) {
226 aMallocSizeOf(this) + mData
.ShallowSizeOfExcludingThis(aMallocSizeOf
);
228 for (auto iter
: *this) {
229 size
+= iter
.SizeOfExcludingThis(aMallocSizeOf
);
235 size_t AccAttributes::Entry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) {
238 // We don't count the size of Name() since it's counted by the atoms table
241 if (mValue
->is
<nsTArray
<int32_t>>()) {
242 size
+= mValue
->as
<nsTArray
<int32_t>>().ShallowSizeOfExcludingThis(
244 } else if (mValue
->is
<UniquePtr
<nsString
>>()) {
245 // String data will never be shared.
246 size
+= mValue
->as
<UniquePtr
<nsString
>>()->SizeOfIncludingThisIfUnshared(
248 } else if (mValue
->is
<RefPtr
<AccAttributes
>>()) {
250 mValue
->as
<RefPtr
<AccAttributes
>>()->SizeOfIncludingThis(aMallocSizeOf
);
251 } else if (mValue
->is
<UniquePtr
<AccGroupInfo
>>()) {
252 size
+= mValue
->as
<UniquePtr
<AccGroupInfo
>>()->SizeOfIncludingThis(
254 } else if (mValue
->is
<UniquePtr
<gfx::Matrix4x4
>>()) {
255 size
+= aMallocSizeOf(mValue
->as
<UniquePtr
<gfx::Matrix4x4
>>().get());
256 } else if (mValue
->is
<nsTArray
<uint64_t>>()) {
257 size
+= mValue
->as
<nsTArray
<uint64_t>>().ShallowSizeOfExcludingThis(
260 // This type is stored directly and already counted or is an atom and
261 // stored and counted in the atoms table.
262 // Assert that we have exhausted all the remaining variant types.
263 MOZ_ASSERT(mValue
->is
<RefPtr
<nsAtom
>>() || mValue
->is
<bool>() ||
264 mValue
->is
<float>() || mValue
->is
<double>() ||
265 mValue
->is
<int32_t>() || mValue
->is
<uint64_t>() ||
266 mValue
->is
<CSSCoord
>() || mValue
->is
<FontSize
>() ||
267 mValue
->is
<Color
>() || mValue
->is
<DeleteEntry
>());