Bug 1631735 Part 1: Make nsCocoaWindow animated transitions asynchronous and atomic...
[gecko.git] / accessible / base / AccAttributes.cpp
blob2c557fe66be168ec3056ac913731bc6873c35951
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/Maybe.h"
9 #include "mozilla/ToString.h"
10 #include "nsAtom.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);
18 return true;
21 return false;
24 void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
25 const AttrValueType& aValue,
26 nsAString& aValueString) {
27 aValueString.Truncate();
29 aValue.match(
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]);
49 } else {
50 // The array is empty
51 NS_WARNING(
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]);
90 } else {
91 // The array is empty
92 NS_WARNING(
93 "Hmm, should we have used a DeleteEntry() for this instead?");
94 aValueString.Append(u"[ ]");
96 });
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());
103 } else {
104 mData.InsertOrUpdate(iter.Key(), std::move(iter.Data()));
106 iter.Remove();
110 bool AccAttributes::Equal(const AccAttributes* aOther) const {
111 if (Count() != aOther->Count()) {
112 return false;
114 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
115 const auto otherEntry = aOther->mData.Lookup(iter.Key());
116 if (!otherEntry) {
117 return false;
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>>()) {
123 return false;
125 const auto& thisStr = iter.Data().as<UniquePtr<nsString>>();
126 const auto& otherStr = otherEntry->as<UniquePtr<nsString>>();
127 if (*thisStr != *otherStr) {
128 return false;
130 } else if (iter.Data() != otherEntry.Data()) {
131 return false;
134 return true;
137 void AccAttributes::CopyTo(AccAttributes* aDest) const {
138 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
139 iter.Data().match(
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");
201 #ifdef A11Y_LOG
202 void AccAttributes::DebugPrint(const char* aPrefix,
203 const AccAttributes& aAttributes) {
204 nsAutoString prettyString;
205 prettyString.AssignLiteral("{\n");
206 for (const auto& iter : aAttributes) {
207 nsAutoString name;
208 iter.NameAsString(name);
210 nsAutoString value;
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());
222 #endif
224 size_t AccAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
225 size_t size =
226 aMallocSizeOf(this) + mData.ShallowSizeOfExcludingThis(aMallocSizeOf);
228 for (auto iter : *this) {
229 size += iter.SizeOfExcludingThis(aMallocSizeOf);
232 return size;
235 size_t AccAttributes::Entry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) {
236 size_t size = 0;
238 // We don't count the size of Name() since it's counted by the atoms table
239 // memory reporter.
241 if (mValue->is<nsTArray<int32_t>>()) {
242 size += mValue->as<nsTArray<int32_t>>().ShallowSizeOfExcludingThis(
243 aMallocSizeOf);
244 } else if (mValue->is<UniquePtr<nsString>>()) {
245 // String data will never be shared.
246 size += mValue->as<UniquePtr<nsString>>()->SizeOfIncludingThisIfUnshared(
247 aMallocSizeOf);
248 } else if (mValue->is<RefPtr<AccAttributes>>()) {
249 size +=
250 mValue->as<RefPtr<AccAttributes>>()->SizeOfIncludingThis(aMallocSizeOf);
251 } else if (mValue->is<UniquePtr<AccGroupInfo>>()) {
252 size += mValue->as<UniquePtr<AccGroupInfo>>()->SizeOfIncludingThis(
253 aMallocSizeOf);
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(
258 aMallocSizeOf);
259 } else {
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>());
270 return size;