diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm')
-rw-r--r-- | WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm | 162 |
1 files changed, 124 insertions, 38 deletions
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm index e9361f2..a39dabb 100644 --- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm +++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm @@ -57,32 +57,11 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification, @interface NSObject (WebKitAccessibilityAdditions) - (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount; -- (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context; +- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost; - (NSUInteger)accessibilityIndexOfChild:(id)child; +- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute; @end -AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) - : m_element(element) - , m_notificationFunctionCallback(0) -{ - [m_element retain]; -} - -AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other) - : m_element(other.m_element) - , m_notificationFunctionCallback(0) -{ - [m_element retain]; -} - -AccessibilityUIElement::~AccessibilityUIElement() -{ - // Make sure that our notification callback does not stick around. - if (m_notificationFunctionCallback) - [m_element accessibilitySetPostedNotificationCallback:0 withContext:0]; - [m_element release]; -} - @interface NSString (JSStringRefAdditions) + (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef; - (JSStringRef)createJSStringRef; @@ -106,6 +85,88 @@ AccessibilityUIElement::~AccessibilityUIElement() @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<JSStringRef> 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) @@ -439,6 +500,12 @@ JSStringRef AccessibilityUIElement::language() return concatenateAttributeAndValue(@"AXLanguage", description); } +JSStringRef AccessibilityUIElement::helpText() const +{ + id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element); + return concatenateAttributeAndValue(@"AXHelp", description); +} + double AccessibilityUIElement::x() { NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute]; @@ -676,6 +743,16 @@ JSStringRef AccessibilityUIElement::attributesOfHeader() return descriptionOfElements(headerVector); } +int AccessibilityUIElement::rowCount() +{ + return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute]; +} + +int AccessibilityUIElement::columnCount() +{ + return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute]; +} + int AccessibilityUIElement::indexInTable() { NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute]; @@ -736,6 +813,11 @@ void AccessibilityUIElement::showMenu() [m_element accessibilityPerformAction:NSAccessibilityShowMenuAction]; } +void AccessibilityUIElement::press() +{ + [m_element accessibilityPerformAction:NSAccessibilityPressAction]; +} + JSStringRef AccessibilityUIElement::accessibilityValue() const { // FIXME: implement @@ -758,28 +840,30 @@ JSStringRef AccessibilityUIElement::url() return [[url absoluteString] createJSStringRef]; } -static void _accessibilityNotificationCallback(id element, NSString* notification, void* context) -{ - if (!context) - return; - - JSObjectRef functionCallback = static_cast<JSObjectRef>(context); - - JSRetainPtr<JSStringRef> jsNotification(Adopt, [notification createJSStringRef]); - JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get()); - JSObjectCallAsFunction([mainFrame globalContext], functionCallback, NULL, 1, &argument, NULL); -} - bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback) { if (!functionCallback) return false; - m_notificationFunctionCallback = functionCallback; - [platformUIElement() accessibilitySetPostedNotificationCallback:_accessibilityNotificationCallback withContext:reinterpret_cast<void*>(m_notificationFunctionCallback)]; + // 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 @@ -812,7 +896,9 @@ bool AccessibilityUIElement::isCollapsed() const bool AccessibilityUIElement::hasPopup() const { - // FIXME: implement + id value = [m_element accessibilityAttributeValue:@"AXHasPopup"]; + if ([value isKindOfClass:[NSNumber class]]) + return [value boolValue]; return false; } |