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