tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Maccessible/base/ARIAMap.cpp | 18+++++++++++-------
Maccessible/base/ARIAMap.h | 11++++++-----
Maccessible/base/nsAccUtils.cpp | 4++--
Maccessible/base/nsAccUtils.h | 2+-
Maccessible/basetypes/Accessible.cpp | 191+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Maccessible/basetypes/Accessible.h | 19+++++++++++++++++++
Maccessible/generic/LocalAccessible.cpp | 197-------------------------------------------------------------------------------
Maccessible/generic/LocalAccessible.h | 18+-----------------
Maccessible/ipc/RemoteAccessible.h | 2++
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. */