mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1682985 - Support aria-busy with AXElementBusy and AXElementBusyChanged. r=morgan
Differential Revision: https://phabricator.services.mozilla.com/D100838
This commit is contained in:
parent
093ed43459
commit
c21730a605
@ -124,6 +124,9 @@
|
|||||||
// AXRequired
|
// AXRequired
|
||||||
- (NSNumber* _Nullable)moxRequired;
|
- (NSNumber* _Nullable)moxRequired;
|
||||||
|
|
||||||
|
// AXElementBusy
|
||||||
|
- (NSNumber* _Nullable)moxElementBusy;
|
||||||
|
|
||||||
// AXDOMIdentifier
|
// AXDOMIdentifier
|
||||||
- (NSString* _Nullable)moxDOMIdentifier;
|
- (NSString* _Nullable)moxDOMIdentifier;
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ using namespace mozilla::a11y;
|
|||||||
// override
|
// override
|
||||||
- (BOOL)moxBlockSelector:(SEL)selector;
|
- (BOOL)moxBlockSelector:(SEL)selector;
|
||||||
|
|
||||||
|
// override
|
||||||
|
- (void)moxPostNotification:(NSString*)notification;
|
||||||
|
|
||||||
// override
|
// override
|
||||||
- (void)handleAccessibleEvent:(uint32_t)eventType;
|
- (void)handleAccessibleEvent:(uint32_t)eventType;
|
||||||
|
|
||||||
|
@ -223,9 +223,23 @@ using namespace mozilla::a11y;
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selector == @selector(moxElementBusy)) {
|
||||||
|
// Don't confuse aria-busy with a document's busy state.
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
return [super moxBlockSelector:selector];
|
return [super moxBlockSelector:selector];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)moxPostNotification:(NSString*)notification {
|
||||||
|
if (![notification isEqualToString:@"AXElementBusyChanged"]) {
|
||||||
|
// Suppress AXElementBusyChanged since it uses gecko's BUSY state
|
||||||
|
// to tell VoiceOver about aria-busy changes. We use that state
|
||||||
|
// differently in documents.
|
||||||
|
[super moxPostNotification:notification];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id)rootGroup {
|
- (id)rootGroup {
|
||||||
NSArray* children = [super moxUnignoredChildren];
|
NSArray* children = [super moxUnignoredChildren];
|
||||||
if (mRole != roles::APPLICATION && [children count] == 1 &&
|
if (mRole != roles::APPLICATION && [children count] == 1 &&
|
||||||
|
@ -208,6 +208,9 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
|||||||
// override
|
// override
|
||||||
- (NSNumber*)moxRequired;
|
- (NSNumber*)moxRequired;
|
||||||
|
|
||||||
|
// override
|
||||||
|
- (NSNumber*)moxElementBusy;
|
||||||
|
|
||||||
// override
|
// override
|
||||||
- (id)moxEditableAncestor;
|
- (id)moxEditableAncestor;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ using namespace mozilla::a11y;
|
|||||||
static const uint64_t kCachedStates =
|
static const uint64_t kCachedStates =
|
||||||
states::CHECKED | states::PRESSED | states::MIXED | states::EXPANDED |
|
states::CHECKED | states::PRESSED | states::MIXED | states::EXPANDED |
|
||||||
states::CURRENT | states::SELECTED | states::TRAVERSED | states::LINKED |
|
states::CURRENT | states::SELECTED | states::TRAVERSED | states::LINKED |
|
||||||
states::HASPOPUP;
|
states::HASPOPUP | states::BUSY;
|
||||||
static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
||||||
|
|
||||||
- (uint64_t)state {
|
- (uint64_t)state {
|
||||||
@ -143,19 +143,20 @@ static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
|
- (void)stateChanged:(uint64_t)state isEnabled:(BOOL)enabled {
|
||||||
if ((state & kCachedStates) == 0) {
|
if ((state & kCachedStates) != 0) {
|
||||||
return;
|
if (!(mCachedState & kCacheInitialized)) {
|
||||||
|
[self state];
|
||||||
|
} else {
|
||||||
|
if (enabled) {
|
||||||
|
mCachedState |= state;
|
||||||
|
} else {
|
||||||
|
mCachedState &= ~state;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mCachedState & kCacheInitialized)) {
|
if (state == states::BUSY) {
|
||||||
[self state];
|
[self moxPostNotification:@"AXElementBusyChanged"];
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled) {
|
|
||||||
mCachedState |= state;
|
|
||||||
} else {
|
|
||||||
mCachedState &= ~state;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,6 +790,10 @@ struct RoleDescrComparator {
|
|||||||
return @([self stateWithMask:states::REQUIRED] != 0);
|
return @([self stateWithMask:states::REQUIRED] != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSNumber*)moxElementBusy {
|
||||||
|
return @([self stateWithMask:states::BUSY] != 0);
|
||||||
|
}
|
||||||
|
|
||||||
- (mozAccessible*)topWebArea {
|
- (mozAccessible*)topWebArea {
|
||||||
AccessibleOrProxy doc = [self geckoDocument];
|
AccessibleOrProxy doc = [self geckoDocument];
|
||||||
while (!doc.IsNull()) {
|
while (!doc.IsNull()) {
|
||||||
|
@ -46,3 +46,4 @@ skip-if = os == 'mac' && debug # Bug 1664577
|
|||||||
[browser_menulist.js]
|
[browser_menulist.js]
|
||||||
[browser_rich_listbox.js]
|
[browser_rich_listbox.js]
|
||||||
[browser_live_regions.js]
|
[browser_live_regions.js]
|
||||||
|
[browser_aria_busy.js]
|
||||||
|
44
accessible/tests/browser/mac/browser_aria_busy.js
Normal file
44
accessible/tests/browser/mac/browser_aria_busy.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* import-globals-from ../../mochitest/role.js */
|
||||||
|
/* import-globals-from ../../mochitest/states.js */
|
||||||
|
loadScripts(
|
||||||
|
{ name: "role.js", dir: MOCHITESTS_DIR },
|
||||||
|
{ name: "states.js", dir: MOCHITESTS_DIR }
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test aria-busy
|
||||||
|
*/
|
||||||
|
addAccessibleTask(
|
||||||
|
`<div id="section" role="group">Hello</div>`,
|
||||||
|
async (browser, accDoc) => {
|
||||||
|
let section = getNativeInterface(accDoc, "section");
|
||||||
|
|
||||||
|
ok(!section.getAttributeValue("AXElementBusy"), "section is not busy");
|
||||||
|
|
||||||
|
let busyChanged = waitForMacEvent("AXElementBusyChanged", "section");
|
||||||
|
await SpecialPowers.spawn(browser, [], () => {
|
||||||
|
content.document
|
||||||
|
.getElementById("section")
|
||||||
|
.setAttribute("aria-busy", "true");
|
||||||
|
});
|
||||||
|
await busyChanged;
|
||||||
|
|
||||||
|
ok(section.getAttributeValue("AXElementBusy"), "section is busy");
|
||||||
|
|
||||||
|
busyChanged = waitForMacEvent("AXElementBusyChanged", "section");
|
||||||
|
await SpecialPowers.spawn(browser, [], () => {
|
||||||
|
content.document
|
||||||
|
.getElementById("section")
|
||||||
|
.setAttribute("aria-busy", "false");
|
||||||
|
});
|
||||||
|
await busyChanged;
|
||||||
|
|
||||||
|
ok(!section.getAttributeValue("AXElementBusy"), "section is not busy");
|
||||||
|
}
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user