<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[185924] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/185924">185924</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-06-24 13:51:13 -0700 (Wed, 24 Jun 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>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&lt;JSStringRef&gt; { Adopt, string } to adopt(string).

Patch by Doug Russell &lt;d_russell@apple.com&gt; 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 &lt;d_russell@apple.com&gt; 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 &lt;d_russell@apple.com&gt; 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 &lt;d_russell@apple.com&gt; 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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSRetainPtrh">trunk/Source/JavaScriptCore/API/JSRetainPtr.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAXObjectCachecpp">trunk/Source/WebCore/accessibility/AXObjectCache.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAXObjectCacheh">trunk/Source/WebCore/accessibility/AXObjectCache.h</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityObjectcpp">trunk/Source/WebCore/accessibility/AccessibilityObject.cpp</a></li>
<li><a href="#trunkSourceWebCoreaccessibilityAccessibilityObjecth">trunk/Source/WebCore/accessibility/AccessibilityObject.h</a></li>
<li><a href="#trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperBasemm">trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm</a></li>
<li><a href="#trunkSourceWebCoreeditingmacFrameSelectionMacmm">trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreemacAccessibilityNotificationHandlermm">trunk/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundlemacAccessibilityNotificationHandlermm">trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsplatformmacaccessibilityselectionelementtabbingtolinkexpectedtxt">trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt</a></li>
<li><a href="#trunkLayoutTestsplatformmacaccessibilityselectionelementtabbingtolinkhtml">trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/LayoutTests/ChangeLog        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-06-24  Doug Russell  &lt;d_russell@apple.com&gt;
+
+        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
+
+        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.
+
</ins><span class="cx"> 2015-06-24  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Strict Equality on objects should only check that one of the two sides is an object.
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacaccessibilityselectionelementtabbingtolinkexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt (0 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link-expected.txt        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+one two
+This tests that tabbing between links includes a relevant accessibilityObject in the userInfo when on the boundary between an ignored accessibilityObject and an unignored accessibilityObject.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS addedNotification is true
+PASS ancestorWithRole(changeElementOne, &quot;AXRole: AXLink&quot;).isEqual(linkTwo) is true
+PASS ancestorWithRole(changeElementTwo, &quot;AXRole: AXLink&quot;).isEqual(linkOne) is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacaccessibilityselectionelementtabbingtolinkhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link.html (0 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link.html                                (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/selection-element-tabbing-to-link.html        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body id=&quot;body&quot;&gt;
+
+&lt;div&gt;
+&lt;a href=&quot;&quot; id=&quot;one&quot;&gt;one&lt;/a&gt;
+&lt;a href=&quot;&quot; id=&quot;two&quot;&gt;two&lt;/a&gt;
+&lt;/div&gt;
+
+&lt;p id=&quot;description&quot;&gt;&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;notifications&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+
+    description(&quot;This tests that tabbing between links includes a relevant accessibilityObject in the userInfo when on the boundary between an ignored accessibilityObject and an unignored accessibilityObject.&quot;);
+
+    var axTextChangeElement = 0;
+    var webArea = 0;
+    var changeElementOne = 0;
+    var changeElementTwo = 0;
+    var linkTwo = 0;
+    var linkOne = 0;
+    var count = 0;
+
+    function ancestorWithRole(axElement, role) {
+        var ancestor = axElement;
+        while (ancestor) {
+            if (ancestor.role == role)
+                break;
+            ancestor = ancestor.parentElement();
+        }
+        return ancestor;
+    }
+
+    function notificationCallback(notification, userInfo) {
+        if (notification == &quot;AXSelectedTextChanged&quot;) {
+            count++;
+            if (count == 1) {
+                changeElementOne = userInfo[&quot;AXTextChangeElement&quot;];
+                linkTwo = accessibilityController.accessibleElementById(&quot;two&quot;);
+                shouldBe(&quot;ancestorWithRole(changeElementOne, \&quot;AXRole: AXLink\&quot;).isEqual(linkTwo)&quot;, &quot;true&quot;);
+            } else if (count == 2) {
+                changeElementTwo = userInfo[&quot;AXTextChangeElement&quot;];
+                linkOne = accessibilityController.accessibleElementById(&quot;one&quot;);
+                shouldBe(&quot;ancestorWithRole(changeElementTwo, \&quot;AXRole: AXLink\&quot;).isEqual(linkOne)&quot;, &quot;true&quot;);
+                webArea.removeNotificationListener();
+                testRunner.notifyDone();
+            }
+        }
+    }
+
+    if (window.accessibilityController) {
+        testRunner.waitUntilDone();
+        testRunner.overridePreference(&quot;WebKitTabToLinksPreferenceKey&quot;, 1);
+
+        accessibilityController.enableEnhancedAccessibility(true);
+        webArea = accessibilityController.rootElement.childAtIndex(0);
+        webArea.setBoolAttributeValue(&quot;AXCaretBrowsingEnabled&quot;, true)
+
+        link = document.getElementById(&quot;one&quot;);
+        link.focus();
+
+        var addedNotification = webArea.addNotificationListener(notificationCallback);
+        shouldBe(&quot;addedNotification&quot;, &quot;true&quot;);
+
+        eventSender.keyDown(&quot;\t&quot;);
+        eventSender.keyDown(&quot;\t&quot;, [&quot;shiftKey&quot;]);
+    }
+
+&lt;/script&gt;
+
+&lt;script src=&quot;../../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSRetainPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSRetainPtr.h (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSRetainPtr.h        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/JavaScriptCore/API/JSRetainPtr.h        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -75,6 +75,16 @@
</span><span class="cx">     T m_ptr;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+inline JSRetainPtr&lt;JSStringRef&gt; adopt(JSStringRef o)
+{
+    return JSRetainPtr&lt;JSStringRef&gt;(Adopt, o);
+}
+
+inline JSRetainPtr&lt;JSGlobalContextRef&gt; adopt(JSGlobalContextRef o)
+{
+    return JSRetainPtr&lt;JSGlobalContextRef&gt;(Adopt, o);
+}
+
</ins><span class="cx"> template&lt;typename T&gt; inline JSRetainPtr&lt;T&gt;::JSRetainPtr(const JSRetainPtr&amp; o)
</span><span class="cx">     : m_ptr(o.m_ptr)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2015-06-24  Doug Russell  &lt;d_russell@apple.com&gt;
+
+        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&lt;JSStringRef&gt; { Adopt, string } to adopt(string).
+
+        Reviewed by Darin Adler.
+
+        * API/JSRetainPtr.h:
+        (adopt):
+
</ins><span class="cx"> 2015-06-24  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Strict Equality on objects should only check that one of the two sides is an object.
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/ChangeLog        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2015-06-24  Doug Russell  &lt;d_russell@apple.com&gt;
+
+        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
+
+        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):
+
</ins><span class="cx"> 2015-06-24  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Enable -Winconsistent-missing-override when building with Xcode
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAXObjectCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -1006,16 +1006,56 @@
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     stopCachingComputedObjectAttributes();
</span><span class="cx"> 
</span><ins>+    postTextStateChangeNotification(getOrCreate(node), intent, selection);
+#else
+    postNotification(node-&gt;renderer(), AXObjectCache::AXSelectedTextChanged, TargetObservableParent);
+    UNUSED_PARAM(intent);
+    UNUSED_PARAM(selection);
+#endif
+}
+
+void AXObjectCache::postTextStateChangeNotification(const Position&amp; position, const AXTextStateChangeIntent&amp; intent, const VisibleSelection&amp; selection)
+{
+    Node* node = position.deprecatedNode();
+    if (!node)
+        return;
+
+    stopCachingComputedObjectAttributes();
+
+#if PLATFORM(COCOA)
</ins><span class="cx">     AccessibilityObject* object = getOrCreate(node);
</span><ins>+    if (object &amp;&amp; object-&gt;accessibilityIsIgnored()) {
+        if (position.atLastEditingPositionForNode()) {
+            if (AccessibilityObject* nextSibling = object-&gt;nextSiblingUnignored(1))
+                object = nextSibling;
+        } else if (position.atFirstEditingPositionForNode()) {
+            if (AccessibilityObject* previousSibling = object-&gt;previousSiblingUnignored(1))
+                object = previousSibling;
+        }
+    }
+
+    postTextStateChangeNotification(object, intent, selection);
+#else
+    postTextStateChangeNotification(node, intent, selection);
+#endif
+}
+
+void AXObjectCache::postTextStateChangeNotification(AccessibilityObject* object, const AXTextStateChangeIntent&amp; intent, const VisibleSelection&amp; selection)
+{
+    stopCachingComputedObjectAttributes();
+
+#if PLATFORM(COCOA)
</ins><span class="cx">     if (object) {
</span><span class="cx">         if (isPasswordFieldOrContainedByPasswordField(object))
</span><span class="cx">             return;
</span><del>-        object = object-&gt;observableObject();
</del><ins>+
+        if (auto observableObject = object-&gt;observableObject())
+            object = observableObject;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     postTextStateChangePlatformNotification(object, (intent.type == AXTextStateChangeTypeUnknown || m_isSynchronizingSelection) ? m_textSelectionIntent : intent, selection);
</span><span class="cx"> #else
</span><del>-    postNotification(node-&gt;renderer(), AXObjectCache::AXSelectedTextChanged, TargetObservableParent);
</del><ins>+    UNUSED_PARAM(object);
</ins><span class="cx">     UNUSED_PARAM(intent);
</span><span class="cx">     UNUSED_PARAM(selection);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAXObjectCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AXObjectCache.h (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AXObjectCache.h        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.h        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -205,6 +205,7 @@
</span><span class="cx">     void postTextStateChangeNotification(Node*, AXTextEditType, const String&amp;, const VisiblePosition&amp;);
</span><span class="cx">     void postTextReplacementNotification(Node*, AXTextEditType deletionType, const String&amp; deletedText, AXTextEditType insertionType, const String&amp; insertedText, const VisiblePosition&amp;);
</span><span class="cx">     void postTextStateChangeNotification(Node*, const AXTextStateChangeIntent&amp;, const VisibleSelection&amp;);
</span><ins>+    void postTextStateChangeNotification(const Position&amp;, const AXTextStateChangeIntent&amp;, const VisibleSelection&amp;);
</ins><span class="cx"> 
</span><span class="cx">     enum AXLoadingEvent {
</span><span class="cx">         AXLoadingStarted,
</span><span class="lines">@@ -259,6 +260,8 @@
</span><span class="cx"> 
</span><span class="cx">     void notificationPostTimerFired();
</span><span class="cx"> 
</span><ins>+    void postTextStateChangeNotification(AccessibilityObject*, const AXTextStateChangeIntent&amp;, const VisibleSelection&amp;);
+
</ins><span class="cx">     bool enqueuePasswordValueChangeNotification(AccessibilityObject*);
</span><span class="cx">     void passwordNotificationPostTimerFired();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -457,6 +457,30 @@
</span><span class="cx">     return parent;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+AccessibilityObject* AccessibilityObject::previousSiblingUnignored(int limit) const
+{
+    AccessibilityObject* previous;
+    ASSERT(limit &gt;= 0);
+    for (previous = previousSibling(); previous &amp;&amp; previous-&gt;accessibilityIsIgnored(); previous = previous-&gt;previousSibling()) {
+        limit--;
+        if (limit &lt;= 0)
+            break;
+    }
+    return previous;
+}
+
+AccessibilityObject* AccessibilityObject::nextSiblingUnignored(int limit) const
+{
+    AccessibilityObject* next;
+    ASSERT(limit &gt;= 0);
+    for (next = nextSibling(); next &amp;&amp; next-&gt;accessibilityIsIgnored(); next = next-&gt;nextSibling()) {
+        limit--;
+        if (limit &lt;= 0)
+            break;
+    }
+    return next;
+}
+
</ins><span class="cx"> AccessibilityObject* AccessibilityObject::firstAccessibleObjectFromNode(const Node* node)
</span><span class="cx"> {
</span><span class="cx">     if (!node)
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityObject.h        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -645,6 +645,8 @@
</span><span class="cx">     virtual AccessibilityObject* lastChild() const { return nullptr; }
</span><span class="cx">     virtual AccessibilityObject* previousSibling() const { return nullptr; }
</span><span class="cx">     virtual AccessibilityObject* nextSibling() const { return nullptr; }
</span><ins>+    virtual AccessibilityObject* nextSiblingUnignored(int limit) const;
+    virtual AccessibilityObject* previousSiblingUnignored(int limit) const;
</ins><span class="cx">     virtual AccessibilityObject* parentObject() const = 0;
</span><span class="cx">     virtual AccessibilityObject* parentObjectUnignored() const;
</span><span class="cx">     virtual AccessibilityObject* parentObjectIfExists() const { return nullptr; }
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperBasemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperBase.mm        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -394,17 +394,22 @@
</span><span class="cx">         [self accessibilityPostedNotification:notificationName userInfo:nil];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static NSArray *arrayRemovingNonJSONTypes(NSArray *array)
</del><ins>+static bool isValueTypeSupported(id value)
</ins><span class="cx"> {
</span><ins>+    return [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[WebAccessibilityObjectWrapperBase class]];
+}
+
+static NSArray *arrayRemovingNonSupportedTypes(NSArray *array)
+{
</ins><span class="cx">     ASSERT([array isKindOfClass:[NSArray class]]);
</span><span class="cx">     NSMutableArray *mutableArray = [array mutableCopy];
</span><span class="cx">     for (NSUInteger i = 0; i &lt; [mutableArray count];) {
</span><span class="cx">         id value = [mutableArray objectAtIndex:i];
</span><span class="cx">         if ([value isKindOfClass:[NSDictionary class]])
</span><del>-            [mutableArray replaceObjectAtIndex:i withObject:dictionaryRemovingNonJSONTypes(value)];
</del><ins>+            [mutableArray replaceObjectAtIndex:i withObject:dictionaryRemovingNonSupportedTypes(value)];
</ins><span class="cx">         else if ([value isKindOfClass:[NSArray class]])
</span><del>-            [mutableArray replaceObjectAtIndex:i withObject:arrayRemovingNonJSONTypes(value)];
-        else if (!([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]])) {
</del><ins>+            [mutableArray replaceObjectAtIndex:i withObject:arrayRemovingNonSupportedTypes(value)];
+        else if (!isValueTypeSupported(value)) {
</ins><span class="cx">             [mutableArray removeObjectAtIndex:i];
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="lines">@@ -413,17 +418,19 @@
</span><span class="cx">     return [mutableArray autorelease];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static NSDictionary *dictionaryRemovingNonJSONTypes(NSDictionary *dictionary)
</del><ins>+static NSDictionary *dictionaryRemovingNonSupportedTypes(NSDictionary *dictionary)
</ins><span class="cx"> {
</span><ins>+    if (!dictionary)
+        return nil;
</ins><span class="cx">     ASSERT([dictionary isKindOfClass:[NSDictionary class]]);
</span><span class="cx">     NSMutableDictionary *mutableDictionary = [dictionary mutableCopy];
</span><span class="cx">     for (NSString *key in dictionary) {
</span><span class="cx">         id value = [dictionary objectForKey:key];
</span><span class="cx">         if ([value isKindOfClass:[NSDictionary class]])
</span><del>-            [mutableDictionary setObject:dictionaryRemovingNonJSONTypes(value) forKey:key];
</del><ins>+            [mutableDictionary setObject:dictionaryRemovingNonSupportedTypes(value) forKey:key];
</ins><span class="cx">         else if ([value isKindOfClass:[NSArray class]])
</span><del>-            [mutableDictionary setObject:arrayRemovingNonJSONTypes(value) forKey:key];
-        else if (!([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]))
</del><ins>+            [mutableDictionary setObject:arrayRemovingNonSupportedTypes(value) forKey:key];
+        else if (!isValueTypeSupported(value))
</ins><span class="cx">             [mutableDictionary removeObjectForKey:key];
</span><span class="cx">     }
</span><span class="cx">     return [mutableDictionary autorelease];
</span><span class="lines">@@ -433,18 +440,8 @@
</span><span class="cx"> {
</span><span class="cx">     if (accessibilityShouldRepostNotifications) {
</span><span class="cx">         ASSERT(notificationName);
</span><del>-        NSDictionary *info = nil;
-        if (userInfo) {
-            NSData *userInfoData = [NSJSONSerialization dataWithJSONObject:dictionaryRemovingNonJSONTypes(userInfo) options:(NSJSONWritingOptions)0 error:nil];
-            if (userInfoData) {
-                NSString *userInfoString = [[NSString alloc] initWithData:userInfoData encoding:NSUTF8StringEncoding];
-                if (userInfoString)
-                    info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @&quot;notificationName&quot;, userInfoString, @&quot;userInfo&quot;, nil];
-                [userInfoString release];
-            }
-        }
-        if (!info)
-            info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @&quot;notificationName&quot;, nil];
</del><ins>+        userInfo = dictionaryRemovingNonSupportedTypes(userInfo);
+        NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:notificationName, @&quot;notificationName&quot;, userInfo, @&quot;userInfo&quot;, nil];
</ins><span class="cx">         [[NSNotificationCenter defaultCenter] postNotificationName:@&quot;AXDRTNotification&quot; object:self userInfo:info];
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingmacFrameSelectionMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Source/WebCore/editing/mac/FrameSelectionMac.mm        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_selection.start().isNotNull() &amp;&amp; m_selection.end().isNotNull()) {
</span><span class="cx">         if (AXObjectCache* cache = document-&gt;existingAXObjectCache())
</span><del>-            cache-&gt;postTextStateChangeNotification(m_selection.start().deprecatedNode(), intent, m_selection);
</del><ins>+            cache-&gt;postTextStateChangeNotification(m_selection.start(), intent, m_selection);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Tools/ChangeLog        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2015-06-24  Doug Russell  &lt;d_russell@apple.com&gt;
+
+        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
+
+        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:]):
+
</ins><span class="cx"> 2015-06-24  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Subpixel rendering: roundToDevicePixel() snaps to wrong value.
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacAccessibilityNotificationHandlermm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Tools/DumpRenderTree/mac/AccessibilityNotificationHandler.mm        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #import &lt;JavaScriptCore/JSStringRef.h&gt;
</span><span class="cx"> #import &lt;JavaScriptCore/JSStringRefCF.h&gt;
</span><span class="cx"> #import &lt;WebKit/WebFrame.h&gt;
</span><ins>+#import &lt;objc/runtime.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> @interface NSObject (WebAccessibilityObjectWrapperAdditions)
</span><span class="lines">@@ -93,14 +94,19 @@
</span><span class="cx">     JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static Class webAccessibilityObjectWrapperClass()
+{
+    static Class cls = objc_getClass(&quot;WebAccessibilityObjectWrapper&quot;);
+    ASSERT(cls);
+    return cls;
+}
+
</ins><span class="cx"> - (void)startObserving
</span><span class="cx"> {
</span><span class="cx">     // Once we start requesting notifications, it's on for the duration of the program.
</span><span class="cx">     // This is to avoid any race conditions between tests turning this flag on and off. Instead
</span><span class="cx">     // AccessibilityNotificationHandler can ignore events it doesn't care about.
</span><del>-    id webAccessibilityObjectWrapperClass = NSClassFromString(@&quot;WebAccessibilityObjectWrapper&quot;);
-    ASSERT(webAccessibilityObjectWrapperClass);
-    [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
</del><ins>+    [webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
</ins><span class="cx">     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@&quot;AXDRTNotification&quot; object:nil];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -109,6 +115,48 @@
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static JSValueRef makeValueRefForValue(JSContextRef context, id value)
+{
+    if ([value isKindOfClass:[NSString class]])
+        return JSValueMakeString(context, adopt([value createJSStringRef]).get());
+    if ([value isKindOfClass:[NSNumber class]]) {
+        if (!strcmp([value objCType], @encode(BOOL)))
+            return JSValueMakeBoolean(context, [value boolValue]);
+        return JSValueMakeNumber(context, [value doubleValue]);
+    }
+    if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
+        return AccessibilityUIElement::makeJSAccessibilityUIElement(context, value);
+    if ([value isKindOfClass:[NSDictionary class]])
+        return makeObjectRefForDictionary(context, value);
+    if ([value isKindOfClass:[NSArray class]])
+        return makeArrayRefForArray(context, value);
+    return nullptr;
+}
+
+static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
+{
+    NSUInteger count = array.count;
+    JSValueRef arguments[count];
+
+    for (NSUInteger i = 0; i &lt; count; i++)
+        arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
+
+    return JSObjectMakeArray(context, count, arguments, nullptr);
+}
+
+static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
+{
+    JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
+
+    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop)
+    {
+        if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
+            JSObjectSetProperty(context, object, adopt([key createJSStringRef]).get(), propertyValue, kJSPropertyAttributeNone, nullptr);
+    }];
+
+    return object;
+}
+
</ins><span class="cx"> - (void)_notificationReceived:(NSNotification *)notification
</span><span class="cx"> {
</span><span class="cx">     NSString *notificationName = [[notification userInfo] objectForKey:@&quot;notificationName&quot;];
</span><span class="lines">@@ -117,27 +165,22 @@
</span><span class="cx">     if (m_platformElement &amp;&amp; m_platformElement != [notification object])
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    NSString *userInfoJSONValue = [[notification userInfo] objectForKey:@&quot;userInfo&quot;];
</del><ins>+    NSDictionary *userInfo = [[notification userInfo] objectForKey:@&quot;userInfo&quot;];
</ins><span class="cx"> 
</span><del>-    JSRetainPtr&lt;JSStringRef&gt; jsNotification(Adopt, [notificationName createJSStringRef]);
-    JSValueRef notificationNameArgument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
-    JSValueRef userInfoJSONValueArgument = nil;
-    if ([userInfoJSONValue length]) {
-        JSRetainPtr&lt;JSStringRef&gt; jsUserInfoJSONValue(Adopt, [userInfoJSONValue createJSStringRef]);
-        userInfoJSONValueArgument = JSValueMakeFromJSONString([mainFrame globalContext], jsUserInfoJSONValue.get());
-    }
</del><ins>+    JSValueRef notificationNameArgument = JSValueMakeString([mainFrame globalContext], adopt([notificationName createJSStringRef]).get());
+    JSValueRef userInfoArgument = makeObjectRefForDictionary([mainFrame globalContext], userInfo);
</ins><span class="cx">     if (m_platformElement) {
</span><span class="cx">         // Listener for one element gets the notification name and userInfo.
</span><span class="cx">         JSValueRef arguments[2];
</span><span class="cx">         arguments[0] = notificationNameArgument;
</span><del>-        arguments[1] = userInfoJSONValueArgument;
</del><ins>+        arguments[1] = userInfoArgument;
</ins><span class="cx">         JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 2, arguments, 0);
</span><span class="cx">     } else {
</span><span class="cx">         // A global listener gets the element, notification name and userInfo.
</span><span class="cx">         JSValueRef arguments[3];
</span><span class="cx">         arguments[0] = AccessibilityUIElement::makeJSAccessibilityUIElement([mainFrame globalContext], AccessibilityUIElement([notification object]));
</span><span class="cx">         arguments[1] = notificationNameArgument;
</span><del>-        arguments[2] = userInfoJSONValueArgument;
</del><ins>+        arguments[2] = userInfoArgument;
</ins><span class="cx">         JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 2, arguments, 0);
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundlemacAccessibilityNotificationHandlermm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm (185923 => 185924)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm        2015-06-24 20:48:13 UTC (rev 185923)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityNotificationHandler.mm        2015-06-24 20:51:13 UTC (rev 185924)
</span><span class="lines">@@ -39,6 +39,7 @@
</span><span class="cx"> #import &lt;JavaScriptCore/JSStringRef.h&gt;
</span><span class="cx"> #import &lt;JavaScriptCore/JSStringRefCF.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKBundleFrame.h&gt;
</span><ins>+#import &lt;objc/runtime.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> @interface NSObject (WebAccessibilityObjectWrapperAdditions)
</span><span class="lines">@@ -101,14 +102,19 @@
</span><span class="cx">     JSValueProtect(context, m_notificationFunctionCallback);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static Class webAccessibilityObjectWrapperClass()
+{
+    static Class cls = objc_getClass(&quot;WebAccessibilityObjectWrapper&quot;);
+    ASSERT(cls);
+    return cls;
+}
+
</ins><span class="cx"> - (void)startObserving
</span><span class="cx"> {
</span><span class="cx">     // Once we start requesting notifications, it's on for the duration of the program.
</span><span class="cx">     // This is to avoid any race conditions between tests turning this flag on and off. Instead
</span><span class="cx">     // AccessibilityNotificationHandler can ignore events it doesn't care about.
</span><del>-    id webAccessibilityObjectWrapperClass = NSClassFromString(@&quot;WebAccessibilityObjectWrapper&quot;);
-    ASSERT(webAccessibilityObjectWrapperClass);
-    [webAccessibilityObjectWrapperClass accessibilitySetShouldRepostNotifications:YES];
</del><ins>+    [webAccessibilityObjectWrapperClass() accessibilitySetShouldRepostNotifications:YES];
</ins><span class="cx">     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@&quot;AXDRTNotification&quot; object:nil];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -117,6 +123,48 @@
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static JSValueRef makeValueRefForValue(JSContextRef context, id value)
+{
+    if ([value isKindOfClass:[NSString class]])
+        return JSValueMakeString(context, adopt([value createJSStringRef]).get());
+    if ([value isKindOfClass:[NSNumber class]]) {
+        if (!strcmp([value objCType], @encode(BOOL)))
+            return JSValueMakeBoolean(context, [value boolValue]);
+        return JSValueMakeNumber(context, [value doubleValue]);
+    }
+    if ([value isKindOfClass:webAccessibilityObjectWrapperClass()])
+        return toJS(context, WTR::AccessibilityUIElement::create(static_cast&lt;PlatformUIElement&gt;(value)).get());
+    if ([value isKindOfClass:[NSDictionary class]])
+        return makeObjectRefForDictionary(context, value);
+    if ([value isKindOfClass:[NSArray class]])
+        return makeArrayRefForArray(context, value);
+    return nullptr;
+}
+
+static JSValueRef makeArrayRefForArray(JSContextRef context, NSArray *array)
+{
+    NSUInteger count = array.count;
+    JSValueRef arguments[count];
+
+    for (NSUInteger i = 0; i &lt; count; i++)
+        arguments[i] = makeValueRefForValue(context, [array objectAtIndex:i]);
+
+    return JSObjectMakeArray(context, count, arguments, nullptr);
+}
+
+static JSValueRef makeObjectRefForDictionary(JSContextRef context, NSDictionary *dictionary)
+{
+    JSObjectRef object = JSObjectMake(context, nullptr, nullptr);
+
+    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop)
+    {
+        if (JSValueRef propertyValue = makeValueRefForValue(context, obj))
+            JSObjectSetProperty(context, object, adopt([key createJSStringRef]).get(), propertyValue, kJSPropertyAttributeNone, nullptr);
+    }];
+
+    return object;
+}
+
</ins><span class="cx"> - (void)_notificationReceived:(NSNotification *)notification
</span><span class="cx"> {
</span><span class="cx">     NSString *notificationName = [[notification userInfo] objectForKey:@&quot;notificationName&quot;];
</span><span class="lines">@@ -125,31 +173,26 @@
</span><span class="cx">     if (m_platformElement &amp;&amp; m_platformElement != [notification object])
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    NSString *userInfoJSONValue = [[notification userInfo] objectForKey:@&quot;userInfo&quot;];
</del><ins>+    NSDictionary *userInfo = [[notification userInfo] objectForKey:@&quot;userInfo&quot;];
</ins><span class="cx"> 
</span><span class="cx">     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(WTR::InjectedBundle::singleton().page()-&gt;page());
</span><span class="cx">     JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
</span><span class="cx"> 
</span><del>-    JSRetainPtr&lt;JSStringRef&gt; jsNotification(Adopt, [notificationName createJSStringRef]);
-    JSValueRef notificationNameArgument = JSValueMakeString(context, jsNotification.get());
-    JSValueRef userInfoJSONValueArgument = nil;
-    if ([userInfoJSONValue length]) {
-        JSRetainPtr&lt;JSStringRef&gt; jsUserInfoJSONValue(Adopt, [userInfoJSONValue createJSStringRef]);
-        userInfoJSONValueArgument = JSValueMakeFromJSONString(context, jsUserInfoJSONValue.get());
-    }
</del><ins>+    JSValueRef notificationNameArgument = JSValueMakeString(context, adopt([notificationName createJSStringRef]).get());
+    JSValueRef userInfoArgument = makeObjectRefForDictionary(context, userInfo);
</ins><span class="cx">     if (m_platformElement) {
</span><span class="cx">         // Listener for one element gets the notification name and userInfo.
</span><span class="cx">         JSValueRef arguments[2];
</span><span class="cx">         arguments[0] = notificationNameArgument;
</span><del>-        arguments[1] = userInfoJSONValueArgument;
</del><ins>+        arguments[1] = userInfoArgument;
</ins><span class="cx">         JSObjectCallAsFunction(context, const_cast&lt;JSObjectRef&gt;(m_notificationFunctionCallback), 0, 2, arguments, 0);
</span><span class="cx">     } else {
</span><span class="cx">         // A global listener gets the element, notification name and userInfo.
</span><span class="cx">         JSValueRef arguments[3];
</span><del>-        arguments[0] = toJS(context, WTF::getPtr(WTR::AccessibilityUIElement::create([notification object])));
</del><ins>+        arguments[0] = toJS(context, WTR::AccessibilityUIElement::create([notification object]).get());
</ins><span class="cx">         arguments[1] = notificationNameArgument;
</span><del>-        arguments[2] = userInfoJSONValueArgument;
-        JSObjectCallAsFunction(context, const_cast&lt;JSObjectRef&gt;(m_notificationFunctionCallback), 0, 2, arguments, 0);
</del><ins>+        arguments[2] = userInfoArgument;
+        JSObjectCallAsFunction(context, const_cast&lt;JSObjectRef&gt;(m_notificationFunctionCallback), 0, 3, arguments, 0);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>