From 7f79cc04000f982b0787328d68b671ef08731265 Mon Sep 17 00:00:00 2001 From: James Teh Date: Mon, 1 Nov 2021 23:27:39 +0000 Subject: [PATCH] Bug 1730096 part 6: Add AccAttributes::CopyTo to copy an AccAttributes. r=eeejay This is necessary for two reasons: 1. Leaf text attributes and default text attributes are cached separately, since the caller can choose whether to include defaults or not. This means merging them together. 2. Methods for retrieving attributes currently return a non-const AccAttributes. We might be able to change this in future for some of them, but I didn't want to deal with that in this work. Differential Revision: https://phabricator.services.mozilla.com/D129472 --- accessible/base/AccAttributes.cpp | 48 +++++++++++++++++++++++++++++++ accessible/base/AccAttributes.h | 9 ++++++ 2 files changed, 57 insertions(+) diff --git a/accessible/base/AccAttributes.cpp b/accessible/base/AccAttributes.cpp index 238d22831348..79a8f8860696 100644 --- a/accessible/base/AccAttributes.cpp +++ b/accessible/base/AccAttributes.cpp @@ -98,3 +98,51 @@ bool AccAttributes::Equal(const AccAttributes* aOther) const { } return true; } + +void AccAttributes::CopyTo(AccAttributes* aDest) const { + for (auto iter = mData.ConstIter(); !iter.Done(); iter.Next()) { + iter.Data().match( + [&iter, &aDest](const bool& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const float& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const double& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const int32_t& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const RefPtr& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [](const nsTArray& val) { + // We don't copy arrays. + MOZ_ASSERT_UNREACHABLE( + "Trying to copy an AccAttributes containing an array"); + }, + [&iter, &aDest](const CSSCoord& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const FontSize& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [&iter, &aDest](const Color& val) { + aDest->mData.InsertOrUpdate(iter.Key(), AsVariant(val)); + }, + [](const DeleteEntry& val) { + // We don't copy DeleteEntry. + MOZ_ASSERT_UNREACHABLE( + "Trying to copy an AccAttributes containing a DeleteEntry"); + }, + [&iter, &aDest](const UniquePtr& val) { + aDest->SetAttributeStringCopy(iter.Key(), *val); + }, + [](const RefPtr& val) { + // We don't copy nested AccAttributes. + MOZ_ASSERT_UNREACHABLE( + "Trying to copy an AccAttributes containing an AccAttributes"); + }); + } +} diff --git a/accessible/base/AccAttributes.h b/accessible/base/AccAttributes.h index 3584626f31cd..2e8e3a67ab17 100644 --- a/accessible/base/AccAttributes.h +++ b/accessible/base/AccAttributes.h @@ -151,6 +151,15 @@ class AccAttributes { */ bool Equal(const AccAttributes* aOther) const; + /** + * Copy attributes from this instance to another instance. + * This should only be used in very specific cases; e.g. merging two sets of + * cached attributes without modifying the cache. It can only copy simple + * value types; e.g. it can't copy array values. Attempting to copy an + * AccAttributes with uncopyable values will cause an assertion. + */ + void CopyTo(AccAttributes* aDest) const; + // An entry class for our iterator. class Entry { public: