diff -r 4f2f89ce4247 -r 303757a437d3 WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm Fri Sep 17 09:02:29 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1161 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "DumpRenderTree.h" -#import "AccessibilityUIElement.h" - -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#ifdef BUILDING_ON_TIGER -#define NSAccessibilityValueDescriptionAttribute @"AXValueDescription" -#endif - -#ifndef NSAccessibilityOwnsAttribute -#define NSAccessibilityOwnsAttribute @"AXOwns" -#endif - -#ifndef NSAccessibilityGrabbedAttribute -#define NSAccessibilityGrabbedAttribute @"AXGrabbed" -#endif - -#ifndef NSAccessibilityDropEffectsAttribute -#define NSAccessibilityDropEffectsAttribute @"AXDropEffects" -#endif - -// If an unsupported attribute is passed in, it will raise an accessibility exception. These are usually caught by the Accessibility Runtime to inform -// the AX client app of the error. However, DRT is the AX client app, so it must catch these exceptions. -#define BEGIN_AX_OBJC_EXCEPTIONS @try { -#define END_AX_OBJC_EXCEPTIONS } @catch(NSException *e) { if (![[e name] isEqualToString:NSAccessibilityException]) @throw; } - - -typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, void* context); - -@interface NSObject (WebKitAccessibilityAdditions) -- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount; -- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost; -- (NSUInteger)accessibilityIndexOfChild:(id)child; -- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute; -@end - -@interface NSString (JSStringRefAdditions) -+ (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef; -- (JSStringRef)createJSStringRef; -@end - -@implementation NSString (JSStringRefAdditions) - -+ (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef -{ - if (!jsStringRef) - return NULL; - - CFStringRef cfString = JSStringCopyCFString(kCFAllocatorDefault, jsStringRef); - return [(NSString *)cfString autorelease]; -} - -- (JSStringRef)createJSStringRef -{ - return JSStringCreateWithCFString((CFStringRef)self); -} - -@end - -@interface AccessibilityNotificationHandler : NSObject -{ - id m_platformElement; - JSObjectRef m_notificationFunctionCallback; -} - -@end - -@implementation AccessibilityNotificationHandler - -- (id)initWithPlatformElement:(id)platformElement -{ - self = [super init]; - - m_platformElement = platformElement; - - // Once an object starts requesting notifications, it's on for the duration of the program. - // This is to avoid any race conditions between tests turning this flag on and off. Instead - // AccessibilityNotificationHandler can just listen when they want to. - [m_platformElement accessibilitySetShouldRepostNotifications:YES]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil]; - - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); - m_notificationFunctionCallback = 0; - - [super dealloc]; -} - -- (void)_notificationReceived:(NSNotification *)notification -{ - NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"]; - if (!notificationName) - return; - - JSRetainPtr jsNotification(Adopt, [notificationName createJSStringRef]); - JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get()); - JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &argument, 0); -} - -- (void)setCallback:(JSObjectRef)callback -{ - if (!callback) - return; - - // Release the old callback. - if (m_notificationFunctionCallback) - JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback); - - m_notificationFunctionCallback = callback; - JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback); -} - -@end - -AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) - : m_element(element) - , m_notificationHandler(0) -{ - // FIXME: ap@webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac. - [m_element retain]; -} - -AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) - : m_element(other.m_element) - , m_notificationHandler(0) -{ - [m_element retain]; -} - -AccessibilityUIElement::~AccessibilityUIElement() -{ - // The notification handler should be nil because removeNotificationListener() should have been called in the test. - ASSERT(!m_notificationHandler); - [m_element release]; -} - -static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject) -{ - if (!valueObject) - return NULL; - - if ([valueObject isKindOfClass:[NSArray class]]) - return [NSString stringWithFormat:@"", [(NSArray*)valueObject count]]; - - if ([valueObject isKindOfClass:[NSNumber class]]) - return [(NSNumber*)valueObject stringValue]; - - if ([valueObject isKindOfClass:[NSValue class]]) { - NSString* type = [NSString stringWithCString:[valueObject objCType] encoding:NSASCIIStringEncoding]; - NSValue* value = (NSValue*)valueObject; - if ([type rangeOfString:@"NSRect"].length > 0) - return [NSString stringWithFormat:@"NSRect: %@", NSStringFromRect([value rectValue])]; - if ([type rangeOfString:@"NSPoint"].length > 0) - return [NSString stringWithFormat:@"NSPoint: %@", NSStringFromPoint([value pointValue])]; - if ([type rangeOfString:@"NSSize"].length > 0) - return [NSString stringWithFormat:@"NSSize: %@", NSStringFromSize([value sizeValue])]; - if ([type rangeOfString:@"NSRange"].length > 0) - return [NSString stringWithFormat:@"NSRange: %@", NSStringFromRange([value rangeValue])]; - } - - // Strip absolute URL paths - NSString* description = [valueObject description]; - NSRange range = [description rangeOfString:@"LayoutTests"]; - if (range.length) - return [description substringFromIndex:range.location]; - - // Strip pointer locations - if ([description rangeOfString:@"0x"].length) { - NSString* role = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityRoleAttribute]; - NSString* title = [focusedAccessibilityObject accessibilityAttributeValue:NSAccessibilityTitleAttribute]; - if ([title length]) - return [NSString stringWithFormat:@"<%@: '%@'>", role, title]; - return [NSString stringWithFormat:@"<%@>", role]; - } - - return [valueObject description]; -} - -static NSString* attributesOfElement(id accessibilityObject) -{ - NSArray* supportedAttributes = [accessibilityObject accessibilityAttributeNames]; - - NSMutableString* attributesString = [NSMutableString string]; - for (NSUInteger i = 0; i < [supportedAttributes count]; ++i) { - NSString* attribute = [supportedAttributes objectAtIndex:i]; - - // Right now, position provides useless and screen-specific information, so we do not - // want to include it for the sake of universally passing tests. - if ([attribute isEqualToString:@"AXPosition"]) - continue; - - // accessibilityAttributeValue: can throw an if an attribute is not returned. - // For DumpRenderTree's purpose, we should ignore those exceptions - BEGIN_AX_OBJC_EXCEPTIONS - id valueObject = [accessibilityObject accessibilityAttributeValue:attribute]; - NSString* value = descriptionOfValue(valueObject, accessibilityObject); - [attributesString appendFormat:@"%@: %@\n", attribute, value]; - END_AX_OBJC_EXCEPTIONS - } - - return attributesString; -} - -static JSStringRef concatenateAttributeAndValue(NSString* attribute, NSString* value) -{ - Vector buffer([attribute length]); - [attribute getCharacters:buffer.data()]; - buffer.append(':'); - buffer.append(' '); - - Vector valueBuffer([value length]); - [value getCharacters:valueBuffer.data()]; - buffer.append(valueBuffer); - - return JSStringCreateWithCharacters(buffer.data(), buffer.size()); -} - -static void convertNSArrayToVector(NSArray* array, Vector& elementVector) -{ - NSUInteger count = [array count]; - for (NSUInteger i = 0; i < count; ++i) - elementVector.append(AccessibilityUIElement([array objectAtIndex:i])); -} - -static JSStringRef descriptionOfElements(Vector& elementVector) -{ - NSMutableString* allElementString = [NSMutableString string]; - size_t size = elementVector.size(); - for (size_t i = 0; i < size; ++i) { - NSString* attributes = attributesOfElement(elementVector[i].platformUIElement()); - [allElementString appendFormat:@"%@\n------------\n", attributes]; - } - - return [allElementString createJSStringRef]; -} - -void AccessibilityUIElement::getLinkedUIElements(Vector& elementVector) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; - convertNSArrayToVector(linkedElements, elementVector); - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::getDocumentLinks(Vector& elementVector) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"]; - convertNSArrayToVector(linkElements, elementVector); - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::getChildren(Vector& elementVector) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute]; - convertNSArrayToVector(children, elementVector); - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::getChildrenWithRange(Vector& elementVector, unsigned location, unsigned length) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length]; - convertNSArrayToVector(children, elementVector); - END_AX_OBJC_EXCEPTIONS -} - -int AccessibilityUIElement::childrenCount() -{ - Vector children; - getChildren(children); - - return children.size(); -} - -AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y) -{ - id element = [m_element accessibilityHitTest:NSMakePoint(x, y)]; - if (!element) - return nil; - - return AccessibilityUIElement(element); -} - -unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element) -{ - return [m_element accessibilityIndexOfChild:element->platformUIElement()]; -} - -AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index) -{ - Vector children; - getChildrenWithRange(children, index, 1); - - if (children.size() == 1) - return children[0]; - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; - if (index < [objects count]) - return [objects objectAtIndex:index]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityOwnsAttribute]; - if (index < [objects count]) - return [objects objectAtIndex:index]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* objects = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute]; - if (index < [objects count]) - return [objects objectAtIndex:index]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedRowsAttribute]; - if (index < [rows count]) - return [rows objectAtIndex:index]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* rows = [m_element accessibilityAttributeValue:NSAccessibilitySelectedRowsAttribute]; - if (index < [rows count]) - return [rows objectAtIndex:index]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::titleUIElement() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityTitleUIElementAttribute]; - if (accessibilityObject) - return AccessibilityUIElement(accessibilityObject); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::parentElement() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityParentAttribute]; - if (accessibilityObject) - return AccessibilityUIElement(accessibilityObject); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::disclosedByRow() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id accessibilityObject = [m_element accessibilityAttributeValue:NSAccessibilityDisclosedByRowAttribute]; - if (accessibilityObject) - return AccessibilityUIElement(accessibilityObject); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements() -{ - Vector linkedElements; - getLinkedUIElements(linkedElements); - return descriptionOfElements(linkedElements); -} - -JSStringRef AccessibilityUIElement::attributesOfDocumentLinks() -{ - Vector linkElements; - getDocumentLinks(linkElements); - return descriptionOfElements(linkElements); -} - -JSStringRef AccessibilityUIElement::attributesOfChildren() -{ - Vector children; - getChildren(children); - return descriptionOfElements(children); -} - -JSStringRef AccessibilityUIElement::allAttributes() -{ - NSString* attributes = attributesOfElement(m_element); - return [attributes createJSStringRef]; -} - -JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute) -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; - if ([value isKindOfClass:[NSString class]]) - return [value createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute) -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute) -{ - BEGIN_AX_OBJC_EXCEPTIONS - return [m_element accessibilityIsAttributeSettable:[NSString stringWithJSStringRef:attribute]]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) -{ - BEGIN_AX_OBJC_EXCEPTIONS - return [[m_element accessibilityAttributeNames] containsObject:[NSString stringWithJSStringRef:attribute]]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -JSStringRef AccessibilityUIElement::parameterizedAttributeNames() -{ - NSArray* supportedParameterizedAttributes = [m_element accessibilityParameterizedAttributeNames]; - - NSMutableString* attributesString = [NSMutableString string]; - for (NSUInteger i = 0; i < [supportedParameterizedAttributes count]; ++i) { - [attributesString appendFormat:@"%@\n", [supportedParameterizedAttributes objectAtIndex:i]]; - } - - return [attributesString createJSStringRef]; -} - -JSStringRef AccessibilityUIElement::role() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSString *role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleAttribute], m_element); - return concatenateAttributeAndValue(@"AXRole", role); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::subrole() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilitySubroleAttribute], m_element); - return concatenateAttributeAndValue(@"AXSubrole", role); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::roleDescription() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSString* role = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityRoleDescriptionAttribute], m_element); - return concatenateAttributeAndValue(@"AXRoleDescription", role); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::title() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSString* title = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityTitleAttribute], m_element); - return concatenateAttributeAndValue(@"AXTitle", title); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::description() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityDescriptionAttribute], m_element); - return concatenateAttributeAndValue(@"AXDescription", description); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::orientation() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityOrientationAttribute], m_element); - return concatenateAttributeAndValue(@"AXOrientation", description); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::stringValue() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityValueAttribute], m_element); - return concatenateAttributeAndValue(@"AXValue", description); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::language() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id description = descriptionOfValue([m_element accessibilityAttributeValue:@"AXLanguage"], m_element); - return concatenateAttributeAndValue(@"AXLanguage", description); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::helpText() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element); - return concatenateAttributeAndValue(@"AXHelp", description); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -double AccessibilityUIElement::x() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; - return static_cast([positionValue pointValue].x); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::y() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; - return static_cast([positionValue pointValue].y); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::width() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; - return static_cast([sizeValue sizeValue].width); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::height() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* sizeValue = [m_element accessibilityAttributeValue:NSAccessibilitySizeAttribute]; - return static_cast([sizeValue sizeValue].height); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::clickPointX() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; - return static_cast([positionValue pointValue].x); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::clickPointY() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* positionValue = [m_element accessibilityAttributeValue:@"AXClickPoint"]; - return static_cast([positionValue pointValue].y); - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::intValue() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityValueAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [(NSNumber*)value doubleValue]; - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::minValue() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityMinValueAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [(NSNumber*)value doubleValue]; - END_AX_OBJC_EXCEPTIONS - - return 0.0f; -} - -double AccessibilityUIElement::maxValue() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityMaxValueAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [(NSNumber*)value doubleValue]; - END_AX_OBJC_EXCEPTIONS - - return 0.0; -} - -JSStringRef AccessibilityUIElement::valueDescription() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSString* valueDescription = [m_element accessibilityAttributeValue:NSAccessibilityValueDescriptionAttribute]; - if ([valueDescription isKindOfClass:[NSString class]]) - return [valueDescription createJSStringRef]; - - END_AX_OBJC_EXCEPTIONS - return 0; -} - -int AccessibilityUIElement::insertionPointLineNumber() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityInsertionPointLineNumberAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [(NSNumber *)value intValue]; - END_AX_OBJC_EXCEPTIONS - - return -1; -} - -bool AccessibilityUIElement::isActionSupported(JSStringRef action) -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* actions = [m_element accessibilityActionNames]; - return [actions containsObject:[NSString stringWithJSStringRef:action]]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isEnabled() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityEnabledAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isRequired() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:@"AXRequired"]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isSelected() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilitySelectedAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isExpanded() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityExpandedAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -bool AccessibilityUIElement::isChecked() const -{ - // On the Mac, intValue()==1 if a a checkable control is checked. - return intValue() == 1; -} - -int AccessibilityUIElement::hierarchicalLevel() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityDisclosureLevelAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [value intValue]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -bool AccessibilityUIElement::ariaIsGrabbed() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityGrabbedAttribute]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -JSStringRef AccessibilityUIElement::ariaDropEffects() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityDropEffectsAttribute]; - if (![value isKindOfClass:[NSArray class]]) - return 0; - - NSMutableString* dropEffects = [NSMutableString string]; - NSInteger length = [value count]; - for (NSInteger k = 0; k < length; ++k) { - [dropEffects appendString:[value objectAtIndex:k]]; - if (k < length - 1) - [dropEffects appendString:@","]; - } - - return [dropEffects createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -// parameterized attributes -int AccessibilityUIElement::lineForIndex(int index) -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:[NSNumber numberWithInt:index]]; - if ([value isKindOfClass:[NSNumber class]]) - return [(NSNumber *)value intValue]; - END_AX_OBJC_EXCEPTIONS - - return -1; -} - -JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length) -{ - NSRange range = NSMakeRange(location, length); - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:NSAccessibilityBoundsForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; - NSRect rect = NSMakeRect(0,0,0,0); - if ([value isKindOfClass:[NSValue class]]) - rect = [value rectValue]; - - // don't return position information because it is platform dependent - NSMutableString* boundsDescription = [NSMutableString stringWithFormat:@"{{%f, %f}, {%f, %f}}",-1.0f,-1.0f,rect.size.width,rect.size.height]; - return [boundsDescription createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::stringForRange(unsigned location, unsigned length) -{ - NSRange range = NSMakeRange(location, length); - BEGIN_AX_OBJC_EXCEPTIONS - id string = [m_element accessibilityAttributeValue:NSAccessibilityStringForRangeParameterizedAttribute forParameter:[NSValue valueWithRange:range]]; - if (![string isKindOfClass:[NSString class]]) - return 0; - - return [string createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfColumnHeaders() -{ - // not yet defined in AppKit... odd - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"]; - Vector columnHeadersVector; - convertNSArrayToVector(columnHeadersArray, columnHeadersVector); - return descriptionOfElements(columnHeadersVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfRowHeaders() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"]; - Vector rowHeadersVector; - convertNSArrayToVector(rowHeadersArray, rowHeadersVector); - return descriptionOfElements(rowHeadersVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfColumns() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute]; - Vector columnsVector; - convertNSArrayToVector(columnsArray, columnsVector); - return descriptionOfElements(columnsVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfRows() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute]; - Vector rowsVector; - convertNSArrayToVector(rowsArray, rowsVector); - return descriptionOfElements(rowsVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfVisibleCells() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"]; - Vector cellsVector; - convertNSArrayToVector(cellsArray, cellsVector); - return descriptionOfElements(cellsVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::attributesOfHeader() -{ - BEGIN_AX_OBJC_EXCEPTIONS - id headerObject = [m_element accessibilityAttributeValue:NSAccessibilityHeaderAttribute]; - if (!headerObject) - return [@"" createJSStringRef]; - - Vector headerVector; - headerVector.append(headerObject); - return descriptionOfElements(headerVector); - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -int AccessibilityUIElement::rowCount() -{ - BEGIN_AX_OBJC_EXCEPTIONS - return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -int AccessibilityUIElement::columnCount() -{ - BEGIN_AX_OBJC_EXCEPTIONS - return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -int AccessibilityUIElement::indexInTable() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute]; - if (indexNumber) - return [indexNumber intValue]; - END_AX_OBJC_EXCEPTIONS - - return -1; -} - -JSStringRef AccessibilityUIElement::rowIndexRange() -{ - NSRange range = NSMakeRange(0,0); - BEGIN_AX_OBJC_EXCEPTIONS - NSValue* indexRange = [m_element accessibilityAttributeValue:@"AXRowIndexRange"]; - if (indexRange) - range = [indexRange rangeValue]; - NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; - return [rangeDescription createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::columnIndexRange() -{ - NSRange range = NSMakeRange(0,0); - BEGIN_AX_OBJC_EXCEPTIONS - NSNumber* indexRange = [m_element accessibilityAttributeValue:@"AXColumnIndexRange"]; - if (indexRange) - range = [indexRange rangeValue]; - NSMutableString* rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; - return [rangeDescription createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned col, unsigned row) -{ - NSArray *colRowArray = [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:col], [NSNumber numberWithUnsignedInt:row], nil]; - BEGIN_AX_OBJC_EXCEPTIONS - return [m_element accessibilityAttributeValue:@"AXCellForColumnAndRow" forParameter:colRowArray]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -JSStringRef AccessibilityUIElement::selectedTextRange() -{ - NSRange range = NSMakeRange(NSNotFound, 0); - BEGIN_AX_OBJC_EXCEPTIONS - NSValue *indexRange = [m_element accessibilityAttributeValue:NSAccessibilitySelectedTextRangeAttribute]; - if (indexRange) - range = [indexRange rangeValue]; - NSMutableString *rangeDescription = [NSMutableString stringWithFormat:@"{%d, %d}",range.location, range.length]; - return [rangeDescription createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return 0; -} - -void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length) -{ - NSRange textRange = NSMakeRange(location, length); - NSValue *textRangeValue = [NSValue valueWithRange:textRange]; - BEGIN_AX_OBJC_EXCEPTIONS - [m_element accessibilitySetValue:textRangeValue forAttribute:NSAccessibilitySelectedTextRangeAttribute]; - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::increment() -{ - BEGIN_AX_OBJC_EXCEPTIONS - [m_element accessibilityPerformAction:NSAccessibilityIncrementAction]; - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::decrement() -{ - BEGIN_AX_OBJC_EXCEPTIONS - [m_element accessibilityPerformAction:NSAccessibilityDecrementAction]; - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::showMenu() -{ - BEGIN_AX_OBJC_EXCEPTIONS - [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction]; - END_AX_OBJC_EXCEPTIONS -} - -void AccessibilityUIElement::press() -{ - BEGIN_AX_OBJC_EXCEPTIONS - [m_element accessibilityPerformAction:NSAccessibilityPressAction]; - END_AX_OBJC_EXCEPTIONS -} - -JSStringRef AccessibilityUIElement::accessibilityValue() const -{ - // FIXME: implement - return JSStringCreateWithCharacters(0, 0); -} - -JSStringRef AccessibilityUIElement::documentEncoding() -{ - return JSStringCreateWithCharacters(0, 0); -} - -JSStringRef AccessibilityUIElement::documentURI() -{ - return JSStringCreateWithCharacters(0, 0); -} - -JSStringRef AccessibilityUIElement::url() -{ - BEGIN_AX_OBJC_EXCEPTIONS - NSURL *url = [m_element accessibilityAttributeValue:NSAccessibilityURLAttribute]; - return [[url absoluteString] createJSStringRef]; - END_AX_OBJC_EXCEPTIONS - - return nil; -} - -bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback) -{ - if (!functionCallback) - return false; - - // Mac programmers should not be adding more than one notification listener per element. - // Other platforms may be different. - if (m_notificationHandler) - return false; - m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()]; - [m_notificationHandler setCallback:functionCallback]; - - return true; -} - -void AccessibilityUIElement::removeNotificationListener() -{ - // Mac programmers should not be trying to remove a listener that's already removed. - ASSERT(m_notificationHandler); - - [m_notificationHandler release]; - m_notificationHandler = nil; -} - -bool AccessibilityUIElement::isSelectable() const -{ - // FIXME: implement - return false; -} - -bool AccessibilityUIElement::isMultiSelectable() const -{ - // FIXME: implement - return false; -} - -bool AccessibilityUIElement::isVisible() const -{ - // FIXME: implement - return false; -} - -bool AccessibilityUIElement::isOffScreen() const -{ - // FIXME: implement - return false; -} - -bool AccessibilityUIElement::isCollapsed() const -{ - // FIXME: implement - return false; -} - -bool AccessibilityUIElement::hasPopup() const -{ - BEGIN_AX_OBJC_EXCEPTIONS - id value = [m_element accessibilityAttributeValue:@"AXHasPopup"]; - if ([value isKindOfClass:[NSNumber class]]) - return [value boolValue]; - END_AX_OBJC_EXCEPTIONS - - return false; -} - -void AccessibilityUIElement::takeFocus() -{ - // FIXME: implement -} - -void AccessibilityUIElement::takeSelection() -{ - // FIXME: implement -} - -void AccessibilityUIElement::addSelection() -{ - // FIXME: implement -} - -void AccessibilityUIElement::removeSelection() -{ - // FIXME: implement -}