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

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

Issue 2969293002: Revert of Fix lifetime problems in AXPlatformNodeCocoa. (Closed)
Patch Set: Created 3 years, 5 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
« no previous file with comments | « no previous file | ui/views/widget/native_widget_mac_accessibility_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 } 304 }
305 305
306 - (NSString*)getAXValueAsString { 306 - (NSString*)getAXValueAsString {
307 id value = [self AXValue]; 307 id value = [self AXValue];
308 return [value isKindOfClass:[NSString class]] ? value : nil; 308 return [value isKindOfClass:[NSString class]] ? value : nil;
309 } 309 }
310 310
311 // NSAccessibility informal protocol implementation. 311 // NSAccessibility informal protocol implementation.
312 312
313 - (BOOL)accessibilityIsIgnored { 313 - (BOOL)accessibilityIsIgnored {
314 if (!node_)
315 return YES;
316
317 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] || 314 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] ||
318 node_->GetData().HasState(ui::AX_STATE_INVISIBLE); 315 node_->GetData().HasState(ui::AX_STATE_INVISIBLE);
319 } 316 }
320 317
321 - (id)accessibilityHitTest:(NSPoint)point { 318 - (id)accessibilityHitTest:(NSPoint)point {
322 for (AXPlatformNodeCocoa* child in [self AXChildren]) { 319 for (AXPlatformNodeCocoa* child in [self AXChildren]) {
323 if (![child accessibilityIsIgnored] && 320 if (![child accessibilityIsIgnored] &&
324 NSPointInRect(point, child.boundsInScreen)) { 321 NSPointInRect(point, child.boundsInScreen)) {
325 return [child accessibilityHitTest:point]; 322 return [child accessibilityHitTest:point];
326 } 323 }
327 } 324 }
328 return NSAccessibilityUnignoredAncestor(self); 325 return NSAccessibilityUnignoredAncestor(self);
329 } 326 }
330 327
331 - (BOOL)accessibilityNotifiesWhenDestroyed { 328 - (BOOL)accessibilityNotifiesWhenDestroyed {
332 return YES; 329 return YES;
333 } 330 }
334 331
335 - (id)accessibilityFocusedUIElement { 332 - (id)accessibilityFocusedUIElement {
336 return node_ ? node_->GetDelegate()->GetFocus() : nil; 333 return node_->GetDelegate()->GetFocus();
337 } 334 }
338 335
339 - (NSArray*)accessibilityActionNames { 336 - (NSArray*)accessibilityActionNames {
340 if (!node_)
341 return @[];
342
343 base::scoped_nsobject<NSMutableArray> axActions( 337 base::scoped_nsobject<NSMutableArray> axActions(
344 [[NSMutableArray alloc] init]); 338 [[NSMutableArray alloc] init]);
345 339
346 const ui::AXNodeData& data = node_->GetData(); 340 const ui::AXNodeData& data = node_->GetData();
347 const ActionList& action_list = GetActionList(); 341 const ActionList& action_list = GetActionList();
348 342
349 // VoiceOver expects the "press" action to be first. Note that some roles 343 // VoiceOver expects the "press" action to be first. Note that some roles
350 // should be given a press action implicitly. 344 // should be given a press action implicitly.
351 DCHECK([action_list[0].second isEqualToString:NSAccessibilityPressAction]); 345 DCHECK([action_list[0].second isEqualToString:NSAccessibilityPressAction]);
352 for (const auto item : action_list) { 346 for (const auto item : action_list) {
353 if (data.HasAction(item.first) || HasImplicitAction(data, item.first)) 347 if (data.HasAction(item.first) || HasImplicitAction(data, item.first))
354 [axActions addObject:item.second]; 348 [axActions addObject:item.second];
355 } 349 }
356 350
357 if (AlsoUseShowMenuActionForDefaultAction(data)) 351 if (AlsoUseShowMenuActionForDefaultAction(data))
358 [axActions addObject:NSAccessibilityShowMenuAction]; 352 [axActions addObject:NSAccessibilityShowMenuAction];
359 353
360 return axActions.autorelease(); 354 return axActions.autorelease();
361 } 355 }
362 356
363 - (void)accessibilityPerformAction:(NSString*)action { 357 - (void)accessibilityPerformAction:(NSString*)action {
364 // Actions are performed asynchronously, so it's always possible for an object 358 DCHECK([[self accessibilityActionNames] containsObject:action]);
365 // to change its mind after previously reporting an action as available.
366 if (![[self accessibilityActionNames] containsObject:action])
367 return;
368
369 ui::AXActionData data; 359 ui::AXActionData data;
370 if ([action isEqualToString:NSAccessibilityShowMenuAction] && 360 if ([action isEqualToString:NSAccessibilityShowMenuAction] &&
371 AlsoUseShowMenuActionForDefaultAction(node_->GetData())) { 361 AlsoUseShowMenuActionForDefaultAction(node_->GetData())) {
372 data.action = ui::AX_ACTION_DO_DEFAULT; 362 data.action = ui::AX_ACTION_DO_DEFAULT;
373 } else { 363 } else {
374 for (const ActionList::value_type& entry : GetActionList()) { 364 for (const ActionList::value_type& entry : GetActionList()) {
375 if ([action isEqualToString:entry.second]) { 365 if ([action isEqualToString:entry.second]) {
376 data.action = entry.first; 366 data.action = entry.first;
377 break; 367 break;
378 } 368 }
379 } 369 }
380 } 370 }
381 371
382 // Note ui::AX_ACTIONs which are just overwriting an accessibility attribute 372 // Note ui::AX_ACTIONs which are just overwriting an accessibility attribute
383 // are already implemented in -accessibilitySetValue:forAttribute:, so ignore 373 // are already implemented in -accessibilitySetValue:forAttribute:, so ignore
384 // those here. 374 // those here.
385 375
386 if (data.action != ui::AX_ACTION_NONE) 376 if (data.action != ui::AX_ACTION_NONE)
387 node_->GetDelegate()->AccessibilityPerformAction(data); 377 node_->GetDelegate()->AccessibilityPerformAction(data);
388 } 378 }
389 379
390 - (NSArray*)accessibilityAttributeNames { 380 - (NSArray*)accessibilityAttributeNames {
391 if (!node_)
392 return @[];
393
394 // These attributes are required on all accessibility objects. 381 // These attributes are required on all accessibility objects.
395 NSArray* const kAllRoleAttributes = @[ 382 NSArray* const kAllRoleAttributes = @[
396 NSAccessibilityChildrenAttribute, 383 NSAccessibilityChildrenAttribute,
397 NSAccessibilityParentAttribute, 384 NSAccessibilityParentAttribute,
398 NSAccessibilityPositionAttribute, 385 NSAccessibilityPositionAttribute,
399 NSAccessibilityRoleAttribute, 386 NSAccessibilityRoleAttribute,
400 NSAccessibilitySizeAttribute, 387 NSAccessibilitySizeAttribute,
401 NSAccessibilitySubroleAttribute, 388 NSAccessibilitySubroleAttribute,
402 389
403 // Title is required for most elements. Cocoa asks for the value even if it 390 // Title is required for most elements. Cocoa asks for the value even if it
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 break; 440 break;
454 // TODO(tapted): Add additional attributes based on role. 441 // TODO(tapted): Add additional attributes based on role.
455 default: 442 default:
456 break; 443 break;
457 } 444 }
458 return axAttributes.autorelease(); 445 return axAttributes.autorelease();
459 } 446 }
460 447
461 - (NSArray*)accessibilityParameterizedAttributeNames { 448 - (NSArray*)accessibilityParameterizedAttributeNames {
462 if (!node_) 449 if (!node_)
463 return @[]; 450 return nil;
464 451
465 static NSArray* const kSelectableTextAttributes = [@[ 452 static NSArray* const kSelectableTextAttributes = [@[
466 NSAccessibilityLineForIndexParameterizedAttribute, 453 NSAccessibilityLineForIndexParameterizedAttribute,
467 NSAccessibilityRangeForLineParameterizedAttribute, 454 NSAccessibilityRangeForLineParameterizedAttribute,
468 NSAccessibilityStringForRangeParameterizedAttribute, 455 NSAccessibilityStringForRangeParameterizedAttribute,
469 NSAccessibilityRangeForPositionParameterizedAttribute, 456 NSAccessibilityRangeForPositionParameterizedAttribute,
470 NSAccessibilityRangeForIndexParameterizedAttribute, 457 NSAccessibilityRangeForIndexParameterizedAttribute,
471 NSAccessibilityBoundsForRangeParameterizedAttribute, 458 NSAccessibilityBoundsForRangeParameterizedAttribute,
472 NSAccessibilityRTFForRangeParameterizedAttribute, 459 NSAccessibilityRTFForRangeParameterizedAttribute,
473 NSAccessibilityStyleRangeForIndexParameterizedAttribute, 460 NSAccessibilityStyleRangeForIndexParameterizedAttribute,
474 NSAccessibilityAttributedStringForRangeParameterizedAttribute, 461 NSAccessibilityAttributedStringForRangeParameterizedAttribute,
475 ] retain]; 462 ] retain];
476 463
477 switch (node_->GetData().role) { 464 switch (node_->GetData().role) {
478 case ui::AX_ROLE_TEXT_FIELD: 465 case ui::AX_ROLE_TEXT_FIELD:
479 case ui::AX_ROLE_STATIC_TEXT: 466 case ui::AX_ROLE_STATIC_TEXT:
480 return kSelectableTextAttributes; 467 return kSelectableTextAttributes;
481 default: 468 default:
482 break; 469 break;
483 } 470 }
484 return nil; 471 return nil;
485 } 472 }
486 473
487 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName { 474 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName {
488 if (!node_)
489 return NO;
490
491 if (node_->GetData().HasState(ui::AX_STATE_DISABLED)) 475 if (node_->GetData().HasState(ui::AX_STATE_DISABLED))
492 return NO; 476 return NO;
493 477
494 // Allow certain attributes to be written via an accessibility client. A 478 // Allow certain attributes to be written via an accessibility client. A
495 // writable attribute will only appear as such if the accessibility element 479 // writable attribute will only appear as such if the accessibility element
496 // has a value set for that attribute. 480 // has a value set for that attribute.
497 if ([attributeName 481 if ([attributeName
498 isEqualToString:NSAccessibilitySelectedChildrenAttribute] || 482 isEqualToString:NSAccessibilitySelectedChildrenAttribute] ||
499 [attributeName 483 [attributeName
500 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) { 484 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
(...skipping 17 matching lines...) Expand all
518 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) { 502 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) {
519 return node_->GetData().HasState(ui::AX_STATE_FOCUSABLE); 503 return node_->GetData().HasState(ui::AX_STATE_FOCUSABLE);
520 } 504 }
521 505
522 // TODO(patricialor): Add callbacks for updating the above attributes except 506 // TODO(patricialor): Add callbacks for updating the above attributes except
523 // NSAccessibilityValueAttribute and return YES. 507 // NSAccessibilityValueAttribute and return YES.
524 return NO; 508 return NO;
525 } 509 }
526 510
527 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute { 511 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
528 if (!node_)
529 return;
530
531 ui::AXActionData data; 512 ui::AXActionData data;
532 513
533 // Check for attributes first. Only the |data.action| should be set here - any 514 // Check for attributes first. Only the |data.action| should be set here - any
534 // type-specific information, if needed, should be set below. 515 // type-specific information, if needed, should be set below.
535 if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { 516 if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
536 data.action = node_->GetData().role == ui::AX_ROLE_TAB 517 data.action = node_->GetData().role == ui::AX_ROLE_TAB
537 ? ui::AX_ACTION_SET_SELECTION 518 ? ui::AX_ACTION_SET_SELECTION
538 : ui::AX_ACTION_SET_VALUE; 519 : ui::AX_ACTION_SET_VALUE;
539 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) { 520 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
540 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT; 521 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT;
(...skipping 18 matching lines...) Expand all
559 } 540 }
560 541
561 if (data.action != ui::AX_ACTION_NONE) 542 if (data.action != ui::AX_ACTION_NONE)
562 node_->GetDelegate()->AccessibilityPerformAction(data); 543 node_->GetDelegate()->AccessibilityPerformAction(data);
563 544
564 // TODO(patricialor): Plumb through all the other writable attributes as 545 // TODO(patricialor): Plumb through all the other writable attributes as
565 // specified in accessibilityIsAttributeSettable. 546 // specified in accessibilityIsAttributeSettable.
566 } 547 }
567 548
568 - (id)accessibilityAttributeValue:(NSString*)attribute { 549 - (id)accessibilityAttributeValue:(NSString*)attribute {
569 if (!node_)
570 return nil; // Return nil when detached. Even for AXRole.
571
572 SEL selector = NSSelectorFromString(attribute); 550 SEL selector = NSSelectorFromString(attribute);
573 if ([self respondsToSelector:selector]) 551 if ([self respondsToSelector:selector])
574 return [self performSelector:selector]; 552 return [self performSelector:selector];
575 return nil; 553 return nil;
576 } 554 }
577 555
578 - (id)accessibilityAttributeValue:(NSString*)attribute 556 - (id)accessibilityAttributeValue:(NSString*)attribute
579 forParameter:(id)parameter { 557 forParameter:(id)parameter {
580 if (!node_)
581 return nil;
582
583 SEL selector = NSSelectorFromString([attribute stringByAppendingString:@":"]); 558 SEL selector = NSSelectorFromString([attribute stringByAppendingString:@":"]);
584 if ([self respondsToSelector:selector]) 559 if ([self respondsToSelector:selector])
585 return [self performSelector:selector withObject:parameter]; 560 return [self performSelector:selector withObject:parameter];
586 return nil; 561 return nil;
587 } 562 }
588 563
589 // NSAccessibility attributes. Order them according to 564 // NSAccessibility attributes. Order them according to
590 // NSAccessibilityConstants.h, or see https://crbug.com/678898. 565 // NSAccessibilityConstants.h, or see https://crbug.com/678898.
591 566
592 - (NSString*)AXRole { 567 - (NSString*)AXRole {
593 if (!node_) 568 if (!node_)
594 return nil; 569 return nil;
595
596 return [[self class] nativeRoleFromAXRole:node_->GetData().role]; 570 return [[self class] nativeRoleFromAXRole:node_->GetData().role];
597 } 571 }
598 572
599 - (NSString*)AXRoleDescription { 573 - (NSString*)AXRoleDescription {
600 switch (node_->GetData().role) { 574 switch (node_->GetData().role) {
601 case ui::AX_ROLE_TAB: 575 case ui::AX_ROLE_TAB:
602 // There is no NSAccessibilityTabRole or similar (AXRadioButton is used 576 // There is no NSAccessibilityTabRole or similar (AXRadioButton is used
603 // instead). Do the same as NSTabView and put "tab" in the description. 577 // instead). Do the same as NSTabView and put "tab" in the description.
604 return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB_ROLE_DESCRIPTION) 578 return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB_ROLE_DESCRIPTION)
605 lowercaseString]; 579 lowercaseString];
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 } 627 }
654 628
655 - (id)AXParent { 629 - (id)AXParent {
656 if (!node_) 630 if (!node_)
657 return nil; 631 return nil;
658 return NSAccessibilityUnignoredAncestor(node_->GetParent()); 632 return NSAccessibilityUnignoredAncestor(node_->GetParent());
659 } 633 }
660 634
661 - (NSArray*)AXChildren { 635 - (NSArray*)AXChildren {
662 if (!node_) 636 if (!node_)
663 return @[]; 637 return nil;
664
665 int count = node_->GetChildCount(); 638 int count = node_->GetChildCount();
666 NSMutableArray* children = [NSMutableArray arrayWithCapacity:count]; 639 NSMutableArray* children = [NSMutableArray arrayWithCapacity:count];
667 for (int i = 0; i < count; ++i) 640 for (int i = 0; i < count; ++i)
668 [children addObject:node_->ChildAtIndex(i)]; 641 [children addObject:node_->ChildAtIndex(i)];
669 return NSAccessibilityUnignoredChildren(children); 642 return NSAccessibilityUnignoredChildren(children);
670 } 643 }
671 644
672 - (id)AXWindow { 645 - (id)AXWindow {
673 return node_->GetDelegate()->GetTopLevelWidget(); 646 return node_->GetDelegate()->GetTopLevelWidget();
674 } 647 }
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 } 820 }
848 NotifyMacEvent(native_node_, event_type); 821 NotifyMacEvent(native_node_, event_type);
849 } 822 }
850 823
851 int AXPlatformNodeMac::GetIndexInParent() { 824 int AXPlatformNodeMac::GetIndexInParent() {
852 // TODO(dmazzoni): implement this. http://crbug.com/396137 825 // TODO(dmazzoni): implement this. http://crbug.com/396137
853 return -1; 826 return -1;
854 } 827 }
855 828
856 } // namespace ui 829 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | ui/views/widget/native_widget_mac_accessibility_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698