diff --git a/accessible/ipc/RemoteAccessibleBase.cpp b/accessible/ipc/RemoteAccessibleBase.cpp index ce8bf097df5a..d649be61d9b6 100644 --- a/accessible/ipc/RemoteAccessibleBase.cpp +++ b/accessible/ipc/RemoteAccessibleBase.cpp @@ -626,6 +626,50 @@ LayoutDeviceIntRect RemoteAccessibleBase::Bounds() const { return BoundsWithOffset(Nothing()); } +template +nsTArray RemoteAccessibleBase::RelationByType( + RelationType aType) const { + nsTArray accs; + + if (!mCachedFields) { + return accs; + } + + for (auto data : kRelationTypeAtoms) { + if (data.mType != aType || + (data.mValidTag && TagName() != data.mValidTag)) { + continue; + } + + if (auto maybeIds = + mCachedFields->GetAttribute>(data.mAtom)) { + for (uint64_t id : *maybeIds) { + if (RemoteAccessible* acc = mDoc->GetAccessible(id)) { + accs.AppendElement(acc); + } + } + } + // Each relation type has only one relevant cached attribute, + // so break after we've handled the attr for this type, + // even if we didn't find any targets. + break; + } + + if (auto accRelMapEntry = mDoc->mReverseRelations.Lookup(ID())) { + if (auto reverseIdsEntry = + accRelMapEntry.Data().Lookup(static_cast(aType))) { + nsTArray& reverseIds = reverseIdsEntry.Data(); + for (uint64_t id : reverseIds) { + if (RemoteAccessible* acc = mDoc->GetAccessible(id)) { + accs.AppendElement(acc); + } + } + } + } + + return accs; +} + template void RemoteAccessibleBase::AppendTextTo(nsAString& aText, uint32_t aStartOffset, diff --git a/accessible/ipc/RemoteAccessibleBase.h b/accessible/ipc/RemoteAccessibleBase.h index e21ff2250667..1b562b131668 100644 --- a/accessible/ipc/RemoteAccessibleBase.h +++ b/accessible/ipc/RemoteAccessibleBase.h @@ -183,6 +183,8 @@ class RemoteAccessibleBase : public Accessible, public HyperTextAccessibleBase { virtual nsRect BoundsInAppUnits() const override; + virtual nsTArray RelationByType(RelationType aType) const; + virtual uint64_t State() override; virtual already_AddRefed Attributes() override; diff --git a/accessible/ipc/RemoteAccessibleShared.h b/accessible/ipc/RemoteAccessibleShared.h index fd5e91b33985..4ce0f5aa8673 100644 --- a/accessible/ipc/RemoteAccessibleShared.h +++ b/accessible/ipc/RemoteAccessibleShared.h @@ -51,13 +51,8 @@ virtual already_AddRefed Attributes() override; /** * Return set of targets of given relation type. */ -nsTArray RelationByType(RelationType aType) const; - -/** - * Get all relations for this accessible. - */ -void Relations(nsTArray* aTypes, - nsTArray>* aTargetSets) const; +virtual nsTArray RelationByType( + RelationType aType) const override; bool IsSearchbox() const; diff --git a/accessible/ipc/other/RemoteAccessible.cpp b/accessible/ipc/other/RemoteAccessible.cpp index d5adff2c5247..7ed86b2f2779 100644 --- a/accessible/ipc/other/RemoteAccessible.cpp +++ b/accessible/ipc/other/RemoteAccessible.cpp @@ -78,6 +78,10 @@ already_AddRefed RemoteAccessible::Attributes() { nsTArray RemoteAccessible::RelationByType( RelationType aType) const { + if (StaticPrefs::accessibility_cache_enabled_AtStartup()) { + return RemoteAccessibleBase::RelationByType(aType); + } + nsTArray targetIDs; Unused << mDoc->SendRelationByType(mID, static_cast(aType), &targetIDs); diff --git a/accessible/ipc/other/RemoteAccessible.h b/accessible/ipc/other/RemoteAccessible.h index 363ad3493924..afed32df27f2 100644 --- a/accessible/ipc/other/RemoteAccessible.h +++ b/accessible/ipc/other/RemoteAccessible.h @@ -77,6 +77,12 @@ class RemoteAccessible : public RemoteAccessibleBase { virtual bool TableIsProbablyForLayout() override; + /** + * Get all relations for this accessible. + */ + void Relations(nsTArray* aTypes, + nsTArray>* aTargetSets) const; + protected: explicit RemoteAccessible(DocAccessibleParent* aThisAsDoc) : RemoteAccessibleBase(aThisAsDoc) { diff --git a/accessible/ipc/win/RemoteAccessible.cpp b/accessible/ipc/win/RemoteAccessible.cpp index 15b25ebb62ea..4bfe09dfd35f 100644 --- a/accessible/ipc/win/RemoteAccessible.cpp +++ b/accessible/ipc/win/RemoteAccessible.cpp @@ -392,6 +392,10 @@ already_AddRefed RemoteAccessible::Attributes() { nsTArray RemoteAccessible::RelationByType( RelationType aType) const { + if (StaticPrefs::accessibility_cache_enabled_AtStartup()) { + return RemoteAccessibleBase::RelationByType(aType); + } + RefPtr acc = QueryInterface(this); if (!acc) { return nsTArray();