Changeset 185924 in webkit


Ignore:
Timestamp:
Jun 24, 2015 1:51:13 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Source/JavaScriptCore:
Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
when posting a selection notification when on the border between two accessibilityObjects
https://bugs.webkit.org/show_bug.cgi?id=146177

Add an adopt() function to simplify JSRetainPtr<JSStringRef> { Adopt, string } to adopt(string).

Patch by Doug Russell <d_russell@apple.com> on 2015-06-24
Reviewed by Darin Adler.

  • API/JSRetainPtr.h:

(adopt):

Source/WebCore:
Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
when posting a selection notification when on the border between two accessibilityObjects
https://bugs.webkit.org/show_bug.cgi?id=146177

Patch by Doug Russell <d_russell@apple.com> on 2015-06-24
Reviewed by Darin Adler.

Add support for position to be passed for selection changes to allow checking.
for boundaries in the case of ignored elements.
Add support for searching for unignored siblings of AccessibilityObjects.
Include AccessibilityObject wrappers in notifications for tests.

Test: platform/mac/accessibility/selection-element-tabbing-to-link.html

  • accessibility/AXObjectCache.cpp:

(WebCore::AXObjectCache::postTextStateChangeNotification):

  • accessibility/AXObjectCache.h:
  • accessibility/AccessibilityObject.cpp:

(WebCore::AccessibilityObject::previousSiblingUnignored):
(WebCore::AccessibilityObject::nextSiblingUnignored):

  • accessibility/AccessibilityObject.h:
  • accessibility/mac/WebAccessibilityObjectWrapperBase.mm:

(isValueTypeSupported):
(arrayRemovingNonSupportedTypes):
(dictionaryRemovingNonSupportedTypes):
(-[WebAccessibilityObjectWrapperBase accessibilityPostedNotification:userInfo:]):

  • editing/mac/FrameSelectionMac.mm:

(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):

Tools:
Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
when posting a selection notification when on the border between two accessibilityObjects
https://bugs.webkit.org/show_bug.cgi?id=146177

Patch by Doug Russell <d_russell@apple.com> on 2015-06-24
Reviewed by Darin Adler.

Add support for mapping WebCore Accessibility types into JSValueRef types
so they can be used in tests.

  • DumpRenderTree/mac/AccessibilityNotificationHandler.mm:

(webAccessibilityObjectWrapperClass):
(-[AccessibilityNotificationHandler startObserving]):
(makeValueRefForValue):
(makeArrayRefForArray):
(makeObjectRefForDictionary):
(-[AccessibilityNotificationHandler _notificationReceived:]):

  • WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm:

(webAccessibilityObjectWrapperClass):
(-[AccessibilityNotificationHandler startObserving]):
(makeValueRefForValue):
(makeArrayRefForArray):
(makeObjectRefForDictionary):
(-[AccessibilityNotificationHandler _notificationReceived:]):

LayoutTests:
Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
when posting a selection notification when on the border between two accessibilityObjects
https://bugs.webkit.org/show_bug.cgi?id=146177

Add test for forward and backward tabbing between links and corresponding notifications
change element

Patch by Doug Russell <d_russell@apple.com> on 2015-06-24
Reviewed by Darin Adler.

  • platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt: Added.
  • platform/mac/accessibility/selection-element-tabbing-to-link.html: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r185920 r185924  
     12015-06-24  Doug Russell  <d_russell@apple.com>
     2
     3        Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
     4        when posting a selection notification when on the border between two accessibilityObjects
     5        https://bugs.webkit.org/show_bug.cgi?id=146177
     6
     7        Add test for forward and backward tabbing between links and corresponding notifications
     8        change element
     9
     10        Reviewed by Darin Adler.
     11
     12        * platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt: Added.
     13        * platform/mac/accessibility/selection-element-tabbing-to-link.html: Added.
     14
    1152015-06-24  Keith Miller  <keith_miller@apple.com>
    216
  • trunk/Source/JavaScriptCore/API/JSRetainPtr.h

    r165676 r185924  
    7676};
    7777
     78inline JSRetainPtr<JSStringRef> adopt(JSStringRef o)
     79{
     80    return JSRetainPtr<JSStringRef>(Adopt, o);
     81}
     82
     83inline JSRetainPtr<JSGlobalContextRef> adopt(JSGlobalContextRef o)
     84{
     85    return JSRetainPtr<JSGlobalContextRef>(Adopt, o);
     86}
     87
    7888template<typename T> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr& o)
    7989    : m_ptr(o.m_ptr)
  • trunk/Source/JavaScriptCore/ChangeLog

    r185920 r185924  
     12015-06-24  Doug Russell  <d_russell@apple.com>
     2
     3        Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
     4        when posting a selection notification when on the border between two accessibilityObjects
     5        https://bugs.webkit.org/show_bug.cgi?id=146177
     6
     7        Add an adopt() function to simplify JSRetainPtr<JSStringRef> { Adopt, string } to adopt(string).
     8
     9        Reviewed by Darin Adler.
     10
     11        * API/JSRetainPtr.h:
     12        (adopt):
     13
    1142015-06-24  Keith Miller  <keith_miller@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r185923 r185924  
     12015-06-24  Doug Russell  <d_russell@apple.com>
     2
     3        Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
     4        when posting a selection notification when on the border between two accessibilityObjects
     5        https://bugs.webkit.org/show_bug.cgi?id=146177
     6
     7        Reviewed by Darin Adler.
     8
     9        Add support for position to be passed for selection changes to allow checking.
     10        for boundaries in the case of ignored elements.
     11        Add support for searching for unignored siblings of AccessibilityObjects.
     12        Include AccessibilityObject wrappers in notifications for tests.
     13
     14        Test: platform/mac/accessibility/selection-element-tabbing-to-link.html
     15
     16        * accessibility/AXObjectCache.cpp:
     17        (WebCore::AXObjectCache::postTextStateChangeNotification):
     18        * accessibility/AXObjectCache.h:
     19        * accessibility/AccessibilityObject.cpp:
     20        (WebCore::AccessibilityObject::previousSiblingUnignored):
     21        (WebCore::AccessibilityObject::nextSiblingUnignored):
     22        * accessibility/AccessibilityObject.h:
     23        * accessibility/mac/WebAccessibilityObjectWrapperBase.mm:
     24        (isValueTypeSupported):
     25        (arrayRemovingNonSupportedTypes):
     26        (dictionaryRemovingNonSupportedTypes):
     27        (-[WebAccessibilityObjectWrapperBase accessibilityPostedNotification:userInfo:]):
     28        * editing/mac/FrameSelectionMac.mm:
     29        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
     30
    1312015-06-24  Anders Carlsson  <andersca@apple.com>
    232
  • trunk/Source/WebCore/accessibility/AXObjectCache.cpp

    r185459 r185924  
    10071007    stopCachingComputedObjectAttributes();
    10081008
     1009    postTextStateChangeNotification(getOrCreate(node), intent, selection);
     1010#else
     1011    postNotification(node->renderer(), AXObjectCache::AXSelectedTextChanged, TargetObservableParent);
     1012    UNUSED_PARAM(intent);
     1013    UNUSED_PARAM(selection);
     1014#endif
     1015}
     1016
     1017void AXObjectCache::postTextStateChangeNotification(const Position& position, const AXTextStateChangeIntent& intent, const VisibleSelection& selection)
     1018{
     1019    Node* node = position.deprecatedNode();
     1020    if (!node)
     1021        return;
     1022
     1023    stopCachingComputedObjectAttributes();
     1024
     1025#if PLATFORM(COCOA)
    10091026    AccessibilityObject* object = getOrCreate(node);
     1027    if (object && object->accessibilityIsIgnored()) {
     1028        if (position.atLastEditingPositionForNode()) {
     1029            if (AccessibilityObject* nextSibling = object->nextSiblingUnignored(1))
     1030                object = nextSibling;
     1031        } else if (position.atFirstEditingPositionForNode()) {
     1032            if (AccessibilityObject* previousSibling = object->previousSiblingUnignored(1))
     1033                object = previousSibling;
     1034        }
     1035    }
     1036
     1037    postTextStateChangeNotification(object, intent, selection);
     1038#else
     1039    postTextStateChangeNotification(node, intent, selection);
     1040#endif
     1041}
     1042
     1043void AXObjectCache::postTextStateChangeNotification(AccessibilityObject* object, const AXTextStateChangeIntent& intent, const VisibleSelection& selection)
     1044{
     1045    stopCachingComputedObjectAttributes();
     1046
     1047#if PLATFORM(COCOA)
    10101048    if (object) {
    10111049        if (isPasswordFieldOrContainedByPasswordField(object))
    10121050            return;
    1013         object = object->observableObject();
     1051
     1052        if (auto observableObject = object->observableObject())
     1053            object = observableObject;
    10141054    }
    10151055
    10161056    postTextStateChangePlatformNotification(object, (intent.type == AXTextStateChangeTypeUnknown || m_isSynchronizingSelection) ? m_textSelectionIntent : intent, selection);
    10171057#else
    1018     postNotification(node->renderer(), AXObjectCache::AXSelectedTextChanged, TargetObservableParent);
     1058    UNUSED_PARAM(object);
    10191059    UNUSED_PARAM(intent);
    10201060    UNUSED_PARAM(selection);
  • trunk/Source/WebCore/accessibility/AXObjectCache.h

    r183783 r185924  
    206206    void postTextReplacementNotification(Node*, AXTextEditType deletionType, const String& deletedText, AXTextEditType insertionType, const String& insertedText, const VisiblePosition&);
    207207    void postTextStateChangeNotification(Node*, const AXTextStateChangeIntent&, const VisibleSelection&);
     208    void postTextStateChangeNotification(const Position&, const AXTextStateChangeIntent&, const VisibleSelection&);
    208209
    209210    enum AXLoadingEvent {
     
    259260
    260261    void notificationPostTimerFired();
     262
     263    void postTextStateChangeNotification(AccessibilityObject*, const AXTextStateChangeIntent&, const VisibleSelection&);
    261264
    262265    bool enqueuePasswordValueChangeNotification(AccessibilityObject*);
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r185593 r185924  
    456456   
    457457    return parent;
     458}
     459
     460AccessibilityObject* AccessibilityObject::previousSiblingUnignored(int limit) const
     461{
     462    AccessibilityObject* previous;
     463    ASSERT(limit >= 0);
     464    for (previous = previousSibling(); previous && previous->accessibilityIsIgnored(); previous = previous->previousSibling()) {
     465        limit--;
     466        if (limit <= 0)
     467            break;
     468    }
     469    return previous;
     470}
     471
     472AccessibilityObject* AccessibilityObject::nextSiblingUnignored(int limit) const
     473{
     474    AccessibilityObject* next;
     475    ASSERT(limit >= 0);
     476    for (next = nextSibling(); next && next->accessibilityIsIgnored(); next = next->nextSibling()) {
     477        limit--;
     478        if (limit <= 0)
     479            break;
     480    }
     481    return next;
    458482}
    459483
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r185558 r185924  
    646646    virtual AccessibilityObject* previousSibling() const { return nullptr; }
    647647    virtual AccessibilityObject* nextSibling() const { return nullptr; }
     648    virtual AccessibilityObject* nextSiblingUnignored(int limit) const;
     649    virtual AccessibilityObject* previousSiblingUnignored(int limit) const;
    648650    virtual AccessibilityObject* parentObject() const = 0;
    649651    virtual AccessibilityObject* parentObjectUnignored() const;
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm

    r183368 r185924  
    395395}
    396396
    397 static NSArray *arrayRemovingNonJSONTypes(NSArray *array)
     397static bool isValueTypeSupported(id value)
     398{
     399    return [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[WebAccessibilityObjectWrapperBase class]];
     400}
     401
     402static NSArray *arrayRemovingNonSupportedTypes(NSArray *array)
    398403{
    399404    ASSERT([array isKindOfClass:[NSArray class]]);
     
    402407        id value = [mutableArray objectAtIndex:i];
    403408        if ([value isKindOfClass:[NSDictionary class]])
    404             [mutableArray replaceObjectAtIndex:i withObject:dictionaryRemovingNonJSONTypes(value)];
     409            [mutableArray replaceObjectAtIndex:i withObject:dictionaryRemovingNonSupportedTypes(value)];
    405410        else if ([value isKindOfClass:[NSArray class]])
    406             [mutableArray replaceObjectAtIndex:i withObject:arrayRemovingNonJSONTypes(value)];
    407         else if (!([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]])) {
     411            [mutableArray replaceObjectAtIndex:i withObject:arrayRemovingNonSupportedTypes(value)];
     412        else if (!isValueTypeSupported(value)) {
    408413            [mutableArray removeObjectAtIndex:i];
    409414            continue;
     
    414419}
    415420
    416 static NSDictionary *dictionaryRemovingNonJSONTypes(NSDictionary *dictionary)
    417 {
     421static NSDictionary *dictionaryRemovingNonSupportedTypes(NSDictionary *dictionary)
     422{
     423    if (!dictionary)
     424        return nil;
    418425    ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
    419426    NSMutableDictionary *mutableDictionary = [dictionary mutableCopy];
     
    421428        id value = [dictionary objectForKey:key];
    422429        if ([value isKindOfClass:[NSDictionary class]])
    423             [mutableDictionary setObject:dictionaryRemovingNonJSONTypes(value) forKey:key];
     430            [mutableDictionary setObject:dictionaryRemovingNonSupportedTypes(value) forKey:key];
    424431        else if ([value isKindOfClass:[NSArray class]])
    425             [mutableDictionary setObject:arrayRemovingNonJSONTypes(value) forKey:key];
    426         else if (!([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]))
     432            [mutableDictionary setObject:arrayRemovingNonSupportedTypes(value) forKey:key];
     433        else if (!isValueTypeSupported(value))
    427434            [mutableDictionary removeObjectForKey:key];
    428435    }
     
    434441    if (accessibilityShouldRepostNotifications) {
    435442        ASSERT(notificationName);
    436         NSDictionary *info = nil;
    437         if (userInfo) {
    438             NSData *userInfoData = [NSJSONSerialization dataWithJSONObject:dictionaryRemovingNonJSONTypes(userInfo) options:(NSJSONWritingOptions)0 error:nil];
    439             if (userInfoData) {
    440                 NSString *userInfoString = [[NSString alloc] initWithData:userInfoData encoding:NSUTF8StringEncoding];
    441                 if (userInfoString)
    442                     info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @"notificationName", userInfoString, @"userInfo", nil];
    443                 [userInfoString release];
    444             }
    445         }
    446         if (!info)
    447             info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @"notificationName", nil];
     443        userInfo = dictionaryRemovingNonSupportedTypes(userInfo);
     444        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @"notificationName", userInfo, @"userInfo", nil];
    448445        [[NSNotificationCenter defaultCenter] postNotificationName:@"AXDRTNotification" object:self userInfo:info];
    449446    }
  • trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm

    r183368 r185924  
    5454    if (m_selection.start().isNotNull() && m_selection.end().isNotNull()) {
    5555        if (AXObjectCache* cache = document->existingAXObjectCache())
    56             cache->postTextStateChangeNotification(m_selection.start().deprecatedNode(), intent, m_selection);
     56            cache->postTextStateChangeNotification(m_selection.start(), intent, m_selection);
    5757    }
    5858
  • trunk/Tools/ChangeLog

    r185916 r185924  
     12015-06-24  Doug Russell  <d_russell@apple.com>
     2
     3        Bug 146177 - AX: AXObjectCache should try to use an unignored accessibilityObject
     4        when posting a selection notification when on the border between two accessibilityObjects
     5        https://bugs.webkit.org/show_bug.cgi?id=146177
     6
     7        Reviewed by Darin Adler.
     8
     9        Add support for mapping WebCore Accessibility types into JSValueRef types
     10        so they can be used in tests.
     11
     12        * DumpRenderTree/mac/AccessibilityNotificationHandler.mm:
     13        (webAccessibilityObjectWrapperClass):
     14        (-[AccessibilityNotificationHandler startObserving]):
     15        (makeValueRefForValue):
     16        (makeArrayRefForArray):
     17        (makeObjectRefForDictionary):
     18        (-[AccessibilityNotificationHandler _notificationReceived:]):
     19        * WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm:
     20        (webAccessibilityObjectWrapperClass):
     21        (-[AccessibilityNotificationHandler startObserving]):
     22        (makeValueRefForValue):
     23        (makeArrayRefForArray):
     24        (makeObjectRefForDictionary):
     25        (-[AccessibilityNotificationHandler _notificationReceived:]):
     26
    1272015-06-24  Zalan Bujtas  <zalan@apple.com>
    228
  • trunk/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm

    r183434 r185924  
    3838#import <JavaScriptCore/JSStringRefCF.h>
    3939#import <WebKit/WebFrame.h>
     40#import <objc/runtime.h>
    4041#import <wtf/RetainPtr.h>
    4142
     
    9495}
    9596
     97static Class webAccessibilityObjectWrapperClass()
     98{
     99    static Class cls = objc_getClass("WebAccessibilityObjectWrapper");
     100    ASSERT(cls);
     101    return cls;
     102}
     103
    96104- (void)startObserving
    97105{
     
    99107    // This is to avoid any race conditions between tests turning this flag on and off. Instead
    100108    // AccessibilityNotificationHandler can ignore events it doesn't care about.
    101     id webAccessibilityObjectWrapperClass = NSClassFromString(@"WebAccessibilityObjectWrapper");
    102     ASSERT(webAccessibilityObjectWrapperClass);
    103     [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
     109    [webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
    104110    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
    105111}
     
    108114{
    109115    [[NSNotificationCenter defaultCenter] removeObserver:self];
     116}
     117
     118static JSValueRef makeValueRefForValue(JSContextRef context, id value)
     119{
     120    if ([value isKindOfClass:[NSString class]])
     121        return JSValueMakeString(context, adopt([value createJSStringRef]).get());
     122    if ([value isKindOfClass:[NSNumber class]]) {
     123        if (!strcmp([value objCType], @encode(BOOL)))
     124            return JSValueMakeBoolean(context, [value boolValue]);
     125        return JSValueMakeNumber(context, [value doubleValue]);
     126    }
     127    if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
     128        return AccessibilityUIElement::makeJSAccessibilityUIElement(context, value);
     129    if ([value isKindOfClass:[NSDictionary class]])
     130        return makeObjectRefForDictionary(context, value);
     131    if ([value isKindOfClass:[NSArray class]])
     132        return makeArrayRefForArray(context, value);
     133    return nullptr;
     134}
     135
     136static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
     137{
     138    NSUInteger count = array.count;
     139    JSValueRef arguments[count];
     140
     141    for (NSUInteger i = 0; i < count; i++)
     142        arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
     143
     144    return JSObjectMakeArray(context, count, arguments, nullptr);
     145}
     146
     147static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
     148{
     149    JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
     150
     151    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop)
     152    {
     153        if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
     154            JSObjectSetProperty(context, object, adopt([key createJSStringRef]).get(), propertyValue, kJSPropertyAttributeNone, nullptr);
     155    }];
     156
     157    return object;
    110158}
    111159
     
    118166        return;
    119167
    120     NSString *userInfoJSONValue = [[notification userInfo] objectForKey:@"userInfo"];
     168    NSDictionary *userInfo = [[notification userInfo] objectForKey:@"userInfo"];
    121169
    122     JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
    123     JSValueRef notificationNameArgument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
    124     JSValueRef userInfoJSONValueArgument = nil;
    125     if ([userInfoJSONValue length]) {
    126         JSRetainPtr<JSStringRef> jsUserInfoJSONValue(Adopt, [userInfoJSONValue createJSStringRef]);
    127         userInfoJSONValueArgument = JSValueMakeFromJSONString([mainFrame globalContext], jsUserInfoJSONValue.get());
    128     }
     170    JSValueRef notificationNameArgument = JSValueMakeString([mainFrame globalContext], adopt([notificationName createJSStringRef]).get());
     171    JSValueRef userInfoArgument = makeObjectRefForDictionary([mainFrame globalContext], userInfo);
    129172    if (m_platformElement) {
    130173        // Listener for one element gets the notification name and userInfo.
    131174        JSValueRef arguments[2];
    132175        arguments[0] = notificationNameArgument;
    133         arguments[1] = userInfoJSONValueArgument;
     176        arguments[1] = userInfoArgument;
    134177        JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 2, arguments, 0);
    135178    } else {
     
    138181        arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement([mainFrame globalContext], AccessibilityUIElement([notification object]));
    139182        arguments[1] = notificationNameArgument;
    140         arguments[2] = userInfoJSONValueArgument;
     183        arguments[2] = userInfoArgument;
    141184        JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 2, arguments, 0);
    142185    }
  • trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm

    r183439 r185924  
    4040#import <JavaScriptCore/JSStringRefCF.h>
    4141#import <WebKit/WKBundleFrame.h>
     42#import <objc/runtime.h>
    4243#import <wtf/RetainPtr.h>
    4344
     
    100101    m_notificationFunctionCallback = callback;
    101102    JSValueProtect(context, m_notificationFunctionCallback);
     103}
     104
     105static Class webAccessibilityObjectWrapperClass()
     106{
     107    static Class cls = objc_getClass("WebAccessibilityObjectWrapper");
     108    ASSERT(cls);
     109    return cls;
    102110}
    103111
     
    107115    // This is to avoid any race conditions between tests turning this flag on and off. Instead
    108116    // AccessibilityNotificationHandler can ignore events it doesn't care about.
    109     id webAccessibilityObjectWrapperClass = NSClassFromString(@"WebAccessibilityObjectWrapper");
    110     ASSERT(webAccessibilityObjectWrapperClass);
    111     [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
     117    [webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
    112118    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
    113119}
     
    116122{
    117123    [[NSNotificationCenter defaultCenter] removeObserver:self];
     124}
     125
     126static JSValueRef makeValueRefForValue(JSContextRef context, id value)
     127{
     128    if ([value isKindOfClass:[NSString class]])
     129        return JSValueMakeString(context, adopt([value createJSStringRef]).get());
     130    if ([value isKindOfClass:[NSNumber class]]) {
     131        if (!strcmp([value objCType], @encode(BOOL)))
     132            return JSValueMakeBoolean(context, [value boolValue]);
     133        return JSValueMakeNumber(context, [value doubleValue]);
     134    }
     135    if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
     136        return toJS(context, WTR::AccessibilityUIElement::create(static_cast<PlatformUIElement>(value)).get());
     137    if ([value isKindOfClass:[NSDictionary class]])
     138        return makeObjectRefForDictionary(context, value);
     139    if ([value isKindOfClass:[NSArray class]])
     140        return makeArrayRefForArray(context, value);
     141    return nullptr;
     142}
     143
     144static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
     145{
     146    NSUInteger count = array.count;
     147    JSValueRef arguments[count];
     148
     149    for (NSUInteger i = 0; i < count; i++)
     150        arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
     151
     152    return JSObjectMakeArray(context, count, arguments, nullptr);
     153}
     154
     155static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
     156{
     157    JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
     158
     159    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop)
     160    {
     161        if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
     162            JSObjectSetProperty(context, object, adopt([key createJSStringRef]).get(), propertyValue, kJSPropertyAttributeNone, nullptr);
     163    }];
     164
     165    return object;
    118166}
    119167
     
    126174        return;
    127175
    128     NSString *userInfoJSONValue = [[notification userInfo] objectForKey:@"userInfo"];
     176    NSDictionary *userInfo = [[notification userInfo] objectForKey:@"userInfo"];
    129177
    130178    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::singleton().page()->page());
    131179    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
    132180
    133     JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
    134     JSValueRef notificationNameArgument = JSValueMakeString(context, jsNotification.get());
    135     JSValueRef userInfoJSONValueArgument = nil;
    136     if ([userInfoJSONValue length]) {
    137         JSRetainPtr<JSStringRef> jsUserInfoJSONValue(Adopt, [userInfoJSONValue createJSStringRef]);
    138         userInfoJSONValueArgument = JSValueMakeFromJSONString(context, jsUserInfoJSONValue.get());
    139     }
     181    JSValueRef notificationNameArgument = JSValueMakeString(context, adopt([notificationName createJSStringRef]).get());
     182    JSValueRef userInfoArgument = makeObjectRefForDictionary(context, userInfo);
    140183    if (m_platformElement) {
    141184        // Listener for one element gets the notification name and userInfo.
    142185        JSValueRef arguments[2];
    143186        arguments[0] = notificationNameArgument;
    144         arguments[1] = userInfoJSONValueArgument;
     187        arguments[1] = userInfoArgument;
    145188        JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 2, arguments, 0);
    146189    } else {
    147190        // A global listener gets the element, notification name and userInfo.
    148191        JSValueRef arguments[3];
    149         arguments[0] = toJS(context, WTF::getPtr(WTR::AccessibilityUIElement::create([notification object])));
     192        arguments[0] = toJS(context, WTR::AccessibilityUIElement::create([notification object]).get());
    150193        arguments[1] = notificationNameArgument;
    151         arguments[2] = userInfoJSONValueArgument;
    152         JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 2, arguments, 0);
     194        arguments[2] = userInfoArgument;
     195        JSObjectCallAsFunction(context, const_cast<JSObjectRef>(m_notificationFunctionCallback), 0, 3, arguments, 0);
    153196    }
    154197}
Note: See TracChangeset for help on using the changeset viewer.