Home | History | Annotate | Download | only in mac
      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 (at) 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::selectedChildAtIndex(unsigned index) const
    385 {
    386     BEGIN_AX_OBJC_EXCEPTIONS
    387     NSArray* array = [m_element accessibilityAttributeValue:NSAccessibilitySelectedChildrenAttribute];
    388     if (index < [array count])
    389         return [array objectAtIndex:index];
    390     END_AX_OBJC_EXCEPTIONS
    391 
    392     return 0;
    393 }
    394 
    395 unsigned AccessibilityUIElement::selectedChildrenCount() const
    396 {
    397     BEGIN_AX_OBJC_EXCEPTIONS
    398     return [m_element accessibilityArrayAttributeCount:NSAccessibilitySelectedChildrenAttribute];
    399     END_AX_OBJC_EXCEPTIONS
    400 
    401     return 0;
    402 }
    403 
    404 AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
    405 {
    406     BEGIN_AX_OBJC_EXCEPTIONS
    407     NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute];
    408     if (index < [rows count])
    409         return [rows objectAtIndex:index];
    410     END_AX_OBJC_EXCEPTIONS
    411 
    412     return 0;
    413 }
    414 
    415 AccessibilityUIElement AccessibilityUIElement::titleUIElement()
    416 {
    417     BEGIN_AX_OBJC_EXCEPTIONS
    418     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute];
    419     if (accessibilityObject)
    420         return AccessibilityUIElement(accessibilityObject);
    421     END_AX_OBJC_EXCEPTIONS
    422 
    423     return 0;
    424 }
    425 
    426 AccessibilityUIElement AccessibilityUIElement::parentElement()
    427 {
    428     BEGIN_AX_OBJC_EXCEPTIONS
    429     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute];
    430     if (accessibilityObject)
    431         return AccessibilityUIElement(accessibilityObject);
    432     END_AX_OBJC_EXCEPTIONS
    433 
    434     return 0;
    435 }
    436 
    437 AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
    438 {
    439     BEGIN_AX_OBJC_EXCEPTIONS
    440     id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute];
    441     if (accessibilityObject)
    442         return AccessibilityUIElement(accessibilityObject);
    443     END_AX_OBJC_EXCEPTIONS
    444 
    445     return 0;
    446 }
    447 
    448 JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
    449 {
    450     Vector<AccessibilityUIElement> linkedElements;
    451     getLinkedUIElements(linkedElements);
    452     return descriptionOfElements(linkedElements);
    453 }
    454 
    455 JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
    456 {
    457     Vector<AccessibilityUIElement> linkElements;
    458     getDocumentLinks(linkElements);
    459     return descriptionOfElements(linkElements);
    460 }
    461 
    462 JSStringRef AccessibilityUIElement::attributesOfChildren()
    463 {
    464     Vector<AccessibilityUIElement> children;
    465     getChildren(children);
    466     return descriptionOfElements(children);
    467 }
    468 
    469 JSStringRef AccessibilityUIElement::allAttributes()
    470 {
    471     NSString* attributes = attributesOfElement(m_element);
    472     return [attributes createJSStringRef];
    473 }
    474 
    475 JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
    476 {
    477     BEGIN_AX_OBJC_EXCEPTIONS
    478     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
    479     if ([value isKindOfClass:[NSString class]])
    480         return [value createJSStringRef];
    481     END_AX_OBJC_EXCEPTIONS
    482 
    483     return 0;
    484 }
    485 
    486 bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
    487 {
    488     BEGIN_AX_OBJC_EXCEPTIONS
    489     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
    490     if ([value isKindOfClass:[NSNumber class]])
    491         return [value boolValue];
    492     END_AX_OBJC_EXCEPTIONS
    493 
    494     return false;
    495 }
    496 
    497 bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
    498 {
    499     BEGIN_AX_OBJC_EXCEPTIONS
    500     return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]];
    501     END_AX_OBJC_EXCEPTIONS
    502 
    503     return false;
    504 }
    505 
    506 bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
    507 {
    508     BEGIN_AX_OBJC_EXCEPTIONS
    509     return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]];
    510     END_AX_OBJC_EXCEPTIONS
    511 
    512     return false;
    513 }
    514 
    515 JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
    516 {
    517     NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames];
    518 
    519     NSMutableString* attributesString = [NSMutableString string];
    520     for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) {
    521         [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]];
    522     }
    523 
    524     return [attributesString createJSStringRef];
    525 }
    526 
    527 JSStringRef AccessibilityUIElement::role()
    528 {
    529     BEGIN_AX_OBJC_EXCEPTIONS
    530     NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element);
    531     return concatenateAttributeAndValue(@"AXRole", role);
    532     END_AX_OBJC_EXCEPTIONS
    533 
    534     return 0;
    535 }
    536 
    537 JSStringRef AccessibilityUIElement::subrole()
    538 {
    539     BEGIN_AX_OBJC_EXCEPTIONS
    540     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element);
    541     return concatenateAttributeAndValue(@"AXSubrole", role);
    542     END_AX_OBJC_EXCEPTIONS
    543 
    544     return 0;
    545 }
    546 
    547 JSStringRef AccessibilityUIElement::roleDescription()
    548 {
    549     BEGIN_AX_OBJC_EXCEPTIONS
    550     NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element);
    551     return concatenateAttributeAndValue(@"AXRoleDescription", role);
    552     END_AX_OBJC_EXCEPTIONS
    553 
    554     return 0;
    555 }
    556 
    557 JSStringRef AccessibilityUIElement::title()
    558 {
    559     BEGIN_AX_OBJC_EXCEPTIONS
    560     NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element);
    561     return concatenateAttributeAndValue(@"AXTitle", title);
    562     END_AX_OBJC_EXCEPTIONS
    563 
    564     return 0;
    565 }
    566 
    567 JSStringRef AccessibilityUIElement::description()
    568 {
    569     BEGIN_AX_OBJC_EXCEPTIONS
    570     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element);
    571     return concatenateAttributeAndValue(@"AXDescription", description);
    572     END_AX_OBJC_EXCEPTIONS
    573 
    574     return 0;
    575 }
    576 
    577 JSStringRef AccessibilityUIElement::orientation() const
    578 {
    579     BEGIN_AX_OBJC_EXCEPTIONS
    580     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element);
    581     return concatenateAttributeAndValue(@"AXOrientation", description);
    582     END_AX_OBJC_EXCEPTIONS
    583 
    584     return 0;
    585 }
    586 
    587 JSStringRef AccessibilityUIElement::stringValue()
    588 {
    589     BEGIN_AX_OBJC_EXCEPTIONS
    590     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element);
    591     return concatenateAttributeAndValue(@"AXValue", description);
    592     END_AX_OBJC_EXCEPTIONS
    593 
    594     return 0;
    595 }
    596 
    597 JSStringRef AccessibilityUIElement::language()
    598 {
    599     BEGIN_AX_OBJC_EXCEPTIONS
    600     id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element);
    601     return concatenateAttributeAndValue(@"AXLanguage", description);
    602     END_AX_OBJC_EXCEPTIONS
    603 
    604     return 0;
    605 }
    606 
    607 JSStringRef AccessibilityUIElement::helpText() const
    608 {
    609     BEGIN_AX_OBJC_EXCEPTIONS
    610     id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element);
    611     return concatenateAttributeAndValue(@"AXHelp", description);
    612     END_AX_OBJC_EXCEPTIONS
    613 
    614     return 0;
    615 }
    616 
    617 double AccessibilityUIElement::x()
    618 {
    619     BEGIN_AX_OBJC_EXCEPTIONS
    620     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
    621     return static_cast<double>([positionValue pointValue].x);
    622     END_AX_OBJC_EXCEPTIONS
    623 
    624     return 0.0f;
    625 }
    626 
    627 double AccessibilityUIElement::y()
    628 {
    629     BEGIN_AX_OBJC_EXCEPTIONS
    630     NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
    631     return static_cast<double>([positionValue pointValue].y);
    632     END_AX_OBJC_EXCEPTIONS
    633 
    634     return 0.0f;
    635 }
    636 
    637 double AccessibilityUIElement::width()
    638 {
    639     BEGIN_AX_OBJC_EXCEPTIONS
    640     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
    641     return static_cast<double>([sizeValue sizeValue].width);
    642     END_AX_OBJC_EXCEPTIONS
    643 
    644     return 0.0f;
    645 }
    646 
    647 double AccessibilityUIElement::height()
    648 {
    649     BEGIN_AX_OBJC_EXCEPTIONS
    650     NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute];
    651     return static_cast<double>([sizeValue sizeValue].height);
    652     END_AX_OBJC_EXCEPTIONS
    653 
    654     return 0.0f;
    655 }
    656 
    657 double AccessibilityUIElement::clickPointX()
    658 {
    659     BEGIN_AX_OBJC_EXCEPTIONS
    660     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
    661     return static_cast<double>([positionValue pointValue].x);
    662     END_AX_OBJC_EXCEPTIONS
    663 
    664     return 0.0f;
    665 }
    666 
    667 double AccessibilityUIElement::clickPointY()
    668 {
    669     BEGIN_AX_OBJC_EXCEPTIONS
    670     NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"];
    671     return static_cast<double>([positionValue pointValue].y);
    672     END_AX_OBJC_EXCEPTIONS
    673 
    674     return 0.0f;
    675 }
    676 
    677 double AccessibilityUIElement::intValue() const
    678 {
    679     BEGIN_AX_OBJC_EXCEPTIONS
    680     id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute];
    681     if ([value isKindOfClass:[NSNumber class]])
    682         return [(NSNumber*)value doubleValue];
    683     END_AX_OBJC_EXCEPTIONS
    684 
    685     return 0.0f;
    686 }
    687 
    688 double AccessibilityUIElement::minValue()
    689 {
    690     BEGIN_AX_OBJC_EXCEPTIONS
    691     id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute];
    692     if ([value isKindOfClass:[NSNumber class]])
    693         return [(NSNumber*)value doubleValue];
    694     END_AX_OBJC_EXCEPTIONS
    695 
    696     return 0.0f;
    697 }
    698 
    699 double AccessibilityUIElement::maxValue()
    700 {
    701     BEGIN_AX_OBJC_EXCEPTIONS
    702     id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute];
    703     if ([value isKindOfClass:[NSNumber class]])
    704         return [(NSNumber*)value doubleValue];
    705     END_AX_OBJC_EXCEPTIONS
    706 
    707     return 0.0;
    708 }
    709 
    710 JSStringRef AccessibilityUIElement::valueDescription()
    711 {
    712     BEGIN_AX_OBJC_EXCEPTIONS
    713     NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute];
    714     if ([valueDescription isKindOfClass:[NSString class]])
    715          return [valueDescription createJSStringRef];
    716 
    717     END_AX_OBJC_EXCEPTIONS
    718     return 0;
    719 }
    720 
    721 int AccessibilityUIElement::insertionPointLineNumber()
    722 {
    723     BEGIN_AX_OBJC_EXCEPTIONS
    724     id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute];
    725     if ([value isKindOfClass:[NSNumber class]])
    726         return [(NSNumber *)value intValue];
    727     END_AX_OBJC_EXCEPTIONS
    728 
    729     return -1;
    730 }
    731 
    732 bool AccessibilityUIElement::isActionSupported(JSStringRef action)
    733 {
    734     BEGIN_AX_OBJC_EXCEPTIONS
    735     NSArray* actions = [m_element accessibilityActionNames];
    736     return [actions containsObject:[NSString stringWithJSStringRef:action]];
    737     END_AX_OBJC_EXCEPTIONS
    738 
    739     return false;
    740 }
    741 
    742 bool AccessibilityUIElement::isEnabled()
    743 {
    744     BEGIN_AX_OBJC_EXCEPTIONS
    745     id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute];
    746     if ([value isKindOfClass:[NSNumber class]])
    747         return [value boolValue];
    748     END_AX_OBJC_EXCEPTIONS
    749 
    750     return false;
    751 }
    752 
    753 bool AccessibilityUIElement::isRequired() const
    754 {
    755     BEGIN_AX_OBJC_EXCEPTIONS
    756     id value = [m_element accessibilityAttributeValue:@"AXRequired"];
    757     if ([value isKindOfClass:[NSNumber class]])
    758         return [value boolValue];
    759     END_AX_OBJC_EXCEPTIONS
    760 
    761     return false;
    762 }
    763 
    764 bool AccessibilityUIElement::isFocused() const
    765 {
    766     // FIXME: implement
    767     return false;
    768 }
    769 
    770 bool AccessibilityUIElement::isSelected() const
    771 {
    772     BEGIN_AX_OBJC_EXCEPTIONS
    773     id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute];
    774     if ([value isKindOfClass:[NSNumber class]])
    775         return [value boolValue];
    776     END_AX_OBJC_EXCEPTIONS
    777 
    778     return false;
    779 }
    780 
    781 bool AccessibilityUIElement::isExpanded() const
    782 {
    783     BEGIN_AX_OBJC_EXCEPTIONS
    784     id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute];
    785     if ([value isKindOfClass:[NSNumber class]])
    786         return [value boolValue];
    787     END_AX_OBJC_EXCEPTIONS
    788 
    789     return false;
    790 }
    791 
    792 bool AccessibilityUIElement::isChecked() const
    793 {
    794     // On the Mac, intValue()==1 if a a checkable control is checked.
    795     return intValue() == 1;
    796 }
    797 
    798 int AccessibilityUIElement::hierarchicalLevel() const
    799 {
    800     BEGIN_AX_OBJC_EXCEPTIONS
    801     id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute];
    802     if ([value isKindOfClass:[NSNumber class]])
    803         return [value intValue];
    804     END_AX_OBJC_EXCEPTIONS
    805 
    806     return 0;
    807 }
    808 
    809 JSStringRef AccessibilityUIElement::speak()
    810 {
    811     BEGIN_AX_OBJC_EXCEPTIONS
    812     id value = [m_element accessibilityAttributeValue:@"AXDRTSpeechAttribute"];
    813     if ([value isKindOfClass:[NSString class]])
    814         return [value createJSStringRef];
    815     END_AX_OBJC_EXCEPTIONS
    816 
    817     return 0;
    818 }
    819 
    820 bool AccessibilityUIElement::ariaIsGrabbed() const
    821 {
    822     BEGIN_AX_OBJC_EXCEPTIONS
    823     id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute];
    824     if ([value isKindOfClass:[NSNumber class]])
    825         return [value boolValue];
    826     END_AX_OBJC_EXCEPTIONS
    827 
    828     return false;
    829 }
    830 
    831 JSStringRef AccessibilityUIElement::ariaDropEffects() const
    832 {
    833     BEGIN_AX_OBJC_EXCEPTIONS
    834     id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute];
    835     if (![value isKindOfClass:[NSArray class]])
    836         return 0;
    837 
    838     NSMutableString* dropEffects = [NSMutableString string];
    839     NSInteger length = [value count];
    840     for (NSInteger k = 0; k < length; ++k) {
    841         [dropEffects appendString:[value objectAtIndex:k]];
    842         if (k < length - 1)
    843             [dropEffects appendString:@","];
    844     }
    845 
    846     return [dropEffects createJSStringRef];
    847     END_AX_OBJC_EXCEPTIONS
    848 
    849     return 0;
    850 }
    851 
    852 // parameterized attributes
    853 int AccessibilityUIElement::lineForIndex(int index)
    854 {
    855     BEGIN_AX_OBJC_EXCEPTIONS
    856     id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]];
    857     if ([value isKindOfClass:[NSNumber class]])
    858         return [(NSNumber *)value intValue];
    859     END_AX_OBJC_EXCEPTIONS
    860 
    861     return -1;
    862 }
    863 
    864 JSStringRef AccessibilityUIElement::rangeForLine(int line)
    865 {
    866     BEGIN_AX_OBJC_EXCEPTIONS
    867     id value = [m_element accessibilityAttributeValue:NSAccessibilityRangeForLineParameterizedAttribute forParameter:[NSNumber numberWithInt:line]];
    868     if ([value isKindOfClass:[NSValue class]]) {
    869         return [NSStringFromRange([value rangeValue]) createJSStringRef];
    870     }
    871     END_AX_OBJC_EXCEPTIONS
    872 
    873     return 0;
    874 }
    875 
    876 JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
    877 {
    878     NSRange range = NSMakeRange(location, length);
    879     BEGIN_AX_OBJC_EXCEPTIONS
    880     id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
    881     NSRect rect = NSMakeRect(0,0,0,0);
    882     if ([value isKindOfClass:[NSValue class]])
    883         rect = [value rectValue];
    884 
    885     // don't return position information because it is platform dependent
    886     NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height];
    887     return [boundsDescription createJSStringRef];
    888     END_AX_OBJC_EXCEPTIONS
    889 
    890     return 0;
    891 }
    892 
    893 JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length)
    894 {
    895     NSRange range = NSMakeRange(location, length);
    896     BEGIN_AX_OBJC_EXCEPTIONS
    897     id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
    898     if (![string isKindOfClass:[NSString class]])
    899         return 0;
    900 
    901     return [string createJSStringRef];
    902     END_AX_OBJC_EXCEPTIONS
    903 
    904     return 0;
    905 }
    906 
    907 JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned location, unsigned length)
    908 {
    909     NSRange range = NSMakeRange(location, length);
    910     BEGIN_AX_OBJC_EXCEPTIONS
    911     NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
    912     if (![string isKindOfClass:[NSAttributedString class]])
    913         return 0;
    914 
    915     NSString* stringWithAttrs = [string description];
    916     return [stringWithAttrs createJSStringRef];
    917     END_AX_OBJC_EXCEPTIONS
    918 
    919     return 0;
    920 }
    921 
    922 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
    923 {
    924     NSRange range = NSMakeRange(location, length);
    925     BEGIN_AX_OBJC_EXCEPTIONS
    926     NSAttributedString* string = [m_element accessibilityAttributeValue:NSAccessibilityAttributedStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]];
    927     if (![string isKindOfClass:[NSAttributedString class]])
    928         return false;
    929 
    930     NSDictionary* attrs = [string attributesAtIndex:0 effectiveRange:nil];
    931     if([[attrs objectForKey:NSAccessibilityMisspelledTextAttribute] boolValue])
    932         return true;
    933     END_AX_OBJC_EXCEPTIONS
    934 
    935     return false;
    936 }
    937 
    938 JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
    939 {
    940     // not yet defined in AppKit... odd
    941     BEGIN_AX_OBJC_EXCEPTIONS
    942     NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
    943     Vector<AccessibilityUIElement> columnHeadersVector;
    944     convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
    945     return descriptionOfElements(columnHeadersVector);
    946     END_AX_OBJC_EXCEPTIONS
    947 
    948     return 0;
    949 }
    950 
    951 JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
    952 {
    953     BEGIN_AX_OBJC_EXCEPTIONS
    954     NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
    955     Vector<AccessibilityUIElement> rowHeadersVector;
    956     convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
    957     return descriptionOfElements(rowHeadersVector);
    958     END_AX_OBJC_EXCEPTIONS
    959 
    960     return 0;
    961 }
    962 
    963 JSStringRef AccessibilityUIElement::attributesOfColumns()
    964 {
    965     BEGIN_AX_OBJC_EXCEPTIONS
    966     NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
    967     Vector<AccessibilityUIElement> columnsVector;
    968     convertNSArrayToVector(columnsArray, columnsVector);
    969     return descriptionOfElements(columnsVector);
    970     END_AX_OBJC_EXCEPTIONS
    971 
    972     return 0;
    973 }
    974 
    975 JSStringRef AccessibilityUIElement::attributesOfRows()
    976 {
    977     BEGIN_AX_OBJC_EXCEPTIONS
    978     NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
    979     Vector<AccessibilityUIElement> rowsVector;
    980     convertNSArrayToVector(rowsArray, rowsVector);
    981     return descriptionOfElements(rowsVector);
    982     END_AX_OBJC_EXCEPTIONS
    983 
    984     return 0;
    985 }
    986 
    987 JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
    988 {
    989     BEGIN_AX_OBJC_EXCEPTIONS
    990     NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
    991     Vector<AccessibilityUIElement> cellsVector;
    992     convertNSArrayToVector(cellsArray, cellsVector);
    993     return descriptionOfElements(cellsVector);
    994     END_AX_OBJC_EXCEPTIONS
    995 
    996     return 0;
    997 }
    998 
    999 JSStringRef AccessibilityUIElement::attributesOfHeader()
   1000 {
   1001     BEGIN_AX_OBJC_EXCEPTIONS
   1002     id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute];
   1003     if (!headerObject)
   1004         return [@"" createJSStringRef];
   1005 
   1006     Vector<AccessibilityUIElement> headerVector;
   1007     headerVector.append(headerObject);
   1008     return descriptionOfElements(headerVector);
   1009     END_AX_OBJC_EXCEPTIONS
   1010 
   1011     return 0;
   1012 }
   1013 
   1014 int AccessibilityUIElement::rowCount()
   1015 {
   1016     BEGIN_AX_OBJC_EXCEPTIONS
   1017     return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute];
   1018     END_AX_OBJC_EXCEPTIONS
   1019 
   1020     return 0;
   1021 }
   1022 
   1023 int AccessibilityUIElement::columnCount()
   1024 {
   1025     BEGIN_AX_OBJC_EXCEPTIONS
   1026     return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute];
   1027     END_AX_OBJC_EXCEPTIONS
   1028 
   1029     return 0;
   1030 }
   1031 
   1032 int AccessibilityUIElement::indexInTable()
   1033 {
   1034     BEGIN_AX_OBJC_EXCEPTIONS
   1035     NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
   1036     if (indexNumber)
   1037         return [indexNumber intValue];
   1038     END_AX_OBJC_EXCEPTIONS
   1039 
   1040     return -1;
   1041 }
   1042 
   1043 JSStringRef AccessibilityUIElement::rowIndexRange()
   1044 {
   1045     NSRange range = NSMakeRange(0,0);
   1046     BEGIN_AX_OBJC_EXCEPTIONS
   1047     NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"];
   1048     if (indexRange)
   1049         range = [indexRange rangeValue];
   1050     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
   1051     return [rangeDescription createJSStringRef];
   1052     END_AX_OBJC_EXCEPTIONS
   1053 
   1054     return 0;
   1055 }
   1056 
   1057 JSStringRef AccessibilityUIElement::columnIndexRange()
   1058 {
   1059     NSRange range = NSMakeRange(0,0);
   1060     BEGIN_AX_OBJC_EXCEPTIONS
   1061     NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"];
   1062     if (indexRange)
   1063         range = [indexRange rangeValue];
   1064     NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
   1065     return [rangeDescription createJSStringRef];
   1066     END_AX_OBJC_EXCEPTIONS
   1067 
   1068     return 0;
   1069 }
   1070 
   1071 AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row)
   1072 {
   1073     NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil];
   1074     BEGIN_AX_OBJC_EXCEPTIONS
   1075     return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray];
   1076     END_AX_OBJC_EXCEPTIONS
   1077 
   1078     return 0;
   1079 }
   1080 
   1081 JSStringRef AccessibilityUIElement::selectedTextRange()
   1082 {
   1083     NSRange range = NSMakeRange(NSNotFound, 0);
   1084     BEGIN_AX_OBJC_EXCEPTIONS
   1085     NSValue *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute];
   1086     if (indexRange)
   1087         range = [indexRange rangeValue];
   1088     NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length];
   1089     return [rangeDescription createJSStringRef];
   1090     END_AX_OBJC_EXCEPTIONS
   1091 
   1092     return 0;
   1093 }
   1094 
   1095 void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
   1096 {
   1097     NSRange textRange = NSMakeRange(location, length);
   1098     NSValue *textRangeValue = [NSValue valueWithRange:textRange];
   1099     BEGIN_AX_OBJC_EXCEPTIONS
   1100     [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute];
   1101     END_AX_OBJC_EXCEPTIONS
   1102 }
   1103 
   1104 void AccessibilityUIElement::increment()
   1105 {
   1106     BEGIN_AX_OBJC_EXCEPTIONS
   1107     [m_element accessibilityPerformAction:NSAccessibilityIncrementAction];
   1108     END_AX_OBJC_EXCEPTIONS
   1109 }
   1110 
   1111 void AccessibilityUIElement::decrement()
   1112 {
   1113     BEGIN_AX_OBJC_EXCEPTIONS
   1114     [m_element accessibilityPerformAction:NSAccessibilityDecrementAction];
   1115     END_AX_OBJC_EXCEPTIONS
   1116 }
   1117 
   1118 void AccessibilityUIElement::showMenu()
   1119 {
   1120     BEGIN_AX_OBJC_EXCEPTIONS
   1121     [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction];
   1122     END_AX_OBJC_EXCEPTIONS
   1123 }
   1124 
   1125 void AccessibilityUIElement::press()
   1126 {
   1127     BEGIN_AX_OBJC_EXCEPTIONS
   1128     [m_element accessibilityPerformAction:NSAccessibilityPressAction];
   1129     END_AX_OBJC_EXCEPTIONS
   1130 }
   1131 
   1132 void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
   1133 {
   1134     BEGIN_AX_OBJC_EXCEPTIONS
   1135     NSArray* array = [NSArray arrayWithObject:element->platformUIElement()];
   1136     [m_element accessibilitySetValue:array forAttribute:NSAccessibilitySelectedChildrenAttribute];
   1137     END_AX_OBJC_EXCEPTIONS
   1138 }
   1139 
   1140 JSStringRef AccessibilityUIElement::accessibilityValue() const
   1141 {
   1142     // FIXME: implement
   1143     return JSStringCreateWithCharacters(0, 0);
   1144 }
   1145 
   1146 JSStringRef AccessibilityUIElement::documentEncoding()
   1147 {
   1148     return JSStringCreateWithCharacters(0, 0);
   1149 }
   1150 
   1151 JSStringRef AccessibilityUIElement::documentURI()
   1152 {
   1153     return JSStringCreateWithCharacters(0, 0);
   1154 }
   1155 
   1156 JSStringRef AccessibilityUIElement::url()
   1157 {
   1158     BEGIN_AX_OBJC_EXCEPTIONS
   1159     NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute];
   1160     return [[url absoluteString] createJSStringRef];
   1161     END_AX_OBJC_EXCEPTIONS
   1162 
   1163     return nil;
   1164 }
   1165 
   1166 bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
   1167 {
   1168     if (!functionCallback)
   1169         return false;
   1170 
   1171     // Mac programmers should not be adding more than one notification listener per element.
   1172     // Other platforms may be different.
   1173     if (m_notificationHandler)
   1174         return false;
   1175     m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()];
   1176     [m_notificationHandler setCallback:functionCallback];
   1177 
   1178     return true;
   1179 }
   1180 
   1181 void AccessibilityUIElement::removeNotificationListener()
   1182 {
   1183     // Mac programmers should not be trying to remove a listener that's already removed.
   1184     ASSERT(m_notificationHandler);
   1185 
   1186     [m_notificationHandler release];
   1187     m_notificationHandler = nil;
   1188 }
   1189 
   1190 bool AccessibilityUIElement::isFocusable() const
   1191 {
   1192     // FIXME: implement
   1193     return false;
   1194 }
   1195 
   1196 bool AccessibilityUIElement::isSelectable() const
   1197 {
   1198     // FIXME: implement
   1199     return false;
   1200 }
   1201 
   1202 bool AccessibilityUIElement::isMultiSelectable() const
   1203 {
   1204     // FIXME: implement
   1205     return false;
   1206 }
   1207 
   1208 bool AccessibilityUIElement::isVisible() const
   1209 {
   1210     // FIXME: implement
   1211     return false;
   1212 }
   1213 
   1214 bool AccessibilityUIElement::isOffScreen() const
   1215 {
   1216     // FIXME: implement
   1217     return false;
   1218 }
   1219 
   1220 bool AccessibilityUIElement::isCollapsed() const
   1221 {
   1222     // FIXME: implement
   1223     return false;
   1224 }
   1225 
   1226 bool AccessibilityUIElement::isIgnored() const
   1227 {
   1228     BOOL result = NO;
   1229     BEGIN_AX_OBJC_EXCEPTIONS
   1230     result = [m_element accessibilityIsIgnored];
   1231     END_AX_OBJC_EXCEPTIONS
   1232     return result;
   1233 }
   1234 
   1235 bool AccessibilityUIElement::hasPopup() const
   1236 {
   1237     BEGIN_AX_OBJC_EXCEPTIONS
   1238     id value = [m_element accessibilityAttributeValue:@"AXHasPopup"];
   1239     if ([value isKindOfClass:[NSNumber class]])
   1240         return [value boolValue];
   1241     END_AX_OBJC_EXCEPTIONS
   1242 
   1243     return false;
   1244 }
   1245 
   1246 void AccessibilityUIElement::takeFocus()
   1247 {
   1248     // FIXME: implement
   1249 }
   1250 
   1251 void AccessibilityUIElement::takeSelection()
   1252 {
   1253     // FIXME: implement
   1254 }
   1255 
   1256 void AccessibilityUIElement::addSelection()
   1257 {
   1258     // FIXME: implement
   1259 }
   1260 
   1261 void AccessibilityUIElement::removeSelection()
   1262 {
   1263     // FIXME: implement
   1264 }
   1265 
   1266 #if SUPPORTS_AX_TEXTMARKERS
   1267 
   1268 // Text markers
   1269 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
   1270 {
   1271     BEGIN_AX_OBJC_EXCEPTIONS
   1272     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUIElement" forParameter:element->platformUIElement()];
   1273     return AccessibilityTextMarkerRange(textMarkerRange);
   1274     END_AX_OBJC_EXCEPTIONS
   1275 
   1276     return 0;
   1277 }
   1278 
   1279 int AccessibilityUIElement::textMarkerRangeLength(AccessibilityTextMarkerRange* range)
   1280 {
   1281     BEGIN_AX_OBJC_EXCEPTIONS
   1282     NSNumber* lengthValue = [m_element accessibilityAttributeValue:@"AXLengthForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
   1283     return [lengthValue intValue];
   1284     END_AX_OBJC_EXCEPTIONS
   1285 
   1286     return 0;
   1287 }
   1288 
   1289 
   1290 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker)
   1291 {
   1292     BEGIN_AX_OBJC_EXCEPTIONS
   1293     NSArray* textMarkers = [NSArray arrayWithObjects:(id)startMarker->platformTextMarker(), (id)endMarker->platformTextMarker(), nil];
   1294     id textMarkerRange = [m_element accessibilityAttributeValue:@"AXTextMarkerRangeForUnorderedTextMarkers" forParameter:textMarkers];
   1295     return AccessibilityTextMarkerRange(textMarkerRange);
   1296     END_AX_OBJC_EXCEPTIONS
   1297 
   1298     return 0;
   1299 }
   1300 
   1301 AccessibilityTextMarker AccessibilityUIElement::startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
   1302 {
   1303     BEGIN_AX_OBJC_EXCEPTIONS
   1304     id textMarker = [m_element accessibilityAttributeValue:@"AXStartTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
   1305     return AccessibilityTextMarker(textMarker);
   1306     END_AX_OBJC_EXCEPTIONS
   1307 
   1308     return 0;
   1309 }
   1310 
   1311 AccessibilityTextMarker AccessibilityUIElement::endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange* range)
   1312 {
   1313     BEGIN_AX_OBJC_EXCEPTIONS
   1314     id textMarker = [m_element accessibilityAttributeValue:@"AXEndTextMarkerForTextMarkerRange" forParameter:(id)range->platformTextMarkerRange()];
   1315     return AccessibilityTextMarker(textMarker);
   1316     END_AX_OBJC_EXCEPTIONS
   1317 
   1318     return 0;
   1319 }
   1320 
   1321 AccessibilityTextMarker AccessibilityUIElement::textMarkerForPoint(int x, int y)
   1322 {
   1323     BEGIN_AX_OBJC_EXCEPTIONS
   1324     id textMarker = [m_element accessibilityAttributeValue:@"AXTextMarkerForPosition" forParameter:[NSValue valueWithPoint:NSMakePoint(x, y)]];
   1325     return AccessibilityTextMarker(textMarker);
   1326     END_AX_OBJC_EXCEPTIONS
   1327 
   1328     return 0;
   1329 }
   1330 
   1331 AccessibilityUIElement AccessibilityUIElement::accessibilityElementForTextMarker(AccessibilityTextMarker* marker)
   1332 {
   1333     BEGIN_AX_OBJC_EXCEPTIONS
   1334     id uiElement = [m_element accessibilityAttributeValue:@"AXUIElementForTextMarker" forParameter:(id)marker->platformTextMarker()];
   1335     return AccessibilityUIElement(uiElement);
   1336     END_AX_OBJC_EXCEPTIONS
   1337 
   1338     return 0;
   1339 }
   1340 
   1341 #endif // SUPPORTS_AX_TEXTMARKERS
   1342