Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: ui/accessibility/platform/ax_platform_node_mac.mm

Issue 2016243002: Mac a11y: Add RoleDescription and Value attributes to accessibility information. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase again. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/accessibility/platform/ax_platform_node_mac.h" 5 #import "ui/accessibility/platform/ax_platform_node_mac.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
12 #import "ui/accessibility/ax_node_data.h" 12 #import "ui/accessibility/ax_node_data.h"
tapted 2016/06/17 03:32:49 nit: can you update this to #include while you're
Patti Lor 2016/06/17 05:57:35 Done.
13 #include "ui/accessibility/ax_view_state.h"
13 #import "ui/accessibility/platform/ax_platform_node_delegate.h" 14 #import "ui/accessibility/platform/ax_platform_node_delegate.h"
tapted 2016/06/17 03:32:49 this too - these are not objc headers
Patti Lor 2016/06/17 05:57:35 Done, thanks for noticing :)
14 #import "ui/gfx/mac/coordinate_conversion.h" 15 #import "ui/gfx/mac/coordinate_conversion.h"
15 16
16 namespace { 17 namespace {
17 18
18 struct MapEntry { 19 struct MapEntry {
19 ui::AXRole value; 20 ui::AXRole value;
20 NSString* nativeValue; 21 NSString* nativeValue;
21 }; 22 };
22 23
23 typedef std::map<ui::AXRole, NSString*> RoleMap; 24 typedef std::map<ui::AXRole, NSString*> RoleMap;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 }; 184 };
184 185
185 RoleMap subrole_map; 186 RoleMap subrole_map;
186 for (size_t i = 0; i < arraysize(subroles); ++i) 187 for (size_t i = 0; i < arraysize(subroles); ++i)
187 subrole_map[subroles[i].value] = subroles[i].nativeValue; 188 subrole_map[subroles[i].value] = subroles[i].nativeValue;
188 return subrole_map; 189 return subrole_map;
189 } 190 }
190 191
191 } // namespace 192 } // namespace
192 193
194 @interface AXPlatformNodeCocoa ()
195 // Helper function for string attributes that don't require extra processing.
196 - (NSString*)getStringAttribute:(ui::AXStringAttribute)attribute;
197 @end
198
193 @implementation AXPlatformNodeCocoa 199 @implementation AXPlatformNodeCocoa
194 200
195 // A mapping of AX roles to native roles. 201 // A mapping of AX roles to native roles.
196 + (NSString*)nativeRoleFromAXRole:(ui::AXRole)role { 202 + (NSString*)nativeRoleFromAXRole:(ui::AXRole)role {
197 CR_DEFINE_STATIC_LOCAL(RoleMap, role_map, (BuildRoleMap())); 203 CR_DEFINE_STATIC_LOCAL(RoleMap, role_map, (BuildRoleMap()));
198 RoleMap::iterator it = role_map.find(role); 204 RoleMap::iterator it = role_map.find(role);
199 return it != role_map.end() ? it->second : NSAccessibilityUnknownRole; 205 return it != role_map.end() ? it->second : NSAccessibilityUnknownRole;
200 } 206 }
201 207
202 // A mapping of AX roles to native subroles. 208 // A mapping of AX roles to native subroles.
(...skipping 13 matching lines...) Expand all
216 - (void)detach { 222 - (void)detach {
217 node_ = nil; 223 node_ = nil;
218 } 224 }
219 225
220 - (NSRect)boundsInScreen { 226 - (NSRect)boundsInScreen {
221 if (!node_) 227 if (!node_)
222 return NSZeroRect; 228 return NSZeroRect;
223 return gfx::ScreenRectToNSRect(node_->GetBoundsInScreen()); 229 return gfx::ScreenRectToNSRect(node_->GetBoundsInScreen());
224 } 230 }
225 231
226 - (NSArray*)AXChildren { 232 - (NSString*)getStringAttribute:(ui::AXStringAttribute)attribute {
227 if (!node_) 233 std::string attributeValue;
228 return nil; 234 if (node_->GetStringAttribute(attribute, &attributeValue))
229 int count = node_->GetChildCount(); 235 return base::SysUTF8ToNSString(attributeValue);
230 NSMutableArray* children = [NSMutableArray arrayWithCapacity:count];
231 for (int i = 0; i < count; ++i)
232 [children addObject:node_->ChildAtIndex(i)];
233 return NSAccessibilityUnignoredChildren(children);
234 }
235
236 - (id)AXParent {
237 if (!node_)
238 return nil;
239 return NSAccessibilityUnignoredAncestor(node_->GetParent());
240 }
241
242 - (NSValue*)AXPosition {
243 return [NSValue valueWithPoint:self.boundsInScreen.origin];
244 }
245
246 - (NSString*)AXRole {
247 if (!node_)
248 return nil;
249 return [[self class] nativeRoleFromAXRole:node_->GetData().role];
250 }
251
252 - (NSValue*)AXSize {
253 return [NSValue valueWithSize:self.boundsInScreen.size];
254 }
255
256 - (NSString*)AXTitle {
257 std::string value;
258 if (node_->GetStringAttribute(ui::AX_ATTR_NAME, &value))
259 return base::SysUTF8ToNSString(value);
260 return nil; 236 return nil;
261 } 237 }
262 238
263 // NSAccessibility informal protocol implementation. 239 // NSAccessibility informal protocol implementation.
264 240
265 - (BOOL)accessibilityIsIgnored { 241 - (BOOL)accessibilityIsIgnored {
266 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole]; 242 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole];
267 } 243 }
268 244
269 - (id)accessibilityHitTest:(NSPoint)point { 245 - (id)accessibilityHitTest:(NSPoint)point {
270 for (AXPlatformNodeCocoa* child in [self AXChildren]) { 246 for (AXPlatformNodeCocoa* child in [self AXChildren]) {
271 if (NSPointInRect(point, child.boundsInScreen)) 247 if (NSPointInRect(point, child.boundsInScreen))
272 return [child accessibilityHitTest:point]; 248 return [child accessibilityHitTest:point];
273 } 249 }
274 return NSAccessibilityUnignoredAncestor(self); 250 return NSAccessibilityUnignoredAncestor(self);
275 } 251 }
276 252
277 - (NSArray*)accessibilityActionNames { 253 - (NSArray*)accessibilityActionNames {
278 return nil; 254 return nil;
279 } 255 }
280 256
281 - (NSArray*)accessibilityAttributeNames { 257 - (NSArray*)accessibilityAttributeNames {
282 // These attributes are required on all accessibility objects. 258 // These attributes are required on all accessibility objects.
283 return @[ 259 NSArray* const kAllRoleAttributes = @[
284 NSAccessibilityChildrenAttribute, 260 NSAccessibilityChildrenAttribute, NSAccessibilityParentAttribute,
285 NSAccessibilityParentAttribute, 261 NSAccessibilityPositionAttribute, NSAccessibilityRoleAttribute,
286 NSAccessibilityPositionAttribute, 262 NSAccessibilitySizeAttribute, NSAccessibilitySubroleAttribute,
287 NSAccessibilityRoleAttribute,
288 NSAccessibilitySizeAttribute,
289 263
290 // Title is required for most elements. Cocoa asks for the value even if it 264 // Title is required for most elements. Cocoa asks for the value even if it
291 // is omitted here, but won't present it to accessibility APIs without this. 265 // is omitted here, but won't present it to accessibility APIs without this.
292 NSAccessibilityTitleAttribute, 266 NSAccessibilityTitleAttribute,
267
268 // Attributes which are not required, but are general to all roles.
269 NSAccessibilityRoleDescriptionAttribute
tapted 2016/06/17 03:32:49 nit: comma after
Patti Lor 2016/06/17 05:57:35 Done.
293 ]; 270 ];
294 // TODO(tapted): Add additional attributes based on role. 271
272 // Attributes required for user-editable controls.
273 NSArray* const kValueAttributes = @[ NSAccessibilityValueAttribute ];
274
275 base::scoped_nsobject<NSMutableArray> axAttributes(
276 [[NSMutableArray alloc] init]);
277 [axAttributes addObjectsFromArray:kAllRoleAttributes];
tapted 2016/06/17 03:32:49 nit: blank line before
Patti Lor 2016/06/17 05:57:35 Done.
278 switch (node_->GetData().role) {
279 case ui::AX_ROLE_CHECK_BOX:
280 case ui::AX_ROLE_COMBO_BOX:
281 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
282 case ui::AX_ROLE_MENU_ITEM_RADIO:
283 case ui::AX_ROLE_RADIO_BUTTON:
284 case ui::AX_ROLE_SEARCH_BOX:
285 case ui::AX_ROLE_SLIDER:
286 case ui::AX_ROLE_SLIDER_THUMB:
287 case ui::AX_ROLE_TOGGLE_BUTTON:
288 case ui::AX_ROLE_TEXT_FIELD:
289 [axAttributes addObjectsFromArray:kValueAttributes];
290 break;
291 // TODO(tapted): Add additional attributes based on role.
292 default:
293 break;
294 }
295 return axAttributes.autorelease();
295 } 296 }
296 297
297 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute { 298 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute {
298 return NO; 299 return NO;
299 } 300 }
300 301
301 - (id)accessibilityAttributeValue:(NSString*)attribute { 302 - (id)accessibilityAttributeValue:(NSString*)attribute {
302 SEL selector = NSSelectorFromString(attribute); 303 SEL selector = NSSelectorFromString(attribute);
303 if ([self respondsToSelector:selector]) 304 if ([self respondsToSelector:selector])
304 return [self performSelector:selector]; 305 return [self performSelector:selector];
305 return nil; 306 return nil;
306 } 307 }
307 308
309 // NSAccessibility attributes.
310
311 - (NSArray*)AXChildren {
312 if (!node_)
313 return nil;
314 int count = node_->GetChildCount();
315 NSMutableArray* children = [NSMutableArray arrayWithCapacity:count];
316 for (int i = 0; i < count; ++i)
317 [children addObject:node_->ChildAtIndex(i)];
318 return NSAccessibilityUnignoredChildren(children);
319 }
320
321 - (id)AXParent {
322 if (!node_)
323 return nil;
324 return NSAccessibilityUnignoredAncestor(node_->GetParent());
325 }
326
327 - (NSValue*)AXPosition {
328 return [NSValue valueWithPoint:self.boundsInScreen.origin];
329 }
330
331 - (NSString*)AXRole {
332 if (!node_)
333 return nil;
334 return [[self class] nativeRoleFromAXRole:node_->GetData().role];
335 }
336
337 - (NSString*)AXSubrole {
338 ui::AXRole role = node_->GetData().role;
339 switch (role) {
340 case ui::AX_ROLE_TEXT_FIELD:
341 if (ui::AXViewState::IsFlagSet(node_->GetData().state,
342 ui::AX_STATE_PROTECTED)) {
343 return NSAccessibilitySecureTextFieldSubrole;
344 }
tapted 2016/06/17 03:32:49 nit: no curlies required
Patti Lor 2016/06/17 05:57:35 Done.
345 break;
346 default:
347 break;
348 }
349 return [AXPlatformNodeCocoa nativeSubroleFromAXRole:role];
350 }
351
352 - (NSString*)AXRoleDescription {
353 NSString* description = [self getStringAttribute:ui::AX_ATTR_DESCRIPTION];
354 if (!description)
355 return NSAccessibilityRoleDescription([self AXRole], [self AXSubrole]);
356 return description;
357 }
358
359 - (NSValue*)AXSize {
360 return [NSValue valueWithSize:self.boundsInScreen.size];
361 }
362
363 - (NSString*)AXTitle {
364 return [self getStringAttribute:ui::AX_ATTR_NAME];
365 }
366
367 - (NSString*)AXValue {
368 return [self getStringAttribute:ui::AX_ATTR_VALUE];
369 }
370
308 @end 371 @end
309 372
310 namespace ui { 373 namespace ui {
311 374
312 // static 375 // static
313 AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { 376 AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
314 AXPlatformNodeBase* node = new AXPlatformNodeMac(); 377 AXPlatformNodeBase* node = new AXPlatformNodeMac();
315 node->Init(delegate); 378 node->Init(delegate);
316 return node; 379 return node;
317 } 380 }
(...skipping 19 matching lines...) Expand all
337 void AXPlatformNodeMac::NotifyAccessibilityEvent(ui::AXEvent event_type) { 400 void AXPlatformNodeMac::NotifyAccessibilityEvent(ui::AXEvent event_type) {
338 // TODO(dmazzoni): implement this. http://crbug.com/396137 401 // TODO(dmazzoni): implement this. http://crbug.com/396137
339 } 402 }
340 403
341 int AXPlatformNodeMac::GetIndexInParent() { 404 int AXPlatformNodeMac::GetIndexInParent() {
342 // TODO(dmazzoni): implement this. http://crbug.com/396137 405 // TODO(dmazzoni): implement this. http://crbug.com/396137
343 return -1; 406 return -1;
344 } 407 }
345 408
346 } // namespace ui 409 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698