Bug 1635517 - Ignore all invisible XUL elements. r=morgan

Differential Revision: https://phabricator.services.mozilla.com/D74433
This commit is contained in:
Eitan Isaacson 2020-05-12 17:26:34 +00:00
Родитель ac48c6ea9a
Коммит f395ad8878
3 изменённых файлов: 66 добавлений и 25 удалений

Просмотреть файл

@ -158,6 +158,14 @@ static inline NSMutableArray* ConvertToNSArray(nsTArray<ProxyAccessible*>& aArra
}
- (BOOL)ignoreWithParent:(mozAccessible*)parent {
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
if (accWrap->IsContent() && accWrap->GetContent()->IsXULElement()) {
if (accWrap->VisibilityState() & states::INVISIBLE) {
return YES;
}
}
}
return [parent ignoreChild:self];
}

Просмотреть файл

@ -89,29 +89,6 @@ static id<mozAccessible, mozView> getNativeViewFromRootAccessible(Accessible* aA
return YES;
}
- (NSArray*)children {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
return [[super children]
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(mozAccessible* child,
NSDictionary* bindings) {
AccessibleWrap* childAcc = [child getGeckoAccessible];
if (childAcc) {
if (((childAcc->VisibilityState() & states::INVISIBLE) != 0)) {
// Filter out all invisible XUL popup menus, dialogs, alerts and panes. Invisible
// elements in our browser chrome are unique in the sense that we want screen readers to
// ignore them. These only exist in the top level process so we don't do a similar check
// on proxies.
return NO;
}
}
return YES;
}]];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// this will return our parallell NSView. see mozDocAccessible.h
- (id)representedView {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;

Просмотреть файл

@ -11,10 +11,10 @@ loadScripts(
{ name: "states.js", dir: MOCHITESTS_DIR }
);
function getMacAccessible(id) {
function getMacAccessible(accOrElmOrID) {
return new Promise(resolve => {
let intervalId = setInterval(() => {
let acc = getAccessible(id);
let acc = getAccessible(accOrElmOrID);
if (acc) {
clearInterval(intervalId);
resolve(
@ -103,3 +103,59 @@ add_task(async () => {
// Close all open tabs
await Promise.all(newTabs.map(t => BrowserTestUtils.removeTab(t)));
});
/**
* Test ignored invisible items in root
*/
add_task(async () => {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: "about:license",
},
async browser => {
let root = await getMacAccessible(document);
let rootChildCount = () => root.getAttributeValue("AXChildren").length;
// With no popups, the root accessible has 5 visible children:
// 1. Tab bar (#TabsToolbar)
// 2. Navigation bar (#nav-bar)
// 3. Content area (#tabbrowser-tabpanels)
// 4. Some fullscreen pointer grabber (#fullscreen-and-pointerlock-wrapper)
// 5. Accessibility announcements dialog (#a11y-announcement)
is(rootChildCount(), 5, "Root with no popups has 5 children");
// Open a context menu
const menu = document.getElementById("contentAreaContextMenu");
EventUtils.synthesizeMouseAtCenter(document.body, {
type: "contextmenu",
});
await BrowserTestUtils.waitForPopupEvent(menu, "shown");
// Now root has 6 children
is(rootChildCount(), 6, "Root has 6 children");
// Close context menu
EventUtils.synthesizeKey("KEY_Escape");
await BrowserTestUtils.waitForPopupEvent(menu, "hidden");
// We're back to 5
is(rootChildCount(), 5, "Root has 5 children");
// Open site identity popup
const identityPopup = document.getElementById("identity-popup");
document.getElementById("identity-box").click();
await BrowserTestUtils.waitForPopupEvent(identityPopup, "shown");
// Now root has 6 children
is(rootChildCount(), 6, "Root has 6 children");
// Close popup
EventUtils.synthesizeKey("KEY_Escape");
await BrowserTestUtils.waitForPopupEvent(identityPopup, "hidden");
// We're back to 5
is(rootChildCount(), 5, "Root has 5 children");
}
);
});