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

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

Issue 2860883003: A11y: Add/refactor methods for manipulating bitfields on AXNodeData. (Closed)
Patch Set: Delete AXNodeData::Init() and clear bitfields in AXNodeData() instead. Created 3 years, 7 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"
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 std::string attributeValue; 284 std::string attributeValue;
285 if (node_->GetStringAttribute(attribute, &attributeValue)) 285 if (node_->GetStringAttribute(attribute, &attributeValue))
286 return base::SysUTF8ToNSString(attributeValue); 286 return base::SysUTF8ToNSString(attributeValue);
287 return nil; 287 return nil;
288 } 288 }
289 289
290 // NSAccessibility informal protocol implementation. 290 // NSAccessibility informal protocol implementation.
291 291
292 - (BOOL)accessibilityIsIgnored { 292 - (BOOL)accessibilityIsIgnored {
293 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] || 293 return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] ||
294 node_->GetData().HasStateFlag(ui::AX_STATE_INVISIBLE); 294 node_->GetData().HasState(ui::AX_STATE_INVISIBLE);
295 } 295 }
296 296
297 - (id)accessibilityHitTest:(NSPoint)point { 297 - (id)accessibilityHitTest:(NSPoint)point {
298 for (AXPlatformNodeCocoa* child in [self AXChildren]) { 298 for (AXPlatformNodeCocoa* child in [self AXChildren]) {
299 if (NSPointInRect(point, child.boundsInScreen)) 299 if (NSPointInRect(point, child.boundsInScreen))
300 return [child accessibilityHitTest:point]; 300 return [child accessibilityHitTest:point];
301 } 301 }
302 return NSAccessibilityUnignoredAncestor(self); 302 return NSAccessibilityUnignoredAncestor(self);
303 } 303 }
304 304
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 NSString* const kTextfieldAttributes = 374 NSString* const kTextfieldAttributes =
375 NSAccessibilityPlaceholderValueAttribute; 375 NSAccessibilityPlaceholderValueAttribute;
376 376
377 base::scoped_nsobject<NSMutableArray> axAttributes( 377 base::scoped_nsobject<NSMutableArray> axAttributes(
378 [[NSMutableArray alloc] init]); 378 [[NSMutableArray alloc] init]);
379 379
380 [axAttributes addObjectsFromArray:kAllRoleAttributes]; 380 [axAttributes addObjectsFromArray:kAllRoleAttributes];
381 switch (node_->GetData().role) { 381 switch (node_->GetData().role) {
382 case ui::AX_ROLE_TEXT_FIELD: 382 case ui::AX_ROLE_TEXT_FIELD:
383 [axAttributes addObject:kTextfieldAttributes]; 383 [axAttributes addObject:kTextfieldAttributes];
384 if (!ui::AXNodeData::IsFlagSet(node_->GetData().state, 384 if (!node_->GetData().HasState(ui::AX_STATE_PROTECTED))
385 ui::AX_STATE_PROTECTED)) {
386 [axAttributes addObjectsFromArray:kUnprotectedTextfieldAttributes]; 385 [axAttributes addObjectsFromArray:kUnprotectedTextfieldAttributes];
387 }
388 // Fallthrough. 386 // Fallthrough.
389 case ui::AX_ROLE_CHECK_BOX: 387 case ui::AX_ROLE_CHECK_BOX:
390 case ui::AX_ROLE_COMBO_BOX: 388 case ui::AX_ROLE_COMBO_BOX:
391 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: 389 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
392 case ui::AX_ROLE_MENU_ITEM_RADIO: 390 case ui::AX_ROLE_MENU_ITEM_RADIO:
393 case ui::AX_ROLE_RADIO_BUTTON: 391 case ui::AX_ROLE_RADIO_BUTTON:
394 case ui::AX_ROLE_SEARCH_BOX: 392 case ui::AX_ROLE_SEARCH_BOX:
395 case ui::AX_ROLE_SLIDER: 393 case ui::AX_ROLE_SLIDER:
396 case ui::AX_ROLE_SLIDER_THUMB: 394 case ui::AX_ROLE_SLIDER_THUMB:
397 case ui::AX_ROLE_TOGGLE_BUTTON: 395 case ui::AX_ROLE_TOGGLE_BUTTON:
398 [axAttributes addObjectsFromArray:kValueAttributes]; 396 [axAttributes addObjectsFromArray:kValueAttributes];
399 break; 397 break;
400 // TODO(tapted): Add additional attributes based on role. 398 // TODO(tapted): Add additional attributes based on role.
401 default: 399 default:
402 break; 400 break;
403 } 401 }
404 return axAttributes.autorelease(); 402 return axAttributes.autorelease();
405 } 403 }
406 404
407 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName { 405 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName {
408 if (node_->GetData().HasStateFlag(ui::AX_STATE_DISABLED)) 406 if (node_->GetData().HasState(ui::AX_STATE_DISABLED))
409 return NO; 407 return NO;
410 408
411 // Allow certain attributes to be written via an accessibility client. A 409 // Allow certain attributes to be written via an accessibility client. A
412 // writable attribute will only appear as such if the accessibility element 410 // writable attribute will only appear as such if the accessibility element
413 // has a value set for that attribute. 411 // has a value set for that attribute.
414 if ([attributeName 412 if ([attributeName
415 isEqualToString:NSAccessibilitySelectedChildrenAttribute] || 413 isEqualToString:NSAccessibilitySelectedChildrenAttribute] ||
416 [attributeName 414 [attributeName
417 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) { 415 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
418 return NO; 416 return NO;
419 } 417 }
420 418
421 if ([attributeName isEqualToString:NSAccessibilityValueAttribute]) { 419 if ([attributeName isEqualToString:NSAccessibilityValueAttribute]) {
422 // NSSecureTextField doesn't allow values to be edited (despite showing up 420 // NSSecureTextField doesn't allow values to be edited (despite showing up
423 // as editable), match its behavior. 421 // as editable), match its behavior.
424 if (node_->GetData().HasStateFlag(ui::AX_STATE_PROTECTED)) 422 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
425 return NO; 423 return NO;
426 // Since tabs use the Radio Button role on Mac, the standard way to set 424 // Since tabs use the Radio Button role on Mac, the standard way to set
427 // them is via the value attribute rather than the selected attribute. 425 // them is via the value attribute rather than the selected attribute.
428 if (node_->GetData().role == ui::AX_ROLE_TAB) 426 if (node_->GetData().role == ui::AX_ROLE_TAB)
429 return !node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED); 427 return !node_->GetData().HasState(ui::AX_STATE_SELECTED);
430 } 428 }
431 429
432 if ([attributeName isEqualToString:NSAccessibilityValueAttribute] || 430 if ([attributeName isEqualToString:NSAccessibilityValueAttribute] ||
433 [attributeName isEqualToString:NSAccessibilitySelectedTextAttribute] || 431 [attributeName isEqualToString:NSAccessibilitySelectedTextAttribute] ||
434 [attributeName 432 [attributeName
435 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { 433 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
436 return !ui::AXNodeData::IsFlagSet(node_->GetData().state, 434 return !node_->GetData().HasState(ui::AX_STATE_READ_ONLY);
437 ui::AX_STATE_READ_ONLY);
438 } 435 }
439 436
440 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) { 437 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) {
441 return ui::AXNodeData::IsFlagSet(node_->GetData().state, 438 return node_->GetData().HasState(ui::AX_STATE_FOCUSABLE);
442 ui::AX_STATE_FOCUSABLE);
443 } 439 }
444 440
445 // TODO(patricialor): Add callbacks for updating the above attributes except 441 // TODO(patricialor): Add callbacks for updating the above attributes except
446 // NSAccessibilityValueAttribute and return YES. 442 // NSAccessibilityValueAttribute and return YES.
447 return NO; 443 return NO;
448 } 444 }
449 445
450 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute { 446 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
451 ui::AXActionData data; 447 ui::AXActionData data;
452 448
453 // Check for attributes first. Only the |data.action| should be set here - any 449 // Check for attributes first. Only the |data.action| should be set here - any
454 // type-specific information, if needed, should be set below. 450 // type-specific information, if needed, should be set below.
455 if ([attribute isEqualToString:NSAccessibilityValueAttribute] && 451 if ([attribute isEqualToString:NSAccessibilityValueAttribute] &&
456 !node_->GetData().HasStateFlag(ui::AX_STATE_PROTECTED)) { 452 !node_->GetData().HasState(ui::AX_STATE_PROTECTED)) {
457 data.action = node_->GetData().role == ui::AX_ROLE_TAB 453 data.action = node_->GetData().role == ui::AX_ROLE_TAB
458 ? ui::AX_ACTION_SET_SELECTION 454 ? ui::AX_ACTION_SET_SELECTION
459 : ui::AX_ACTION_SET_VALUE; 455 : ui::AX_ACTION_SET_VALUE;
460 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) { 456 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
461 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT; 457 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT;
462 } else if ([attribute 458 } else if ([attribute
463 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { 459 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
464 data.action = ui::AX_ACTION_SET_SELECTION; 460 data.action = ui::AX_ACTION_SET_SELECTION;
465 } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { 461 } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
466 if ([value isKindOfClass:[NSNumber class]]) { 462 if ([value isKindOfClass:[NSNumber class]]) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 default: 508 default:
513 break; 509 break;
514 } 510 }
515 return NSAccessibilityRoleDescription([self AXRole], [self AXSubrole]); 511 return NSAccessibilityRoleDescription([self AXRole], [self AXSubrole]);
516 } 512 }
517 513
518 - (NSString*)AXSubrole { 514 - (NSString*)AXSubrole {
519 ui::AXRole role = node_->GetData().role; 515 ui::AXRole role = node_->GetData().role;
520 switch (role) { 516 switch (role) {
521 case ui::AX_ROLE_TEXT_FIELD: 517 case ui::AX_ROLE_TEXT_FIELD:
522 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, 518 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
523 ui::AX_STATE_PROTECTED))
524 return NSAccessibilitySecureTextFieldSubrole; 519 return NSAccessibilitySecureTextFieldSubrole;
525 break; 520 break;
526 default: 521 default:
527 break; 522 break;
528 } 523 }
529 return [AXPlatformNodeCocoa nativeSubroleFromAXRole:role]; 524 return [AXPlatformNodeCocoa nativeSubroleFromAXRole:role];
530 } 525 }
531 526
532 - (NSString*)AXHelp { 527 - (NSString*)AXHelp {
533 return [self getStringAttribute:ui::AX_ATTR_DESCRIPTION]; 528 return [self getStringAttribute:ui::AX_ATTR_DESCRIPTION];
534 } 529 }
535 530
536 - (id)AXValue { 531 - (id)AXValue {
537 if (node_->GetData().role == ui::AX_ROLE_TAB) 532 if (node_->GetData().role == ui::AX_ROLE_TAB)
538 return [self AXSelected]; 533 return [self AXSelected];
539 return [self getStringAttribute:ui::AX_ATTR_VALUE]; 534 return [self getStringAttribute:ui::AX_ATTR_VALUE];
540 } 535 }
541 536
542 - (NSNumber*)AXEnabled { 537 - (NSNumber*)AXEnabled {
543 return @(!ui::AXNodeData::IsFlagSet(node_->GetData().state, 538 return @(!node_->GetData().HasState(ui::AX_STATE_DISABLED));
544 ui::AX_STATE_DISABLED));
545 } 539 }
546 540
547 - (NSNumber*)AXFocused { 541 - (NSNumber*)AXFocused {
548 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, 542 if (node_->GetData().HasState(ui::AX_STATE_FOCUSABLE))
549 ui::AX_STATE_FOCUSABLE))
550 return 543 return
551 @(node_->GetDelegate()->GetFocus() == node_->GetNativeViewAccessible()); 544 @(node_->GetDelegate()->GetFocus() == node_->GetNativeViewAccessible());
552 return @NO; 545 return @NO;
553 } 546 }
554 547
555 - (id)AXParent { 548 - (id)AXParent {
556 if (!node_) 549 if (!node_)
557 return nil; 550 return nil;
558 return NSAccessibilityUnignoredAncestor(node_->GetParent()); 551 return NSAccessibilityUnignoredAncestor(node_->GetParent());
559 } 552 }
(...skipping 24 matching lines...) Expand all
584 return [NSValue valueWithSize:self.boundsInScreen.size]; 577 return [NSValue valueWithSize:self.boundsInScreen.size];
585 } 578 }
586 579
587 - (NSString*)AXTitle { 580 - (NSString*)AXTitle {
588 return [self getStringAttribute:ui::AX_ATTR_NAME]; 581 return [self getStringAttribute:ui::AX_ATTR_NAME];
589 } 582 }
590 583
591 // Misc attributes. 584 // Misc attributes.
592 585
593 - (NSNumber*)AXSelected { 586 - (NSNumber*)AXSelected {
594 return @(node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED)); 587 return @(node_->GetData().HasState(ui::AX_STATE_SELECTED));
595 } 588 }
596 589
597 - (NSString*)AXPlaceholderValue { 590 - (NSString*)AXPlaceholderValue {
598 return [self getStringAttribute:ui::AX_ATTR_PLACEHOLDER]; 591 return [self getStringAttribute:ui::AX_ATTR_PLACEHOLDER];
599 } 592 }
600 593
601 // Text-specific attributes. 594 // Text-specific attributes.
602 595
603 - (NSString*)AXSelectedText { 596 - (NSString*)AXSelectedText {
604 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED)) 597 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
605 return nil; 598 return nil;
606 599
607 NSRange selectedTextRange; 600 NSRange selectedTextRange;
608 [[self AXSelectedTextRange] getValue:&selectedTextRange]; 601 [[self AXSelectedTextRange] getValue:&selectedTextRange];
609 return [[self AXValue] substringWithRange:selectedTextRange]; 602 return [[self AXValue] substringWithRange:selectedTextRange];
610 } 603 }
611 604
612 - (NSValue*)AXSelectedTextRange { 605 - (NSValue*)AXSelectedTextRange {
613 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED)) 606 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
614 return nil; 607 return nil;
615 608
616 int textDir, start, end; 609 int textDir, start, end;
617 node_->GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, &textDir); 610 node_->GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, &textDir);
618 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &start); 611 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &start);
619 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &end); 612 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &end);
620 // NSRange cannot represent the direction the text was selected in, so make 613 // NSRange cannot represent the direction the text was selected in, so make
621 // sure the correct selection index is used when creating a new range, taking 614 // sure the correct selection index is used when creating a new range, taking
622 // into account the textfield text direction as well. 615 // into account the textfield text direction as well.
623 bool isReversed = (textDir == ui::AX_TEXT_DIRECTION_RTL) || 616 bool isReversed = (textDir == ui::AX_TEXT_DIRECTION_RTL) ||
624 (textDir == ui::AX_TEXT_DIRECTION_BTT); 617 (textDir == ui::AX_TEXT_DIRECTION_BTT);
625 int beginSelectionIndex = (end > start && !isReversed) ? start : end; 618 int beginSelectionIndex = (end > start && !isReversed) ? start : end;
626 return [NSValue valueWithRange:{beginSelectionIndex, abs(end - start)}]; 619 return [NSValue valueWithRange:{beginSelectionIndex, abs(end - start)}];
627 } 620 }
628 621
629 - (NSNumber*)AXNumberOfCharacters { 622 - (NSNumber*)AXNumberOfCharacters {
630 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED)) 623 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
631 return nil; 624 return nil;
632 return @([[self AXValue] length]); 625 return @([[self AXValue] length]);
633 } 626 }
634 627
635 - (NSValue*)AXVisibleCharacterRange { 628 - (NSValue*)AXVisibleCharacterRange {
636 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED)) 629 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
637 return nil; 630 return nil;
638 return [NSValue valueWithRange:{0, [[self AXNumberOfCharacters] intValue]}]; 631 return [NSValue valueWithRange:{0, [[self AXNumberOfCharacters] intValue]}];
639 } 632 }
640 633
641 - (NSNumber*)AXInsertionPointLineNumber { 634 - (NSNumber*)AXInsertionPointLineNumber {
642 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED)) 635 if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
643 return nil; 636 return nil;
644 // Multiline is not supported on views. 637 // Multiline is not supported on views.
645 return @0; 638 return @0;
646 } 639 }
647 640
648 @end 641 @end
649 642
650 namespace ui { 643 namespace ui {
651 644
652 // static 645 // static
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 692 }
700 NotifyMacEvent(native_node_, event_type); 693 NotifyMacEvent(native_node_, event_type);
701 } 694 }
702 695
703 int AXPlatformNodeMac::GetIndexInParent() { 696 int AXPlatformNodeMac::GetIndexInParent() {
704 // TODO(dmazzoni): implement this. http://crbug.com/396137 697 // TODO(dmazzoni): implement this. http://crbug.com/396137
705 return -1; 698 return -1;
706 } 699 }
707 700
708 } // namespace ui 701 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698