tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Maccessible/base/AccAttributes.cpp | 22++++++++++++++++++++++
Maccessible/base/AccAttributes.h | 6++++--
Maccessible/generic/LocalAccessible.cpp | 19+++++++++++++------
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()); + } } }