1 /* |
|
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
7 * 1. Redistributions of source code must retain the above copyright |
|
8 * notice, this list of conditions and the following disclaimer. |
|
9 * 2. Redistributions in binary form must reproduce the above copyright |
|
10 * notice, this list of conditions and the following disclaimer in the |
|
11 * documentation and/or other materials provided with the distribution. |
|
12 * |
|
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
|
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
|
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
24 */ |
|
25 |
|
26 #import "config.h" |
|
27 #import "DumpRenderTree.h" |
|
28 #import "AccessibilityUIElement.h" |
|
29 |
|
30 #import <Foundation/Foundation.h> |
|
31 #import <JavaScriptCore/JSRetainPtr.h> |
|
32 #import <JavaScriptCore/JSStringRef.h> |
|
33 #import <JavaScriptCore/JSStringRefCF.h> |
|
34 #import <WebKit/WebFrame.h> |
|
35 #import <WebKit/WebHTMLView.h> |
|
36 #import <WebKit/WebTypesInternal.h> |
|
37 #import <wtf/RetainPtr.h> |
|
38 #import <wtf/Vector.h> |
|
39 |
|
40 #ifdef BUILDING_ON_TIGER |
|
41 #define NSAccessibilityValueDescriptionAttribute @"AXValueDescription" |
|
42 #endif |
|
43 |
|
44 #ifndef NSAccessibilityOwnsAttribute |
|
45 #define NSAccessibilityOwnsAttribute @"AXOwns" |
|
46 #endif |
|
47 |
|
48 #ifndef NSAccessibilityGrabbedAttribute |
|
49 #define NSAccessibilityGrabbedAttribute @"AXGrabbed" |
|
50 #endif |
|
51 |
|
52 #ifndef NSAccessibilityDropEffectsAttribute |
|
53 #define NSAccessibilityDropEffectsAttribute @"AXDropEffects" |
|
54 #endif |
|
55 |
|
56 // If an unsupported attribute is passed in, it will raise an accessibility exception. These are usually caught by the Accessibility Runtime to inform |
|
57 // the AX client app of the error. However, DRT is the AX client app, so it must catch these exceptions. |
|
58 #define BEGIN_AX_OBJC_EXCEPTIONS @try { |
|
59 #define END_AX_OBJC_EXCEPTIONS } @catch(NSException *e) { if (![[e name] isEqualToString:NSAccessibilityException]) @throw; } |
|
60 |
|
61 |
|
62 typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context); |
|
63 |
|
64 @interface NSObject (WebKitAccessibilityAdditions) |
|
65 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount; |
|
66 - (void)accessibilitySetShouldRepostNotifications:(BOOL)repost; |
|
67 - (NSUInteger)accessibilityIndexOfChild:(id)child; |
|
68 - (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute; |
|
69 @end |
|
70 |
|
71 @interface NSString (JSStringRefAdditions) |
|
72 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef; |
|
73 - (JSStringRef)createJSStringRef; |
|
74 @end |
|
75 |
|
76 @implementation NSString (JSStringRefAdditions) |
|
77 |
|
78 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef |
|
79 { |
|
80 if (!jsStringRef) |
|
81 return NULL; |
|
82 |
|
83 CFStringRef cfString = JSStringCopyCFString(kCFAllocatorDefault, jsStringRef); |
|
84 return [(NSString *)cfString autorelease]; |
|
85 } |
|
86 |
|
87 - (JSStringRef)createJSStringRef |
|
88 { |
|
89 return JSStringCreateWithCFString((CFStringRef)self); |
|
90 } |
|
91 |
|
92 @end |
|
93 |
|
94 @interface AccessibilityNotificationHandler : NSObject |
|
95 { |
|
96 id m_platformElement; |
|
97 JSObjectRef m_notificationFunctionCallback; |
|
98 } |
|
99 |
|
100 @end |
|
101 |
|
102 @implementation AccessibilityNotificationHandler |
|
103 |
|
104 - (id)initWithPlatformElement:(id)platformElement |
|
105 { |
|
106 self = [super init]; |
|
107 |
|
108 m_platformElement = platformElement; |
|
109 |
|
110 // Once an object starts requesting notifications, it's on for the duration of the program. |
|
111 // This is to avoid any race conditions between tests turning this flag on and off. Instead |
|
112 // AccessibilityNotificationHandler can just listen when they want to. |
|
113 [m_platformElement accessibilitySetShouldRepostNotifications:YES]; |
|
114 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil]; |
|
115 |
|
116 return self; |
|
117 } |
|
118 |
|
119 - (void)dealloc |
|
120 { |
|
121 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
122 JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); |
|
123 m_notificationFunctionCallback = 0; |
|
124 |
|
125 [super dealloc]; |
|
126 } |
|
127 |
|
128 - (void)_notificationReceived:(NSNotification *)notification |
|
129 { |
|
130 NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"]; |
|
131 if (!notificationName) |
|
132 return; |
|
133 |
|
134 JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]); |
|
135 JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get()); |
|
136 JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &argument, 0); |
|
137 } |
|
138 |
|
139 - (void)setCallback:(JSObjectRef)callback |
|
140 { |
|
141 if (!callback) |
|
142 return; |
|
143 |
|
144 // Release the old callback. |
|
145 if (m_notificationFunctionCallback) |
|
146 JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); |
|
147 |
|
148 m_notificationFunctionCallback = callback; |
|
149 JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback); |
|
150 } |
|
151 |
|
152 @end |
|
153 |
|
154 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) |
|
155 : m_element(element) |
|
156 , m_notificationHandler(0) |
|
157 { |
|
158 // FIXME: ap@webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac. |
|
159 [m_element retain]; |
|
160 } |
|
161 |
|
162 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) |
|
163 : m_element(other.m_element) |
|
164 , m_notificationHandler(0) |
|
165 { |
|
166 [m_element retain]; |
|
167 } |
|
168 |
|
169 AccessibilityUIElement::~AccessibilityUIElement() |
|
170 { |
|
171 // The notification handler should be nil because removeNotificationListener() should have been called in the test. |
|
172 ASSERT(!m_notificationHandler); |
|
173 [m_element release]; |
|
174 } |
|
175 |
|
176 static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject) |
|
177 { |
|
178 if (!valueObject) |
|
179 return NULL; |
|
180 |
|
181 if ([valueObject isKindOfClass:[NSArray class]]) |
|
182 return [NSString stringWithFormat:@"<array of size %d>", [(NSArray*)valueObject count]]; |
|
183 |
|
184 if ([valueObject isKindOfClass:[NSNumber class]]) |
|
185 return [(NSNumber*)valueObject stringValue]; |
|
186 |
|
187 if ([valueObject isKindOfClass:[NSValue class]]) { |
|
188 NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding]; |
|
189 NSValue* value = (NSValue*)valueObject; |
|
190 if ([type rangeOfString:@"NSRect"].length > 0) |
|
191 return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])]; |
|
192 if ([type rangeOfString:@"NSPoint"].length > 0) |
|
193 return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])]; |
|
194 if ([type rangeOfString:@"NSSize"].length > 0) |
|
195 return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])]; |
|
196 if ([type rangeOfString:@"NSRange"].length > 0) |
|
197 return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])]; |
|
198 } |
|
199 |
|
200 // Strip absolute URL paths |
|
201 NSString* description = [valueObject description]; |
|
202 NSRange range = [description rangeOfString:@"LayoutTests"]; |
|
203 if (range.length) |
|
204 return [description substringFromIndex:range.location]; |
|
205 |
|
206 // Strip pointer locations |
|
207 if ([description rangeOfString:@"0x"].length) { |
|
208 NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityRoleAttribute]; |
|
209 NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityTitleAttribute]; |
|
210 if ([title length]) |
|
211 return [NSString stringWithFormat:@"<%@: '%@'>", role, title]; |
|
212 return [NSString stringWithFormat:@"<%@>", role]; |
|
213 } |
|
214 |
|
215 return [valueObject description]; |
|
216 } |
|
217 |
|
218 static NSString* attributesOfElement(id accessibilityObject) |
|
219 { |
|
220 NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames]; |
|
221 |
|
222 NSMutableString* attributesString = [NSMutableString string]; |
|
223 for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) { |
|
224 NSString* attribute = [supportedAttributes objectAtIndex:i]; |
|
225 |
|
226 // Right now, position provides useless and screen-specific information, so we do not |
|
227 // want to include it for the sake of universally passing tests. |
|
228 if ([attribute isEqualToString:@"AXPosition"]) |
|
229 continue; |
|
230 |
|
231 // accessibilityAttributeValue: can throw an if an attribute is not returned. |
|
232 // For DumpRenderTree's purpose, we should ignore those exceptions |
|
233 BEGIN_AX_OBJC_EXCEPTIONS |
|
234 id valueObject = [accessibilityObject accessibilityAttributeValue:attribute]; |
|
235 NSString* value = descriptionOfValue(valueObject, accessibilityObject); |
|
236 [attributesString appendFormat:@"%@: %@\n", attribute, value]; |
|
237 END_AX_OBJC_EXCEPTIONS |
|
238 } |
|
239 |
|
240 return attributesString; |
|
241 } |
|
242 |
|
243 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value) |
|
244 { |
|
245 Vector<UniChar> buffer([attribute length]); |
|
246 [attribute getCharacters:buffer.data()]; |
|
247 buffer.append(':'); |
|
248 buffer.append(' '); |
|
249 |
|
250 Vector<UniChar> valueBuffer([value length]); |
|
251 [value getCharacters:valueBuffer.data()]; |
|
252 buffer.append(valueBuffer); |
|
253 |
|
254 return JSStringCreateWithCharacters(buffer.data(), buffer.size()); |
|
255 } |
|
256 |
|
257 static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector) |
|
258 { |
|
259 NSUInteger count = [array count]; |
|
260 for (NSUInteger i = 0; i < count; ++i) |
|
261 elementVector.append(AccessibilityUIElement([array objectAtIndex:i])); |
|
262 } |
|
263 |
|
264 static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector) |
|
265 { |
|
266 NSMutableString* allElementString = [NSMutableString string]; |
|
267 size_t size = elementVector.size(); |
|
268 for (size_t i = 0; i < size; ++i) { |
|
269 NSString* attributes = attributesOfElement(elementVector[i].platformUIElement()); |
|
270 [allElementString appendFormat:@"%@\n------------\n", attributes]; |
|
271 } |
|
272 |
|
273 return [allElementString createJSStringRef]; |
|
274 } |
|
275 |
|
276 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector) |
|
277 { |
|
278 BEGIN_AX_OBJC_EXCEPTIONS |
|
279 NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; |
|
280 convertNSArrayToVector(linkedElements, elementVector); |
|
281 END_AX_OBJC_EXCEPTIONS |
|
282 } |
|
283 |
|
284 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector) |
|
285 { |
|
286 BEGIN_AX_OBJC_EXCEPTIONS |
|
287 NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; |
|
288 convertNSArrayToVector(linkElements, elementVector); |
|
289 END_AX_OBJC_EXCEPTIONS |
|
290 } |
|
291 |
|
292 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector) |
|
293 { |
|
294 BEGIN_AX_OBJC_EXCEPTIONS |
|
295 NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; |
|
296 convertNSArrayToVector(children, elementVector); |
|
297 END_AX_OBJC_EXCEPTIONS |
|
298 } |
|
299 |
|
300 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length) |
|
301 { |
|
302 BEGIN_AX_OBJC_EXCEPTIONS |
|
303 NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; |
|
304 convertNSArrayToVector(children, elementVector); |
|
305 END_AX_OBJC_EXCEPTIONS |
|
306 } |
|
307 |
|
308 int AccessibilityUIElement::childrenCount() |
|
309 { |
|
310 Vector<AccessibilityUIElement> children; |
|
311 getChildren(children); |
|
312 |
|
313 return children.size(); |
|
314 } |
|
315 |
|
316 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) |
|
317 { |
|
318 id element = [m_element accessibilityHitTest:NSMakePoint(x, y)]; |
|
319 if (!element) |
|
320 return nil; |
|
321 |
|
322 return AccessibilityUIElement(element); |
|
323 } |
|
324 |
|
325 unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) |
|
326 { |
|
327 return [m_element accessibilityIndexOfChild:element->platformUIElement()]; |
|
328 } |
|
329 |
|
330 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) |
|
331 { |
|
332 Vector<AccessibilityUIElement> children; |
|
333 getChildrenWithRange(children, index, 1); |
|
334 |
|
335 if (children.size() == 1) |
|
336 return children[0]; |
|
337 return 0; |
|
338 } |
|
339 |
|
340 AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) |
|
341 { |
|
342 BEGIN_AX_OBJC_EXCEPTIONS |
|
343 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; |
|
344 if (index < [objects count]) |
|
345 return [objects objectAtIndex:index]; |
|
346 END_AX_OBJC_EXCEPTIONS |
|
347 |
|
348 return 0; |
|
349 } |
|
350 |
|
351 AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index) |
|
352 { |
|
353 BEGIN_AX_OBJC_EXCEPTIONS |
|
354 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityOwnsAttribute]; |
|
355 if (index < [objects count]) |
|
356 return [objects objectAtIndex:index]; |
|
357 END_AX_OBJC_EXCEPTIONS |
|
358 |
|
359 return 0; |
|
360 } |
|
361 |
|
362 AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index) |
|
363 { |
|
364 BEGIN_AX_OBJC_EXCEPTIONS |
|
365 NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; |
|
366 if (index < [objects count]) |
|
367 return [objects objectAtIndex:index]; |
|
368 END_AX_OBJC_EXCEPTIONS |
|
369 |
|
370 return 0; |
|
371 } |
|
372 |
|
373 AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index) |
|
374 { |
|
375 BEGIN_AX_OBJC_EXCEPTIONS |
|
376 NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute]; |
|
377 if (index < [rows count]) |
|
378 return [rows objectAtIndex:index]; |
|
379 END_AX_OBJC_EXCEPTIONS |
|
380 |
|
381 return 0; |
|
382 } |
|
383 |
|
384 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index) |
|
385 { |
|
386 BEGIN_AX_OBJC_EXCEPTIONS |
|
387 NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute]; |
|
388 if (index < [rows count]) |
|
389 return [rows objectAtIndex:index]; |
|
390 END_AX_OBJC_EXCEPTIONS |
|
391 |
|
392 return 0; |
|
393 } |
|
394 |
|
395 AccessibilityUIElement AccessibilityUIElement::titleUIElement() |
|
396 { |
|
397 BEGIN_AX_OBJC_EXCEPTIONS |
|
398 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute]; |
|
399 if (accessibilityObject) |
|
400 return AccessibilityUIElement(accessibilityObject); |
|
401 END_AX_OBJC_EXCEPTIONS |
|
402 |
|
403 return 0; |
|
404 } |
|
405 |
|
406 AccessibilityUIElement AccessibilityUIElement::parentElement() |
|
407 { |
|
408 BEGIN_AX_OBJC_EXCEPTIONS |
|
409 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute]; |
|
410 if (accessibilityObject) |
|
411 return AccessibilityUIElement(accessibilityObject); |
|
412 END_AX_OBJC_EXCEPTIONS |
|
413 |
|
414 return 0; |
|
415 } |
|
416 |
|
417 AccessibilityUIElement AccessibilityUIElement::disclosedByRow() |
|
418 { |
|
419 BEGIN_AX_OBJC_EXCEPTIONS |
|
420 id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute]; |
|
421 if (accessibilityObject) |
|
422 return AccessibilityUIElement(accessibilityObject); |
|
423 END_AX_OBJC_EXCEPTIONS |
|
424 |
|
425 return 0; |
|
426 } |
|
427 |
|
428 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() |
|
429 { |
|
430 Vector<AccessibilityUIElement> linkedElements; |
|
431 getLinkedUIElements(linkedElements); |
|
432 return descriptionOfElements(linkedElements); |
|
433 } |
|
434 |
|
435 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() |
|
436 { |
|
437 Vector<AccessibilityUIElement> linkElements; |
|
438 getDocumentLinks(linkElements); |
|
439 return descriptionOfElements(linkElements); |
|
440 } |
|
441 |
|
442 JSStringRef AccessibilityUIElement::attributesOfChildren() |
|
443 { |
|
444 Vector<AccessibilityUIElement> children; |
|
445 getChildren(children); |
|
446 return descriptionOfElements(children); |
|
447 } |
|
448 |
|
449 JSStringRef AccessibilityUIElement::allAttributes() |
|
450 { |
|
451 NSString* attributes = attributesOfElement(m_element); |
|
452 return [attributes createJSStringRef]; |
|
453 } |
|
454 |
|
455 JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute) |
|
456 { |
|
457 BEGIN_AX_OBJC_EXCEPTIONS |
|
458 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; |
|
459 if ([value isKindOfClass:[NSString class]]) |
|
460 return [value createJSStringRef]; |
|
461 END_AX_OBJC_EXCEPTIONS |
|
462 |
|
463 return 0; |
|
464 } |
|
465 |
|
466 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute) |
|
467 { |
|
468 BEGIN_AX_OBJC_EXCEPTIONS |
|
469 id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; |
|
470 if ([value isKindOfClass:[NSNumber class]]) |
|
471 return [value boolValue]; |
|
472 END_AX_OBJC_EXCEPTIONS |
|
473 |
|
474 return false; |
|
475 } |
|
476 |
|
477 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) |
|
478 { |
|
479 BEGIN_AX_OBJC_EXCEPTIONS |
|
480 return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]]; |
|
481 END_AX_OBJC_EXCEPTIONS |
|
482 |
|
483 return false; |
|
484 } |
|
485 |
|
486 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) |
|
487 { |
|
488 BEGIN_AX_OBJC_EXCEPTIONS |
|
489 return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]]; |
|
490 END_AX_OBJC_EXCEPTIONS |
|
491 |
|
492 return false; |
|
493 } |
|
494 |
|
495 JSStringRef AccessibilityUIElement::parameterizedAttributeNames() |
|
496 { |
|
497 NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames]; |
|
498 |
|
499 NSMutableString* attributesString = [NSMutableString string]; |
|
500 for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) { |
|
501 [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]]; |
|
502 } |
|
503 |
|
504 return [attributesString createJSStringRef]; |
|
505 } |
|
506 |
|
507 JSStringRef AccessibilityUIElement::role() |
|
508 { |
|
509 BEGIN_AX_OBJC_EXCEPTIONS |
|
510 NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element); |
|
511 return concatenateAttributeAndValue(@"AXRole", role); |
|
512 END_AX_OBJC_EXCEPTIONS |
|
513 |
|
514 return 0; |
|
515 } |
|
516 |
|
517 JSStringRef AccessibilityUIElement::subrole() |
|
518 { |
|
519 BEGIN_AX_OBJC_EXCEPTIONS |
|
520 NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element); |
|
521 return concatenateAttributeAndValue(@"AXSubrole", role); |
|
522 END_AX_OBJC_EXCEPTIONS |
|
523 |
|
524 return 0; |
|
525 } |
|
526 |
|
527 JSStringRef AccessibilityUIElement::roleDescription() |
|
528 { |
|
529 BEGIN_AX_OBJC_EXCEPTIONS |
|
530 NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element); |
|
531 return concatenateAttributeAndValue(@"AXRoleDescription", role); |
|
532 END_AX_OBJC_EXCEPTIONS |
|
533 |
|
534 return 0; |
|
535 } |
|
536 |
|
537 JSStringRef AccessibilityUIElement::title() |
|
538 { |
|
539 BEGIN_AX_OBJC_EXCEPTIONS |
|
540 NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element); |
|
541 return concatenateAttributeAndValue(@"AXTitle", title); |
|
542 END_AX_OBJC_EXCEPTIONS |
|
543 |
|
544 return 0; |
|
545 } |
|
546 |
|
547 JSStringRef AccessibilityUIElement::description() |
|
548 { |
|
549 BEGIN_AX_OBJC_EXCEPTIONS |
|
550 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element); |
|
551 return concatenateAttributeAndValue(@"AXDescription", description); |
|
552 END_AX_OBJC_EXCEPTIONS |
|
553 |
|
554 return 0; |
|
555 } |
|
556 |
|
557 JSStringRef AccessibilityUIElement::orientation() const |
|
558 { |
|
559 BEGIN_AX_OBJC_EXCEPTIONS |
|
560 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element); |
|
561 return concatenateAttributeAndValue(@"AXOrientation", description); |
|
562 END_AX_OBJC_EXCEPTIONS |
|
563 |
|
564 return 0; |
|
565 } |
|
566 |
|
567 JSStringRef AccessibilityUIElement::stringValue() |
|
568 { |
|
569 BEGIN_AX_OBJC_EXCEPTIONS |
|
570 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element); |
|
571 return concatenateAttributeAndValue(@"AXValue", description); |
|
572 END_AX_OBJC_EXCEPTIONS |
|
573 |
|
574 return 0; |
|
575 } |
|
576 |
|
577 JSStringRef AccessibilityUIElement::language() |
|
578 { |
|
579 BEGIN_AX_OBJC_EXCEPTIONS |
|
580 id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element); |
|
581 return concatenateAttributeAndValue(@"AXLanguage", description); |
|
582 END_AX_OBJC_EXCEPTIONS |
|
583 |
|
584 return 0; |
|
585 } |
|
586 |
|
587 JSStringRef AccessibilityUIElement::helpText() const |
|
588 { |
|
589 BEGIN_AX_OBJC_EXCEPTIONS |
|
590 id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element); |
|
591 return concatenateAttributeAndValue(@"AXHelp", description); |
|
592 END_AX_OBJC_EXCEPTIONS |
|
593 |
|
594 return 0; |
|
595 } |
|
596 |
|
597 double AccessibilityUIElement::x() |
|
598 { |
|
599 BEGIN_AX_OBJC_EXCEPTIONS |
|
600 NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; |
|
601 return static_cast<double>([positionValue pointValue].x); |
|
602 END_AX_OBJC_EXCEPTIONS |
|
603 |
|
604 return 0.0f; |
|
605 } |
|
606 |
|
607 double AccessibilityUIElement::y() |
|
608 { |
|
609 BEGIN_AX_OBJC_EXCEPTIONS |
|
610 NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; |
|
611 return static_cast<double>([positionValue pointValue].y); |
|
612 END_AX_OBJC_EXCEPTIONS |
|
613 |
|
614 return 0.0f; |
|
615 } |
|
616 |
|
617 double AccessibilityUIElement::width() |
|
618 { |
|
619 BEGIN_AX_OBJC_EXCEPTIONS |
|
620 NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; |
|
621 return static_cast<double>([sizeValue sizeValue].width); |
|
622 END_AX_OBJC_EXCEPTIONS |
|
623 |
|
624 return 0.0f; |
|
625 } |
|
626 |
|
627 double AccessibilityUIElement::height() |
|
628 { |
|
629 BEGIN_AX_OBJC_EXCEPTIONS |
|
630 NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; |
|
631 return static_cast<double>([sizeValue sizeValue].height); |
|
632 END_AX_OBJC_EXCEPTIONS |
|
633 |
|
634 return 0.0f; |
|
635 } |
|
636 |
|
637 double AccessibilityUIElement::clickPointX() |
|
638 { |
|
639 BEGIN_AX_OBJC_EXCEPTIONS |
|
640 NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; |
|
641 return static_cast<double>([positionValue pointValue].x); |
|
642 END_AX_OBJC_EXCEPTIONS |
|
643 |
|
644 return 0.0f; |
|
645 } |
|
646 |
|
647 double AccessibilityUIElement::clickPointY() |
|
648 { |
|
649 BEGIN_AX_OBJC_EXCEPTIONS |
|
650 NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; |
|
651 return static_cast<double>([positionValue pointValue].y); |
|
652 END_AX_OBJC_EXCEPTIONS |
|
653 |
|
654 return 0.0f; |
|
655 } |
|
656 |
|
657 double AccessibilityUIElement::intValue() const |
|
658 { |
|
659 BEGIN_AX_OBJC_EXCEPTIONS |
|
660 id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute]; |
|
661 if ([value isKindOfClass:[NSNumber class]]) |
|
662 return [(NSNumber*)value doubleValue]; |
|
663 END_AX_OBJC_EXCEPTIONS |
|
664 |
|
665 return 0.0f; |
|
666 } |
|
667 |
|
668 double AccessibilityUIElement::minValue() |
|
669 { |
|
670 BEGIN_AX_OBJC_EXCEPTIONS |
|
671 id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute]; |
|
672 if ([value isKindOfClass:[NSNumber class]]) |
|
673 return [(NSNumber*)value doubleValue]; |
|
674 END_AX_OBJC_EXCEPTIONS |
|
675 |
|
676 return 0.0f; |
|
677 } |
|
678 |
|
679 double AccessibilityUIElement::maxValue() |
|
680 { |
|
681 BEGIN_AX_OBJC_EXCEPTIONS |
|
682 id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute]; |
|
683 if ([value isKindOfClass:[NSNumber class]]) |
|
684 return [(NSNumber*)value doubleValue]; |
|
685 END_AX_OBJC_EXCEPTIONS |
|
686 |
|
687 return 0.0; |
|
688 } |
|
689 |
|
690 JSStringRef AccessibilityUIElement::valueDescription() |
|
691 { |
|
692 BEGIN_AX_OBJC_EXCEPTIONS |
|
693 NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute]; |
|
694 if ([valueDescription isKindOfClass:[NSString class]]) |
|
695 return [valueDescription createJSStringRef]; |
|
696 |
|
697 END_AX_OBJC_EXCEPTIONS |
|
698 return 0; |
|
699 } |
|
700 |
|
701 int AccessibilityUIElement::insertionPointLineNumber() |
|
702 { |
|
703 BEGIN_AX_OBJC_EXCEPTIONS |
|
704 id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute]; |
|
705 if ([value isKindOfClass:[NSNumber class]]) |
|
706 return [(NSNumber *)value intValue]; |
|
707 END_AX_OBJC_EXCEPTIONS |
|
708 |
|
709 return -1; |
|
710 } |
|
711 |
|
712 bool AccessibilityUIElement::isActionSupported(JSStringRef action) |
|
713 { |
|
714 BEGIN_AX_OBJC_EXCEPTIONS |
|
715 NSArray* actions = [m_element accessibilityActionNames]; |
|
716 return [actions containsObject:[NSString stringWithJSStringRef:action]]; |
|
717 END_AX_OBJC_EXCEPTIONS |
|
718 |
|
719 return false; |
|
720 } |
|
721 |
|
722 bool AccessibilityUIElement::isEnabled() |
|
723 { |
|
724 BEGIN_AX_OBJC_EXCEPTIONS |
|
725 id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute]; |
|
726 if ([value isKindOfClass:[NSNumber class]]) |
|
727 return [value boolValue]; |
|
728 END_AX_OBJC_EXCEPTIONS |
|
729 |
|
730 return false; |
|
731 } |
|
732 |
|
733 bool AccessibilityUIElement::isRequired() const |
|
734 { |
|
735 BEGIN_AX_OBJC_EXCEPTIONS |
|
736 id value = [m_element accessibilityAttributeValue:@"AXRequired"]; |
|
737 if ([value isKindOfClass:[NSNumber class]]) |
|
738 return [value boolValue]; |
|
739 END_AX_OBJC_EXCEPTIONS |
|
740 |
|
741 return false; |
|
742 } |
|
743 |
|
744 bool AccessibilityUIElement::isSelected() const |
|
745 { |
|
746 BEGIN_AX_OBJC_EXCEPTIONS |
|
747 id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute]; |
|
748 if ([value isKindOfClass:[NSNumber class]]) |
|
749 return [value boolValue]; |
|
750 END_AX_OBJC_EXCEPTIONS |
|
751 |
|
752 return false; |
|
753 } |
|
754 |
|
755 bool AccessibilityUIElement::isExpanded() const |
|
756 { |
|
757 BEGIN_AX_OBJC_EXCEPTIONS |
|
758 id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute]; |
|
759 if ([value isKindOfClass:[NSNumber class]]) |
|
760 return [value boolValue]; |
|
761 END_AX_OBJC_EXCEPTIONS |
|
762 |
|
763 return false; |
|
764 } |
|
765 |
|
766 bool AccessibilityUIElement::isChecked() const |
|
767 { |
|
768 // On the Mac, intValue()==1 if a a checkable control is checked. |
|
769 return intValue() == 1; |
|
770 } |
|
771 |
|
772 int AccessibilityUIElement::hierarchicalLevel() const |
|
773 { |
|
774 BEGIN_AX_OBJC_EXCEPTIONS |
|
775 id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute]; |
|
776 if ([value isKindOfClass:[NSNumber class]]) |
|
777 return [value intValue]; |
|
778 END_AX_OBJC_EXCEPTIONS |
|
779 |
|
780 return 0; |
|
781 } |
|
782 |
|
783 bool AccessibilityUIElement::ariaIsGrabbed() const |
|
784 { |
|
785 BEGIN_AX_OBJC_EXCEPTIONS |
|
786 id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute]; |
|
787 if ([value isKindOfClass:[NSNumber class]]) |
|
788 return [value boolValue]; |
|
789 END_AX_OBJC_EXCEPTIONS |
|
790 |
|
791 return false; |
|
792 } |
|
793 |
|
794 JSStringRef AccessibilityUIElement::ariaDropEffects() const |
|
795 { |
|
796 BEGIN_AX_OBJC_EXCEPTIONS |
|
797 id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute]; |
|
798 if (![value isKindOfClass:[NSArray class]]) |
|
799 return 0; |
|
800 |
|
801 NSMutableString* dropEffects = [NSMutableString string]; |
|
802 NSInteger length = [value count]; |
|
803 for (NSInteger k = 0; k < length; ++k) { |
|
804 [dropEffects appendString:[value objectAtIndex:k]]; |
|
805 if (k < length - 1) |
|
806 [dropEffects appendString:@","]; |
|
807 } |
|
808 |
|
809 return [dropEffects createJSStringRef]; |
|
810 END_AX_OBJC_EXCEPTIONS |
|
811 |
|
812 return 0; |
|
813 } |
|
814 |
|
815 // parameterized attributes |
|
816 int AccessibilityUIElement::lineForIndex(int index) |
|
817 { |
|
818 BEGIN_AX_OBJC_EXCEPTIONS |
|
819 id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]]; |
|
820 if ([value isKindOfClass:[NSNumber class]]) |
|
821 return [(NSNumber *)value intValue]; |
|
822 END_AX_OBJC_EXCEPTIONS |
|
823 |
|
824 return -1; |
|
825 } |
|
826 |
|
827 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) |
|
828 { |
|
829 NSRange range = NSMakeRange(location, length); |
|
830 BEGIN_AX_OBJC_EXCEPTIONS |
|
831 id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; |
|
832 NSRect rect = NSMakeRect(0,0,0,0); |
|
833 if ([value isKindOfClass:[NSValue class]]) |
|
834 rect = [value rectValue]; |
|
835 |
|
836 // don't return position information because it is platform dependent |
|
837 NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height]; |
|
838 return [boundsDescription createJSStringRef]; |
|
839 END_AX_OBJC_EXCEPTIONS |
|
840 |
|
841 return 0; |
|
842 } |
|
843 |
|
844 JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) |
|
845 { |
|
846 NSRange range = NSMakeRange(location, length); |
|
847 BEGIN_AX_OBJC_EXCEPTIONS |
|
848 id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; |
|
849 if (![string isKindOfClass:[NSString class]]) |
|
850 return 0; |
|
851 |
|
852 return [string createJSStringRef]; |
|
853 END_AX_OBJC_EXCEPTIONS |
|
854 |
|
855 return 0; |
|
856 } |
|
857 |
|
858 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() |
|
859 { |
|
860 // not yet defined in AppKit... odd |
|
861 BEGIN_AX_OBJC_EXCEPTIONS |
|
862 NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; |
|
863 Vector<AccessibilityUIElement> columnHeadersVector; |
|
864 convertNSArrayToVector(columnHeadersArray, columnHeadersVector); |
|
865 return descriptionOfElements(columnHeadersVector); |
|
866 END_AX_OBJC_EXCEPTIONS |
|
867 |
|
868 return 0; |
|
869 } |
|
870 |
|
871 JSStringRef AccessibilityUIElement::attributesOfRowHeaders() |
|
872 { |
|
873 BEGIN_AX_OBJC_EXCEPTIONS |
|
874 NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; |
|
875 Vector<AccessibilityUIElement> rowHeadersVector; |
|
876 convertNSArrayToVector(rowHeadersArray, rowHeadersVector); |
|
877 return descriptionOfElements(rowHeadersVector); |
|
878 END_AX_OBJC_EXCEPTIONS |
|
879 |
|
880 return 0; |
|
881 } |
|
882 |
|
883 JSStringRef AccessibilityUIElement::attributesOfColumns() |
|
884 { |
|
885 BEGIN_AX_OBJC_EXCEPTIONS |
|
886 NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; |
|
887 Vector<AccessibilityUIElement> columnsVector; |
|
888 convertNSArrayToVector(columnsArray, columnsVector); |
|
889 return descriptionOfElements(columnsVector); |
|
890 END_AX_OBJC_EXCEPTIONS |
|
891 |
|
892 return 0; |
|
893 } |
|
894 |
|
895 JSStringRef AccessibilityUIElement::attributesOfRows() |
|
896 { |
|
897 BEGIN_AX_OBJC_EXCEPTIONS |
|
898 NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; |
|
899 Vector<AccessibilityUIElement> rowsVector; |
|
900 convertNSArrayToVector(rowsArray, rowsVector); |
|
901 return descriptionOfElements(rowsVector); |
|
902 END_AX_OBJC_EXCEPTIONS |
|
903 |
|
904 return 0; |
|
905 } |
|
906 |
|
907 JSStringRef AccessibilityUIElement::attributesOfVisibleCells() |
|
908 { |
|
909 BEGIN_AX_OBJC_EXCEPTIONS |
|
910 NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; |
|
911 Vector<AccessibilityUIElement> cellsVector; |
|
912 convertNSArrayToVector(cellsArray, cellsVector); |
|
913 return descriptionOfElements(cellsVector); |
|
914 END_AX_OBJC_EXCEPTIONS |
|
915 |
|
916 return 0; |
|
917 } |
|
918 |
|
919 JSStringRef AccessibilityUIElement::attributesOfHeader() |
|
920 { |
|
921 BEGIN_AX_OBJC_EXCEPTIONS |
|
922 id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute]; |
|
923 if (!headerObject) |
|
924 return [@"" createJSStringRef]; |
|
925 |
|
926 Vector<AccessibilityUIElement> headerVector; |
|
927 headerVector.append(headerObject); |
|
928 return descriptionOfElements(headerVector); |
|
929 END_AX_OBJC_EXCEPTIONS |
|
930 |
|
931 return 0; |
|
932 } |
|
933 |
|
934 int AccessibilityUIElement::rowCount() |
|
935 { |
|
936 BEGIN_AX_OBJC_EXCEPTIONS |
|
937 return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute]; |
|
938 END_AX_OBJC_EXCEPTIONS |
|
939 |
|
940 return 0; |
|
941 } |
|
942 |
|
943 int AccessibilityUIElement::columnCount() |
|
944 { |
|
945 BEGIN_AX_OBJC_EXCEPTIONS |
|
946 return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute]; |
|
947 END_AX_OBJC_EXCEPTIONS |
|
948 |
|
949 return 0; |
|
950 } |
|
951 |
|
952 int AccessibilityUIElement::indexInTable() |
|
953 { |
|
954 BEGIN_AX_OBJC_EXCEPTIONS |
|
955 NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute]; |
|
956 if (indexNumber) |
|
957 return [indexNumber intValue]; |
|
958 END_AX_OBJC_EXCEPTIONS |
|
959 |
|
960 return -1; |
|
961 } |
|
962 |
|
963 JSStringRef AccessibilityUIElement::rowIndexRange() |
|
964 { |
|
965 NSRange range = NSMakeRange(0,0); |
|
966 BEGIN_AX_OBJC_EXCEPTIONS |
|
967 NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"]; |
|
968 if (indexRange) |
|
969 range = [indexRange rangeValue]; |
|
970 NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; |
|
971 return [rangeDescription createJSStringRef]; |
|
972 END_AX_OBJC_EXCEPTIONS |
|
973 |
|
974 return 0; |
|
975 } |
|
976 |
|
977 JSStringRef AccessibilityUIElement::columnIndexRange() |
|
978 { |
|
979 NSRange range = NSMakeRange(0,0); |
|
980 BEGIN_AX_OBJC_EXCEPTIONS |
|
981 NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"]; |
|
982 if (indexRange) |
|
983 range = [indexRange rangeValue]; |
|
984 NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; |
|
985 return [rangeDescription createJSStringRef]; |
|
986 END_AX_OBJC_EXCEPTIONS |
|
987 |
|
988 return 0; |
|
989 } |
|
990 |
|
991 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row) |
|
992 { |
|
993 NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil]; |
|
994 BEGIN_AX_OBJC_EXCEPTIONS |
|
995 return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray]; |
|
996 END_AX_OBJC_EXCEPTIONS |
|
997 |
|
998 return 0; |
|
999 } |
|
1000 |
|
1001 JSStringRef AccessibilityUIElement::selectedTextRange() |
|
1002 { |
|
1003 NSRange range = NSMakeRange(NSNotFound, 0); |
|
1004 BEGIN_AX_OBJC_EXCEPTIONS |
|
1005 NSValue *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute]; |
|
1006 if (indexRange) |
|
1007 range = [indexRange rangeValue]; |
|
1008 NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; |
|
1009 return [rangeDescription createJSStringRef]; |
|
1010 END_AX_OBJC_EXCEPTIONS |
|
1011 |
|
1012 return 0; |
|
1013 } |
|
1014 |
|
1015 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) |
|
1016 { |
|
1017 NSRange textRange = NSMakeRange(location, length); |
|
1018 NSValue *textRangeValue = [NSValue valueWithRange:textRange]; |
|
1019 BEGIN_AX_OBJC_EXCEPTIONS |
|
1020 [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute]; |
|
1021 END_AX_OBJC_EXCEPTIONS |
|
1022 } |
|
1023 |
|
1024 void AccessibilityUIElement::increment() |
|
1025 { |
|
1026 BEGIN_AX_OBJC_EXCEPTIONS |
|
1027 [m_element accessibilityPerformAction:NSAccessibilityIncrementAction]; |
|
1028 END_AX_OBJC_EXCEPTIONS |
|
1029 } |
|
1030 |
|
1031 void AccessibilityUIElement::decrement() |
|
1032 { |
|
1033 BEGIN_AX_OBJC_EXCEPTIONS |
|
1034 [m_element accessibilityPerformAction:NSAccessibilityDecrementAction]; |
|
1035 END_AX_OBJC_EXCEPTIONS |
|
1036 } |
|
1037 |
|
1038 void AccessibilityUIElement::showMenu() |
|
1039 { |
|
1040 BEGIN_AX_OBJC_EXCEPTIONS |
|
1041 [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction]; |
|
1042 END_AX_OBJC_EXCEPTIONS |
|
1043 } |
|
1044 |
|
1045 void AccessibilityUIElement::press() |
|
1046 { |
|
1047 BEGIN_AX_OBJC_EXCEPTIONS |
|
1048 [m_element accessibilityPerformAction:NSAccessibilityPressAction]; |
|
1049 END_AX_OBJC_EXCEPTIONS |
|
1050 } |
|
1051 |
|
1052 JSStringRef AccessibilityUIElement::accessibilityValue() const |
|
1053 { |
|
1054 // FIXME: implement |
|
1055 return JSStringCreateWithCharacters(0, 0); |
|
1056 } |
|
1057 |
|
1058 JSStringRef AccessibilityUIElement::documentEncoding() |
|
1059 { |
|
1060 return JSStringCreateWithCharacters(0, 0); |
|
1061 } |
|
1062 |
|
1063 JSStringRef AccessibilityUIElement::documentURI() |
|
1064 { |
|
1065 return JSStringCreateWithCharacters(0, 0); |
|
1066 } |
|
1067 |
|
1068 JSStringRef AccessibilityUIElement::url() |
|
1069 { |
|
1070 BEGIN_AX_OBJC_EXCEPTIONS |
|
1071 NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute]; |
|
1072 return [[url absoluteString] createJSStringRef]; |
|
1073 END_AX_OBJC_EXCEPTIONS |
|
1074 |
|
1075 return nil; |
|
1076 } |
|
1077 |
|
1078 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback) |
|
1079 { |
|
1080 if (!functionCallback) |
|
1081 return false; |
|
1082 |
|
1083 // Mac programmers should not be adding more than one notification listener per element. |
|
1084 // Other platforms may be different. |
|
1085 if (m_notificationHandler) |
|
1086 return false; |
|
1087 m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()]; |
|
1088 [m_notificationHandler setCallback:functionCallback]; |
|
1089 |
|
1090 return true; |
|
1091 } |
|
1092 |
|
1093 void AccessibilityUIElement::removeNotificationListener() |
|
1094 { |
|
1095 // Mac programmers should not be trying to remove a listener that's already removed. |
|
1096 ASSERT(m_notificationHandler); |
|
1097 |
|
1098 [m_notificationHandler release]; |
|
1099 m_notificationHandler = nil; |
|
1100 } |
|
1101 |
|
1102 bool AccessibilityUIElement::isSelectable() const |
|
1103 { |
|
1104 // FIXME: implement |
|
1105 return false; |
|
1106 } |
|
1107 |
|
1108 bool AccessibilityUIElement::isMultiSelectable() const |
|
1109 { |
|
1110 // FIXME: implement |
|
1111 return false; |
|
1112 } |
|
1113 |
|
1114 bool AccessibilityUIElement::isVisible() const |
|
1115 { |
|
1116 // FIXME: implement |
|
1117 return false; |
|
1118 } |
|
1119 |
|
1120 bool AccessibilityUIElement::isOffScreen() const |
|
1121 { |
|
1122 // FIXME: implement |
|
1123 return false; |
|
1124 } |
|
1125 |
|
1126 bool AccessibilityUIElement::isCollapsed() const |
|
1127 { |
|
1128 // FIXME: implement |
|
1129 return false; |
|
1130 } |
|
1131 |
|
1132 bool AccessibilityUIElement::hasPopup() const |
|
1133 { |
|
1134 BEGIN_AX_OBJC_EXCEPTIONS |
|
1135 id value = [m_element accessibilityAttributeValue:@"AXHasPopup"]; |
|
1136 if ([value isKindOfClass:[NSNumber class]]) |
|
1137 return [value boolValue]; |
|
1138 END_AX_OBJC_EXCEPTIONS |
|
1139 |
|
1140 return false; |
|
1141 } |
|
1142 |
|
1143 void AccessibilityUIElement::takeFocus() |
|
1144 { |
|
1145 // FIXME: implement |
|
1146 } |
|
1147 |
|
1148 void AccessibilityUIElement::takeSelection() |
|
1149 { |
|
1150 // FIXME: implement |
|
1151 } |
|
1152 |
|
1153 void AccessibilityUIElement::addSelection() |
|
1154 { |
|
1155 // FIXME: implement |
|
1156 } |
|
1157 |
|
1158 void AccessibilityUIElement::removeSelection() |
|
1159 { |
|
1160 // FIXME: implement |
|
1161 } |
|