commit 09aedb6aef474d6d27b27be1065d6f126fb6f044
parent ccd1be9f2f7645e5278dec84fed833540f4a5098
Author: Eitan Isaacson <eitan@monotonous.org>
Date: Fri, 17 Oct 2025 05:30:07 +0000
Bug 1994030 - P2: Expose aria-actions via accessibilityCustomActions. r=morgan
Differential Revision: https://phabricator.services.mozilla.com/D268472
Diffstat:
8 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/accessible/mac/MOXAccessibleBase.h b/accessible/mac/MOXAccessibleBase.h
@@ -79,6 +79,9 @@ inline id<mozAccessible> GetObjectOrRepresentedView(id<mozAccessible> aObject) {
- (id)accessibilityFocusedUIElement;
// override, final
+- (NSArray*)accessibilityCustomActions;
+
+// override, final
- (BOOL)isAccessibilityElement;
// final
@@ -97,6 +100,9 @@ inline id<mozAccessible> GetObjectOrRepresentedView(id<mozAccessible> aObject) {
- (id)moxFocusedUIElement;
// override
+- (NSArray*)moxCustomActions;
+
+// override
- (void)moxPostNotification:(NSString*)notification;
// override
diff --git a/accessible/mac/MOXAccessibleBase.mm b/accessible/mac/MOXAccessibleBase.mm
@@ -390,6 +390,12 @@ mozilla::LogModule* GetMacAccessibilityLog() {
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
+- (id)accessibilityCustomActions {
+ NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
+ return [self moxCustomActions];
+ NS_OBJC_END_TRY_BLOCK_RETURN(nil);
+}
+
- (BOOL)isAccessibilityElement {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
@@ -586,6 +592,10 @@ mozilla::LogModule* GetMacAccessibilityLog() {
return nil;
}
+- (NSArray*)moxCustomActions {
+ return nil;
+}
+
#pragma mark - Private
- (BOOL)isSelectorSupported:(SEL)selector {
diff --git a/accessible/mac/MOXAccessibleProtocol.h b/accessible/mac/MOXAccessibleProtocol.h
@@ -25,6 +25,9 @@
// Forwarded from accessibilityFocusedUIElement.
- (id _Nullable)moxFocusedUIElement;
+// Retrieve a list of custom actions.
+- (NSArray* _Nullable)moxCustomActions;
+
// Sends a notification to any observing assistive applications.
- (void)moxPostNotification:(NSString* _Nonnull)notification;
diff --git a/accessible/mac/mozAccessible.h b/accessible/mac/mozAccessible.h
@@ -188,6 +188,9 @@ enum CheckedState {
- (NSArray*)moxCustomContent;
// override
+- (NSArray*)moxCustomActions;
+
+// override
- (NSNumber*)moxEnabled;
// override
diff --git a/accessible/mac/mozAccessible.mm b/accessible/mac/mozAccessible.mm
@@ -580,6 +580,35 @@ static bool ProvidesTitle(const Accessible* aAccessible, nsString& aName) {
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
}
+- (NSArray*)moxCustomActions {
+ if (@available(macOS 13.0, *)) {
+ NSMutableArray<NSAccessibilityCustomAction*>* customActions =
+ [[[NSMutableArray alloc] init] autorelease];
+ Relation relatedActions(
+ mGeckoAccessible->RelationByType(RelationType::ACTION));
+ while (Accessible* target = relatedActions.Next()) {
+ if (target->HasPrimaryAction()) {
+ // Any ACTION related accesibles should be considered a custom action.
+ mozAccessible* nativeTarget = GetNativeFromGeckoAccessible(target);
+ if (nativeTarget) {
+ nsAutoString name;
+ // Use the name of the target as the action name.
+ target->Name(name);
+ NSAccessibilityCustomAction* action =
+ [[NSAccessibilityCustomAction alloc]
+ initWithName:nsCocoaUtils::ToNSString(name)
+ target:nativeTarget
+ selector:@selector(moxPerformPress)];
+ [customActions addObject:action];
+ }
+ }
+ }
+ return customActions;
+ }
+
+ return nil;
+}
+
- (NSWindow*)moxWindow {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
diff --git a/accessible/mac/mozAccessibleProtocol.h b/accessible/mac/mozAccessibleProtocol.h
@@ -45,6 +45,8 @@
// currently focused UI element (possibly a child accessible)
- (id)accessibilityFocusedUIElement;
+- (NSArray*)accessibilityCustomActions;
+
/*** attributes ***/
// all supported attributes
diff --git a/accessible/tests/browser/mac/browser.toml b/accessible/tests/browser/mac/browser.toml
@@ -47,6 +47,8 @@ skip-if = ["os == 'mac' && os_version == '15.30' && arch == 'aarch64' && opt"] #
["browser_combobox.js"]
+["browser_custom_actions.js"]
+
["browser_description.js"]
["browser_details_summary.js"]
diff --git a/accessible/tests/browser/mac/browser_custom_actions.js b/accessible/tests/browser/mac/browser_custom_actions.js
@@ -0,0 +1,39 @@
+/* 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 custom action
+addAccessibleTask(
+ `<div id="container">
+ <dialog aria-actions="btn" id="dlg" open>
+ Hello
+ <form method="dialog">
+ <button id="btn">Close</button>
+ </form>
+ </dialog>
+ </div>`,
+ async (browser, accDoc) => {
+ let dialog = getNativeInterface(accDoc, "dlg");
+ let actionNames = dialog.actionNames;
+ let customAction = actionNames.find(name => name.startsWith("Name:Close"));
+ ok(!!customAction, "Dialog should have a custom action");
+ is(
+ dialog.getActionDescription(customAction),
+ "Close",
+ "Correct action description"
+ );
+
+ const reorder = waitForEvent(EVENT_REORDER, "container");
+ dialog.performAction(customAction);
+ await reorder;
+ }
+);