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

Side by Side Diff: content/browser/accessibility/browser_accessibility_cocoa.mm

Issue 1134653003: Implement UIElementsForSearchPredicate accessibility APIs for OS X. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix win test failure Created 5 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 (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/app/strings/grit/content_strings.h" 15 #include "content/app/strings/grit/content_strings.h"
16 #include "content/browser/accessibility/browser_accessibility_manager.h" 16 #include "content/browser/accessibility/browser_accessibility_manager.h"
17 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" 17 #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
18 #include "content/browser/accessibility/one_shot_accessibility_tree_search.h"
18 #include "content/public/common/content_client.h" 19 #include "content/public/common/content_client.h"
19 #import "ui/accessibility/platform/ax_platform_node_mac.h" 20 #import "ui/accessibility/platform/ax_platform_node_mac.h"
20 21
21 // See http://openradar.appspot.com/9896491. This SPI has been tested on 10.5, 22 // See http://openradar.appspot.com/9896491. This SPI has been tested on 10.5,
22 // 10.6, and 10.7. It allows accessibility clients to observe events posted on 23 // 10.6, and 10.7. It allows accessibility clients to observe events posted on
23 // this object. 24 // this object.
24 extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element); 25 extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element);
25 26
26 using ui::AXNodeData; 27 using ui::AXNodeData;
28 using content::AccessibilityMatchPredicate;
27 using content::BrowserAccessibility; 29 using content::BrowserAccessibility;
28 using content::BrowserAccessibilityDelegate; 30 using content::BrowserAccessibilityDelegate;
29 using content::BrowserAccessibilityManager; 31 using content::BrowserAccessibilityManager;
30 using content::BrowserAccessibilityManagerMac; 32 using content::BrowserAccessibilityManagerMac;
31 using content::ContentClient; 33 using content::ContentClient;
34 using content::OneShotAccessibilityTreeSearch;
32 typedef ui::AXStringAttribute StringAttribute; 35 typedef ui::AXStringAttribute StringAttribute;
33 36
34 namespace { 37 namespace {
35 38
36 // Returns an autoreleased copy of the AXNodeData's attribute. 39 // Returns an autoreleased copy of the AXNodeData's attribute.
37 NSString* NSStringForStringAttribute( 40 NSString* NSStringForStringAttribute(
38 BrowserAccessibility* browserAccessibility, 41 BrowserAccessibility* browserAccessibility,
39 StringAttribute attribute) { 42 StringAttribute attribute) {
40 return base::SysUTF8ToNSString( 43 return base::SysUTF8ToNSString(
41 browserAccessibility->GetStringAttribute(attribute)); 44 browserAccessibility->GetStringAttribute(attribute));
42 } 45 }
43 46
44 // GetState checks the bitmask used in AXNodeData to check 47 // GetState checks the bitmask used in AXNodeData to check
45 // if the given state was set on the accessibility object. 48 // if the given state was set on the accessibility object.
46 bool GetState(BrowserAccessibility* accessibility, ui::AXState state) { 49 bool GetState(BrowserAccessibility* accessibility, ui::AXState state) {
47 return ((accessibility->GetState() >> state) & 1); 50 return ((accessibility->GetState() >> state) & 1);
48 } 51 }
49 52
50 // A mapping from an accessibility attribute to its method name. 53 // A mapping from an accessibility attribute to its method name.
51 NSDictionary* attributeToMethodNameMap = nil; 54 NSDictionary* attributeToMethodNameMap = nil;
52 55
56 // Given a search key provided to AXUIElementCountForSearchPredicate or
57 // AXUIElementsForSearchPredicate, return a predicate that can be added
58 // to OneShotAccessibilityTreeSearch.
59 AccessibilityMatchPredicate PredicateForSearchKey(NSString* searchKey) {
60 if ([searchKey isEqualToString:@"AXAnyTypeSearchKey"]) {
61 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
62 return true;
63 };
64 } else if ([searchKey isEqualToString:@"AXBlockquoteSameLevelSearchKey"] ||
65 [searchKey isEqualToString:@"AXBlockquoteSearchKey"]) {
66 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
67 // TODO(dmazzoni): implement the "same level" part.
68 return current->GetRole() == ui::AX_ROLE_BLOCKQUOTE;
69 };
70 } else if ([searchKey isEqualToString:@"AXBoldFontSearchKey"]) {
71 // TODO(dmazzoni): implement this.
72 return nullptr;
73 } else if ([searchKey isEqualToString:@"AXButtonSearchKey"]) {
74 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
75 return (current->GetRole() == ui::AX_ROLE_BUTTON ||
76 current->GetRole() == ui::AX_ROLE_MENU_BUTTON ||
77 current->GetRole() == ui::AX_ROLE_POP_UP_BUTTON ||
78 current->GetRole() == ui::AX_ROLE_SWITCH ||
79 current->GetRole() == ui::AX_ROLE_TOGGLE_BUTTON);
80 };
81 } else if ([searchKey isEqualToString:@"AXCheckBoxSearchKey"]) {
82 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
83 return (current->GetRole() == ui::AX_ROLE_CHECK_BOX ||
84 current->GetRole() == ui::AX_ROLE_MENU_ITEM_CHECK_BOX);
85 };
86 } else if ([searchKey isEqualToString:@"AXControlSearchKey"]) {
87 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
88 if (current->IsControl())
89 return true;
90 if (current->HasState(ui::AX_STATE_FOCUSABLE) &&
91 current->GetRole() != ui::AX_ROLE_IMAGE_MAP_LINK &&
92 current->GetRole() != ui::AX_ROLE_LINK) {
93 return true;
94 }
95 return false;
96 };
97 } else if ([searchKey isEqualToString:@"AXDifferentTypeSearchKey"]) {
98 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
99 return current->GetRole() != start->GetRole();
100 };
101 } else if ([searchKey isEqualToString:@"AXFontChangeSearchKey"]) {
102 // TODO(dmazzoni): implement this.
103 return nullptr;
104 } else if ([searchKey isEqualToString:@"AXFontColorChangeSearchKey"]) {
105 // TODO(dmazzoni): implement this.
106 return nullptr;
107 } else if ([searchKey isEqualToString:@"AXFrameSearchKey"]) {
108 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
109 if (current->IsWebAreaForPresentationalIframe())
110 return false;
111 return (current->GetRole() == ui::AX_ROLE_WEB_AREA ||
112 current->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA);
113 };
114 } else if ([searchKey isEqualToString:@"AXGraphicSearchKey"]) {
115 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
116 return current->GetRole() == ui::AX_ROLE_IMAGE;
117 };
118 } else if ([searchKey isEqualToString:@"AXHeadingLevel1SearchKey"]) {
119 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
120 return (current->GetRole() == ui::AX_ROLE_HEADING &&
121 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 1);
122 };
123 } else if ([searchKey isEqualToString:@"AXHeadingLevel2SearchKey"]) {
124 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
125 return (current->GetRole() == ui::AX_ROLE_HEADING &&
126 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 2);
127 };
128 } else if ([searchKey isEqualToString:@"AXHeadingLevel3SearchKey"]) {
129 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
130 return (current->GetRole() == ui::AX_ROLE_HEADING &&
131 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 3);
132 };
133 } else if ([searchKey isEqualToString:@"AXHeadingLevel4SearchKey"]) {
134 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
135 return (current->GetRole() == ui::AX_ROLE_HEADING &&
136 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 4);
137 };
138 } else if ([searchKey isEqualToString:@"AXHeadingLevel5SearchKey"]) {
139 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
140 return (current->GetRole() == ui::AX_ROLE_HEADING &&
141 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 5);
142 };
143 } else if ([searchKey isEqualToString:@"AXHeadingLevel6SearchKey"]) {
144 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
145 return (current->GetRole() == ui::AX_ROLE_HEADING &&
146 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 6);
147 };
148 } else if ([searchKey isEqualToString:@"AXHeadingSameLevelSearchKey"]) {
149 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
150 return (current->GetRole() == ui::AX_ROLE_HEADING &&
151 start->GetRole() == ui::AX_ROLE_HEADING &&
152 (current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) ==
153 start->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL)));
154 };
155 } else if ([searchKey isEqualToString:@"AXHeadingSearchKey"]) {
156 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
157 return current->GetRole() == ui::AX_ROLE_HEADING;
158 };
159 } else if ([searchKey isEqualToString:@"AXHighlightedSearchKey"]) {
160 // TODO(dmazzoni): implement this.
161 return nullptr;
162 } else if ([searchKey isEqualToString:@"AXItalicFontSearchKey"]) {
163 // TODO(dmazzoni): implement this.
164 return nullptr;
165 } else if ([searchKey isEqualToString:@"AXLandmarkSearchKey"]) {
166 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
167 return (current->GetRole() == ui::AX_ROLE_APPLICATION ||
168 current->GetRole() == ui::AX_ROLE_BANNER ||
169 current->GetRole() == ui::AX_ROLE_COMPLEMENTARY ||
170 current->GetRole() == ui::AX_ROLE_CONTENT_INFO ||
171 current->GetRole() == ui::AX_ROLE_FORM ||
172 current->GetRole() == ui::AX_ROLE_MAIN ||
173 current->GetRole() == ui::AX_ROLE_NAVIGATION ||
174 current->GetRole() == ui::AX_ROLE_SEARCH);
175 };
176 } else if ([searchKey isEqualToString:@"AXLinkSearchKey"]) {
177 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
178 return current->GetRole() == ui::AX_ROLE_LINK;
179 };
180 } else if ([searchKey isEqualToString:@"AXListSearchKey"]) {
181 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
182 return current->GetRole() == ui::AX_ROLE_LIST;
183 };
184 } else if ([searchKey isEqualToString:@"AXLiveRegionSearchKey"]) {
185 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
186 return current->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS);
187 };
188 } else if ([searchKey isEqualToString:@"AXMisspelledWordSearchKey"]) {
189 // TODO(dmazzoni): implement this.
190 return nullptr;
191 } else if ([searchKey isEqualToString:@"AXOutlineSearchKey"]) {
192 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
193 return current->GetRole() == ui::AX_ROLE_TREE;
194 };
195 } else if ([searchKey isEqualToString:@"AXPlainTextSearchKey"]) {
196 // TODO(dmazzoni): implement this.
197 return nullptr;
198 } else if ([searchKey isEqualToString:@"AXRadioGroupSearchKey"]) {
199 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
200 return current->GetRole() == ui::AX_ROLE_RADIO_GROUP;
201 };
202 } else if ([searchKey isEqualToString:@"AXSameTypeSearchKey"]) {
203 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
204 return current->GetRole() == start->GetRole();
205 };
206 } else if ([searchKey isEqualToString:@"AXStaticTextSearchKey"]) {
207 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
208 return current->GetRole() == ui::AX_ROLE_STATIC_TEXT;
209 };
210 } else if ([searchKey isEqualToString:@"AXStyleChangeSearchKey"]) {
211 // TODO(dmazzoni): implement this.
212 return nullptr;
213 } else if ([searchKey isEqualToString:@"AXTableSameLevelSearchKey"]) {
214 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
215 // TODO(dmazzoni): implement the "same level" part.
David Tseng 2015/05/14 19:31:55 You could probably easily do this now by checking
dmazzoni 2015/05/14 23:00:57 I think so, I'll look into that as a follow-up.
216 return current->GetRole() == ui::AX_ROLE_GRID ||
217 current->GetRole() == ui::AX_ROLE_TABLE;
218 };
219 } else if ([searchKey isEqualToString:@"AXTableSearchKey"]) {
220 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
221 return current->GetRole() == ui::AX_ROLE_GRID ||
222 current->GetRole() == ui::AX_ROLE_TABLE;
223 };
224 } else if ([searchKey isEqualToString:@"AXTextFieldSearchKey"]) {
225 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
226 return current->GetRole() == ui::AX_ROLE_TEXT_FIELD;
227 };
228 } else if ([searchKey isEqualToString:@"AXUnderlineSearchKey"]) {
229 // TODO(dmazzoni): implement this.
230 return nullptr;
231 } else if ([searchKey isEqualToString:@"AXUnvisitedLinkSearchKey"]) {
232 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
233 return (current->GetRole() == ui::AX_ROLE_LINK &&
234 !current->HasState(ui::AX_STATE_VISITED));
235 };
236 } else if ([searchKey isEqualToString:@"AXVisitedLinkSearchKey"]) {
237 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
238 return (current->GetRole() == ui::AX_ROLE_LINK &&
239 current->HasState(ui::AX_STATE_VISITED));
240 };
241 }
242
243 return nullptr;
244 }
245
246 // Initialize a OneShotAccessibilityTreeSearch object given the parameters
247 // passed to AXUIElementCountForSearchPredicate or
248 // AXUIElementsForSearchPredicate. Return true on success.
249 bool InitializeAccessibilityTreeSearch(
250 OneShotAccessibilityTreeSearch* search,
251 id parameter) {
252 if (![parameter isKindOfClass:[NSDictionary class]])
253 return false;
254 NSDictionary* dictionary = parameter;
255
256 id startElementParameter = [dictionary objectForKey:@"AXStartElement"];
257 BrowserAccessibility* startNode = nullptr;
258 if ([startElementParameter isKindOfClass:[BrowserAccessibilityCocoa class]]) {
259 BrowserAccessibilityCocoa* startNodeCocoa =
260 (BrowserAccessibilityCocoa*)startElementParameter;
261 startNode = [startNodeCocoa browserAccessibility];
262 }
263
264 bool immediateDescendantsOnly = false;
265 NSNumber *immediateDescendantsOnlyParameter =
266 [dictionary objectForKey:@"AXImmediateDescendantsOnly"];
267 if ([immediateDescendantsOnlyParameter isKindOfClass:[NSNumber class]])
268 immediateDescendantsOnly = [immediateDescendantsOnlyParameter boolValue];
269
270 bool visibleOnly = false;
271 NSNumber *visibleOnlyParameter = [dictionary objectForKey:@"AXVisibleOnly"];
272 if ([visibleOnlyParameter isKindOfClass:[NSNumber class]])
273 visibleOnly = [visibleOnlyParameter boolValue];
274
275 content::OneShotAccessibilityTreeSearch::Direction direction =
276 content::OneShotAccessibilityTreeSearch::FORWARDS;
277 NSString* directionParameter = [dictionary objectForKey:@"AXDirection"];
278 if ([directionParameter isKindOfClass:[NSString class]]) {
279 if ([directionParameter isEqualToString:@"AXDirectionNext"])
280 direction = content::OneShotAccessibilityTreeSearch::FORWARDS;
281 else if ([directionParameter isEqualToString:@"AXDirectionPrevious"])
282 direction = content::OneShotAccessibilityTreeSearch::BACKWARDS;
283 }
284
285 int resultsLimit = -1;
David Tseng 2015/05/14 19:31:54 nit: name it.
David Tseng 2015/05/14 19:31:55 nit: would be great to define these strings somewh
dmazzoni 2015/05/14 23:00:57 Done.
286 NSNumber* resultsLimitParameter = [dictionary objectForKey:@"AXResultsLimit"];
287 if ([resultsLimitParameter isKindOfClass:[NSNumber class]])
288 resultsLimit = [resultsLimitParameter intValue];
289
290 std::string searchText;
291 NSString* searchTextParameter = [dictionary objectForKey:@"AXSearchText"];
292 if ([searchTextParameter isKindOfClass:[NSString class]])
293 searchText = base::SysNSStringToUTF8(searchTextParameter);
294
295 search->SetStartNode(startNode);
296 search->SetDirection(direction);
297 search->SetImmediateDescendantsOnly(immediateDescendantsOnly);
298 search->SetVisibleOnly(visibleOnly);
299 search->SetSearchText(searchText);
300
301 // Mac uses resultsLimit == -1 for unlimited, that that's
302 // the default for OneShotAccessibilityTreeSearch already.
303 // Only set the results limit if it's nonnegative.
304 if (resultsLimit >= 0)
305 search->SetResultLimit(resultsLimit);
306
307 id searchKey = [dictionary objectForKey:@"AXSearchKey"];
308 if ([searchKey isKindOfClass:[NSString class]]) {
309 AccessibilityMatchPredicate predicate =
310 PredicateForSearchKey((NSString*)searchKey);
311 if (predicate)
312 search->AddPredicate(predicate);
313 } else if ([searchKey isKindOfClass:[NSArray class]]) {
314 size_t searchKeyCount = static_cast<size_t>([searchKey count]);
315 for (size_t i = 0; i < searchKeyCount; ++i) {
316 id key = [searchKey objectAtIndex:i];
317 if ([key isKindOfClass:[NSString class]]) {
318 AccessibilityMatchPredicate predicate =
319 PredicateForSearchKey((NSString*)key);
320 if (predicate)
321 search->AddPredicate(predicate);
322 }
323 }
324 }
325
326 return true;
327 }
328
53 } // namespace 329 } // namespace
54 330
55 @implementation BrowserAccessibilityCocoa 331 @implementation BrowserAccessibilityCocoa
56 332
57 + (void)initialize { 333 + (void)initialize {
58 const struct { 334 const struct {
59 NSString* attribute; 335 NSString* attribute;
60 NSString* methodName; 336 NSString* methodName;
61 } attributeToMethodNameContainer[] = { 337 } attributeToMethodNameContainer[] = {
62 { NSAccessibilityChildrenAttribute, @"children" }, 338 { NSAccessibilityChildrenAttribute, @"children" },
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 - (ui::AXRole)internalRole { 826 - (ui::AXRole)internalRole {
551 return static_cast<ui::AXRole>(browserAccessibility_->GetRole()); 827 return static_cast<ui::AXRole>(browserAccessibility_->GetRole());
552 } 828 }
553 829
554 - (content::BrowserAccessibilityDelegate*)delegate { 830 - (content::BrowserAccessibilityDelegate*)delegate {
555 return browserAccessibility_->manager() ? 831 return browserAccessibility_->manager() ?
556 browserAccessibility_->manager()->delegate() : 832 browserAccessibility_->manager()->delegate() :
557 nil; 833 nil;
558 } 834 }
559 835
836 - (content::BrowserAccessibility*)browserAccessibility {
837 return browserAccessibility_;
838 }
839
560 - (NSPoint)pointInScreen:(NSPoint)origin 840 - (NSPoint)pointInScreen:(NSPoint)origin
561 size:(NSSize)size { 841 size:(NSSize)size {
562 if (!browserAccessibility_) 842 if (!browserAccessibility_)
563 return NSZeroPoint; 843 return NSZeroPoint;
564 844
565 // Get the delegate for the topmost BrowserAccessibilityManager, because 845 // Get the delegate for the topmost BrowserAccessibilityManager, because
566 // that's the only one that can convert points to their origin in the screen. 846 // that's the only one that can convert points to their origin in the screen.
567 BrowserAccessibilityDelegate* delegate = 847 BrowserAccessibilityDelegate* delegate =
568 browserAccessibility_->manager()->GetDelegateFromRootManager(); 848 browserAccessibility_->manager()->GetDelegateFromRootManager();
569 if (delegate) { 849 if (delegate) {
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 NSRange range = [(NSValue*)parameter rangeValue]; 1486 NSRange range = [(NSValue*)parameter rangeValue];
1207 gfx::Rect rect = browserAccessibility_->GetGlobalBoundsForRange( 1487 gfx::Rect rect = browserAccessibility_->GetGlobalBoundsForRange(
1208 range.location, range.length); 1488 range.location, range.length);
1209 NSPoint origin = NSMakePoint(rect.x(), rect.y()); 1489 NSPoint origin = NSMakePoint(rect.x(), rect.y());
1210 NSSize size = NSMakeSize(rect.width(), rect.height()); 1490 NSSize size = NSMakeSize(rect.width(), rect.height());
1211 NSPoint pointInScreen = [self pointInScreen:origin size:size]; 1491 NSPoint pointInScreen = [self pointInScreen:origin size:size];
1212 NSRect nsrect = NSMakeRect( 1492 NSRect nsrect = NSMakeRect(
1213 pointInScreen.x, pointInScreen.y, rect.width(), rect.height()); 1493 pointInScreen.x, pointInScreen.y, rect.width(), rect.height());
1214 return [NSValue valueWithRect:nsrect]; 1494 return [NSValue valueWithRect:nsrect];
1215 } 1495 }
1496 if ([attribute isEqualToString:@"AXUIElementCountForSearchPredicate"]) {
1497 OneShotAccessibilityTreeSearch search(browserAccessibility_->manager());
1498 if (InitializeAccessibilityTreeSearch(&search, parameter))
1499 return [NSNumber numberWithInt:search.CountMatches()];
1500 return nil;
1501 }
1502
1503 if ([attribute isEqualToString:@"AXUIElementsForSearchPredicate"]) {
1504 OneShotAccessibilityTreeSearch search(browserAccessibility_->manager());
1505 if (InitializeAccessibilityTreeSearch(&search, parameter)) {
1506 size_t count = search.CountMatches();
1507 NSMutableArray* result = [NSMutableArray arrayWithCapacity:count];
1508 for (size_t i = 0; i < count; i++) {
David Tseng 2015/05/14 19:31:55 nit: ++i
dmazzoni 2015/05/14 23:00:57 Done.
1509 BrowserAccessibility* match = search.GetMatchAtIndex(i);
1510 [result addObject:match->ToBrowserAccessibilityCocoa()];
1511 }
1512 return result;
1513 }
1514 return nil;
1515 }
1216 1516
1217 // TODO(dtseng): support the following attributes. 1517 // TODO(dtseng): support the following attributes.
1218 if ([attribute isEqualTo: 1518 if ([attribute isEqualTo:
1219 NSAccessibilityRangeForPositionParameterizedAttribute] || 1519 NSAccessibilityRangeForPositionParameterizedAttribute] ||
1220 [attribute isEqualTo: 1520 [attribute isEqualTo:
1221 NSAccessibilityRangeForIndexParameterizedAttribute] || 1521 NSAccessibilityRangeForIndexParameterizedAttribute] ||
1222 [attribute isEqualTo:NSAccessibilityRTFForRangeParameterizedAttribute] || 1522 [attribute isEqualTo:NSAccessibilityRTFForRangeParameterizedAttribute] ||
1223 [attribute isEqualTo: 1523 [attribute isEqualTo:
1224 NSAccessibilityStyleRangeForIndexParameterizedAttribute]) { 1524 NSAccessibilityStyleRangeForIndexParameterizedAttribute]) {
1225 return nil; 1525 return nil;
1226 } 1526 }
1227 return nil; 1527 return nil;
1228 } 1528 }
1229 1529
1230 // Returns an array of parameterized attributes names that this object will 1530 // Returns an array of parameterized attributes names that this object will
1231 // respond to. 1531 // respond to.
1232 - (NSArray*)accessibilityParameterizedAttributeNames { 1532 - (NSArray*)accessibilityParameterizedAttributeNames {
1233 if (!browserAccessibility_) 1533 if (!browserAccessibility_)
1234 return nil; 1534 return nil;
1235 1535
1536 // General attributes.
1537 NSMutableArray* ret = [NSMutableArray arrayWithObjects:
1538 @"AXUIElementCountForSearchPredicate",
1539 @"AXUIElementsForSearchPredicate",
1540 nil];
1541
1236 if ([[self role] isEqualToString:NSAccessibilityTableRole] || 1542 if ([[self role] isEqualToString:NSAccessibilityTableRole] ||
1237 [[self role] isEqualToString:NSAccessibilityGridRole]) { 1543 [[self role] isEqualToString:NSAccessibilityGridRole]) {
1238 return [NSArray arrayWithObjects: 1544 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1239 NSAccessibilityCellForColumnAndRowParameterizedAttribute, 1545 NSAccessibilityCellForColumnAndRowParameterizedAttribute,
1240 nil]; 1546 nil]];
1241 } 1547 }
1242 if ([[self role] isEqualToString:NSAccessibilityTextFieldRole]) { 1548 if ([[self role] isEqualToString:NSAccessibilityTextFieldRole]) {
1243 return [NSArray arrayWithObjects: 1549 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1244 NSAccessibilityLineForIndexParameterizedAttribute, 1550 NSAccessibilityLineForIndexParameterizedAttribute,
1245 NSAccessibilityRangeForLineParameterizedAttribute, 1551 NSAccessibilityRangeForLineParameterizedAttribute,
1246 NSAccessibilityStringForRangeParameterizedAttribute, 1552 NSAccessibilityStringForRangeParameterizedAttribute,
1247 NSAccessibilityRangeForPositionParameterizedAttribute, 1553 NSAccessibilityRangeForPositionParameterizedAttribute,
1248 NSAccessibilityRangeForIndexParameterizedAttribute, 1554 NSAccessibilityRangeForIndexParameterizedAttribute,
1249 NSAccessibilityBoundsForRangeParameterizedAttribute, 1555 NSAccessibilityBoundsForRangeParameterizedAttribute,
1250 NSAccessibilityRTFForRangeParameterizedAttribute, 1556 NSAccessibilityRTFForRangeParameterizedAttribute,
1251 NSAccessibilityAttributedStringForRangeParameterizedAttribute, 1557 NSAccessibilityAttributedStringForRangeParameterizedAttribute,
1252 NSAccessibilityStyleRangeForIndexParameterizedAttribute, 1558 NSAccessibilityStyleRangeForIndexParameterizedAttribute,
1253 nil]; 1559 nil]];
1254 } 1560 }
1255 if ([self internalRole] == ui::AX_ROLE_STATIC_TEXT) { 1561 if ([self internalRole] == ui::AX_ROLE_STATIC_TEXT) {
1256 return [NSArray arrayWithObjects: 1562 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1257 NSAccessibilityBoundsForRangeParameterizedAttribute, 1563 NSAccessibilityBoundsForRangeParameterizedAttribute,
1258 nil]; 1564 nil]];
1259 } 1565 }
1260 return nil; 1566 return ret;
1261 } 1567 }
1262 1568
1263 // Returns an array of action names that this object will respond to. 1569 // Returns an array of action names that this object will respond to.
1264 - (NSArray*)accessibilityActionNames { 1570 - (NSArray*)accessibilityActionNames {
1265 if (!browserAccessibility_) 1571 if (!browserAccessibility_)
1266 return nil; 1572 return nil;
1267 1573
1268 NSMutableArray* ret = 1574 NSMutableArray* ret =
1269 [NSMutableArray arrayWithObject:NSAccessibilityShowMenuAction]; 1575 [NSMutableArray arrayWithObject:NSAccessibilityShowMenuAction];
1270 NSString* role = [self role]; 1576 NSString* role = [self role];
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 if (!browserAccessibility_) 1968 if (!browserAccessibility_)
1663 return [super hash]; 1969 return [super hash];
1664 return browserAccessibility_->GetId(); 1970 return browserAccessibility_->GetId();
1665 } 1971 }
1666 1972
1667 - (BOOL)accessibilityShouldUseUniqueId { 1973 - (BOOL)accessibilityShouldUseUniqueId {
1668 return YES; 1974 return YES;
1669 } 1975 }
1670 1976
1671 @end 1977 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698