commit 3f346719e60d7ce37c38f0e30e2731a2076e6bde
parent 03e80f7313cfe2bd7fecf8d8777b671bdae35dd5
Author: Eitan Isaacson <eitan@monotonous.org>
Date: Fri, 3 Oct 2025 14:55:35 +0000
Bug 1990631 - P5: Implement Accessible::Role in Accessible. r=morgan
Use the newly refactored ARIATransformRole to transform a "minimal role"
to a final aria role remotely.
Differential Revision: https://phabricator.services.mozilla.com/D266501
Diffstat:
8 files changed, 58 insertions(+), 27 deletions(-)
diff --git a/accessible/basetypes/Accessible.cpp b/accessible/basetypes/Accessible.cpp
@@ -43,6 +43,16 @@ void Accessible::StaticAsserts() const {
"Accessible::mGenericType was oversized by eLastAccGenericType!");
}
+mozilla::a11y::role Accessible::Role() const {
+ const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
+ mozilla::a11y::role r =
+ (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole)
+ ? NativeRole()
+ : roleMapEntry->role;
+ r = ARIATransformRole(r);
+ return GetMinimumRole(r);
+}
+
bool Accessible::IsBefore(const Accessible* aAcc) const {
// Build the chain of parents.
const Accessible* thisP = this;
diff --git a/accessible/basetypes/Accessible.h b/accessible/basetypes/Accessible.h
@@ -181,8 +181,6 @@ class Accessible {
virtual Accessible* Parent() const = 0;
- virtual role Role() const = 0;
-
virtual role NativeRole() const = 0;
/**
@@ -197,6 +195,11 @@ class Accessible {
virtual int32_t IndexInParent() const = 0;
+ /**
+ * Returns the accessible's calculated, final, role.
+ */
+ role Role() const;
+
bool HasChildren() const { return !!FirstChild(); }
inline Accessible* FirstChild() const {
diff --git a/accessible/generic/LocalAccessible-inl.h b/accessible/generic/LocalAccessible-inl.h
@@ -20,16 +20,6 @@
namespace mozilla {
namespace a11y {
-inline mozilla::a11y::role LocalAccessible::Role() const {
- const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
- mozilla::a11y::role r =
- (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole)
- ? NativeRole()
- : roleMapEntry->role;
- r = ARIATransformRole(r);
- return GetMinimumRole(r);
-}
-
inline mozilla::a11y::role LocalAccessible::ARIARole() {
const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
if (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole) {
diff --git a/accessible/generic/LocalAccessible.h b/accessible/generic/LocalAccessible.h
@@ -167,11 +167,6 @@ class LocalAccessible : public nsISupports, public Accessible {
virtual void ApplyARIAState(uint64_t* aState) const;
/**
- * Return enumerated accessible role (see constants in Role.h).
- */
- virtual mozilla::a11y::role Role() const override;
-
- /**
* Return accessible role specified by ARIA (see constants in
* roles).
*/
diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp
@@ -76,7 +76,8 @@ AccessibleData DocAccessibleChild::SerializeAcc(LocalAccessible* aAcc) {
}
}
- return AccessibleData(aAcc->ID(), aAcc->Role(), aAcc->LocalParent()->ID(),
+ return AccessibleData(aAcc->ID(), aAcc->NativeRole(),
+ aAcc->LocalParent()->ID(),
static_cast<int32_t>(aAcc->IndexInParent()),
static_cast<AccType>(aAcc->mType),
static_cast<AccGenericType>(genericTypes),
diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp
@@ -840,7 +840,7 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvRoleChangedEvent(
return IPC_FAIL(this, "Invalid role map entry index");
}
- mRole = aRole;
+ mNativeRole = aRole;
mRoleMapEntryIndex = aRoleMapEntryIndex;
#ifdef MOZ_WIDGET_COCOA
diff --git a/accessible/ipc/RemoteAccessible.h b/accessible/ipc/RemoteAccessible.h
@@ -145,11 +145,11 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
LocalAccessible* OuterDocOfRemoteBrowser() const;
/**
- * Get the role of the accessible we're proxying.
+ * Get the native role of the accessible we're proxying.
*/
- virtual role Role() const override { return mRole; }
-
- virtual role NativeRole() const override { return role::NOTHING; }
+ virtual mozilla::a11y::role NativeRole() const override {
+ return mNativeRole;
+ }
/**
* Return true if this is an embedded object.
@@ -436,7 +436,7 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
mWrapper(0),
mID(aID),
mCachedFields(nullptr),
- mRole(aRole) {
+ mNativeRole(aRole) {
MOZ_COUNT_CTOR(RemoteAccessible);
}
@@ -446,7 +446,7 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
mWrapper(0),
mID(0),
mCachedFields(nullptr),
- mRole(roles::DOCUMENT) {
+ mNativeRole(roles::DOCUMENT) {
mGenericTypes = eDocument | eHyperText;
MOZ_COUNT_CTOR(RemoteAccessible);
}
@@ -535,7 +535,7 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
// XXX DocAccessibleParent gets to change this to change the role of
// documents.
- role mRole : 27;
+ role mNativeRole : 27;
};
////////////////////////////////////////////////////////////////////////////////
diff --git a/accessible/tests/browser/role/browser_roles_generic.js b/accessible/tests/browser/role/browser_roles_generic.js
@@ -338,7 +338,7 @@ addAccessibleTask(
<table role="application" id="application_table">application table
<tr><td>hi</td></tr></table>
<table role="aPPLICATIOn" id="application_table_mixed">application table
- <tr><td>hi</td></tr></table>
+ <tr><td>hi</td></tr></table>
<table role="banner" id="banner_table">banner table
<tr><td>hi</td></tr></table>
<table role="bANNEr" id="banner_table_mixed">banner table
@@ -721,3 +721,35 @@ addAccessibleTask(
},
{ chrome: true, topLevel: true }
);
+
+/**
+ * Test re-parented list item's role gets recomputed.
+ */
+addAccessibleTask(
+ `<div role="list" id="aria-list">
+ </div>
+ <div role="listitem" id="aria-listitem">Bananas</div>`,
+ async function testListItemRelocation(browser, accDoc) {
+ is(
+ findAccessibleChildByID(accDoc, "aria-listitem").role,
+ ROLE_SECTION,
+ "List item in list should have section role"
+ );
+
+ let evt = waitForEvent(EVENT_INNER_REORDER, "aria-list");
+ await invokeSetAttribute(
+ browser,
+ "aria-list",
+ "aria-owns",
+ "aria-listitem"
+ );
+ await evt;
+
+ is(
+ findAccessibleChildByID(accDoc, "aria-listitem").role,
+ ROLE_LISTITEM,
+ "List item in list should have listitem role"
+ );
+ },
+ { chrome: true, topLevel: true }
+);