7762f75891ea5da7fe3ad686e9ba6fa888873180
[WebKit-https.git] / WebKitTools / DumpRenderTree / mac / AccessibilityUIElementMac.mm
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/JSStringRef.h>
32 #import <JavaScriptCore/JSStringRefCF.h>
33 #import <WebKit/WebFrame.h>
34 #import <WebKit/WebHTMLView.h>
35 #import <WebKit/WebTypesInternal.h>
36 #import <wtf/RetainPtr.h>
37 #import <wtf/Vector.h>
38
39 #ifdef BUILDING_ON_TIGER
40 #define NSAccessibilityValueDescriptionAttribute @"AXValueDescription"
41 #endif
42
43 @interface NSObject (WebKitAccessibilityArrayCategory)
44 - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
45 @end
46
47 AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
48     : m_element(element)
49 {
50     [m_element retain];
51 }
52
53 AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
54     : m_element(other.m_element)
55 {
56     [m_element retain];
57 }
58
59 AccessibilityUIElement::~AccessibilityUIElement()
60 {
61     [m_element release];
62 }
63
64 @interface NSString (JSStringRefAdditions)
65 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef;
66 - (JSStringRef)createJSStringRef;
67 @end
68
69 @implementation NSString (JSStringRefAdditions)
70
71 + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef
72 {
73     if (!jsStringRef)
74         return NULL;
75     
76     CFStringRef cfString = JSStringCopyCFString(kCFAllocatorDefault, jsStringRef);
77     return [(NSString *)cfString autorelease];
78 }
79
80 - (JSStringRef)createJSStringRef
81 {
82     return JSStringCreateWithCFString((CFStringRef)self);
83 }
84
85 @end
86
87 static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject)
88 {
89     if (!valueObject)
90         return NULL;
91
92     if ([valueObject isKindOfClass:[NSArray class]])
93         return [NSString stringWithFormat:@"<array of size %d>", [(NSArray*)valueObject count]];
94
95     if ([valueObject isKindOfClass:[NSNumber class]])
96         return [(NSNumber*)valueObject stringValue];
97
98     if ([valueObject isKindOfClass:[NSValue class]]) {
99         NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding];
100         NSValue* value = (NSValue*)valueObject;
101         if ([type rangeOfString:@"NSRect"].length > 0)
102             return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])];
103         if ([type rangeOfString:@"NSPoint"].length > 0)
104             return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])];
105         if ([type rangeOfString:@"NSSize"].length > 0)
106             return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])];
107         if ([type rangeOfString:@"NSRange"].length > 0)
108             return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])];
109     }
110
111     // Strip absolute URL paths
112     NSString* description = [valueObject description];
113     NSRange range = [description rangeOfString:@"LayoutTests"];
114     if (range.length)
115         return [description substringFromIndex:range.location];
116
117     // Strip pointer locations
118     if ([description rangeOfString:@"0x"].length) {
119         NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityRoleAttribute];
120         NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityTitleAttribute];
121         if ([title length])
122             return [NSString stringWithFormat:@"<%@: '%@'>", role, title];
123         return [NSString stringWithFormat:@"<%@>", role];
124     }
125     
126     return [valueObject description];
127 }
128
129 static NSString* attributesOfElement(id accessibilityObject)
130 {
131     NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames];
132
133     NSMutableString* attributesString = [NSMutableString string];
134     for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) {
135         NSString* attribute = [supportedAttributes objectAtIndex:i];
136         
137         // Right now, position provides useless and screen-specific information, so we do not
138         // want to include it for the sake of universally passing tests.
139         if ([attribute isEqualToString:@"AXPosition"])
140             continue;
141         
142         // accessibilityAttributeValue: can throw an if an attribute is not returned.
143         // For DumpRenderTree's purpose, we should ignore those exceptions
144         @try {
145             id valueObject = [accessibilityObject accessibilityAttributeValue:attribute];
146             NSString* value = descriptionOfValue(valueObject, accessibilityObject);
147             [attributesString appendFormat:@"%@: %@\n", attribute, value];
148         } @catch (NSException* e) { }
149     }
150     
151     return attributesString;
152 }
153
154 static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value)
155 {
156     Vector<UniChar> buffer([attribute length]);
157     [attribute getCharacters:buffer.data()];
158     buffer.append(':');
159     buffer.append(' ');
160
161     Vector<UniChar> valueBuffer([value length]);
162     [value getCharacters:valueBuffer.data()];
163     buffer.append(valueBuffer);
164
165     return JSStringCreateWithCharacters(buffer.data(), buffer.size());
166 }
167
168 static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector)
169 {
170     NSUInteger count = [array count];
171     for (NSUInteger i = 0; i < count; ++i)
172         elementVector.append(AccessibilityUIElement([array objectAtIndex:i]));
173 }
174
175 static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& elementVector)
176 {
177     NSMutableString* allElementString = [NSMutableString string];
178     size_t size = elementVector.size();
179     for (size_t i = 0; i < size; ++i) {
180         NSString* attributes = attributesOfElement(elementVector[i].platformUIElement());
181         [allElementString appendFormat:@"%@\n------------\n", attributes];
182     }
183     
184     return [allElementString createJSStringRef];
185 }
186
187 void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
188 {
189     NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
190     convertNSArrayToVector(linkedElements, elementVector);
191 }
192
193 void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>& elementVector)
194 {
195     NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
196     convertNSArrayToVector(linkElements, elementVector);
197 }
198
199 void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& elementVector)
200 {
201     NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
202     convertNSArrayToVector(children, elementVector);
203 }
204
205 void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned location, unsigned length)
206 {
207     NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length];
208     convertNSArrayToVector(children, elementVector);
209 }
210
211 int AccessibilityUIElement::childrenCount()
212 {
213     Vector<AccessibilityUIElement> children;
214     getChildren(children);
215     
216     return children.size();
217 }
218
219 AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
220 {
221     id element = [m_element accessibilityHitTest:NSMakePoint(x, y)];
222     if (!element)
223         return nil;
224     
225     return AccessibilityUIElement(element); 
226 }
227
228 AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
229 {
230     Vector<AccessibilityUIElement> children;
231     getChildrenWithRange(children, index, 1);
232
233     if (children.size() == 1)
234         return children[0];
235     return 0;
236 }
237
238 AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
239 {
240     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute];
241     if (index < [rows count])
242         return [rows objectAtIndex:index];
243
244     return 0;
245 }
246
247 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
248 {
249     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute];
250     if (index < [rows count])
251         return [rows objectAtIndex:index];
252     
253     return 0;
254 }
255
256 AccessibilityUIElement AccessibilityUIElement::titleUIElement()
257 {
258     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute];
259     if (accessibilityObject)
260         return AccessibilityUIElement(accessibilityObject);
261     
262     return 0;
263 }
264
265 AccessibilityUIElement AccessibilityUIElement::parentElement()
266 {
267     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute];
268     if (accessibilityObject)
269         return AccessibilityUIElement(accessibilityObject);
270     
271     return 0;
272 }
273
274 AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
275 {
276     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute];
277     if (accessibilityObject)
278         return AccessibilityUIElement(accessibilityObject);
279     
280     return 0;
281 }
282
283 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
284 {
285     Vector<AccessibilityUIElement> linkedElements;
286     getLinkedUIElements(linkedElements);
287     return descriptionOfElements(linkedElements);
288 }
289
290 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
291 {
292     Vector<AccessibilityUIElement> linkElements;
293     getDocumentLinks(linkElements);
294     return descriptionOfElements(linkElements);
295 }
296
297 JSStringRef AccessibilityUIElement::attributesOfChildren()
298 {
299     Vector<AccessibilityUIElement> children;
300     getChildren(children);
301     return descriptionOfElements(children);
302 }
303
304 JSStringRef AccessibilityUIElement::allAttributes()
305 {
306     NSString* attributes = attributesOfElement(m_element);
307     return [attributes createJSStringRef];
308 }
309
310 JSStringRef AccessibilityUIElement::attributeValue(JSStringRef attribute)
311 {
312     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
313     if (![value isKindOfClass:[NSString class]])
314         return NULL;
315     return [value createJSStringRef];
316 }
317
318 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
319 {
320     return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]];
321 }
322
323 JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
324 {
325     NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames];
326     
327     NSMutableString* attributesString = [NSMutableString string];
328     for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) {
329         [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]];
330     }
331     
332     return [attributesString createJSStringRef];
333 }
334
335 JSStringRef AccessibilityUIElement::role()
336 {
337     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element);
338     return concatenateAttributeAndValue(@"AXRole", role);
339 }
340
341 JSStringRef AccessibilityUIElement::subrole()
342 {
343     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element);
344     return concatenateAttributeAndValue(@"AXSubrole", role);
345 }
346
347 JSStringRef AccessibilityUIElement::title()
348 {
349     NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element);
350     return concatenateAttributeAndValue(@"AXTitle", title);
351 }
352
353 JSStringRef AccessibilityUIElement::description()
354 {
355     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element);
356     return concatenateAttributeAndValue(@"AXDescription", description);
357 }
358
359 JSStringRef AccessibilityUIElement::stringValue()
360 {
361     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element);
362     return concatenateAttributeAndValue(@"AXValue", description);
363 }
364
365 JSStringRef AccessibilityUIElement::language()
366 {
367     id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element);
368     return concatenateAttributeAndValue(@"AXLanguage", description);
369 }
370
371 double AccessibilityUIElement::x()
372 {
373     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
374     return static_cast<double>([positionValue pointValue].x);    
375 }
376
377 double AccessibilityUIElement::y()
378 {
379     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
380     return static_cast<double>([positionValue pointValue].y);    
381 }
382
383 double AccessibilityUIElement::width()
384 {
385     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
386     return static_cast<double>([sizeValue sizeValue].width);
387 }
388
389 double AccessibilityUIElement::height()
390 {
391     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
392     return static_cast<double>([sizeValue sizeValue].height);
393 }
394
395 double AccessibilityUIElement::clickPointX()
396 {
397     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
398     return static_cast<double>([positionValue pointValue].x);        
399 }
400
401 double AccessibilityUIElement::clickPointY()
402 {
403     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
404     return static_cast<double>([positionValue pointValue].y);
405 }
406
407 double AccessibilityUIElement::intValue()
408 {
409     id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute];
410     if ([value isKindOfClass:[NSNumber class]])
411         return [(NSNumber*)value doubleValue]; 
412     return 0.0f;
413 }
414
415 double AccessibilityUIElement::minValue()
416 {
417     id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute];
418     if ([value isKindOfClass:[NSNumber class]])
419         return [(NSNumber*)value doubleValue]; 
420     return 0.0f;
421 }
422
423 double AccessibilityUIElement::maxValue()
424 {
425     id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute];
426     if ([value isKindOfClass:[NSNumber class]])
427         return [(NSNumber*)value doubleValue]; 
428     return 0.0;
429 }
430
431 JSStringRef AccessibilityUIElement::valueDescription()
432 {
433     NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute];
434     if ([valueDescription isKindOfClass:[NSString class]])
435          return [valueDescription createJSStringRef];
436     return 0;
437 }
438
439 int AccessibilityUIElement::insertionPointLineNumber()
440 {
441     id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute];
442     if ([value isKindOfClass:[NSNumber class]])
443         return [(NSNumber *)value intValue]; 
444     return -1;
445 }
446
447 bool AccessibilityUIElement::isActionSupported(JSStringRef action)
448 {
449     NSArray* actions = [m_element accessibilityActionNames];
450     return [actions containsObject:[NSString stringWithJSStringRef:action]];
451 }
452
453 bool AccessibilityUIElement::isEnabled()
454 {
455     id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute];
456     if ([value isKindOfClass:[NSNumber class]])
457         return [value boolValue];
458     return false;
459 }
460
461 bool AccessibilityUIElement::isRequired() const
462 {
463     id value = [m_element accessibilityAttributeValue:@"AXRequired"];
464     if ([value isKindOfClass:[NSNumber class]])
465         return [value boolValue];
466     return false;
467 }
468
469 bool AccessibilityUIElement::isSelected() const
470 {
471     id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute];
472     if ([value isKindOfClass:[NSNumber class]])
473         return [value boolValue];
474     return false;
475 }
476
477 bool AccessibilityUIElement::isExpanded() const
478 {
479     id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute];
480     if ([value isKindOfClass:[NSNumber class]])
481         return [value boolValue];
482     return false;
483 }
484
485 int AccessibilityUIElement::hierarchicalLevel() const
486 {
487     id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute];
488     if ([value isKindOfClass:[NSNumber class]])
489         return [value intValue];
490     return 0;
491 }
492
493 // parameterized attributes
494 int AccessibilityUIElement::lineForIndex(int index)
495 {
496     id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]];
497     if ([value isKindOfClass:[NSNumber class]])
498         return [(NSNumber *)value intValue]; 
499     return -1;
500 }
501
502 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
503 {
504     NSRange range = NSMakeRange(location, length);
505     id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
506     NSRect rect = NSMakeRect(0,0,0,0);
507     if ([value isKindOfClass:[NSValue class]])
508         rect = [value rectValue]; 
509     
510     // don't return position information because it is platform dependent
511     NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height];
512     return [boundsDescription createJSStringRef];
513 }
514
515 JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
516 {
517     NSRange range = NSMakeRange(location, length);
518     id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
519     if (![string isKindOfClass:[NSString class]])
520         return 0;
521     
522     return [string createJSStringRef];
523 }
524
525 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
526 {
527     // not yet defined in AppKit... odd
528     NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
529     Vector<AccessibilityUIElement> columnHeadersVector;
530     convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
531     return descriptionOfElements(columnHeadersVector);
532 }
533
534 JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
535 {
536     NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
537     Vector<AccessibilityUIElement> rowHeadersVector;
538     convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
539     return descriptionOfElements(rowHeadersVector);
540 }
541
542 JSStringRef AccessibilityUIElement::attributesOfColumns()
543 {
544     NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
545     Vector<AccessibilityUIElement> columnsVector;
546     convertNSArrayToVector(columnsArray, columnsVector);
547     return descriptionOfElements(columnsVector);
548 }
549
550 JSStringRef AccessibilityUIElement::attributesOfRows()
551 {
552     NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
553     Vector<AccessibilityUIElement> rowsVector;
554     convertNSArrayToVector(rowsArray, rowsVector);
555     return descriptionOfElements(rowsVector);
556 }
557
558 JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
559 {
560     NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
561     Vector<AccessibilityUIElement> cellsVector;
562     convertNSArrayToVector(cellsArray, cellsVector);
563     return descriptionOfElements(cellsVector);
564 }
565
566 JSStringRef AccessibilityUIElement::attributesOfHeader()
567 {
568     id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
569     if (!headerObject)
570         return [@"" createJSStringRef];
571     
572     Vector<AccessibilityUIElement> headerVector;
573     headerVector.append(headerObject);
574     return descriptionOfElements(headerVector);
575 }
576
577 int AccessibilityUIElement::indexInTable()
578 {
579     NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
580     if (!indexNumber)
581         return -1;
582     return [indexNumber intValue];
583 }
584
585 JSStringRef AccessibilityUIElement::rowIndexRange()
586 {
587     NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
588     NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
589     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
590     return [rangeDescription createJSStringRef];
591 }
592
593 JSStringRef AccessibilityUIElement::columnIndexRange()
594 {
595     NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
596     NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
597     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
598     return [rangeDescription createJSStringRef];    
599 }
600
601 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
602 {
603     NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
604     return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray];
605 }
606
607 JSStringRef AccessibilityUIElement::selectedTextRange()
608 {
609     NSNumber *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute];
610     NSRange range = indexRange ? [indexRange rangeValue] : NSMakeRange(0,0);
611     NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
612     return [rangeDescription createJSStringRef];    
613 }
614
615 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
616 {
617     NSRange textRange = NSMakeRange(location, length);
618     NSValue *textRangeValue = [NSValue valueWithRange:textRange];
619     [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute];
620 }
621
622 void AccessibilityUIElement::increment()
623 {
624     [m_element accessibilityPerformAction:NSAccessibilityIncrementAction];
625 }
626
627 void AccessibilityUIElement::decrement()
628 {
629     [m_element accessibilityPerformAction:NSAccessibilityDecrementAction];
630 }
631
632 void AccessibilityUIElement::showMenu()
633 {
634     [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction];
635 }
636
637 JSStringRef AccessibilityUIElement::accessibilityValue() const
638 {
639     // FIXME: implement
640     return JSStringCreateWithCharacters(0, 0);
641 }