commit 03e80f7313cfe2bd7fecf8d8777b671bdae35dd5
parent c3b7d1644108660a1186b89fb7c4b60d30088854
Author: Eitan Isaacson <eitan@monotonous.org>
Date: Fri, 3 Oct 2025 14:55:34 +0000
Bug 1990631 - P4: Move ARIATransformRole to Accessible. r=morgan
This will allow us to perform the aria role transform remotely in a
future patch.
Also moved NativeRole to Accessible with temporary implementation in
RemoteAccessible.
Differential Revision: https://phabricator.services.mozilla.com/D266500
Diffstat:
9 files changed, 233 insertions(+), 229 deletions(-)
diff --git a/accessible/base/ARIAMap.cpp b/accessible/base/ARIAMap.cpp
@@ -1482,7 +1482,7 @@ static const AttrCharacteristics gWAIUnivAttrMap[] = {
{nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL | ATTR_REFLECT_ELEMENTS },
{nsGkAtoms::aria_orientation, ATTR_VALTOKEN },
{nsGkAtoms::aria_posinset, ATTR_BYPASSOBJ }, /* handled via groupPosition */
- {nsGkAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
+ {nsGkAtoms::aria_pressed, ATTR_VALTOKEN },
{nsGkAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
{nsGkAtoms::aria_relevant, ATTR_GLOBAL },
{nsGkAtoms::aria_required, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
@@ -1503,15 +1503,14 @@ const nsRoleMapEntry* aria::GetRoleMap(dom::Element* aEl) {
}
uint8_t aria::GetFirstValidRoleMapIndexExcluding(
- dom::Element* aEl, std::initializer_list<nsStaticAtom*> aRolesToSkip) {
- nsAutoString roles;
- if (!aEl || !nsAccUtils::GetARIAAttr(aEl, nsGkAtoms::role, roles) ||
- roles.IsEmpty()) {
+ const nsString& aRoleAttrValue,
+ std::initializer_list<nsStaticAtom*> aRolesToSkip) {
+ if (aRoleAttrValue.IsEmpty()) {
// We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
return NO_ROLE_MAP_ENTRY_INDEX;
}
- nsWhitespaceTokenizer tokenizer(roles);
+ nsWhitespaceTokenizer tokenizer(aRoleAttrValue);
while (tokenizer.hasMoreTokens()) {
// Do a binary search through table for the next role in role list
const nsDependentSubstring role = tokenizer.nextToken();
@@ -1546,8 +1545,13 @@ uint8_t aria::GetFirstValidRoleMapIndexExcluding(
}
uint8_t aria::GetRoleMapIndex(dom::Element* aEl) {
+ nsAutoString roles;
+ if (!aEl || !nsAccUtils::GetARIAAttr(aEl, nsGkAtoms::role, roles)) {
+ return NO_ROLE_MAP_ENTRY_INDEX;
+ }
+
// Get the rolemap index of the first valid role, excluding nothing.
- return GetFirstValidRoleMapIndexExcluding(aEl, {});
+ return GetFirstValidRoleMapIndexExcluding(roles, {});
}
const nsRoleMapEntry* aria::GetRoleMapFromIndex(uint8_t aRoleMapIndex) {
diff --git a/accessible/base/ARIAMap.h b/accessible/base/ARIAMap.h
@@ -245,13 +245,14 @@ const nsRoleMapEntry* GetRoleMap(dom::Element* aEl);
* given roles. This will use the first valid ARIA role if the role attribute
* provides a space delimited list of roles, excluding any given roles.
*
- * @param aEl [in] the DOM node to get the role map entry for
- * @param aRolesToSkip [in] the roles to skip when searching the role string
- * @return the index of the pointer to the role map entry for the
- * ARIA role, or NO_ROLE_MAP_ENTRY_INDEX if none
+ * @param aRoleAttrValue [in] the string value of the aria role(s)
+ * @param aRolesToSkip [in] the roles to skip when searching the role string
+ * @return the index of the pointer to the role map entry for the
+ * ARIA role, or NO_ROLE_MAP_ENTRY_INDEX if none
*/
uint8_t GetFirstValidRoleMapIndexExcluding(
- dom::Element* aEl, std::initializer_list<nsStaticAtom*> aRolesToSkip);
+ const nsString& aRoleAttrValue,
+ std::initializer_list<nsStaticAtom*> aRolesToSkip);
/**
* Get the role map entry pointer's index for a given DOM node. This will use
diff --git a/accessible/base/nsAccUtils.cpp b/accessible/base/nsAccUtils.cpp
@@ -221,12 +221,12 @@ bool nsAccUtils::IsDOMAttrTrue(const LocalAccessible* aAccessible,
return el && ARIAAttrValueIs(el, aAttr, nsGkAtoms::_true, eCaseMatters);
}
-Accessible* nsAccUtils::TableFor(Accessible* aAcc) {
+Accessible* nsAccUtils::TableFor(const Accessible* aAcc) {
if (!aAcc ||
(!aAcc->IsTable() && !aAcc->IsTableRow() && !aAcc->IsTableCell())) {
return nullptr;
}
- Accessible* table = aAcc;
+ Accessible* table = const_cast<Accessible*>(aAcc);
for (; table && !table->IsTable(); table = table->Parent()) {
}
// We don't assert (table && table->IsTable()) here because
diff --git a/accessible/base/nsAccUtils.h b/accessible/base/nsAccUtils.h
@@ -104,7 +104,7 @@ class nsAccUtils {
*/
static HyperTextAccessible* GetTextContainer(nsINode* aNode);
- static Accessible* TableFor(Accessible* aRow);
+ static Accessible* TableFor(const Accessible* aRow);
static LocalAccessible* TableFor(LocalAccessible* aRow);
static const LocalAccessible* TableFor(const LocalAccessible* aAcc) {
diff --git a/accessible/basetypes/Accessible.cpp b/accessible/basetypes/Accessible.cpp
@@ -819,3 +819,194 @@ void KeyBinding::ToAtkFormat(nsAString& aValue) const {
aValue.Append(mKey);
}
+
+role Accessible::FindNextValidARIARole(
+ std::initializer_list<nsStaticAtom*> aRolesToSkip) const {
+ const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
+ if (roleMapEntry) {
+ if (!ARIAAttrValueIs(nsGkAtoms::role, roleMapEntry->roleAtom)) {
+ nsAutoString roles;
+ GetStringARIAAttr(nsGkAtoms::role, roles);
+ // Get the next valid token that isn't in the list of roles to skip.
+ uint8_t roleMapIndex =
+ aria::GetFirstValidRoleMapIndexExcluding(roles, aRolesToSkip);
+ // If we don't find a valid token, fall back to the minimum role.
+ if (roleMapIndex == aria::NO_ROLE_MAP_ENTRY_INDEX ||
+ roleMapIndex == aria::LANDMARK_ROLE_MAP_ENTRY_INDEX) {
+ return NativeRole();
+ }
+ const nsRoleMapEntry* fallbackRoleMapEntry =
+ aria::GetRoleMapFromIndex(roleMapIndex);
+ if (!fallbackRoleMapEntry) {
+ return NativeRole();
+ }
+ // Return the next valid role, but validate that first, too.
+ return ARIATransformRole(fallbackRoleMapEntry->role);
+ }
+ }
+ // Fall back to the minimum role.
+ return NativeRole();
+}
+
+role Accessible::ARIATransformRole(role aRole) const {
+ // Beginning with ARIA 1.1, user agents are expected to use the native host
+ // language role of the element when the form or region roles are used without
+ // a name. Says the spec, "the user agent MUST treat such elements as if no
+ // role had been provided."
+ // https://w3c.github.io/aria/#document-handling_author-errors_roles
+ //
+ // XXX: While the name computation algorithm can be non-trivial in the general
+ // case, it should not be especially bad here: If the author hasn't used the
+ // region role, this calculation won't occur. And the region role's name
+ // calculation rule excludes name from content. That said, this use case is
+ // another example of why we should consider caching the accessible name. See:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
+ if (aRole == roles::REGION || aRole == roles::FORM) {
+ if (NameIsEmpty()) {
+ // If we have a "form" or "region" role, but no accessible name, we need
+ // to search for the next valid role. First, we search through the role
+ // attribute value string - there might be a valid fallback there. Skip
+ // all "form" or "region" attributes; we know they're not valid since
+ // there's no accessible name. If we find a valid role that's not "form"
+ // or "region", fall back to it (but run it through ARIATransformRole
+ // first). Otherwise, fall back to the element's native role.
+ return FindNextValidARIARole({nsGkAtoms::region, nsGkAtoms::form});
+ }
+ return aRole;
+ }
+
+ // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
+ // where the accessible role depends on both the role and ARIA state.
+ if (aRole == roles::PUSHBUTTON) {
+ if (HasARIAAttr(nsGkAtoms::aria_pressed)) {
+ // For simplicity, any existing pressed attribute except "" or "undefined"
+ // indicates a toggle.
+ return roles::TOGGLE_BUTTON;
+ }
+
+ if (ARIAAttrValueIs(nsGkAtoms::aria_haspopup, nsGkAtoms::_true)) {
+ // For button with aria-haspopup="true".
+ return roles::BUTTONMENU;
+ }
+
+ } else if (aRole == roles::LISTBOX) {
+ // A listbox inside of a combobox needs a special role because of ATK
+ // mapping to menu.
+ if (Parent() && Parent()->IsCombobox()) {
+ return roles::COMBOBOX_LIST;
+ }
+
+ } else if (aRole == roles::OPTION) {
+ if (Parent() && Parent()->Role() == roles::COMBOBOX_LIST) {
+ return roles::COMBOBOX_OPTION;
+ }
+
+ // Orphaned option outside the context of a listbox.
+ const Accessible* listbox = FindAncestorIf([](const Accessible& aAcc) {
+ const role accRole = aAcc.Role();
+ return accRole == roles::LISTBOX ? AncestorSearchOption::Found
+ : accRole == roles::GROUPING ? AncestorSearchOption::Continue
+ : AncestorSearchOption::NotFound;
+ });
+ if (!listbox) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::MENUITEM) {
+ // Menuitem has a submenu.
+ if (ARIAAttrValueIs(nsGkAtoms::aria_haspopup, nsGkAtoms::_true)) {
+ return roles::PARENT_MENUITEM;
+ }
+
+ // Orphaned menuitem outside the context of a menu/menubar.
+ const Accessible* menu = FindAncestorIf([](const Accessible& aAcc) {
+ const role accRole = aAcc.Role();
+ return (accRole == roles::MENUBAR || accRole == roles::MENUPOPUP)
+ ? AncestorSearchOption::Found
+ : accRole == roles::GROUPING ? AncestorSearchOption::Continue
+ : AncestorSearchOption::NotFound;
+ });
+ if (!menu) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::RADIO_MENU_ITEM ||
+ aRole == roles::CHECK_MENU_ITEM) {
+ // Orphaned radio/checkbox menuitem outside the context of a menu/menubar.
+ const Accessible* menu = FindAncestorIf([](const Accessible& aAcc) {
+ const role accRole = aAcc.Role();
+ return (accRole == roles::MENUBAR || accRole == roles::MENUPOPUP)
+ ? AncestorSearchOption::Found
+ : accRole == roles::GROUPING ? AncestorSearchOption::Continue
+ : AncestorSearchOption::NotFound;
+ });
+ if (!menu) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::CELL) {
+ // A cell inside an ancestor table element that has a grid role needs a
+ // gridcell role
+ // (https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings).
+ const Accessible* table = nsAccUtils::TableFor(this);
+ if (table && table->IsARIARole(nsGkAtoms::grid)) {
+ return roles::GRID_CELL;
+ }
+ } else if (aRole == roles::ROW) {
+ // Orphaned rows outside the context of a table.
+ const Accessible* table = nsAccUtils::TableFor(this);
+ if (!table) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::ROWGROUP) {
+ // Orphaned rowgroups outside the context of a table.
+ const Accessible* table = FindAncestorIf([](const Accessible& aAcc) {
+ return aAcc.IsTable() ? AncestorSearchOption::Found
+ : AncestorSearchOption::NotFound;
+ });
+ if (!table) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::GRID_CELL || aRole == roles::ROWHEADER ||
+ aRole == roles::COLUMNHEADER) {
+ // Orphaned gridcell/rowheader/columnheader outside the context of a row.
+ const Accessible* row = FindAncestorIf([](const Accessible& aAcc) {
+ return aAcc.IsTableRow() ? AncestorSearchOption::Found
+ : AncestorSearchOption::NotFound;
+ });
+ if (!row) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::LISTITEM) {
+ // doc-biblioentry and doc-endnote should not be treated as listitems.
+ const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
+ if (!roleMapEntry || (roleMapEntry->roleAtom != nsGkAtoms::docBiblioentry &&
+ roleMapEntry->roleAtom != nsGkAtoms::docEndnote)) {
+ // Orphaned listitem outside the context of a list.
+ const Accessible* list = FindAncestorIf([](const Accessible& aAcc) {
+ return aAcc.IsList() ? AncestorSearchOption::Found
+ : AncestorSearchOption::Continue;
+ });
+ if (!list) {
+ return NativeRole();
+ }
+ }
+ } else if (aRole == roles::PAGETAB) {
+ // Orphaned tab outside the context of a tablist.
+ const Accessible* tablist = FindAncestorIf([](const Accessible& aAcc) {
+ return aAcc.Role() == roles::PAGETABLIST ? AncestorSearchOption::Found
+ : AncestorSearchOption::NotFound;
+ });
+ if (!tablist) {
+ return NativeRole();
+ }
+ } else if (aRole == roles::OUTLINEITEM) {
+ // Orphaned treeitem outside the context of a tree.
+ const Accessible* tree = FindAncestorIf([](const Accessible& aAcc) {
+ return aAcc.Role() == roles::OUTLINE ? AncestorSearchOption::Found
+ : AncestorSearchOption::Continue;
+ });
+ if (!tree) {
+ return NativeRole();
+ }
+ }
+
+ return aRole;
+}
diff --git a/accessible/basetypes/Accessible.h b/accessible/basetypes/Accessible.h
@@ -183,6 +183,8 @@ class Accessible {
virtual role Role() const = 0;
+ virtual role NativeRole() const = 0;
+
/**
* Return child accessible at the given index.
*/
@@ -829,12 +831,29 @@ class Accessible {
*/
mozilla::a11y::role GetMinimumRole(mozilla::a11y::role aRole) const;
+ /**
+ * Given a role and an accessible's state, parentage, and other attributes
+ * transform the role to reflect its correct aria role.
+ */
+ mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole) const;
+
private:
static const uint8_t kTypeBits = 6;
static const uint8_t kGenericTypesBits = 18;
void StaticAsserts() const;
+ /*
+ * This function assumes that the current role is not valid. It searches for a
+ * fallback role in the role attribute string, and returns it. If there is no
+ * valid fallback role in the role attribute string, the function returns the
+ * native role. The aRolesToSkip parameter will cause the function to skip any
+ * roles found in the role attribute string when searching for the next valid
+ * role.
+ */
+ role FindNextValidARIARole(
+ std::initializer_list<nsStaticAtom*> aRolesToSkip) const;
+
protected:
uint32_t mType : kTypeBits;
uint32_t mGenericTypes : kGenericTypesBits;
diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp
@@ -1833,203 +1833,6 @@ double LocalAccessible::CurValue() const {
bool LocalAccessible::SetCurValue(double aValue) { return false; }
-role LocalAccessible::FindNextValidARIARole(
- std::initializer_list<nsStaticAtom*> aRolesToSkip) const {
- const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
- if (roleMapEntry && mContent && mContent->IsElement()) {
- dom::Element* elem = mContent->AsElement();
- if (!nsAccUtils::ARIAAttrValueIs(elem, nsGkAtoms::role,
- roleMapEntry->roleAtom, eIgnoreCase)) {
- // Get the next valid token that isn't in the list of roles to skip.
- uint8_t roleMapIndex =
- aria::GetFirstValidRoleMapIndexExcluding(elem, aRolesToSkip);
- // If we don't find a valid token, fall back to the native role.
- if (roleMapIndex == aria::NO_ROLE_MAP_ENTRY_INDEX ||
- roleMapIndex == aria::LANDMARK_ROLE_MAP_ENTRY_INDEX) {
- return NativeRole();
- }
- const nsRoleMapEntry* fallbackRoleMapEntry =
- aria::GetRoleMapFromIndex(roleMapIndex);
- if (!fallbackRoleMapEntry) {
- return NativeRole();
- }
- // Return the next valid role, but validate that first, too.
- return ARIATransformRole(fallbackRoleMapEntry->role);
- }
- }
- // Fall back to the native role.
- return NativeRole();
-}
-
-role LocalAccessible::ARIATransformRole(role aRole) const {
- // Beginning with ARIA 1.1, user agents are expected to use the native host
- // language role of the element when the form or region roles are used without
- // a name. Says the spec, "the user agent MUST treat such elements as if no
- // role had been provided."
- // https://w3c.github.io/aria/#document-handling_author-errors_roles
- //
- // XXX: While the name computation algorithm can be non-trivial in the general
- // case, it should not be especially bad here: If the author hasn't used the
- // region role, this calculation won't occur. And the region role's name
- // calculation rule excludes name from content. That said, this use case is
- // another example of why we should consider caching the accessible name. See:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1378235.
- if (aRole == roles::REGION || aRole == roles::FORM) {
- if (NameIsEmpty()) {
- // If we have a "form" or "region" role, but no accessible name, we need
- // to search for the next valid role. First, we search through the role
- // attribute value string - there might be a valid fallback there. Skip
- // all "form" or "region" attributes; we know they're not valid since
- // there's no accessible name. If we find a valid role that's not "form"
- // or "region", fall back to it (but run it through ARIATransformRole
- // first). Otherwise, fall back to the element's native role.
- return FindNextValidARIARole({nsGkAtoms::region, nsGkAtoms::form});
- }
- return aRole;
- }
-
- // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
- // where the accessible role depends on both the role and ARIA state.
- if (aRole == roles::PUSHBUTTON) {
- if (nsAccUtils::HasDefinedARIAToken(mContent, nsGkAtoms::aria_pressed)) {
- // For simplicity, any existing pressed attribute except "" or "undefined"
- // indicates a toggle.
- return roles::TOGGLE_BUTTON;
- }
-
- if (mContent->IsElement() &&
- nsAccUtils::ARIAAttrValueIs(mContent->AsElement(),
- nsGkAtoms::aria_haspopup, nsGkAtoms::_true,
- eCaseMatters)) {
- // For button with aria-haspopup="true".
- return roles::BUTTONMENU;
- }
-
- } else if (aRole == roles::LISTBOX) {
- // A listbox inside of a combobox needs a special role because of ATK
- // mapping to menu.
- if (mParent && mParent->IsCombobox()) {
- return roles::COMBOBOX_LIST;
- }
-
- } else if (aRole == roles::OPTION) {
- if (mParent && mParent->Role() == roles::COMBOBOX_LIST) {
- return roles::COMBOBOX_OPTION;
- }
-
- // Orphaned option outside the context of a listbox.
- const Accessible* listbox = FindAncestorIf([](const Accessible& aAcc) {
- const role accRole = aAcc.Role();
- return accRole == roles::LISTBOX ? AncestorSearchOption::Found
- : accRole == roles::GROUPING ? AncestorSearchOption::Continue
- : AncestorSearchOption::NotFound;
- });
- if (!listbox) {
- return NativeRole();
- }
- } else if (aRole == roles::MENUITEM) {
- // Menuitem has a submenu.
- if (mContent->IsElement() &&
- nsAccUtils::ARIAAttrValueIs(mContent->AsElement(),
- nsGkAtoms::aria_haspopup, nsGkAtoms::_true,
- eCaseMatters)) {
- return roles::PARENT_MENUITEM;
- }
-
- // Orphaned menuitem outside the context of a menu/menubar.
- const Accessible* menu = FindAncestorIf([](const Accessible& aAcc) {
- const role accRole = aAcc.Role();
- return (accRole == roles::MENUBAR || accRole == roles::MENUPOPUP)
- ? AncestorSearchOption::Found
- : accRole == roles::GROUPING ? AncestorSearchOption::Continue
- : AncestorSearchOption::NotFound;
- });
- if (!menu) {
- return NativeRole();
- }
- } else if (aRole == roles::RADIO_MENU_ITEM ||
- aRole == roles::CHECK_MENU_ITEM) {
- // Orphaned radio/checkbox menuitem outside the context of a menu/menubar.
- const Accessible* menu = FindAncestorIf([](const Accessible& aAcc) {
- const role accRole = aAcc.Role();
- return (accRole == roles::MENUBAR || accRole == roles::MENUPOPUP)
- ? AncestorSearchOption::Found
- : accRole == roles::GROUPING ? AncestorSearchOption::Continue
- : AncestorSearchOption::NotFound;
- });
- if (!menu) {
- return NativeRole();
- }
- } else if (aRole == roles::CELL) {
- // A cell inside an ancestor table element that has a grid role needs a
- // gridcell role
- // (https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings).
- const LocalAccessible* table = nsAccUtils::TableFor(this);
- if (table && table->IsARIARole(nsGkAtoms::grid)) {
- return roles::GRID_CELL;
- }
- } else if (aRole == roles::ROW) {
- // Orphaned rows outside the context of a table.
- const LocalAccessible* table = nsAccUtils::TableFor(this);
- if (!table) {
- return NativeRole();
- }
- } else if (aRole == roles::ROWGROUP) {
- // Orphaned rowgroups outside the context of a table.
- const Accessible* table = FindAncestorIf([](const Accessible& aAcc) {
- return aAcc.IsTable() ? AncestorSearchOption::Found
- : AncestorSearchOption::NotFound;
- });
- if (!table) {
- return NativeRole();
- }
- } else if (aRole == roles::GRID_CELL || aRole == roles::ROWHEADER ||
- aRole == roles::COLUMNHEADER) {
- // Orphaned gridcell/rowheader/columnheader outside the context of a row.
- const Accessible* row = FindAncestorIf([](const Accessible& aAcc) {
- return aAcc.IsTableRow() ? AncestorSearchOption::Found
- : AncestorSearchOption::NotFound;
- });
- if (!row) {
- return NativeRole();
- }
- } else if (aRole == roles::LISTITEM) {
- // doc-biblioentry and doc-endnote should not be treated as listitems.
- const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
- if (!roleMapEntry || (roleMapEntry->roleAtom != nsGkAtoms::docBiblioentry &&
- roleMapEntry->roleAtom != nsGkAtoms::docEndnote)) {
- // Orphaned listitem outside the context of a list.
- const Accessible* list = FindAncestorIf([](const Accessible& aAcc) {
- return aAcc.IsList() ? AncestorSearchOption::Found
- : AncestorSearchOption::Continue;
- });
- if (!list) {
- return NativeRole();
- }
- }
- } else if (aRole == roles::PAGETAB) {
- // Orphaned tab outside the context of a tablist.
- const Accessible* tablist = FindAncestorIf([](const Accessible& aAcc) {
- return aAcc.Role() == roles::PAGETABLIST ? AncestorSearchOption::Found
- : AncestorSearchOption::NotFound;
- });
- if (!tablist) {
- return NativeRole();
- }
- } else if (aRole == roles::OUTLINEITEM) {
- // Orphaned treeitem outside the context of a tree.
- const Accessible* tree = FindAncestorIf([](const Accessible& aAcc) {
- return aAcc.Role() == roles::OUTLINE ? AncestorSearchOption::Found
- : AncestorSearchOption::Continue;
- });
- if (!tree) {
- return NativeRole();
- }
- }
-
- return aRole;
-}
-
role LocalAccessible::NativeRole() const { return roles::NOTHING; }
uint8_t LocalAccessible::ActionCount() const {
diff --git a/accessible/generic/LocalAccessible.h b/accessible/generic/LocalAccessible.h
@@ -181,7 +181,7 @@ class LocalAccessible : public nsISupports, public Accessible {
* Returns enumerated accessible role from native markup (see constants in
* Role.h). Doesn't take into account ARIA roles.
*/
- virtual mozilla::a11y::role NativeRole() const;
+ virtual mozilla::a11y::role NativeRole() const override;
virtual uint64_t State() override;
@@ -867,11 +867,6 @@ class LocalAccessible : public nsISupports, public Accessible {
//////////////////////////////////////////////////////////////////////////////
// Miscellaneous helpers
- /**
- * Return ARIA role (helper method).
- */
- mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole) const;
-
//////////////////////////////////////////////////////////////////////////////
// Name helpers
@@ -1035,17 +1030,6 @@ class LocalAccessible : public nsISupports, public Accessible {
*/
nsIFrame* FindNearestAccessibleAncestorFrame();
- /*
- * This function assumes that the current role is not valid. It searches for a
- * fallback role in the role attribute string, and returns it. If there is no
- * valid fallback role in the role attribute string, the function returns the
- * native role. The aRolesToSkip parameter will cause the function to skip any
- * roles found in the role attribute string when searching for the next valid
- * role.
- */
- role FindNextValidARIARole(
- std::initializer_list<nsStaticAtom*> aRolesToSkip) const;
-
LocalAccessible* GetCommandForDetailsRelation() const;
LocalAccessible* GetPopoverTargetDetailsRelation() const;
diff --git a/accessible/ipc/RemoteAccessible.h b/accessible/ipc/RemoteAccessible.h
@@ -149,6 +149,8 @@ class RemoteAccessible : public Accessible, public HyperTextAccessibleBase {
*/
virtual role Role() const override { return mRole; }
+ virtual role NativeRole() const override { return role::NOTHING; }
+
/**
* Return true if this is an embedded object.
*/