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/. */
5
6 #include "AccAttributes.h"
7 #include "StyleInfo.h"
8 #include "mozilla/ToString.h"
9
10 using namespace mozilla::a11y;
11
GetAttribute(nsAtom * aAttrName,nsAString & aAttrValue)12 bool AccAttributes::GetAttribute(nsAtom* aAttrName, nsAString& aAttrValue) {
13 if (auto value = mData.Lookup(aAttrName)) {
14 StringFromValueAndName(aAttrName, *value, aAttrValue);
15 return true;
16 }
17
18 return false;
19 }
20
StringFromValueAndName(nsAtom * aAttrName,const AttrValueType & aValue,nsAString & aValueString)21 void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
22 const AttrValueType& aValue,
23 nsAString& aValueString) {
24 aValueString.Truncate();
25
26 aValue.match(
27 [&aValueString](const bool& val) {
28 aValueString.Assign(val ? u"true" : u"false");
29 },
30 [&aValueString](const float& val) {
31 aValueString.AppendFloat(val * 100);
32 aValueString.Append(u"%");
33 },
34 [&aValueString](const double& val) { aValueString.AppendFloat(val); },
35 [&aValueString](const int32_t& val) { aValueString.AppendInt(val); },
36 [&aValueString](const RefPtr<nsAtom>& val) {
37 val->ToString(aValueString);
38 },
39 [&aValueString](const nsTArray<int32_t>& val) {
40 for (size_t i = 0; i < val.Length() - 1; i++) {
41 aValueString.AppendInt(val[i]);
42 aValueString.Append(u", ");
43 }
44 aValueString.AppendInt(val[val.Length() - 1]);
45 },
46 [&aValueString](const CSSCoord& val) {
47 aValueString.AppendFloat(val);
48 aValueString.Append(u"px");
49 },
50 [&aValueString](const FontSize& val) {
51 aValueString.AppendInt(val.mValue);
52 aValueString.Append(u"pt");
53 },
54 [&aValueString](const Color& val) {
55 StyleInfo::FormatColor(val.mValue, aValueString);
56 },
57 [&aValueString](const DeleteEntry& val) {
58 aValueString.Append(u"-delete-entry-");
59 },
60 [&aValueString](const UniquePtr<nsString>& val) {
61 aValueString.Assign(*val);
62 },
63 [&aValueString](const RefPtr<AccAttributes>& val) {
64 aValueString.Assign(u"AccAttributes{...}");
65 },
66 [&aValueString](const uint64_t& val) { aValueString.AppendInt(val); },
67 [&aValueString](const UniquePtr<AccGroupInfo>& val) {
68 aValueString.Assign(u"AccGroupInfo{...}");
69 },
70 [&aValueString](const UniquePtr<gfx::Matrix4x4>& val) {
71 aValueString.AppendPrintf("Matrix4x4=%s", ToString(*val).c_str());
72 });
73 }
74
Update(AccAttributes * aOther)75 void AccAttributes::Update(AccAttributes* aOther) {
76 for (auto iter = aOther->mData.Iter(); !iter.Done(); iter.Next()) {
77 if (iter.Data().is<DeleteEntry>()) {
78 mData.Remove(iter.Key());
79 } else {
80 mData.InsertOrUpdate(iter.Key(), std::move(iter.Data()));
81 }
82 iter.Remove();
83 }
84 }
85
Equal(const AccAttributes * aOther) const86 bool AccAttributes::Equal(const AccAttributes* aOther) const {
87 if (Count() != aOther->Count()) {
88 return false;
89 }
90 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
91 const auto otherEntry = aOther->mData.Lookup(iter.Key());
92 if (!otherEntry) {
93 return false;
94 }
95 if (iter.Data().is<UniquePtr<nsString>>()) {
96 // Because we store nsString in a UniquePtr, we must handle it specially
97 // so we compare the string and not the pointer.
98 if (!otherEntry->is<UniquePtr<nsString>>()) {
99 return false;
100 }
101 const auto& thisStr = iter.Data().as<UniquePtr<nsString>>();
102 const auto& otherStr = otherEntry->as<UniquePtr<nsString>>();
103 if (*thisStr != *otherStr) {
104 return false;
105 }
106 } else if (iter.Data() != otherEntry.Data()) {
107 return false;
108 }
109 }
110 return true;
111 }
112
CopyTo(AccAttributes * aDest) const113 void AccAttributes::CopyTo(AccAttributes* aDest) const {
114 for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) {
115 iter.Data().match(
116 [&iter, &aDest](const bool& val) {
117 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
118 },
119 [&iter, &aDest](const float& val) {
120 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
121 },
122 [&iter, &aDest](const double& val) {
123 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
124 },
125 [&iter, &aDest](const int32_t& val) {
126 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
127 },
128 [&iter, &aDest](const RefPtr<nsAtom>& val) {
129 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
130 },
131 [](const nsTArray<int32_t>& val) {
132 // We don't copy arrays.
133 MOZ_ASSERT_UNREACHABLE(
134 "Trying to copy an AccAttributes containing an array");
135 },
136 [&iter, &aDest](const CSSCoord& val) {
137 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
138 },
139 [&iter, &aDest](const FontSize& val) {
140 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
141 },
142 [&iter, &aDest](const Color& val) {
143 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
144 },
145 [](const DeleteEntry& val) {
146 // We don't copy DeleteEntry.
147 MOZ_ASSERT_UNREACHABLE(
148 "Trying to copy an AccAttributes containing a DeleteEntry");
149 },
150 [&iter, &aDest](const UniquePtr<nsString>& val) {
151 aDest->SetAttributeStringCopy(iter.Key(), *val);
152 },
153 [](const RefPtr<AccAttributes>& val) {
154 // We don't copy nested AccAttributes.
155 MOZ_ASSERT_UNREACHABLE(
156 "Trying to copy an AccAttributes containing an AccAttributes");
157 },
158 [&iter, &aDest](const uint64_t& val) {
159 aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
160 },
161 [](const UniquePtr<AccGroupInfo>& val) {
162 MOZ_ASSERT_UNREACHABLE(
163 "Trying to copy an AccAttributes containing an AccGroupInfo");
164 },
165 [](const UniquePtr<gfx::Matrix4x4>& val) {
166 MOZ_ASSERT_UNREACHABLE(
167 "Trying to copy an AccAttributes containing a matrix");
168 });
169 }
170 }
171