WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
changeset 2 303757a437d3
parent 0 4f2f89ce4247
equal deleted inserted replaced
0:4f2f89ce4247 2:303757a437d3
     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 }