commit 1515116d27c2e2f9707e845b2ef6c024e8fe75ea
parent 6cd265bc1128577ba1786a441b3c0fc7f1daa555
Author: Eitan Isaacson <eitan@monotonous.org>
Date: Wed, 3 Dec 2025 19:02:57 +0000
Bug 2002340 - Store class attribute as array of nsAtoms. r=Jamie
DOM class names are meant to be repeated in elements. Therefore, this
should be an array of atoms. DOM's nsAttrValue stores them like this as
well.
Differential Revision: https://phabricator.services.mozilla.com/D274629
Diffstat:
3 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/accessible/base/AccAttributes.cpp b/accessible/base/AccAttributes.cpp
@@ -119,6 +119,20 @@ void AccAttributes::StringFromValueAndName(nsAtom* aAttrName,
},
[&aValueString](const WritingMode& val) {
aValueString.AppendPrintf("WritingModes: %x", val.GetBits());
+ },
+ [&aValueString](const nsTArray<RefPtr<nsAtom>>& val) {
+ if (const size_t len = val.Length()) {
+ for (size_t i = 0; i < len - 1; i++) {
+ aValueString.Append(val[i]->GetUTF16String());
+ aValueString.Append(u" ");
+ }
+ aValueString.Append(val[len - 1]->GetUTF16String());
+ } else {
+ // The array is empty
+ NS_WARNING(
+ "Hmm, should we have used a DeleteEntry() for this instead?");
+ aValueString.Append(u"");
+ }
});
}
@@ -255,6 +269,11 @@ void AccAttributes::CopyTo(AccAttributes* aDest, bool aOnlyMissing) const {
},
[&iter, &aDest](const WritingMode& val) {
aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val));
+ },
+ [](const nsTArray<RefPtr<nsAtom>>& val) {
+ // We don't copy arrays.
+ MOZ_ASSERT_UNREACHABLE(
+ "Trying to copy an AccAttributes containing an array");
});
}
}
@@ -301,6 +320,9 @@ size_t AccAttributes::Entry::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) {
} else if (mValue->is<nsTArray<uint64_t>>()) {
size += mValue->as<nsTArray<uint64_t>>().ShallowSizeOfExcludingThis(
aMallocSizeOf);
+ } else if (mValue->is<nsTArray<RefPtr<nsAtom>>>()) {
+ size += mValue->as<nsTArray<RefPtr<nsAtom>>>().ShallowSizeOfExcludingThis(
+ aMallocSizeOf);
} else {
// This type is stored directly and already counted or is an atom and
// stored and counted in the atoms table.
diff --git a/accessible/base/AccAttributes.h b/accessible/base/AccAttributes.h
@@ -108,7 +108,8 @@ class AccAttributes {
CSSCoord, FontSize, Color, DeleteEntry, UniquePtr<nsString>,
RefPtr<AccAttributes>, uint64_t, UniquePtr<AccGroupInfo>,
UniquePtr<gfx::Matrix4x4>, nsTArray<uint64_t>,
- nsTArray<TextOffsetAttribute>, WritingMode>;
+ nsTArray<TextOffsetAttribute>, WritingMode,
+ nsTArray<RefPtr<nsAtom>>>;
static_assert(sizeof(AttrValueType) <= 16);
using AtomVariantMap = nsTHashMap<RefPtr<nsAtom>, AttrValueType>;
@@ -197,7 +198,8 @@ class AccAttributes {
template <typename T>
Maybe<T&> GetMutableAttribute(nsAtom* aAttrName) const {
static_assert(std::is_same_v<nsTArray<int32_t>, T> ||
- std::is_same_v<nsTArray<uint64_t>, T>,
+ std::is_same_v<nsTArray<uint64_t>, T> ||
+ std::is_same_v<nsTArray<RefPtr<nsAtom>>, T>,
"Only arrays should be mutable attributes");
if (auto value = mData.Lookup(aAttrName)) {
if (value->is<T>()) {
diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp
@@ -3922,12 +3922,19 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
} else if (IsUpdatePush(CacheDomain::DOMNodeIDAndClass)) {
fields->SetAttribute(CacheKey::DOMNodeID, DeleteEntry());
}
- nsString className;
- DOMNodeClass(className);
- if (!className.IsEmpty()) {
- fields->SetAttribute(CacheKey::DOMNodeClass, std::move(className));
- } else if (IsUpdatePush(CacheDomain::DOMNodeIDAndClass)) {
- fields->SetAttribute(CacheKey::DOMNodeClass, DeleteEntry());
+
+ if (dom::Element* el = Elm()) {
+ nsTArray<RefPtr<nsAtom>> classes;
+ if (const nsAttrValue* attr = el->GetClasses()) {
+ for (uint32_t i = 0; i < attr->GetAtomCount(); i++) {
+ classes.AppendElement(attr->AtomAt(i));
+ }
+ }
+ if (!classes.IsEmpty()) {
+ fields->SetAttribute(CacheKey::DOMNodeClass, std::move(classes));
+ } else if (IsUpdatePush(CacheDomain::DOMNodeIDAndClass)) {
+ fields->SetAttribute(CacheKey::DOMNodeClass, DeleteEntry());
+ }
}
}