Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / accessible / base / AccAttributes.cpp
blob4018f09074c713ac47f17cef8b0cccba2683d6f4
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"
7 #include "StyleInfo.h"
8 #include "mozilla/ToString.h"
9 #include "nsAtom.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);
17 return true;
20 return false;
23 void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
24 const AttrValueType& aValue,
25 nsAString& aValueString) {
26 aValueString.Truncate();
28 aValue.match(
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]);
48 } else {
49 // The array is empty
50 NS_WARNING(
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]);
89 } else {
90 // The array is empty
91 NS_WARNING(
92 "Hmm, should we have used a DeleteEntry() for this instead?");
93 aValueString.Append(u"[ ]");
95 });
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());
102 } else {
103 mData.InsertOrUpdate(iter.Key(), std::move(iter.Data()));
105 iter.Remove();
109 bool AccAttributes::Equal(const AccAttributes* aOther) const {
110 if (Count() != aOther->Count()) {
111 return false;
113 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
114 const auto otherEntry = aOther->mData.Lookup(iter.Key());
115 if (!otherEntry) {
116 return false;
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>>()) {
122 return false;
124 const auto& thisStr = iter.Data().as<UniquePtr<nsString>>();
125 const auto& otherStr = otherEntry->as<UniquePtr<nsString>>();
126 if (*thisStr != *otherStr) {
127 return false;
129 } else if (iter.Data() != otherEntry.Data()) {
130 return false;
133 return true;
136 void AccAttributes::CopyTo(AccAttributes* aDest) const {
137 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
138 iter.Data().match(
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");
200 #ifdef A11Y_LOG
201 void AccAttributes::DebugPrint(const char* aPrefix,
202 const AccAttributes& aAttributes) {
203 nsAutoString prettyString;
204 prettyString.AssignLiteral("{\n");
205 for (const auto& iter : aAttributes) {
206 nsAutoString name;
207 iter.NameAsString(name);
209 nsAutoString value;
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());
221 #endif
223 size_t AccAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
224 size_t size =
225 aMallocSizeOf(this) + mData.ShallowSizeOfExcludingThis(aMallocSizeOf);
227 for (auto iter : *this) {
228 size += iter.SizeOfExcludingThis(aMallocSizeOf);
231 return size;
234 size_t AccAttributes::Entry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) {
235 size_t size = 0;
237 // We don't count the size of Name() since it's counted by the atoms table
238 // memory reporter.
240 if (mValue->is<nsTArray<int32_t>>()) {
241 size += mValue->as<nsTArray<int32_t>>().ShallowSizeOfExcludingThis(
242 aMallocSizeOf);
243 } else if (mValue->is<UniquePtr<nsString>>()) {
244 // String data will never be shared.
245 size += mValue->as<UniquePtr<nsString>>()->SizeOfIncludingThisIfUnshared(
246 aMallocSizeOf);
247 } else if (mValue->is<RefPtr<AccAttributes>>()) {
248 size +=
249 mValue->as<RefPtr<AccAttributes>>()->SizeOfIncludingThis(aMallocSizeOf);
250 } else if (mValue->is<UniquePtr<AccGroupInfo>>()) {
251 size += mValue->as<UniquePtr<AccGroupInfo>>()->SizeOfIncludingThis(
252 aMallocSizeOf);
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(
257 aMallocSizeOf);
258 } else {
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>());
269 return size;