commit 7b05d06773aeb756d37bc7d22f95543dc4104281
parent 5ee6854ffbe6ed627a3684fbe8d3481bd6081b4b
Author: James Teh <jteh@mozilla.com>
Date: Tue, 16 Dec 2025 22:44:23 +0000
Bug 1994032 part 2: Add Accessible::HasCustomActions. r=eeejay
Calling Accessible::Attributes is expensive and we don't want UIA doing this multiple times for multiple properties.
Differential Revision: https://phabricator.services.mozilla.com/D276600
Diffstat:
5 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/accessible/basetypes/Accessible.h b/accessible/basetypes/Accessible.h
@@ -794,6 +794,20 @@ class Accessible {
*/
virtual bool HasPrimaryAction() const = 0;
+ /**
+ * Return true if this Accessible has custom actions, even if those actions
+ * aren't currently available. Custom actions are secondary actions provided
+ * by the author using associated elements (e.g. via aria-actions), in
+ * contrast to actions provided by Gecko on the element itself (e.g. click).
+ * Custom actions are queried using RelationByType(RelationType::ACTION).
+ * However, there can be cases where there are associated custom actions, but
+ * the target elements are hidden; e.g. because the origin element isn't
+ * focused. The client might need to know there are actions even if it can't
+ * currently query them. For this case, this function will return true, even
+ * though RelationByType will return nothing.
+ */
+ virtual bool HasCustomActions() const = 0;
+
protected:
// Some abstracted group utility methods.
diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp
@@ -1121,7 +1121,7 @@ already_AddRefed<AccAttributes> LocalAccessible::Attributes() {
attribIter.ExposeAttr(attributes);
}
- if (nsAccUtils::HasARIAAttr(Elm(), nsGkAtoms::aria_actions)) {
+ if (HasCustomActions()) {
attributes->SetAttribute(nsGkAtoms::hasActions, true);
}
@@ -4091,7 +4091,7 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
fields->SetAttribute(CacheKey::ARIAAttributes, DeleteEntry());
}
- if (nsAccUtils::HasARIAAttr(Elm(), nsGkAtoms::aria_actions)) {
+ if (HasCustomActions()) {
fields->SetAttribute(CacheKey::HasActions, true);
} else if (IsUpdatePush(CacheDomain::ARIA)) {
fields->SetAttribute(CacheKey::HasActions, DeleteEntry());
@@ -4566,3 +4566,8 @@ bool LocalAccessible::HasARIAAttr(nsAtom* aAttrName) const {
return mContent ? nsAccUtils::HasDefinedARIAToken(mContent, aAttrName)
: false;
}
+
+bool LocalAccessible::HasCustomActions() const {
+ dom::Element* el = Elm();
+ return el && nsAccUtils::HasARIAAttr(el, nsGkAtoms::aria_actions);
+}
diff --git a/accessible/generic/LocalAccessible.h b/accessible/generic/LocalAccessible.h
@@ -496,6 +496,8 @@ class LocalAccessible : public nsISupports, public Accessible {
virtual bool DoAction(uint8_t aIndex) const override;
+ virtual bool HasCustomActions() const override;
+
virtual KeyBinding AccessKey() const override;
/**
diff --git a/accessible/ipc/RemoteAccessible.cpp b/accessible/ipc/RemoteAccessible.cpp
@@ -1952,9 +1952,8 @@ already_AddRefed<AccAttributes> RemoteAccessible::Attributes() {
attributes->SetAttribute(nsGkAtoms::ispopup, std::move(popupType));
}
- if (auto hasActions =
- mCachedFields->GetAttribute<bool>(CacheKey::HasActions)) {
- attributes->SetAttribute(nsGkAtoms::hasActions, *hasActions);
+ if (HasCustomActions()) {
+ attributes->SetAttribute(nsGkAtoms::hasActions, true);
}
nsString detailsFrom;
@@ -2668,6 +2667,14 @@ void RemoteAccessible::PasteText(int32_t aPosition) {
(void)mDoc->SendPasteText(mID, aPosition);
}
+bool RemoteAccessible::HasCustomActions() const {
+ if (RequestDomainsIfInactive(CacheDomain::ARIA) || !mCachedFields) {
+ return false;
+ }
+ auto hasActions = mCachedFields->GetAttribute<bool>(CacheKey::HasActions);
+ return hasActions && *hasActions;
+}
+
size_t RemoteAccessible::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
diff --git a/accessible/ipc/RemoteAccessible.h b/accessible/ipc/RemoteAccessible.h
@@ -392,6 +392,7 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
virtual bool HasPrimaryAction() const override;
+ virtual bool HasCustomActions() const override;
virtual bool IsEditable() const override;
#if !defined(XP_WIN)