Index: ui/accessibility/platform/ax_platform_node_mac.mm |
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm |
index 240240e6180bc11f40e56de4fa36fdafd9e65b81..2ae6c78132ee1ff34f62c2de0896c8775ba2f2ee 100644 |
--- a/ui/accessibility/platform/ax_platform_node_mac.mm |
+++ b/ui/accessibility/platform/ax_platform_node_mac.mm |
@@ -20,21 +20,15 @@ |
namespace { |
-struct RoleMapEntry { |
- ui::AXRole value; |
- NSString* nativeValue; |
-}; |
+using RoleMap = std::map<ui::AXRole, NSString*>; |
+using EventMap = std::map<ui::AXEvent, NSString*>; |
+using ActionMap = std::map<ui::AXAction, NSString*>; |
-struct EventMapEntry { |
- ui::AXEvent value; |
- NSString* nativeValue; |
-}; |
- |
-typedef std::map<ui::AXRole, NSString*> RoleMap; |
-typedef std::map<ui::AXEvent, NSString*> EventMap; |
+// The AXAction for NSAccessibilityPressAction, which needs special handling. |
+constexpr ui::AXAction kActionForPress = ui::AX_ACTION_DO_DEFAULT; |
RoleMap BuildRoleMap() { |
- const RoleMapEntry roles[] = { |
+ const RoleMap::value_type roles[] = { |
{ui::AX_ROLE_ABBR, NSAccessibilityGroupRole}, |
{ui::AX_ROLE_ALERT, NSAccessibilityGroupRole}, |
{ui::AX_ROLE_ALERT_DIALOG, NSAccessibilityGroupRole}, |
@@ -157,14 +151,11 @@ RoleMap BuildRoleMap() { |
// { ui::AX_ROLE_SCROLL_AREA, NSAccessibilityScrollAreaRole }, |
}; |
- RoleMap role_map; |
- for (size_t i = 0; i < arraysize(roles); ++i) |
- role_map[roles[i].value] = roles[i].nativeValue; |
- return role_map; |
+ return RoleMap(begin(roles), end(roles)); |
} |
RoleMap BuildSubroleMap() { |
- const RoleMapEntry subroles[] = { |
+ const RoleMap::value_type subroles[] = { |
{ui::AX_ROLE_ALERT, @"AXApplicationAlert"}, |
{ui::AX_ROLE_ALERT_DIALOG, @"AXApplicationAlertDialog"}, |
{ui::AX_ROLE_APPLICATION, @"AXLandmarkApplication"}, |
@@ -198,14 +189,11 @@ RoleMap BuildSubroleMap() { |
{ui::AX_ROLE_TREE_ITEM, NSAccessibilityOutlineRowSubrole}, |
}; |
- RoleMap subrole_map; |
- for (size_t i = 0; i < arraysize(subroles); ++i) |
- subrole_map[subroles[i].value] = subroles[i].nativeValue; |
- return subrole_map; |
+ return RoleMap(begin(subroles), end(subroles)); |
} |
EventMap BuildEventMap() { |
- const EventMapEntry events[] = { |
+ const EventMap::value_type events[] = { |
{ui::AX_EVENT_FOCUS, NSAccessibilityFocusedUIElementChangedNotification}, |
{ui::AX_EVENT_TEXT_CHANGED, NSAccessibilityTitleChangedNotification}, |
{ui::AX_EVENT_VALUE_CHANGED, NSAccessibilityValueChangedNotification}, |
@@ -214,10 +202,22 @@ EventMap BuildEventMap() { |
// TODO(patricialor): Add more events. |
}; |
- EventMap event_map; |
- for (size_t i = 0; i < arraysize(events); ++i) |
- event_map[events[i].value] = events[i].nativeValue; |
- return event_map; |
+ return EventMap(begin(events), end(events)); |
+} |
+ |
+ActionMap BuildActionMap() { |
+ const ActionMap::value_type entries[] = { |
+ {ui::AX_ACTION_DECREMENT, NSAccessibilityDecrementAction}, |
+ {kActionForPress, NSAccessibilityPressAction}, |
+ {ui::AX_ACTION_INCREMENT, NSAccessibilityIncrementAction}, |
+ {ui::AX_ACTION_SHOW_CONTEXT_MENU, NSAccessibilityShowMenuAction}, |
+ }; |
+ return ActionMap(begin(entries), end(entries)); |
+} |
+ |
+const ActionMap& GetActionMap() { |
+ CR_DEFINE_STATIC_LOCAL(const ActionMap, action_map, (BuildActionMap())); |
+ return action_map; |
} |
void NotifyMacEvent(AXPlatformNodeCocoa* target, ui::AXEvent event_type) { |
@@ -240,24 +240,21 @@ void NotifyMacEvent(AXPlatformNodeCocoa* target, ui::AXEvent event_type) { |
@synthesize node = node_; |
-// A mapping of AX roles to native roles. |
+ (NSString*)nativeRoleFromAXRole:(ui::AXRole)role { |
- CR_DEFINE_STATIC_LOCAL(RoleMap, role_map, (BuildRoleMap())); |
- RoleMap::iterator it = role_map.find(role); |
+ CR_DEFINE_STATIC_LOCAL(const RoleMap, role_map, (BuildRoleMap())); |
+ RoleMap::const_iterator it = role_map.find(role); |
return it != role_map.end() ? it->second : NSAccessibilityUnknownRole; |
} |
-// A mapping of AX roles to native subroles. |
+ (NSString*)nativeSubroleFromAXRole:(ui::AXRole)role { |
- CR_DEFINE_STATIC_LOCAL(RoleMap, subrole_map, (BuildSubroleMap())); |
- RoleMap::iterator it = subrole_map.find(role); |
+ CR_DEFINE_STATIC_LOCAL(const RoleMap, subrole_map, (BuildSubroleMap())); |
+ RoleMap::const_iterator it = subrole_map.find(role); |
return it != subrole_map.end() ? it->second : nil; |
} |
-// A mapping of AX events to native notifications. |
+ (NSString*)nativeNotificationFromAXEvent:(ui::AXEvent)event { |
- CR_DEFINE_STATIC_LOCAL(EventMap, event_map, (BuildEventMap())); |
- EventMap::iterator it = event_map.find(event); |
+ CR_DEFINE_STATIC_LOCAL(const EventMap, event_map, (BuildEventMap())); |
+ EventMap::const_iterator it = event_map.find(event); |
return it != event_map.end() ? it->second : nil; |
} |
@@ -323,18 +320,34 @@ void NotifyMacEvent(AXPlatformNodeCocoa* target, ui::AXEvent event_type) { |
base::scoped_nsobject<NSMutableArray> axActions( |
[[NSMutableArray alloc] init]); |
+ const ui::AXNodeData& data = node_->GetData(); |
+ |
// VoiceOver expects the "press" action to be first. |
- if (ui::IsRoleClickable(node_->GetData().role)) |
+ if (ui::IsRoleClickable(data.role) || data.HasAction(kActionForPress)) |
[axActions addObject:NSAccessibilityPressAction]; |
+ for (const ActionMap::value_type& entry : GetActionMap()) { |
+ if (entry.first == kActionForPress) |
+ continue; |
+ |
+ DCHECK(![entry.second isEqualToString:NSAccessibilityPressAction]); |
+ |
+ if (data.HasAction(entry.first)) |
+ [axActions addObject:entry.second]; |
+ } |
+ |
return axActions.autorelease(); |
} |
- (void)accessibilityPerformAction:(NSString*)action { |
DCHECK([[self accessibilityActionNames] containsObject:action]); |
ui::AXActionData data; |
- if ([action isEqualToString:NSAccessibilityPressAction]) |
- data.action = ui::AX_ACTION_DO_DEFAULT; |
+ for (const ActionMap::value_type& entry : GetActionMap()) { |
dmazzoni
2017/06/21 06:09:35
It doesn't look like you're ever using ActionMap a
tapted
2017/06/21 06:52:55
Indeed! good catch. and it's as easy as changing t
tapted
2017/06/21 11:13:11
Well.. everything _compiled_ fine with just the ty
|
+ if ([action isEqualToString:entry.second]) { |
+ data.action = entry.first; |
+ break; |
+ } |
+ } |
// Note ui::AX_ACTIONs which are just overwriting an accessibility attribute |
// are already implemented in -accessibilitySetValue:forAttribute:, so ignore |