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

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

Issue 2706743002: MacViews/a11y: Disable most text-specific attributes for protected textfields. (Closed)
Patch Set: Review comments. Created 3 years, 10 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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 NSAccessibilityEnabledAttribute, 348 NSAccessibilityEnabledAttribute,
349 NSAccessibilityFocusedAttribute, 349 NSAccessibilityFocusedAttribute,
350 NSAccessibilityHelpAttribute, 350 NSAccessibilityHelpAttribute,
351 NSAccessibilityTopLevelUIElementAttribute, 351 NSAccessibilityTopLevelUIElementAttribute,
352 NSAccessibilityWindowAttribute, 352 NSAccessibilityWindowAttribute,
353 ]; 353 ];
354 354
355 // Attributes required for user-editable controls. 355 // Attributes required for user-editable controls.
356 NSArray* const kValueAttributes = @[ NSAccessibilityValueAttribute ]; 356 NSArray* const kValueAttributes = @[ NSAccessibilityValueAttribute ];
357 357
358 // Attributes required for textfields. 358 // Attributes required for unprotected textfields.
359 NSArray* const kTextfieldAttributes = @[ 359 NSArray* const kUnprotectedTextfieldAttributes = @[
360 NSAccessibilityInsertionPointLineNumberAttribute, 360 NSAccessibilityInsertionPointLineNumberAttribute,
361 NSAccessibilityNumberOfCharactersAttribute, 361 NSAccessibilityNumberOfCharactersAttribute,
362 NSAccessibilityPlaceholderValueAttribute,
363 NSAccessibilitySelectedTextAttribute, 362 NSAccessibilitySelectedTextAttribute,
364 NSAccessibilitySelectedTextRangeAttribute, 363 NSAccessibilitySelectedTextRangeAttribute,
365 NSAccessibilityVisibleCharacterRangeAttribute, 364 NSAccessibilityVisibleCharacterRangeAttribute,
366 ]; 365 ];
367 366
367 // Required for all textfields, including protected ones.
368 NSString* const kTextfieldAttributes =
369 NSAccessibilityPlaceholderValueAttribute;
370
368 base::scoped_nsobject<NSMutableArray> axAttributes( 371 base::scoped_nsobject<NSMutableArray> axAttributes(
369 [[NSMutableArray alloc] init]); 372 [[NSMutableArray alloc] init]);
370 373
371 [axAttributes addObjectsFromArray:kAllRoleAttributes]; 374 [axAttributes addObjectsFromArray:kAllRoleAttributes];
372 switch (node_->GetData().role) { 375 switch (node_->GetData().role) {
373 case ui::AX_ROLE_TEXT_FIELD: 376 case ui::AX_ROLE_TEXT_FIELD:
374 [axAttributes addObjectsFromArray:kTextfieldAttributes]; 377 [axAttributes addObject:kTextfieldAttributes];
378 if (!ui::AXNodeData::IsFlagSet(node_->GetData().state,
379 ui::AX_STATE_PROTECTED)) {
380 [axAttributes addObjectsFromArray:kUnprotectedTextfieldAttributes];
381 }
375 // Fallthrough. 382 // Fallthrough.
376 case ui::AX_ROLE_CHECK_BOX: 383 case ui::AX_ROLE_CHECK_BOX:
377 case ui::AX_ROLE_COMBO_BOX: 384 case ui::AX_ROLE_COMBO_BOX:
378 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: 385 case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
379 case ui::AX_ROLE_MENU_ITEM_RADIO: 386 case ui::AX_ROLE_MENU_ITEM_RADIO:
380 case ui::AX_ROLE_RADIO_BUTTON: 387 case ui::AX_ROLE_RADIO_BUTTON:
381 case ui::AX_ROLE_SEARCH_BOX: 388 case ui::AX_ROLE_SEARCH_BOX:
382 case ui::AX_ROLE_SLIDER: 389 case ui::AX_ROLE_SLIDER:
383 case ui::AX_ROLE_SLIDER_THUMB: 390 case ui::AX_ROLE_SLIDER_THUMB:
384 case ui::AX_ROLE_TOGGLE_BUTTON: 391 case ui::AX_ROLE_TOGGLE_BUTTON:
(...skipping 13 matching lines...) Expand all
398 // Allow certain attributes to be written via an accessibility client. A 405 // Allow certain attributes to be written via an accessibility client. A
399 // writable attribute will only appear as such if the accessibility element 406 // writable attribute will only appear as such if the accessibility element
400 // has a value set for that attribute. 407 // has a value set for that attribute.
401 if ([attributeName 408 if ([attributeName
402 isEqualToString:NSAccessibilitySelectedChildrenAttribute] || 409 isEqualToString:NSAccessibilitySelectedChildrenAttribute] ||
403 [attributeName 410 [attributeName
404 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) { 411 isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
405 return NO; 412 return NO;
406 } 413 }
407 414
408 // Since tabs use the Radio Button role on Mac, the standard way to set them 415 if ([attributeName isEqualToString:NSAccessibilityValueAttribute]) {
409 // is via the value attribute rather than the selected attribute. 416 // NSSecureTextField doesn't allow values to be edited (despite showing up
410 if ([attributeName isEqualToString:NSAccessibilityValueAttribute] && 417 // as editable), match its behavior.
411 node_->GetData().role == ui::AX_ROLE_TAB) { 418 if (node_->GetData().HasStateFlag(ui::AX_STATE_PROTECTED))
412 return !node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED); 419 return NO;
420 // Since tabs use the Radio Button role on Mac, the standard way to set
421 // them is via the value attribute rather than the selected attribute.
422 if (node_->GetData().role == ui::AX_ROLE_TAB)
423 return !node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED);
413 } 424 }
414 425
415 if ([attributeName isEqualToString:NSAccessibilityValueAttribute] || 426 if ([attributeName isEqualToString:NSAccessibilityValueAttribute] ||
416 [attributeName isEqualToString:NSAccessibilitySelectedTextAttribute] || 427 [attributeName isEqualToString:NSAccessibilitySelectedTextAttribute] ||
417 [attributeName 428 [attributeName
418 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { 429 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
419 return !ui::AXNodeData::IsFlagSet(node_->GetData().state, 430 return !ui::AXNodeData::IsFlagSet(node_->GetData().state,
420 ui::AX_STATE_READ_ONLY); 431 ui::AX_STATE_READ_ONLY);
421 } 432 }
422 433
423 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) { 434 if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) {
424 return ui::AXNodeData::IsFlagSet(node_->GetData().state, 435 return ui::AXNodeData::IsFlagSet(node_->GetData().state,
425 ui::AX_STATE_FOCUSABLE); 436 ui::AX_STATE_FOCUSABLE);
426 } 437 }
427 438
428 // TODO(patricialor): Add callbacks for updating the above attributes except 439 // TODO(patricialor): Add callbacks for updating the above attributes except
429 // NSAccessibilityValueAttribute and return YES. 440 // NSAccessibilityValueAttribute and return YES.
430 return NO; 441 return NO;
431 } 442 }
432 443
433 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute { 444 - (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
434 ui::AXActionData data; 445 ui::AXActionData data;
435 446
436 // Check for attributes first. Only the |data.action| should be set here - any 447 // Check for attributes first. Only the |data.action| should be set here - any
437 // type-specific information, if needed, should be set below. 448 // type-specific information, if needed, should be set below.
438 if ([attribute isEqualToString:NSAccessibilityValueAttribute]) { 449 if ([attribute isEqualToString:NSAccessibilityValueAttribute] &&
450 !node_->GetData().HasStateFlag(ui::AX_STATE_PROTECTED)) {
439 data.action = node_->GetData().role == ui::AX_ROLE_TAB 451 data.action = node_->GetData().role == ui::AX_ROLE_TAB
440 ? ui::AX_ACTION_SET_SELECTION 452 ? ui::AX_ACTION_SET_SELECTION
441 : ui::AX_ACTION_SET_VALUE; 453 : ui::AX_ACTION_SET_VALUE;
442 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) { 454 } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
443 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT; 455 data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT;
444 } else if ([attribute 456 } else if ([attribute
445 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { 457 isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
446 data.action = ui::AX_ACTION_SET_SELECTION; 458 data.action = ui::AX_ACTION_SET_SELECTION;
447 } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { 459 } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
448 if ([value isKindOfClass:[NSNumber class]]) { 460 if ([value isKindOfClass:[NSNumber class]]) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 return @(node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED)); 588 return @(node_->GetData().HasStateFlag(ui::AX_STATE_SELECTED));
577 } 589 }
578 590
579 - (NSString*)AXPlaceholderValue { 591 - (NSString*)AXPlaceholderValue {
580 return [self getStringAttribute:ui::AX_ATTR_PLACEHOLDER]; 592 return [self getStringAttribute:ui::AX_ATTR_PLACEHOLDER];
581 } 593 }
582 594
583 // Text-specific attributes. 595 // Text-specific attributes.
584 596
585 - (NSString*)AXSelectedText { 597 - (NSString*)AXSelectedText {
598 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED))
599 return nil;
600
586 NSRange selectedTextRange; 601 NSRange selectedTextRange;
587 [[self AXSelectedTextRange] getValue:&selectedTextRange]; 602 [[self AXSelectedTextRange] getValue:&selectedTextRange];
588 return [[self AXValue] substringWithRange:selectedTextRange]; 603 return [[self AXValue] substringWithRange:selectedTextRange];
589 } 604 }
590 605
591 - (NSValue*)AXSelectedTextRange { 606 - (NSValue*)AXSelectedTextRange {
607 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED))
608 return nil;
609
592 int textDir, start, end; 610 int textDir, start, end;
593 node_->GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, &textDir); 611 node_->GetIntAttribute(ui::AX_ATTR_TEXT_DIRECTION, &textDir);
594 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &start); 612 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &start);
595 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &end); 613 node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &end);
596 // NSRange cannot represent the direction the text was selected in, so make 614 // NSRange cannot represent the direction the text was selected in, so make
597 // sure the correct selection index is used when creating a new range, taking 615 // sure the correct selection index is used when creating a new range, taking
598 // into account the textfield text direction as well. 616 // into account the textfield text direction as well.
599 bool isReversed = (textDir == ui::AX_TEXT_DIRECTION_RTL) || 617 bool isReversed = (textDir == ui::AX_TEXT_DIRECTION_RTL) ||
600 (textDir == ui::AX_TEXT_DIRECTION_BTT); 618 (textDir == ui::AX_TEXT_DIRECTION_BTT);
601 int beginSelectionIndex = (end > start && !isReversed) ? start : end; 619 int beginSelectionIndex = (end > start && !isReversed) ? start : end;
602 return [NSValue valueWithRange:{beginSelectionIndex, abs(end - start)}]; 620 return [NSValue valueWithRange:{beginSelectionIndex, abs(end - start)}];
603 } 621 }
604 622
605 - (NSNumber*)AXNumberOfCharacters { 623 - (NSNumber*)AXNumberOfCharacters {
624 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED))
625 return nil;
606 return @([[self AXValue] length]); 626 return @([[self AXValue] length]);
607 } 627 }
608 628
609 - (NSValue*)AXVisibleCharacterRange { 629 - (NSValue*)AXVisibleCharacterRange {
630 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED))
631 return nil;
610 return [NSValue valueWithRange:{0, [[self AXNumberOfCharacters] intValue]}]; 632 return [NSValue valueWithRange:{0, [[self AXNumberOfCharacters] intValue]}];
611 } 633 }
612 634
613 - (NSNumber*)AXInsertionPointLineNumber { 635 - (NSNumber*)AXInsertionPointLineNumber {
636 if (ui::AXNodeData::IsFlagSet(node_->GetData().state, ui::AX_STATE_PROTECTED))
637 return nil;
614 // Multiline is not supported on views. 638 // Multiline is not supported on views.
615 return @0; 639 return @0;
616 } 640 }
617 641
618 @end 642 @end
619 643
620 namespace ui { 644 namespace ui {
621 645
622 // static 646 // static
623 AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) { 647 AXPlatformNode* AXPlatformNode::Create(AXPlatformNodeDelegate* delegate) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 685 }
662 NotifyMacEvent(native_node_, event_type); 686 NotifyMacEvent(native_node_, event_type);
663 } 687 }
664 688
665 int AXPlatformNodeMac::GetIndexInParent() { 689 int AXPlatformNodeMac::GetIndexInParent() {
666 // TODO(dmazzoni): implement this. http://crbug.com/396137 690 // TODO(dmazzoni): implement this. http://crbug.com/396137
667 return -1; 691 return -1;
668 } 692 }
669 693
670 } // namespace ui 694 } // namespace ui
OLDNEW
« no previous file with comments | « base/mac/sdk_forward_declarations.h ('k') | ui/views/widget/native_widget_mac_accessibility_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698