diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm index 90607c64c9a6..36b891f25fef 100644 --- a/accessible/mac/mozAccessible.mm +++ b/accessible/mac/mozAccessible.mm @@ -158,6 +158,14 @@ static inline NSMutableArray* ConvertToNSArray(nsTArray& 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]; } diff --git a/accessible/mac/mozRootAccessible.mm b/accessible/mac/mozRootAccessible.mm index e4c854d662da..3c3b6db84b9b 100644 --- a/accessible/mac/mozRootAccessible.mm +++ b/accessible/mac/mozRootAccessible.mm @@ -89,29 +89,6 @@ static id 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; diff --git a/accessible/tests/browser/mac/browser_app.js b/accessible/tests/browser/mac/browser_app.js index bc51e3f2eaa3..75da76d82092 100644 --- a/accessible/tests/browser/mac/browser_app.js +++ b/accessible/tests/browser/mac/browser_app.js @@ -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"); + } + ); +});