Skip to content

Commit 1c409d8

Browse files
committed
Bug 1870783 part 1: Expose a minimum role of GROUPING for popovers. r=eeejay
Differential Revision: https://phabricator.services.mozilla.com/D196944
1 parent a4f3e10 commit 1c409d8

File tree

6 files changed

+91
-5
lines changed

6 files changed

+91
-5
lines changed

accessible/generic/DocAccessible.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,12 @@ bool DocAccessible::UpdateAccessibleOnAttrChange(dom::Element* aElement,
18631863
return true;
18641864
}
18651865

1866+
if (aAttribute == nsGkAtoms::popover && aElement->IsHTMLElement()) {
1867+
// Changing the popover attribute might change the role.
1868+
RecreateAccessible(aElement);
1869+
return true;
1870+
}
1871+
18661872
return false;
18671873
}
18681874

accessible/generic/LocalAccessible-inl.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ namespace a11y {
2222

2323
inline mozilla::a11y::role LocalAccessible::Role() const {
2424
const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
25-
if (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole) {
26-
return ARIATransformRole(NativeRole());
27-
}
28-
29-
return ARIATransformRole(roleMapEntry->role);
25+
mozilla::a11y::role r =
26+
(!roleMapEntry || roleMapEntry->roleRule != kUseMapRole)
27+
? NativeRole()
28+
: roleMapEntry->role;
29+
r = ARIATransformRole(r);
30+
return GetMinimumRole(r);
3031
}
3132

3233
inline mozilla::a11y::role LocalAccessible::ARIARole() {

accessible/generic/LocalAccessible.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,19 @@ role LocalAccessible::ARIATransformRole(role aRole) const {
18971897
return aRole;
18981898
}
18991899

1900+
role LocalAccessible::GetMinimumRole(role aRole) const {
1901+
if (aRole != roles::TEXT && aRole != roles::TEXT_CONTAINER &&
1902+
aRole != roles::SECTION) {
1903+
// This isn't a generic role, so aRole is specific enough.
1904+
return aRole;
1905+
}
1906+
dom::Element* el = Elm();
1907+
if (el && el->IsHTMLElement() && el->HasAttr(nsGkAtoms::popover)) {
1908+
return roles::GROUPING;
1909+
}
1910+
return aRole;
1911+
}
1912+
19001913
role LocalAccessible::NativeRole() const { return roles::NOTHING; }
19011914

19021915
uint8_t LocalAccessible::ActionCount() const {

accessible/generic/LocalAccessible.h

+6
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,12 @@ class LocalAccessible : public nsISupports, public Accessible {
838838
*/
839839
mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole) const;
840840

841+
/**
842+
* Return the minimum role that should be used as a last resort if the element
843+
* does not have a more specific role.
844+
*/
845+
mozilla::a11y::role GetMinimumRole(mozilla::a11y::role aRole) const;
846+
841847
//////////////////////////////////////////////////////////////////////////////
842848
// Name helpers
843849

accessible/tests/browser/role/browser.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ support-files = [
99
prefs = ["javascript.options.asyncstack_capture_debuggee_only=false"]
1010

1111
["browser_computedARIARole.js"]
12+
["browser_minimumRole.js"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
"use strict";
6+
7+
/* import-globals-from ../../mochitest/role.js */
8+
loadScripts({ name: "role.js", dir: MOCHITESTS_DIR });
9+
10+
/**
11+
* Test that popover gets a minimum role.
12+
*/
13+
addAccessibleTask(
14+
`
15+
<div id="generic" popover>generic</div>
16+
<div id="alert" role="alert" popover>alert</div>
17+
<blockquote id="blockquote" popover>blockquote</div>
18+
`,
19+
async function testPopover(browser, docAcc) {
20+
let generic = findAccessibleChildByID(docAcc, "generic");
21+
ok(!generic, "generic doesn't have an Accessible");
22+
info("Showing generic");
23+
let shown = waitForEvent(EVENT_SHOW, "generic");
24+
await invokeContentTask(browser, [], () => {
25+
content.document.getElementById("generic").showPopover();
26+
});
27+
generic = (await shown).accessible;
28+
testRole(generic, ROLE_GROUPING, "generic has minimum role group");
29+
info("Setting popover to null on generic");
30+
// Setting popover to null causes the Accessible to be recreated.
31+
shown = waitForEvent(EVENT_SHOW, "generic");
32+
await invokeContentTask(browser, [], () => {
33+
content.document.getElementById("generic").popover = null;
34+
});
35+
generic = (await shown).accessible;
36+
testRole(generic, ROLE_SECTION, "generic has generic role");
37+
38+
let alert = findAccessibleChildByID(docAcc, "alert");
39+
ok(!alert, "alert doesn't have an Accessible");
40+
info("Showing alert");
41+
shown = waitForEvent(EVENT_SHOW, "alert");
42+
await invokeContentTask(browser, [], () => {
43+
content.document.getElementById("alert").showPopover();
44+
});
45+
alert = (await shown).accessible;
46+
testRole(alert, ROLE_ALERT, "alert has role alert");
47+
48+
let blockquote = findAccessibleChildByID(docAcc, "blockquote");
49+
ok(!blockquote, "blockquote doesn't have an Accessible");
50+
info("Showing blockquote");
51+
shown = waitForEvent(EVENT_SHOW, "blockquote");
52+
await invokeContentTask(browser, [], () => {
53+
content.document.getElementById("blockquote").showPopover();
54+
});
55+
blockquote = (await shown).accessible;
56+
testRole(blockquote, ROLE_BLOCKQUOTE, "blockquote has role blockquote");
57+
},
58+
{ chrome: true, topLevel: true }
59+
);

0 commit comments

Comments
 (0)