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

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: 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/accessibility_tree_search.h"
16 #include "content/browser/accessibility/browser_accessibility_manager.h" 17 #include "content/browser/accessibility/browser_accessibility_manager.h"
17 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" 18 #include "content/browser/accessibility/browser_accessibility_manager_mac.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;
29 using content::AccessibilityTreeSearch;
27 using content::BrowserAccessibility; 30 using content::BrowserAccessibility;
28 using content::BrowserAccessibilityDelegate; 31 using content::BrowserAccessibilityDelegate;
29 using content::BrowserAccessibilityManager; 32 using content::BrowserAccessibilityManager;
30 using content::BrowserAccessibilityManagerMac; 33 using content::BrowserAccessibilityManagerMac;
31 using content::ContentClient; 34 using content::ContentClient;
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 AccessibilityTreeSearch.
59 AccessibilityMatchPredicate PredicateForSearchKey(NSString* searchKey) {
60 if ([searchKey isEqualToString:@"AXAnyTypeSearchKey"]) {
David Tseng 2015/05/08 21:58:25 Is this string defined in NS*? Is this API availab
dmazzoni 2015/05/13 04:22:21 It's not even in 10.10. As far as I can tell the s
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 return current->GetRole() == ui::AX_ROLE_BLOCKQUOTE;
68 };
69 } else if ([searchKey isEqualToString:@"AXBoldFontSearchKey"]) {
70 return nullptr; // TODO(dmazzoni): implement this.
David Tseng 2015/05/08 21:58:25 Can you move the TODO into its own line above?
dmazzoni 2015/05/13 04:22:21 Done throughout.
71 } else if ([searchKey isEqualToString:@"AXButtonSearchKey"]) {
72 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
73 return (current->GetRole() == ui::AX_ROLE_BUTTON ||
David Tseng 2015/05/08 21:58:25 Not sure if they exist on Mac, but menuButton and
dmazzoni 2015/05/13 04:22:21 Done.
74 current->GetRole() == ui::AX_ROLE_POP_UP_BUTTON ||
75 current->GetRole() == ui::AX_ROLE_TOGGLE_BUTTON);
76 };
77 } else if ([searchKey isEqualToString:@"AXCheckBoxSearchKey"]) {
78 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
79 return (current->GetRole() == ui::AX_ROLE_CHECK_BOX ||
80 current->GetRole() == ui::AX_ROLE_MENU_ITEM_CHECK_BOX);
81 };
82 } else if ([searchKey isEqualToString:@"AXControlSearchKey"]) {
83 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
84 return current->HasState(ui::AX_STATE_FOCUSABLE);
David Tseng 2015/05/08 21:58:25 If a button doesn't take focus (like if it were di
dmazzoni 2015/05/13 04:22:20 No, good point. I implemented IsControl but decide
85 };
86 } else if ([searchKey isEqualToString:@"AXDifferentTypeSearchKey"]) {
87 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
88 return current->GetRole() != start->GetRole();
89 };
90 } else if ([searchKey isEqualToString:@"AXFontChangeSearchKey"]) {
91 return nullptr; // TODO(dmazzoni): implement this.
David Tseng 2015/05/08 21:58:25 Ditto
92 } else if ([searchKey isEqualToString:@"AXFontColorChangeSearchKey"]) {
93 return nullptr; // TODO(dmazzoni): implement this.
David Tseng 2015/05/08 21:58:25 Ditto
94 } else if ([searchKey isEqualToString:@"AXFrameSearchKey"]) {
95 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
96 if (current->IsWebAreaForPresentationalIframe())
97 return false;
98 return (current->GetRole() == ui::AX_ROLE_WEB_AREA ||
99 current->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA);
100 };
101 } else if ([searchKey isEqualToString:@"AXGraphicSearchKey"]) {
102 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
103 return current->GetRole() == ui::AX_ROLE_IMAGE;
104 };
105 } else if ([searchKey isEqualToString:@"AXHeadingLevel1SearchKey"]) {
106 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
107 return (current->GetRole() == ui::AX_ROLE_HEADING &&
108 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 1);
109 };
110 } else if ([searchKey isEqualToString:@"AXHeadingLevel2SearchKey"]) {
111 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
112 return (current->GetRole() == ui::AX_ROLE_HEADING &&
113 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 2);
114 };
115 } else if ([searchKey isEqualToString:@"AXHeadingLevel3SearchKey"]) {
116 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
117 return (current->GetRole() == ui::AX_ROLE_HEADING &&
118 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 3);
119 };
120 } else if ([searchKey isEqualToString:@"AXHeadingLevel4SearchKey"]) {
121 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
122 return (current->GetRole() == ui::AX_ROLE_HEADING &&
123 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 4);
124 };
125 } else if ([searchKey isEqualToString:@"AXHeadingLevel5SearchKey"]) {
126 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
127 return (current->GetRole() == ui::AX_ROLE_HEADING &&
128 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 5);
David Tseng 2015/05/08 21:58:25 Maybe worth writing a helper returning a predicate
dmazzoni 2015/05/13 04:22:21 It's only 6 heading levels and they're 2 lines eac
129 };
130 } else if ([searchKey isEqualToString:@"AXHeadingLevel6SearchKey"]) {
131 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
132 return (current->GetRole() == ui::AX_ROLE_HEADING &&
133 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) == 6);
134 };
135 } else if ([searchKey isEqualToString:@"AXHeadingSameLevelSearchKey"]) {
136 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
137 return (current->GetRole() == ui::AX_ROLE_HEADING &&
138 current->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL) ==
139 start->GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL));
David Tseng 2015/05/08 21:58:25 Need to check start is a heading too?
dmazzoni 2015/05/13 04:22:20 Done.
140 };
141 } else if ([searchKey isEqualToString:@"AXHeadingSearchKey"]) {
142 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
143 return current->GetRole() == ui::AX_ROLE_HEADING;
144 };
145 } else if ([searchKey isEqualToString:@"AXHighlightedSearchKey"]) {
146 return nullptr; // TODO(dmazzoni): implement this.
147 } else if ([searchKey isEqualToString:@"AXItalicFontSearchKey"]) {
148 return nullptr; // TODO(dmazzoni): implement this.
149 } else if ([searchKey isEqualToString:@"AXLandmarkSearchKey"]) {
150 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
151 return (current->GetRole() == ui::AX_ROLE_APPLICATION ||
152 current->GetRole() == ui::AX_ROLE_BANNER ||
153 current->GetRole() == ui::AX_ROLE_COMPLEMENTARY ||
154 current->GetRole() == ui::AX_ROLE_CONTENT_INFO ||
155 current->GetRole() == ui::AX_ROLE_FORM ||
156 current->GetRole() == ui::AX_ROLE_MAIN ||
157 current->GetRole() == ui::AX_ROLE_NAVIGATION ||
158 current->GetRole() == ui::AX_ROLE_SEARCH);
159 };
160 } else if ([searchKey isEqualToString:@"AXLinkSearchKey"]) {
161 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
162 return current->GetRole() == ui::AX_ROLE_LINK;
163 };
164 } else if ([searchKey isEqualToString:@"AXListSearchKey"]) {
165 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
166 return current->GetRole() == ui::AX_ROLE_LIST;
167 };
168 } else if ([searchKey isEqualToString:@"AXLiveRegionSearchKey"]) {
169 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
170 return current->HasStringAttribute(ui::AX_ATTR_LIVE_STATUS);
171 };
172 } else if ([searchKey isEqualToString:@"AXMisspelledWordSearchKey"]) {
173 return nullptr; // TODO(dmazzoni): implement this.
174 } else if ([searchKey isEqualToString:@"AXOutlineSearchKey"]) {
175 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
176 return current->GetRole() == ui::AX_ROLE_TREE;
177 };
178 } else if ([searchKey isEqualToString:@"AXPlainTextSearchKey"]) {
179 return nullptr; // TODO(dmazzoni): implement this.
180 } else if ([searchKey isEqualToString:@"AXRadioGroupSearchKey"]) {
181 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
182 return current->GetRole() == ui::AX_ROLE_RADIO_GROUP;
183 };
184 } else if ([searchKey isEqualToString:@"AXSameTypeSearchKey"]) {
185 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
186 return current->GetRole() == start->GetRole();
187 };
188 } else if ([searchKey isEqualToString:@"AXStaticTextSearchKey"]) {
189 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
190 return current->GetRole() == ui::AX_ROLE_STATIC_TEXT;
191 };
192 } else if ([searchKey isEqualToString:@"AXStyleChangeSearchKey"]) {
193 return nullptr; // TODO(dmazzoni): implement this.
194 } else if ([searchKey isEqualToString:@"AXTableSameLevelSearchKey"]) {
195 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
196 return current->GetRole() == ui::AX_ROLE_TABLE;
David Tseng 2015/05/08 21:58:25 What about grid? I think this means you need to ch
dmazzoni 2015/05/13 04:22:21 Done. Added TODO for nested, I wasn't planning on
197 };
198 } else if ([searchKey isEqualToString:@"AXTableSearchKey"]) {
199 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
200 return current->GetRole() == ui::AX_ROLE_TABLE;
201 };
202 } else if ([searchKey isEqualToString:@"AXTextFieldSearchKey"]) {
203 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
204 return current->GetRole() == ui::AX_ROLE_TEXT_FIELD;
205 };
206 } else if ([searchKey isEqualToString:@"AXUnderlineSearchKey"]) {
207 return nullptr; // TODO(dmazzoni): implement this.
208 } else if ([searchKey isEqualToString:@"AXUnvisitedLinkSearchKey"]) {
209 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
210 return (current->GetRole() == ui::AX_ROLE_LINK &&
211 !current->HasState(ui::AX_STATE_VISITED));
212 };
213 } else if ([searchKey isEqualToString:@"AXVisitedLinkSearchKey"]) {
214 return [](BrowserAccessibility* start, BrowserAccessibility* current) {
215 return (current->GetRole() == ui::AX_ROLE_LINK &&
216 current->HasState(ui::AX_STATE_VISITED));
217 };
218 }
219
220 return nullptr;
221 }
222
223 // Initialize an AccessibilityTreeSearch object given the parameters
224 // passed to AXUIElementCountForSearchPredicate or
225 // AXUIElementsForSearchPredicate. Return true on success.
226 bool InitializeAccessibilityTreeSearch(
227 AccessibilityTreeSearch* search,
228 id parameter) {
229 if (![parameter isKindOfClass:[NSDictionary class]])
230 return false;
231 NSDictionary* dictionary = parameter;
232
233 id startElementParameter = [dictionary objectForKey:@"AXStartElement"];
234 BrowserAccessibility* startNode = nullptr;
235 if ([startElementParameter isKindOfClass:[BrowserAccessibilityCocoa class]]) {
236 BrowserAccessibilityCocoa* startNodeCocoa =
237 (BrowserAccessibilityCocoa*)startElementParameter;
238 startNode = [startNodeCocoa browserAccessibility];
239 }
240
241 bool immediateDescendantsOnly = false;
242 NSNumber *immediateDescendantsOnlyParameter =
243 [dictionary objectForKey:@"AXImmediateDescendantsOnly"];
244 if ([immediateDescendantsOnlyParameter isKindOfClass:[NSNumber class]])
245 immediateDescendantsOnly = [immediateDescendantsOnlyParameter boolValue];
246
247 bool visibleOnly = false;
248 NSNumber *visibleOnlyParameter = [dictionary objectForKey:@"AXVisibleOnly"];
249 if ([visibleOnlyParameter isKindOfClass:[NSNumber class]])
250 visibleOnly = [visibleOnlyParameter boolValue];
251
252 content::AccessibilityTreeSearch::Direction direction =
253 content::AccessibilityTreeSearch::FORWARDS;
254 NSString* directionParameter = [dictionary objectForKey:@"AXDirection"];
255 if ([directionParameter isKindOfClass:[NSString class]]) {
256 if ([directionParameter isEqualToString:@"AXDirectionNext"])
257 direction = content::AccessibilityTreeSearch::FORWARDS;
258 else if ([directionParameter isEqualToString:@"AXDirectionPrevious"])
259 direction = content::AccessibilityTreeSearch::BACKWARDS;
260 }
261
262 int resultsLimit = 0;
263 NSNumber* resultsLimitParameter = [dictionary objectForKey:@"AXResultsLimit"];
264 if ([resultsLimitParameter isKindOfClass:[NSNumber class]])
265 resultsLimit = [resultsLimitParameter intValue];
266
267 std::string searchText;
268 NSString* searchTextParameter = [dictionary objectForKey:@"AXSearchText"];
269 if ([searchTextParameter isKindOfClass:[NSString class]])
270 searchText = base::SysNSStringToUTF8(searchTextParameter);
271
272 search->SetStartNode(startNode);
273 search->SetDirection(direction);
274 search->SetResultLimit(resultsLimit);
275 search->SetImmediateDescendantsOnly(immediateDescendantsOnly);
276 search->SetVisibleOnly(visibleOnly);
277 search->SetSearchText(searchText);
David Tseng 2015/05/08 21:58:25 Looks like you do have all args available here; co
dmazzoni 2015/05/13 04:22:20 Two reasons not to: * I think this is more readabl
278
279 id searchKey = [dictionary objectForKey:@"AXSearchKey"];
280 if ([searchKey isKindOfClass:[NSString class]]) {
281 AccessibilityMatchPredicate predicate =
282 PredicateForSearchKey((NSString*)searchKey);
283 if (predicate)
284 search->AddPredicate(predicate);
285 } else if ([searchKey isKindOfClass:[NSArray class]]) {
286 size_t searchKeyCount = static_cast<size_t>([searchKey count]);
287 for (size_t i = 0; i < searchKeyCount; ++i) {
288 id key = [searchKey objectAtIndex:i];
289 if ([key isKindOfClass:[NSString class]]) {
290 AccessibilityMatchPredicate predicate =
291 PredicateForSearchKey((NSString*)key);
292 if (predicate)
293 search->AddPredicate(predicate);
294 }
295 }
296 }
297
298 return true;
299 }
300
53 } // namespace 301 } // namespace
54 302
55 @implementation BrowserAccessibilityCocoa 303 @implementation BrowserAccessibilityCocoa
56 304
57 + (void)initialize { 305 + (void)initialize {
58 const struct { 306 const struct {
59 NSString* attribute; 307 NSString* attribute;
60 NSString* methodName; 308 NSString* methodName;
61 } attributeToMethodNameContainer[] = { 309 } attributeToMethodNameContainer[] = {
62 { NSAccessibilityChildrenAttribute, @"children" }, 310 { NSAccessibilityChildrenAttribute, @"children" },
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 - (ui::AXRole)internalRole { 798 - (ui::AXRole)internalRole {
551 return static_cast<ui::AXRole>(browserAccessibility_->GetRole()); 799 return static_cast<ui::AXRole>(browserAccessibility_->GetRole());
552 } 800 }
553 801
554 - (content::BrowserAccessibilityDelegate*)delegate { 802 - (content::BrowserAccessibilityDelegate*)delegate {
555 return browserAccessibility_->manager() ? 803 return browserAccessibility_->manager() ?
556 browserAccessibility_->manager()->delegate() : 804 browserAccessibility_->manager()->delegate() :
557 nil; 805 nil;
558 } 806 }
559 807
808 - (content::BrowserAccessibility*)browserAccessibility {
809 return browserAccessibility_;
810 }
811
560 - (NSPoint)pointInScreen:(NSPoint)origin 812 - (NSPoint)pointInScreen:(NSPoint)origin
561 size:(NSSize)size { 813 size:(NSSize)size {
562 if (!browserAccessibility_) 814 if (!browserAccessibility_)
563 return NSZeroPoint; 815 return NSZeroPoint;
564 816
565 // Get the delegate for the topmost BrowserAccessibilityManager, because 817 // Get the delegate for the topmost BrowserAccessibilityManager, because
566 // that's the only one that can convert points to their origin in the screen. 818 // that's the only one that can convert points to their origin in the screen.
567 BrowserAccessibilityDelegate* delegate = 819 BrowserAccessibilityDelegate* delegate =
568 browserAccessibility_->manager()->GetDelegateFromRootManager(); 820 browserAccessibility_->manager()->GetDelegateFromRootManager();
569 if (delegate) { 821 if (delegate) {
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 NSRange range = [(NSValue*)parameter rangeValue]; 1458 NSRange range = [(NSValue*)parameter rangeValue];
1207 gfx::Rect rect = browserAccessibility_->GetGlobalBoundsForRange( 1459 gfx::Rect rect = browserAccessibility_->GetGlobalBoundsForRange(
1208 range.location, range.length); 1460 range.location, range.length);
1209 NSPoint origin = NSMakePoint(rect.x(), rect.y()); 1461 NSPoint origin = NSMakePoint(rect.x(), rect.y());
1210 NSSize size = NSMakeSize(rect.width(), rect.height()); 1462 NSSize size = NSMakeSize(rect.width(), rect.height());
1211 NSPoint pointInScreen = [self pointInScreen:origin size:size]; 1463 NSPoint pointInScreen = [self pointInScreen:origin size:size];
1212 NSRect nsrect = NSMakeRect( 1464 NSRect nsrect = NSMakeRect(
1213 pointInScreen.x, pointInScreen.y, rect.width(), rect.height()); 1465 pointInScreen.x, pointInScreen.y, rect.width(), rect.height());
1214 return [NSValue valueWithRect:nsrect]; 1466 return [NSValue valueWithRect:nsrect];
1215 } 1467 }
1468 if ([attribute isEqualToString:@"AXUIElementCountForSearchPredicate"]) {
1469 AccessibilityTreeSearch search(browserAccessibility_->manager());
1470 if (InitializeAccessibilityTreeSearch(&search, parameter))
1471 return [NSNumber numberWithInt:search.CountMatches()];
1472 return nil;
1473 }
1474
1475 if ([attribute isEqualToString:@"AXUIElementsForSearchPredicate"]) {
1476 AccessibilityTreeSearch search(browserAccessibility_->manager());
1477 if (InitializeAccessibilityTreeSearch(&search, parameter)) {
1478 size_t count = search.CountMatches();
1479 NSMutableArray* result = [NSMutableArray arrayWithCapacity:count];
1480 for (size_t i = 0; i < count; i++) {
1481 BrowserAccessibility* match = search.GetMatchAtIndex(i);
1482 [result addObject:match->ToBrowserAccessibilityCocoa()];
1483 }
1484 return result;
1485 }
1486 return nil;
1487 }
1216 1488
1217 // TODO(dtseng): support the following attributes. 1489 // TODO(dtseng): support the following attributes.
1218 if ([attribute isEqualTo: 1490 if ([attribute isEqualTo:
1219 NSAccessibilityRangeForPositionParameterizedAttribute] || 1491 NSAccessibilityRangeForPositionParameterizedAttribute] ||
1220 [attribute isEqualTo: 1492 [attribute isEqualTo:
1221 NSAccessibilityRangeForIndexParameterizedAttribute] || 1493 NSAccessibilityRangeForIndexParameterizedAttribute] ||
1222 [attribute isEqualTo:NSAccessibilityRTFForRangeParameterizedAttribute] || 1494 [attribute isEqualTo:NSAccessibilityRTFForRangeParameterizedAttribute] ||
1223 [attribute isEqualTo: 1495 [attribute isEqualTo:
1224 NSAccessibilityStyleRangeForIndexParameterizedAttribute]) { 1496 NSAccessibilityStyleRangeForIndexParameterizedAttribute]) {
1225 return nil; 1497 return nil;
1226 } 1498 }
1227 return nil; 1499 return nil;
1228 } 1500 }
1229 1501
1230 // Returns an array of parameterized attributes names that this object will 1502 // Returns an array of parameterized attributes names that this object will
1231 // respond to. 1503 // respond to.
1232 - (NSArray*)accessibilityParameterizedAttributeNames { 1504 - (NSArray*)accessibilityParameterizedAttributeNames {
1233 if (!browserAccessibility_) 1505 if (!browserAccessibility_)
1234 return nil; 1506 return nil;
1235 1507
1508 // General attributes.
1509 NSMutableArray* ret = [NSMutableArray arrayWithObjects:
1510 @"AXUIElementCountForSearchPredicate",
1511 @"AXUIElementsForSearchPredicate",
1512 nil];
1513
1236 if ([[self role] isEqualToString:NSAccessibilityTableRole] || 1514 if ([[self role] isEqualToString:NSAccessibilityTableRole] ||
1237 [[self role] isEqualToString:NSAccessibilityGridRole]) { 1515 [[self role] isEqualToString:NSAccessibilityGridRole]) {
1238 return [NSArray arrayWithObjects: 1516 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1239 NSAccessibilityCellForColumnAndRowParameterizedAttribute, 1517 NSAccessibilityCellForColumnAndRowParameterizedAttribute,
1240 nil]; 1518 nil]];
1241 } 1519 }
1242 if ([[self role] isEqualToString:NSAccessibilityTextFieldRole]) { 1520 if ([[self role] isEqualToString:NSAccessibilityTextFieldRole]) {
1243 return [NSArray arrayWithObjects: 1521 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1244 NSAccessibilityLineForIndexParameterizedAttribute, 1522 NSAccessibilityLineForIndexParameterizedAttribute,
1245 NSAccessibilityRangeForLineParameterizedAttribute, 1523 NSAccessibilityRangeForLineParameterizedAttribute,
1246 NSAccessibilityStringForRangeParameterizedAttribute, 1524 NSAccessibilityStringForRangeParameterizedAttribute,
1247 NSAccessibilityRangeForPositionParameterizedAttribute, 1525 NSAccessibilityRangeForPositionParameterizedAttribute,
1248 NSAccessibilityRangeForIndexParameterizedAttribute, 1526 NSAccessibilityRangeForIndexParameterizedAttribute,
1249 NSAccessibilityBoundsForRangeParameterizedAttribute, 1527 NSAccessibilityBoundsForRangeParameterizedAttribute,
1250 NSAccessibilityRTFForRangeParameterizedAttribute, 1528 NSAccessibilityRTFForRangeParameterizedAttribute,
1251 NSAccessibilityAttributedStringForRangeParameterizedAttribute, 1529 NSAccessibilityAttributedStringForRangeParameterizedAttribute,
1252 NSAccessibilityStyleRangeForIndexParameterizedAttribute, 1530 NSAccessibilityStyleRangeForIndexParameterizedAttribute,
1253 nil]; 1531 nil]];
1254 } 1532 }
1255 if ([self internalRole] == ui::AX_ROLE_STATIC_TEXT) { 1533 if ([self internalRole] == ui::AX_ROLE_STATIC_TEXT) {
1256 return [NSArray arrayWithObjects: 1534 [ret addObjectsFromArray:[NSArray arrayWithObjects:
1257 NSAccessibilityBoundsForRangeParameterizedAttribute, 1535 NSAccessibilityBoundsForRangeParameterizedAttribute,
1258 nil]; 1536 nil]];
1259 } 1537 }
1260 return nil; 1538 return ret;
1261 } 1539 }
1262 1540
1263 // Returns an array of action names that this object will respond to. 1541 // Returns an array of action names that this object will respond to.
1264 - (NSArray*)accessibilityActionNames { 1542 - (NSArray*)accessibilityActionNames {
1265 if (!browserAccessibility_) 1543 if (!browserAccessibility_)
1266 return nil; 1544 return nil;
1267 1545
1268 NSMutableArray* ret = 1546 NSMutableArray* ret =
1269 [NSMutableArray arrayWithObject:NSAccessibilityShowMenuAction]; 1547 [NSMutableArray arrayWithObject:NSAccessibilityShowMenuAction];
1270 NSString* role = [self role]; 1548 NSString* role = [self role];
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 if (!browserAccessibility_) 1940 if (!browserAccessibility_)
1663 return [super hash]; 1941 return [super hash];
1664 return browserAccessibility_->GetId(); 1942 return browserAccessibility_->GetId();
1665 } 1943 }
1666 1944
1667 - (BOOL)accessibilityShouldUseUniqueId { 1945 - (BOOL)accessibilityShouldUseUniqueId {
1668 return YES; 1946 return YES;
1669 } 1947 }
1670 1948
1671 @end 1949 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698