| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include <execinfo.h> | 5 #include <execinfo.h> |
| 6 | 6 |
| 7 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 7 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/strings/string16.h" | 12 #include "base/strings/string16.h" |
| 13 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "content/browser/accessibility/browser_accessibility_manager.h" | 15 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 16 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" | 16 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" |
| 17 #include "content/public/common/content_client.h" | 17 #include "content/public/common/content_client.h" |
| 18 #include "grit/webkit_strings.h" | 18 #include "grit/webkit_strings.h" |
| 19 #import "ui/accessibility/platform/ax_platform_node_mac.h" |
| 19 | 20 |
| 20 // See http://openradar.appspot.com/9896491. This SPI has been tested on 10.5, | 21 // See http://openradar.appspot.com/9896491. This SPI has been tested on 10.5, |
| 21 // 10.6, and 10.7. It allows accessibility clients to observe events posted on | 22 // 10.6, and 10.7. It allows accessibility clients to observe events posted on |
| 22 // this object. | 23 // this object. |
| 23 extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element); | 24 extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element); |
| 24 | 25 |
| 25 using ui::AXNodeData; | 26 using ui::AXNodeData; |
| 26 using content::BrowserAccessibility; | 27 using content::BrowserAccessibility; |
| 27 using content::BrowserAccessibilityManager; | 28 using content::BrowserAccessibilityManager; |
| 28 using content::BrowserAccessibilityManagerMac; | 29 using content::BrowserAccessibilityManagerMac; |
| 29 using content::ContentClient; | 30 using content::ContentClient; |
| 30 typedef ui::AXStringAttribute StringAttribute; | 31 typedef ui::AXStringAttribute StringAttribute; |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 // Returns an autoreleased copy of the AXNodeData's attribute. | 35 // Returns an autoreleased copy of the AXNodeData's attribute. |
| 35 NSString* NSStringForStringAttribute( | 36 NSString* NSStringForStringAttribute( |
| 36 BrowserAccessibility* browserAccessibility, | 37 BrowserAccessibility* browserAccessibility, |
| 37 StringAttribute attribute) { | 38 StringAttribute attribute) { |
| 38 return base::SysUTF8ToNSString( | 39 return base::SysUTF8ToNSString( |
| 39 browserAccessibility->GetStringAttribute(attribute)); | 40 browserAccessibility->GetStringAttribute(attribute)); |
| 40 } | 41 } |
| 41 | 42 |
| 42 struct MapEntry { | |
| 43 ui::AXRole webKitValue; | |
| 44 NSString* nativeValue; | |
| 45 }; | |
| 46 | |
| 47 typedef std::map<ui::AXRole, NSString*> RoleMap; | |
| 48 | |
| 49 // GetState checks the bitmask used in AXNodeData to check | 43 // GetState checks the bitmask used in AXNodeData to check |
| 50 // if the given state was set on the accessibility object. | 44 // if the given state was set on the accessibility object. |
| 51 bool GetState(BrowserAccessibility* accessibility, ui::AXState state) { | 45 bool GetState(BrowserAccessibility* accessibility, ui::AXState state) { |
| 52 return ((accessibility->GetState() >> state) & 1); | 46 return ((accessibility->GetState() >> state) & 1); |
| 53 } | 47 } |
| 54 | 48 |
| 55 RoleMap BuildRoleMap() { | |
| 56 const MapEntry roles[] = { | |
| 57 { ui::AX_ROLE_ALERT, NSAccessibilityGroupRole }, | |
| 58 { ui::AX_ROLE_ALERT_DIALOG, NSAccessibilityGroupRole }, | |
| 59 { ui::AX_ROLE_ANNOTATION, NSAccessibilityUnknownRole }, | |
| 60 { ui::AX_ROLE_APPLICATION, NSAccessibilityGroupRole }, | |
| 61 { ui::AX_ROLE_ARTICLE, NSAccessibilityGroupRole }, | |
| 62 { ui::AX_ROLE_BANNER, NSAccessibilityGroupRole }, | |
| 63 { ui::AX_ROLE_BROWSER, NSAccessibilityBrowserRole }, | |
| 64 { ui::AX_ROLE_BUSY_INDICATOR, NSAccessibilityBusyIndicatorRole }, | |
| 65 { ui::AX_ROLE_BUTTON, NSAccessibilityButtonRole }, | |
| 66 { ui::AX_ROLE_CANVAS, NSAccessibilityImageRole }, | |
| 67 { ui::AX_ROLE_CELL, @"AXCell" }, | |
| 68 { ui::AX_ROLE_CHECK_BOX, NSAccessibilityCheckBoxRole }, | |
| 69 { ui::AX_ROLE_COLOR_WELL, NSAccessibilityColorWellRole }, | |
| 70 { ui::AX_ROLE_COLUMN, NSAccessibilityColumnRole }, | |
| 71 { ui::AX_ROLE_COLUMN_HEADER, @"AXCell" }, | |
| 72 { ui::AX_ROLE_COMBO_BOX, NSAccessibilityComboBoxRole }, | |
| 73 { ui::AX_ROLE_COMPLEMENTARY, NSAccessibilityGroupRole }, | |
| 74 { ui::AX_ROLE_CONTENT_INFO, NSAccessibilityGroupRole }, | |
| 75 { ui::AX_ROLE_DEFINITION, NSAccessibilityGroupRole }, | |
| 76 { ui::AX_ROLE_DESCRIPTION_LIST_DETAIL, NSAccessibilityGroupRole }, | |
| 77 { ui::AX_ROLE_DESCRIPTION_LIST_TERM, NSAccessibilityGroupRole }, | |
| 78 { ui::AX_ROLE_DIALOG, NSAccessibilityGroupRole }, | |
| 79 { ui::AX_ROLE_DIRECTORY, NSAccessibilityListRole }, | |
| 80 { ui::AX_ROLE_DISCLOSURE_TRIANGLE, NSAccessibilityDisclosureTriangleRole }, | |
| 81 { ui::AX_ROLE_DIV, NSAccessibilityGroupRole }, | |
| 82 { ui::AX_ROLE_DOCUMENT, NSAccessibilityGroupRole }, | |
| 83 { ui::AX_ROLE_DRAWER, NSAccessibilityDrawerRole }, | |
| 84 { ui::AX_ROLE_EDITABLE_TEXT, NSAccessibilityTextFieldRole }, | |
| 85 { ui::AX_ROLE_FOOTER, NSAccessibilityGroupRole }, | |
| 86 { ui::AX_ROLE_FORM, NSAccessibilityGroupRole }, | |
| 87 { ui::AX_ROLE_GRID, NSAccessibilityGridRole }, | |
| 88 { ui::AX_ROLE_GROUP, NSAccessibilityGroupRole }, | |
| 89 { ui::AX_ROLE_GROW_AREA, NSAccessibilityGrowAreaRole }, | |
| 90 { ui::AX_ROLE_HEADING, @"AXHeading" }, | |
| 91 { ui::AX_ROLE_HELP_TAG, NSAccessibilityHelpTagRole }, | |
| 92 { ui::AX_ROLE_HORIZONTAL_RULE, NSAccessibilityGroupRole }, | |
| 93 { ui::AX_ROLE_IFRAME, NSAccessibilityGroupRole }, | |
| 94 { ui::AX_ROLE_IGNORED, NSAccessibilityUnknownRole }, | |
| 95 { ui::AX_ROLE_IMAGE, NSAccessibilityImageRole }, | |
| 96 { ui::AX_ROLE_IMAGE_MAP, NSAccessibilityGroupRole }, | |
| 97 { ui::AX_ROLE_IMAGE_MAP_LINK, NSAccessibilityLinkRole }, | |
| 98 { ui::AX_ROLE_INCREMENTOR, NSAccessibilityIncrementorRole }, | |
| 99 { ui::AX_ROLE_LABEL_TEXT, NSAccessibilityGroupRole }, | |
| 100 { ui::AX_ROLE_LINK, NSAccessibilityLinkRole }, | |
| 101 { ui::AX_ROLE_LIST, NSAccessibilityListRole }, | |
| 102 { ui::AX_ROLE_LIST_BOX, NSAccessibilityListRole }, | |
| 103 { ui::AX_ROLE_LIST_BOX_OPTION, NSAccessibilityStaticTextRole }, | |
| 104 { ui::AX_ROLE_LIST_ITEM, NSAccessibilityGroupRole }, | |
| 105 { ui::AX_ROLE_LIST_MARKER, @"AXListMarker" }, | |
| 106 { ui::AX_ROLE_LOG, NSAccessibilityGroupRole }, | |
| 107 { ui::AX_ROLE_MAIN, NSAccessibilityGroupRole }, | |
| 108 { ui::AX_ROLE_MARQUEE, NSAccessibilityGroupRole }, | |
| 109 { ui::AX_ROLE_MATH, NSAccessibilityGroupRole }, | |
| 110 { ui::AX_ROLE_MATTE, NSAccessibilityMatteRole }, | |
| 111 { ui::AX_ROLE_MENU, NSAccessibilityMenuRole }, | |
| 112 { ui::AX_ROLE_MENU_BAR, NSAccessibilityMenuBarRole }, | |
| 113 { ui::AX_ROLE_MENU_BUTTON, NSAccessibilityButtonRole }, | |
| 114 { ui::AX_ROLE_MENU_ITEM, NSAccessibilityMenuItemRole }, | |
| 115 { ui::AX_ROLE_MENU_LIST_OPTION, NSAccessibilityMenuItemRole }, | |
| 116 { ui::AX_ROLE_MENU_LIST_POPUP, NSAccessibilityUnknownRole }, | |
| 117 { ui::AX_ROLE_NAVIGATION, NSAccessibilityGroupRole }, | |
| 118 { ui::AX_ROLE_NOTE, NSAccessibilityGroupRole }, | |
| 119 { ui::AX_ROLE_OUTLINE, NSAccessibilityOutlineRole }, | |
| 120 { ui::AX_ROLE_PARAGRAPH, NSAccessibilityGroupRole }, | |
| 121 { ui::AX_ROLE_POP_UP_BUTTON, NSAccessibilityPopUpButtonRole }, | |
| 122 { ui::AX_ROLE_PRESENTATIONAL, NSAccessibilityGroupRole }, | |
| 123 { ui::AX_ROLE_PROGRESS_INDICATOR, NSAccessibilityProgressIndicatorRole }, | |
| 124 { ui::AX_ROLE_RADIO_BUTTON, NSAccessibilityRadioButtonRole }, | |
| 125 { ui::AX_ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole }, | |
| 126 { ui::AX_ROLE_REGION, NSAccessibilityGroupRole }, | |
| 127 { ui::AX_ROLE_ROOT_WEB_AREA, @"AXWebArea" }, | |
| 128 { ui::AX_ROLE_ROW, NSAccessibilityRowRole }, | |
| 129 { ui::AX_ROLE_ROW_HEADER, @"AXCell" }, | |
| 130 { ui::AX_ROLE_RULER, NSAccessibilityRulerRole }, | |
| 131 { ui::AX_ROLE_RULER_MARKER, NSAccessibilityRulerMarkerRole }, | |
| 132 { ui::AX_ROLE_SCROLL_BAR, NSAccessibilityScrollBarRole }, | |
| 133 { ui::AX_ROLE_SEARCH, NSAccessibilityGroupRole }, | |
| 134 { ui::AX_ROLE_SHEET, NSAccessibilitySheetRole }, | |
| 135 { ui::AX_ROLE_SLIDER, NSAccessibilitySliderRole }, | |
| 136 { ui::AX_ROLE_SLIDER_THUMB, NSAccessibilityValueIndicatorRole }, | |
| 137 { ui::AX_ROLE_SPIN_BUTTON, NSAccessibilitySliderRole }, | |
| 138 { ui::AX_ROLE_SPLITTER, NSAccessibilitySplitterRole }, | |
| 139 { ui::AX_ROLE_SPLIT_GROUP, NSAccessibilitySplitGroupRole }, | |
| 140 { ui::AX_ROLE_STATIC_TEXT, NSAccessibilityStaticTextRole }, | |
| 141 { ui::AX_ROLE_STATUS, NSAccessibilityGroupRole }, | |
| 142 { ui::AX_ROLE_SVG_ROOT, NSAccessibilityGroupRole }, | |
| 143 { ui::AX_ROLE_SYSTEM_WIDE, NSAccessibilityUnknownRole }, | |
| 144 { ui::AX_ROLE_TAB, NSAccessibilityRadioButtonRole }, | |
| 145 { ui::AX_ROLE_TABLE, NSAccessibilityTableRole }, | |
| 146 { ui::AX_ROLE_TABLE_HEADER_CONTAINER, NSAccessibilityGroupRole }, | |
| 147 { ui::AX_ROLE_TAB_LIST, NSAccessibilityTabGroupRole }, | |
| 148 { ui::AX_ROLE_TAB_PANEL, NSAccessibilityGroupRole }, | |
| 149 { ui::AX_ROLE_TEXT_AREA, NSAccessibilityTextAreaRole }, | |
| 150 { ui::AX_ROLE_TEXT_FIELD, NSAccessibilityTextFieldRole }, | |
| 151 { ui::AX_ROLE_TIMER, NSAccessibilityGroupRole }, | |
| 152 { ui::AX_ROLE_TOGGLE_BUTTON, NSAccessibilityCheckBoxRole }, | |
| 153 { ui::AX_ROLE_TOOLBAR, NSAccessibilityToolbarRole }, | |
| 154 { ui::AX_ROLE_TOOLTIP, NSAccessibilityGroupRole }, | |
| 155 { ui::AX_ROLE_TREE, NSAccessibilityOutlineRole }, | |
| 156 { ui::AX_ROLE_TREE_GRID, NSAccessibilityTableRole }, | |
| 157 { ui::AX_ROLE_TREE_ITEM, NSAccessibilityRowRole }, | |
| 158 { ui::AX_ROLE_VALUE_INDICATOR, NSAccessibilityValueIndicatorRole }, | |
| 159 { ui::AX_ROLE_WEB_AREA, @"AXWebArea" }, | |
| 160 { ui::AX_ROLE_WINDOW, NSAccessibilityWindowRole }, | |
| 161 | |
| 162 // TODO(dtseng): we don't correctly support the attributes for these roles. | |
| 163 // { ui::AX_ROLE_SCROLL_AREA, NSAccessibilityScrollAreaRole }, | |
| 164 }; | |
| 165 | |
| 166 RoleMap role_map; | |
| 167 for (size_t i = 0; i < arraysize(roles); ++i) | |
| 168 role_map[roles[i].webKitValue] = roles[i].nativeValue; | |
| 169 return role_map; | |
| 170 } | |
| 171 | |
| 172 // A mapping of webkit roles to native roles. | |
| 173 NSString* NativeRoleFromAXRole( | |
| 174 const ui::AXRole& role) { | |
| 175 CR_DEFINE_STATIC_LOCAL(RoleMap, web_accessibility_to_native_role, | |
| 176 (BuildRoleMap())); | |
| 177 RoleMap::iterator it = web_accessibility_to_native_role.find(role); | |
| 178 if (it != web_accessibility_to_native_role.end()) | |
| 179 return it->second; | |
| 180 else | |
| 181 return NSAccessibilityUnknownRole; | |
| 182 } | |
| 183 | |
| 184 RoleMap BuildSubroleMap() { | |
| 185 const MapEntry subroles[] = { | |
| 186 { ui::AX_ROLE_ALERT, @"AXApplicationAlert" }, | |
| 187 { ui::AX_ROLE_ALERT_DIALOG, @"AXApplicationAlertDialog" }, | |
| 188 { ui::AX_ROLE_ARTICLE, @"AXDocumentArticle" }, | |
| 189 { ui::AX_ROLE_DEFINITION, @"AXDefinition" }, | |
| 190 { ui::AX_ROLE_DESCRIPTION_LIST_DETAIL, @"AXDescription" }, | |
| 191 { ui::AX_ROLE_DESCRIPTION_LIST_TERM, @"AXTerm" }, | |
| 192 { ui::AX_ROLE_DIALOG, @"AXApplicationDialog" }, | |
| 193 { ui::AX_ROLE_DOCUMENT, @"AXDocument" }, | |
| 194 { ui::AX_ROLE_FOOTER, @"AXLandmarkContentInfo" }, | |
| 195 { ui::AX_ROLE_APPLICATION, @"AXLandmarkApplication" }, | |
| 196 { ui::AX_ROLE_BANNER, @"AXLandmarkBanner" }, | |
| 197 { ui::AX_ROLE_COMPLEMENTARY, @"AXLandmarkComplementary" }, | |
| 198 { ui::AX_ROLE_CONTENT_INFO, @"AXLandmarkContentInfo" }, | |
| 199 { ui::AX_ROLE_MAIN, @"AXLandmarkMain" }, | |
| 200 { ui::AX_ROLE_NAVIGATION, @"AXLandmarkNavigation" }, | |
| 201 { ui::AX_ROLE_SEARCH, @"AXLandmarkSearch" }, | |
| 202 { ui::AX_ROLE_LOG, @"AXApplicationLog" }, | |
| 203 { ui::AX_ROLE_MARQUEE, @"AXApplicationMarquee" }, | |
| 204 { ui::AX_ROLE_MATH, @"AXDocumentMath" }, | |
| 205 { ui::AX_ROLE_NOTE, @"AXDocumentNote" }, | |
| 206 { ui::AX_ROLE_REGION, @"AXDocumentRegion" }, | |
| 207 { ui::AX_ROLE_STATUS, @"AXApplicationStatus" }, | |
| 208 { ui::AX_ROLE_TAB_PANEL, @"AXTabPanel" }, | |
| 209 { ui::AX_ROLE_TIMER, @"AXApplicationTimer" }, | |
| 210 { ui::AX_ROLE_TOGGLE_BUTTON, @"AXToggleButton" }, | |
| 211 { ui::AX_ROLE_TOOLTIP, @"AXUserInterfaceTooltip" }, | |
| 212 { ui::AX_ROLE_TREE_ITEM, NSAccessibilityOutlineRowSubrole }, | |
| 213 }; | |
| 214 | |
| 215 RoleMap subrole_map; | |
| 216 for (size_t i = 0; i < arraysize(subroles); ++i) | |
| 217 subrole_map[subroles[i].webKitValue] = subroles[i].nativeValue; | |
| 218 return subrole_map; | |
| 219 } | |
| 220 | |
| 221 // A mapping of webkit roles to native subroles. | |
| 222 NSString* NativeSubroleFromAXRole( | |
| 223 const ui::AXRole& role) { | |
| 224 CR_DEFINE_STATIC_LOCAL(RoleMap, web_accessibility_to_native_subrole, | |
| 225 (BuildSubroleMap())); | |
| 226 RoleMap::iterator it = web_accessibility_to_native_subrole.find(role); | |
| 227 if (it != web_accessibility_to_native_subrole.end()) | |
| 228 return it->second; | |
| 229 else | |
| 230 return nil; | |
| 231 } | |
| 232 | |
| 233 // A mapping from an accessibility attribute to its method name. | 49 // A mapping from an accessibility attribute to its method name. |
| 234 NSDictionary* attributeToMethodNameMap = nil; | 50 NSDictionary* attributeToMethodNameMap = nil; |
| 235 | 51 |
| 236 } // namespace | 52 } // namespace |
| 237 | 53 |
| 238 @implementation BrowserAccessibilityCocoa | 54 @implementation BrowserAccessibilityCocoa |
| 239 | 55 |
| 240 + (void)initialize { | 56 + (void)initialize { |
| 241 const struct { | 57 const struct { |
| 242 NSString* attribute; | 58 NSString* attribute; |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 bool isAriaPressedDefined; | 528 bool isAriaPressedDefined; |
| 713 bool isMixed; | 529 bool isMixed; |
| 714 browserAccessibility_->GetAriaTristate("aria-pressed", | 530 browserAccessibility_->GetAriaTristate("aria-pressed", |
| 715 &isAriaPressedDefined, | 531 &isAriaPressedDefined, |
| 716 &isMixed); | 532 &isMixed); |
| 717 if (isAriaPressedDefined) | 533 if (isAriaPressedDefined) |
| 718 return NSAccessibilityCheckBoxRole; | 534 return NSAccessibilityCheckBoxRole; |
| 719 else | 535 else |
| 720 return NSAccessibilityButtonRole; | 536 return NSAccessibilityButtonRole; |
| 721 } | 537 } |
| 722 return NativeRoleFromAXRole(role); | 538 return [AXPlatformNodeCocoa nativeRoleFromAXRole:role]; |
| 723 } | 539 } |
| 724 | 540 |
| 725 // Returns a string indicating the role description of this object. | 541 // Returns a string indicating the role description of this object. |
| 726 - (NSString*)roleDescription { | 542 - (NSString*)roleDescription { |
| 727 NSString* role = [self role]; | 543 NSString* role = [self role]; |
| 728 | 544 |
| 729 ContentClient* content_client = content::GetContentClient(); | 545 ContentClient* content_client = content::GetContentClient(); |
| 730 | 546 |
| 731 // The following descriptions are specific to webkit. | 547 // The following descriptions are specific to webkit. |
| 732 if ([role isEqualToString:@"AXWebArea"]) { | 548 if ([role isEqualToString:@"AXWebArea"]) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 browserAccessibility_, ui::AX_ATTR_HTML_TAG); | 704 browserAccessibility_, ui::AX_ATTR_HTML_TAG); |
| 889 | 705 |
| 890 if (browserAccessibilityRole == ui::AX_ROLE_LIST) { | 706 if (browserAccessibilityRole == ui::AX_ROLE_LIST) { |
| 891 if ([htmlTag isEqualToString:@"dl"]) { | 707 if ([htmlTag isEqualToString:@"dl"]) { |
| 892 return @"AXDescriptionList"; | 708 return @"AXDescriptionList"; |
| 893 } else { | 709 } else { |
| 894 return @"AXContentList"; | 710 return @"AXContentList"; |
| 895 } | 711 } |
| 896 } | 712 } |
| 897 | 713 |
| 898 return NativeSubroleFromAXRole(browserAccessibilityRole); | 714 return [AXPlatformNodeCocoa nativeSubroleFromAXRole:browserAccessibilityRole]; |
| 899 } | 715 } |
| 900 | 716 |
| 901 // Returns all tabs in this subtree. | 717 // Returns all tabs in this subtree. |
| 902 - (NSArray*)tabs { | 718 - (NSArray*)tabs { |
| 903 NSMutableArray* tabSubtree = [[[NSMutableArray alloc] init] autorelease]; | 719 NSMutableArray* tabSubtree = [[[NSMutableArray alloc] init] autorelease]; |
| 904 | 720 |
| 905 if ([self internalRole] == ui::AX_ROLE_TAB) | 721 if ([self internalRole] == ui::AX_ROLE_TAB) |
| 906 [tabSubtree addObject:self]; | 722 [tabSubtree addObject:self]; |
| 907 | 723 |
| 908 for (uint i=0; i < [[self children] count]; ++i) { | 724 for (uint i=0; i < [[self children] count]; ++i) { |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1629 return [super hash]; | 1445 return [super hash]; |
| 1630 return browserAccessibility_->GetId(); | 1446 return browserAccessibility_->GetId(); |
| 1631 } | 1447 } |
| 1632 | 1448 |
| 1633 - (BOOL)accessibilityShouldUseUniqueId { | 1449 - (BOOL)accessibilityShouldUseUniqueId { |
| 1634 return YES; | 1450 return YES; |
| 1635 } | 1451 } |
| 1636 | 1452 |
| 1637 @end | 1453 @end |
| 1638 | 1454 |
| OLD | NEW |