<!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>[244561] 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/244561">244561</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2019-04-23 13:31:51 -0700 (Tue, 23 Apr 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Accessibility text search and selection API enhancements.
https://bugs.webkit.org/show_bug.cgi?id=197095
<rdar://problem/48181791>

Patch by Andres Gonzalez <andresg_22@apple.com> on 2019-04-23
Reviewed by Chris Fleizach.

Source/WebCore:

- Split the existing SelectTextWithCriteria API into two: search text API (SearchTextWithCriteria) and a text operation API (TextOperation: select, replace, capitalize...).
- This allows for more flexibility and extensibility.
- Added the ability to retrieve text markers for multiple search hits.
- Various code clean up and consolidation.
- Added LayoutTest for search API.
- Previous API is marked with "To be deprecated", and is implemented with new implementation. May be removed in a future change.

Test: accessibility/mac/search-text/search-text.html

* accessibility/AccessibilityObject.cpp:
(WebCore::rangeClosestToRange):
(WebCore::AccessibilityObject::rangeOfStringClosestToRangeInDirection const):
(WebCore::AccessibilityObject::findTextRange const):
(WebCore::AccessibilityObject::findTextRanges const):
(WebCore::AccessibilityObject::performTextOperation):
(WebCore::AccessibilityObject::frame const):
(WebCore::AccessibilityObject::selectText): Deleted.
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilitySearchTextCriteria::AccessibilitySearchTextCriteria):
(WebCore::AccessibilityTextOperation::AccessibilityTextOperation):
(WebCore::AccessibilitySelectTextCriteria::AccessibilitySelectTextCriteria): Deleted.
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(accessibilityTextCriteriaForParameterizedAttribute):
(accessibilitySearchTextCriteriaForParameterizedAttribute):
(accessibilityTextOperationForParameterizedAttribute):
(-[WebAccessibilityObjectWrapper IGNORE_WARNINGS_END]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
(accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute): Deleted.

Tools:

Added new API JS binding code for searchTextWithCriteria to both WTR and DRT.

* DumpRenderTree/AccessibilityTextMarker.h:
* DumpRenderTree/AccessibilityUIElement.cpp:
(searchTextWithCriteriaCallback):
(AccessibilityUIElement::getJSClass):
* DumpRenderTree/AccessibilityUIElement.h:
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(convertVectorToObjectArray):
(convertNSArrayToVector):
(searchTextParameterizedAttributeForCriteria):
(AccessibilityUIElement::getLinkedUIElements):
(AccessibilityUIElement::getDocumentLinks):
(AccessibilityUIElement::getChildren):
(AccessibilityUIElement::getChildrenWithRange):
(AccessibilityUIElement::rowHeaders const):
(AccessibilityUIElement::columnHeaders const):
(AccessibilityUIElement::uiElementArrayAttributeValue const):
(AccessibilityUIElement::searchTextWithCriteria):
(AccessibilityUIElement::attributesOfColumnHeaders):
(AccessibilityUIElement::attributesOfRowHeaders):
(AccessibilityUIElement::attributesOfColumns):
(AccessibilityUIElement::attributesOfRows):
(AccessibilityUIElement::attributesOfVisibleCells):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::convertVectorToObjectArray):
(WTR::convertNSArrayToVector):
(WTR::searchTextParameterizedAttributeForCriteria):
(WTR::AccessibilityUIElement::getLinkedUIElements):
(WTR::AccessibilityUIElement::getDocumentLinks):
(WTR::AccessibilityUIElement::getUIElementsWithAttribute const):
(WTR::AccessibilityUIElement::getChildren):
(WTR::AccessibilityUIElement::getChildrenWithRange):
(WTR::AccessibilityUIElement::rowHeaders const):
(WTR::AccessibilityUIElement::columnHeaders const):
(WTR::AccessibilityUIElement::uiElementArrayAttributeValue const):
(WTR::AccessibilityUIElement::searchTextWithCriteria):
(WTR::AccessibilityUIElement::attributesOfColumnHeaders):
(WTR::AccessibilityUIElement::attributesOfRowHeaders):
(WTR::AccessibilityUIElement::attributesOfColumns):
(WTR::AccessibilityUIElement::attributesOfRows):
(WTR::AccessibilityUIElement::attributesOfVisibleCells):
(WTR::convertElementsToObjectArray): Deleted.

LayoutTests:

- Added new test for AccessibilitySearchTextWithCriteria API.
- Updated bounds-for-range expected file that includes a list of available APIs.

* accessibility/mac/bounds-for-range-expected.txt:
* accessibility/mac/search-text/search-text-expected.txt: Added.
* accessibility/mac/search-text/search-text.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsaccessibilitymacboundsforrangeexpectedtxt">trunk/LayoutTests/accessibility/mac/bounds-for-range-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperMacmm">trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeAccessibilityTextMarkerh">trunk/Tools/DumpRenderTree/AccessibilityTextMarker.h</a></li>
<li><a href="#trunkToolsDumpRenderTreeAccessibilityUIElementcpp">trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp</a></li>
<li><a href="#trunkToolsDumpRenderTreeAccessibilityUIElementh">trunk/Tools/DumpRenderTree/AccessibilityUIElement.h</a></li>
<li><a href="#trunkToolsDumpRenderTreemacAccessibilityUIElementMacmm">trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleAccessibilityUIElementcpp">trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleAccessibilityUIElementh">trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundleBindingsAccessibilityUIElementidl">trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl</a></li>
<li><a href="#trunkToolsWebKitTestRunnerInjectedBundlemacAccessibilityUIElementMacmm">trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/accessibility/mac/search-text/</li>
<li><a href="#trunkLayoutTestsaccessibilitymacsearchtextsearchtextexpectedtxt">trunk/LayoutTests/accessibility/mac/search-text/search-text-expected.txt</a></li>
<li><a href="#trunkLayoutTestsaccessibilitymacsearchtextsearchtexthtml">trunk/LayoutTests/accessibility/mac/search-text/search-text.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/LayoutTests/ChangeLog 2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2019-04-23  Andres Gonzalez  <andresg_22@apple.com>
+
+        Accessibility text search and selection API enhancements.
+        https://bugs.webkit.org/show_bug.cgi?id=197095
+        <rdar://problem/48181791>
+
+        Reviewed by Chris Fleizach.
+
+        - Added new test for AccessibilitySearchTextWithCriteria API.
+        - Updated bounds-for-range expected file that includes a list of available APIs.
+
+        * accessibility/mac/bounds-for-range-expected.txt:
+        * accessibility/mac/search-text/search-text-expected.txt: Added.
+        * accessibility/mac/search-text/search-text.html: Added.
+
</ins><span class="cx"> 2019-04-23  Guy Lewin  <guy@lewin.co.il>
</span><span class="cx"> 
</span><span class="cx">         Multiple File Input Icon Set Regardless of File List
</span></span></pre></div>
<a id="trunkLayoutTestsaccessibilitymacboundsforrangeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/accessibility/mac/bounds-for-range-expected.txt (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/mac/bounds-for-range-expected.txt        2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/LayoutTests/accessibility/mac/bounds-for-range-expected.txt   2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx"> AXStartTextMarkerForBounds
</span><span class="cx"> AXLineTextMarkerRangeForTextMarker
</span><span class="cx"> AXSelectTextWithCriteria
</span><ins>+AXSearchTextWithCriteria
+AXTextOperation
</ins><span class="cx"> 
</span><span class="cx"> ----------------------
</span><span class="cx"> {{-1.000000, -1.000000}, {60.000000, 18.000000}}
</span></span></pre></div>
<a id="trunkLayoutTestsaccessibilitymacsearchtextsearchtextexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/mac/search-text/search-text-expected.txt (0 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/mac/search-text/search-text-expected.txt                         (rev 0)
+++ trunk/LayoutTests/accessibility/mac/search-text/search-text-expected.txt    2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+The quick brown fox jumps over the lazy dog.
+
+TEXT2: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
+
+This tests the ability to search for text given a starting point and a direction for the search.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'lazy'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'quick'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'the'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'The'
+PASS result.length is 3
+PASS body.stringForTextMarkerRange(result[i]) is 'dog'
+PASS body.stringForTextMarkerRange(result[i]) is 'dog'
+PASS body.stringForTextMarkerRange(result[i]) is 'dog'
+PASS result.length is 3
+PASS body.stringForTextMarkerRange(result[i]) is 'fox'
+PASS body.stringForTextMarkerRange(result[i]) is 'fox'
+PASS body.stringForTextMarkerRange(result[i]) is 'fox'
+PASS typeof result is 'undefined'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'over'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'fox'
+PASS result.length is 1
+PASS text.stringForTextMarkerRange(result[0]) is 'fox'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsaccessibilitymacsearchtextsearchtexthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/accessibility/mac/search-text/search-text.html (0 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/accessibility/mac/search-text/search-text.html                         (rev 0)
+++ trunk/LayoutTests/accessibility/mac/search-text/search-text.html    2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test-pre.js"></script>
+<title>Search Text 1</title>
+</head>
+<body id="body">
+
+<p contenteditable="true" id="text">The quick brown fox <span id="target">jumps</span> over the lazy dog. </p>
+
+<p contenteditable="true" id="text2">TEXT2: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.</p>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+    description("This tests the ability to search for text given a starting point and a direction for the search.");
+
+    function selectElementText(element) {
+        var range = document.createRange();
+        range.selectNodeContents(element);
+        
+        var selection = window.getSelection();
+        selection.removeAllRanges();
+        selection.addRange(range);
+    }
+
+    if (window.accessibilityController) {
+        var text = accessibilityController.accessibleElementById("text");
+        var result = 0;
+        var selection = 0;
+        var target = document.getElementById("target");
+
+        // Select target element.
+        selectElementText(target);
+
+        // Search for text after selection (single search string).
+        result = text.searchTextWithCriteria("lazy", "AXSearchTextStartFromSelection", "AXSearchTextDirectionForward");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'lazy'");
+
+        // Search for text before selection (single search string).
+        result = text.searchTextWithCriteria("quick", "AXSearchTextStartFromSelection", "AXSearchTextDirectionBackward");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'quick'");
+
+        // Search for text closest to selection (single search string).
+        result = text.searchTextWithCriteria("the", "AXSearchTextStartFromSelection", "AXSearchTextDirectionClosest");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'the'");
+
+        // Search from the beginning (single search string).
+        result = text.searchTextWithCriteria("the", "AXSearchTextStartFromBegin", "AXSearchTextDirectionClosest");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'The'");
+
+        // Search for all occurrences from the beginning of document (single search string).
+        var body = accessibilityController.rootElement.childAtIndex(0);
+        result = body.searchTextWithCriteria("dog", "AXSearchTextStartFromBegin", "AXSearchTextDirectionAll");
+        shouldBe("result.length", "3");
+        for (var i = 0; i < result.length; i++)
+            shouldBe("body.stringForTextMarkerRange(result[i])", "'dog'");
+
+        // Search for all occurrences from the end of document (single search string).
+        result = body.searchTextWithCriteria("fox", "AXSearchTextStartFromEnd", "AXSearchTextDirectionAll");
+        shouldBe("result.length", "3");
+        for (var i = 0; i < result.length; i++)
+            shouldBe("body.stringForTextMarkerRange(result[i])", "'fox'");
+
+        // Search for a non-present string (single search string).
+        result = body.searchTextWithCriteria("cat", "AXSearchTextStartFromBegin", "AXSearchTextDirectionAll");
+        shouldBe("typeof result", "'undefined'");
+
+        // Search for multiple strings after selection.
+        result = text.searchTextWithCriteria(["lazy", "over"], "AXSearchTextStartFromSelection", "AXSearchTextDirectionForward");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'over'");
+
+        // Search for multiple strings before selection.
+        result = text.searchTextWithCriteria(["quick", "fox"], "AXSearchTextStartFromSelection", "AXSearchTextDirectionBackward");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'fox'");
+
+        // Search for multiple strings closest to selection.
+        result = text.searchTextWithCriteria(["dog", "fox"], "AXSearchTextStartFromSelection", "AXSearchTextDirectionClosest");
+        shouldBe("result.length", "1");
+        shouldBe("text.stringForTextMarkerRange(result[0])", "'fox'");
+    }
+</script>
+
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Source/WebCore/ChangeLog      2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2019-04-23  Andres Gonzalez  <andresg_22@apple.com>
+
+        Accessibility text search and selection API enhancements.
+        https://bugs.webkit.org/show_bug.cgi?id=197095
+        <rdar://problem/48181791>
+
+        Reviewed by Chris Fleizach.
+
+        - Split the existing SelectTextWithCriteria API into two: search text API (SearchTextWithCriteria) and a text operation API (TextOperation: select, replace, capitalize...).
+        - This allows for more flexibility and extensibility.
+        - Added the ability to retrieve text markers for multiple search hits.
+        - Various code clean up and consolidation.
+        - Added LayoutTest for search API.
+        - Previous API is marked with "To be deprecated", and is implemented with new implementation. May be removed in a future change.
+
+        Test: accessibility/mac/search-text/search-text.html
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::rangeClosestToRange):
+        (WebCore::AccessibilityObject::rangeOfStringClosestToRangeInDirection const):
+        (WebCore::AccessibilityObject::findTextRange const):
+        (WebCore::AccessibilityObject::findTextRanges const):
+        (WebCore::AccessibilityObject::performTextOperation):
+        (WebCore::AccessibilityObject::frame const):
+        (WebCore::AccessibilityObject::selectText): Deleted.
+        * accessibility/AccessibilityObject.h:
+        (WebCore::AccessibilitySearchTextCriteria::AccessibilitySearchTextCriteria):
+        (WebCore::AccessibilityTextOperation::AccessibilityTextOperation):
+        (WebCore::AccessibilitySelectTextCriteria::AccessibilitySelectTextCriteria): Deleted.
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (accessibilityTextCriteriaForParameterizedAttribute):
+        (accessibilitySearchTextCriteriaForParameterizedAttribute):
+        (accessibilityTextOperationForParameterizedAttribute):
+        (-[WebAccessibilityObjectWrapper IGNORE_WARNINGS_END]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+        (accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute): Deleted.
+
</ins><span class="cx"> 2019-04-23  Guy Lewin  <guy@lewin.co.il>
</span><span class="cx"> 
</span><span class="cx">         Multiple File Input Icon Set Regardless of File List
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp       2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp  2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -757,21 +757,21 @@
</span><span class="cx"> // Returns the range that is fewer positions away from the reference range.
</span><span class="cx"> // NOTE: The after range is expected to ACTUALLY be after the reference range and the before
</span><span class="cx"> // range is expected to ACTUALLY be before. These are not checked for performance reasons.
</span><del>-static RefPtr<Range> rangeClosestToRange(Range* referenceRange, RefPtr<Range>&& afterRange, RefPtr<Range>&& beforeRange)
</del><ins>+static RefPtr<Range> rangeClosestToRange(RefPtr<Range> const& referenceRange, RefPtr<Range>&& afterRange, RefPtr<Range>&& beforeRange)
</ins><span class="cx"> {
</span><span class="cx">     if (!referenceRange)
</span><span class="cx">         return nullptr;
</span><del>-    
</del><ins>+
</ins><span class="cx">     // The treeScope for shadow nodes may not be the same scope as another element in a document.
</span><span class="cx">     // Comparisons may fail in that case, which are expected behavior and should not assert.
</span><span class="cx">     if (afterRange && (referenceRange->endPosition().isNull() || ((afterRange->startPosition().anchorNode()->compareDocumentPosition(*referenceRange->endPosition().anchorNode()) & Node::DOCUMENT_POSITION_DISCONNECTED) == Node::DOCUMENT_POSITION_DISCONNECTED)))
</span><span class="cx">         return nullptr;
</span><del>-    ASSERT(!afterRange || afterRange->startPosition() >= referenceRange->endPosition());
-    
</del><ins>+    ASSERT(!afterRange || afterRange->compareBoundaryPoints(Range::START_TO_START, *referenceRange).releaseReturnValue() >= 0);
+
</ins><span class="cx">     if (beforeRange && (referenceRange->startPosition().isNull() || ((beforeRange->endPosition().anchorNode()->compareDocumentPosition(*referenceRange->startPosition().anchorNode()) & Node::DOCUMENT_POSITION_DISCONNECTED) == Node::DOCUMENT_POSITION_DISCONNECTED)))
</span><span class="cx">         return nullptr;
</span><del>-    ASSERT(!beforeRange || beforeRange->endPosition() <= referenceRange->startPosition());
-    
</del><ins>+    ASSERT(!beforeRange || beforeRange->compareBoundaryPoints(Range::START_TO_START, *referenceRange).releaseReturnValue() <= 0);
+
</ins><span class="cx">     if (!afterRange && !beforeRange)
</span><span class="cx">         return nullptr;
</span><span class="cx">     if (afterRange && !beforeRange)
</span><span class="lines">@@ -785,7 +785,7 @@
</span><span class="cx">     return positionsToAfterRange < positionsToBeforeRange ? afterRange : beforeRange;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<Range> AccessibilityObject::rangeOfStringClosestToRangeInDirection(Range* referenceRange, AccessibilitySearchDirection searchDirection, Vector<String>& searchStrings) const
</del><ins>+RefPtr<Range> AccessibilityObject::rangeOfStringClosestToRangeInDirection(Range* referenceRange, AccessibilitySearchDirection searchDirection, Vector<String> const& searchStrings) const
</ins><span class="cx"> {
</span><span class="cx">     Frame* frame = this->frame();
</span><span class="cx">     if (!frame)
</span><span class="lines">@@ -797,7 +797,7 @@
</span><span class="cx">     bool isBackwardSearch = searchDirection == AccessibilitySearchDirection::Previous;
</span><span class="cx">     FindOptions findOptions { AtWordStarts, AtWordEnds, CaseInsensitive, StartInSelection };
</span><span class="cx">     if (isBackwardSearch)
</span><del>-        findOptions.add(Backwards);
</del><ins>+        findOptions.add(FindOptionFlag::Backwards);
</ins><span class="cx">     
</span><span class="cx">     RefPtr<Range> closestStringRange = nullptr;
</span><span class="cx">     for (const auto& searchString : searchStrings) {
</span><span class="lines">@@ -843,87 +843,137 @@
</span><span class="cx">     return AXObjectCache::rangeForNodeContents(node());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String AccessibilityObject::selectText(AccessibilitySelectTextCriteria* criteria)
</del><ins>+RefPtr<Range> AccessibilityObject::findTextRange(Vector<String> const& searchStrings, RefPtr<Range> const& start, AccessibilitySearchTextDirection direction) const
</ins><span class="cx"> {
</span><del>-    ASSERT(criteria);
-    
-    if (!criteria)
-        return String();
-    
-    Frame* frame = this->frame();
-    if (!frame)
-        return String();
-    
-    AccessibilitySelectTextActivity& activity = criteria->activity;
-    AccessibilitySelectTextAmbiguityResolution& ambiguityResolution = criteria->ambiguityResolution;
-    String& replacementString = criteria->replacementString;
-    Vector<String>& searchStrings = criteria->searchStrings;
-    
-    RefPtr<Range> selectedStringRange = selectionRange();
-    // When starting our search again, make this a zero length range so that search forwards will find this selected range if its appropriate.
-    selectedStringRange->setEnd(selectedStringRange->startContainer(), selectedStringRange->startOffset());
-    
-    RefPtr<Range> closestAfterStringRange = nullptr;
-    RefPtr<Range> closestBeforeStringRange = nullptr;
-    // Search forward if necessary.
-    if (ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestAfter || ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestTo)
-        closestAfterStringRange = rangeOfStringClosestToRangeInDirection(selectedStringRange.get(), AccessibilitySearchDirection::Next, searchStrings);
-    // Search backward if necessary.
-    if (ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestBefore || ambiguityResolution == AccessibilitySelectTextAmbiguityResolution::ClosestTo)
-        closestBeforeStringRange = rangeOfStringClosestToRangeInDirection(selectedStringRange.get(), AccessibilitySearchDirection::Previous, searchStrings);
-    
-    // Determine which candidate is closest to the selection and perform the activity.
-    if (RefPtr<Range> closestStringRange = rangeClosestToRange(selectedStringRange.get(), WTFMove(closestAfterStringRange), WTFMove(closestBeforeStringRange))) {
</del><ins>+    RefPtr<Range> found;
+    if (direction == AccessibilitySearchTextDirection::Forward)
+        found = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Next, searchStrings);
+    else if (direction == AccessibilitySearchTextDirection::Backward)
+        found = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Previous, searchStrings);
+    else if (direction == AccessibilitySearchTextDirection::Closest) {
+        auto foundAfter = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Next, searchStrings);
+        auto foundBefore = rangeOfStringClosestToRangeInDirection(start.get(), AccessibilitySearchDirection::Previous, searchStrings);
+        found = rangeClosestToRange(start.get(), WTFMove(foundAfter), WTFMove(foundBefore));
+    }
+
+    if (found) {
</ins><span class="cx">         // If the search started within a text control, ensure that the result is inside that element.
</span><span class="cx">         if (element() && element()->isTextField()) {
</span><del>-            if (!closestStringRange->startContainer().isDescendantOrShadowDescendantOf(element()) || !closestStringRange->endContainer().isDescendantOrShadowDescendantOf(element()))
-                return String();
</del><ins>+            if (!found->startContainer().isDescendantOrShadowDescendantOf(element())
+                || !found->endContainer().isDescendantOrShadowDescendantOf(element()))
+                return nullptr;
</ins><span class="cx">         }
</span><del>-        
-        String closestString = closestStringRange->text();
</del><ins>+    }
+    return found;
+}
+
+Vector<RefPtr<Range>> AccessibilityObject::findTextRanges(AccessibilitySearchTextCriteria const& criteria) const
+{
+    Vector<RefPtr<Range>> result;
+
+    // Determine start range.
+    RefPtr<Range> startRange;
+    if (criteria.start == AccessibilitySearchTextStartFrom::Selection)
+        startRange = selectionRange();
+    else
+        startRange = elementRange();
+
+    if (startRange) {
+        // Collapse the range to the start unless searching from the end of the doc or searching backwards.
+        if (criteria.start == AccessibilitySearchTextStartFrom::Begin)
+            startRange->collapse(true);
+        else if (criteria.start == AccessibilitySearchTextStartFrom::End)
+            startRange->collapse(false);
+        else
+            startRange->collapse(criteria.direction != AccessibilitySearchTextDirection::Backward);
+    } else
+        return result;
+
+    RefPtr<Range> found;
+    switch (criteria.direction) {
+    case AccessibilitySearchTextDirection::Forward:
+    case AccessibilitySearchTextDirection::Backward:
+    case AccessibilitySearchTextDirection::Closest:
+        found = findTextRange(criteria.searchStrings, startRange, criteria.direction);
+        if (found)
+            result.append(found);
+        break;
+    case AccessibilitySearchTextDirection::All: {
+        auto findAll = [&](AccessibilitySearchTextDirection dir) {
+            found = findTextRange(criteria.searchStrings, startRange, dir);
+            while (found) {
+                result.append(found);
+                found = findTextRange(criteria.searchStrings, found, dir);
+            }
+        };
+        findAll(AccessibilitySearchTextDirection::Forward);
+        findAll(AccessibilitySearchTextDirection::Backward);
+        break;
+    }
+    }
+
+    return result;
+}
+
+Vector<String> AccessibilityObject::performTextOperation(AccessibilityTextOperation const& operation)
+{
+    Vector<String> result;
+
+    if (operation.textRanges.isEmpty())
+        return result;
+
+    Frame* frame = this->frame();
+    if (!frame)
+        return result;
+
+    for (auto textRange : operation.textRanges) {
+        if (!frame->selection().setSelectedRange(textRange.get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes))
+            continue;
+
+        String text = textRange->text();
+        String replacementString = operation.replacementText;
</ins><span class="cx">         bool replaceSelection = false;
</span><del>-        if (frame->selection().setSelectedRange(closestStringRange.get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes)) {
-            switch (activity) {
-            case AccessibilitySelectTextActivity::FindAndCapitalize:
-                replacementString = capitalize(closestString, ' '); // FIXME: Needs to take locale into account to work correctly.
-                replaceSelection = true;
-                break;
-            case AccessibilitySelectTextActivity::FindAndUppercase:
-                replacementString = closestString.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
-                replaceSelection = true;
-                break;
-            case AccessibilitySelectTextActivity::FindAndLowercase:
-                replacementString = closestString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
-                replaceSelection = true;
-                break;
-            case AccessibilitySelectTextActivity::FindAndReplace: {
-                replaceSelection = true;
-                // When applying find and replace activities, we want to match the capitalization of the replaced text,
-                // (unless we're replacing with an abbreviation.)
-                if (closestString.length() > 0 && replacementString.length() > 2 && replacementString != replacementString.convertToUppercaseWithoutLocale()) {
-                    if (closestString[0] == u_toupper(closestString[0]))
-                        replacementString = capitalize(replacementString, ' '); // FIXME: Needs to take locale into account to work correctly.
-                    else
-                        replacementString = replacementString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
-                }
-                break;
</del><ins>+        switch (operation.type) {
+        case AccessibilityTextOperationType::Capitalize:
+            replacementString = capitalize(text, ' '); // FIXME: Needs to take locale into account to work correctly.
+            replaceSelection = true;
+            break;
+        case AccessibilityTextOperationType::Uppercase:
+            replacementString = text.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
+            replaceSelection = true;
+            break;
+        case AccessibilityTextOperationType::Lowercase:
+            replacementString = text.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
+            replaceSelection = true;
+            break;
+        case AccessibilityTextOperationType::Replace: {
+            replaceSelection = true;
+            // When applying find and replace activities, we want to match the capitalization of the replaced text,
+            // (unless we're replacing with an abbreviation.)
+            if (text.length() > 0
+                && replacementString.length() > 2
+                && replacementString != replacementString.convertToUppercaseWithoutLocale()) {
+                if (text[0] == u_toupper(text[0]))
+                    replacementString = capitalize(replacementString, ' '); // FIXME: Needs to take locale into account to work correctly.
+                else
+                    replacementString = replacementString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
</ins><span class="cx">             }
</span><del>-            case AccessibilitySelectTextActivity::FindAndSelect:
-                break;
-            }
-            
-            // A bit obvious, but worth noting the API contract for this method is that we should
-            // return the replacement string when replacing, but the selected string if not.
-            if (replaceSelection) {
-                frame->editor().replaceSelectionWithText(replacementString, Editor::SelectReplacement::Yes, Editor::SmartReplace::Yes);
-                return replacementString;
-            }
-            
-            return closestString;
</del><ins>+            break;
</ins><span class="cx">         }
</span><ins>+        case AccessibilityTextOperationType::Select:
+            break;
+        }
+
+        // A bit obvious, but worth noting the API contract for this method is that we should
+        // return the replacement string when replacing, but the selected string if not.
+        if (replaceSelection) {
+            frame->editor().replaceSelectionWithText(replacementString, Editor::SelectReplacement::Yes, Editor::SmartReplace::Yes);
+            result.append(replacementString);
+        } else
+            result.append(text);
</ins><span class="cx">     }
</span><del>-    
-    return String();
</del><ins>+
+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AccessibilityObject::hasAttributesRequiredForInclusion() const
</span><span class="lines">@@ -1076,10 +1126,7 @@
</span><span class="cx"> Frame* AccessibilityObject::frame() const
</span><span class="cx"> {
</span><span class="cx">     Node* node = this->node();
</span><del>-    if (!node)
-        return nullptr;
-    
-    return node->document().frame();
</del><ins>+    return node ? node->document().frame() : nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Frame* AccessibilityObject::mainFrame() const
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilityAccessibilityObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h    2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -305,33 +305,48 @@
</span><span class="cx">     bool isNull() const { return !start && !length; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-enum class AccessibilitySelectTextActivity {
-    FindAndReplace,
-    FindAndSelect,
-    FindAndCapitalize,
-    FindAndLowercase,
-    FindAndUppercase
</del><ins>+enum class AccessibilitySearchTextStartFrom {
+    Begin, // Search from the beginning of the element.
+    Selection, // Search from the position of the current selection.
+    End // Search from the end of the element.
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-enum class AccessibilitySelectTextAmbiguityResolution {
-    ClosestAfter,
-    ClosestBefore,
-    ClosestTo
</del><ins>+enum class AccessibilitySearchTextDirection {
+    Forward, // Occurrence after the starting range.
+    Backward, // Occurrence before the starting range.
+    Closest, // Closest occurrence to the starting range, whether after or before.
+    All // All occurrences
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-struct AccessibilitySelectTextCriteria {
-    AccessibilitySelectTextActivity activity;
-    AccessibilitySelectTextAmbiguityResolution ambiguityResolution;
-    String replacementString;
-    Vector<String> searchStrings;
-    
-    AccessibilitySelectTextCriteria(AccessibilitySelectTextActivity activity, AccessibilitySelectTextAmbiguityResolution ambiguityResolution, const String& replacementString)
-        : activity(activity)
-        , ambiguityResolution(ambiguityResolution)
-        , replacementString(replacementString)
</del><ins>+struct AccessibilitySearchTextCriteria {
+    Vector<String> searchStrings; // Text strings to search for.
+    AccessibilitySearchTextStartFrom start;
+    AccessibilitySearchTextDirection direction;
+
+    AccessibilitySearchTextCriteria()
+        : start(AccessibilitySearchTextStartFrom::Selection)
+        , direction(AccessibilitySearchTextDirection::Forward)
</ins><span class="cx">     { }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+enum class AccessibilityTextOperationType {
+    Select,
+    Replace,
+    Capitalize,
+    Lowercase,
+    Uppercase
+};
+
+struct AccessibilityTextOperation {
+    Vector<RefPtr<Range>> textRanges; // text on which perform the operation.
+    AccessibilityTextOperationType type;
+    String replacementText; // For type = replace.
+
+    AccessibilityTextOperation()
+        : type(AccessibilityTextOperationType::Select)
+    { }
+};
+
</ins><span class="cx"> enum class AccessibilityMathScriptObjectType { Subscript, Superscript };
</span><span class="cx"> enum class AccessibilityMathMultiscriptObjectType { PreSubscript, PreSuperscript, PostSubscript, PostSuperscript };
</span><span class="cx"> 
</span><span class="lines">@@ -607,12 +622,16 @@
</span><span class="cx">     virtual bool isDescendantOfBarrenParent() const { return false; }
</span><span class="cx"> 
</span><span class="cx">     bool isDescendantOfRole(AccessibilityRole) const;
</span><del>-    
</del><ins>+
</ins><span class="cx">     // Text selection
</span><del>-    RefPtr<Range> rangeOfStringClosestToRangeInDirection(Range*, AccessibilitySearchDirection, Vector<String>&) const;
</del><ins>+private:
+    RefPtr<Range> rangeOfStringClosestToRangeInDirection(Range*, AccessibilitySearchDirection, Vector<String> const&) const;
</ins><span class="cx">     RefPtr<Range> selectionRange() const;
</span><del>-    String selectText(AccessibilitySelectTextCriteria*);
-    
</del><ins>+    RefPtr<Range> findTextRange(Vector<String> const& searchStrings, RefPtr<Range> const& start, AccessibilitySearchTextDirection) const;
+public:
+    Vector<RefPtr<Range>> findTextRanges(AccessibilitySearchTextCriteria const&) const;
+    Vector<String> performTextOperation(AccessibilityTextOperation const&);
+
</ins><span class="cx">     virtual AccessibilityObject* observableObject() const { return nullptr; }
</span><span class="cx">     virtual void linkedUIElements(AccessibilityChildrenVector&) const { }
</span><span class="cx">     virtual AccessibilityObject* titleUIElement() const { return nullptr; }
</span></span></pre></div>
<a id="trunkSourceWebCoreaccessibilitymacWebAccessibilityObjectWrapperMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm       2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm  2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -372,6 +372,112 @@
</span><span class="cx"> #define NSAccessibilitySelectTextWithCriteriaParameterizedAttribute @"AXSelectTextWithCriteria"
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+// Text search
+
+#ifndef NSAccessibilitySearchTextWithCriteriaParameterizedAttribute
+/* Performs a text search with the given parameters.
+ Returns an NSArray of text marker ranges of the search hits.
+ */
+#define NSAccessibilitySearchTextWithCriteriaParameterizedAttribute @"AXSearchTextWithCriteria"
+#endif
+
+#ifndef NSAccessibilitySearchTextSearchStrings
+// NSArray of strings to search for.
+#define NSAccessibilitySearchTextSearchStrings @"AXSearchTextSearchStrings"
+#endif
+
+#ifndef NSAccessibilitySearchTextStartFrom
+// NSString specifying the start point of the search: selection, begin or end.
+#define NSAccessibilitySearchTextStartFrom @"AXSearchTextStartFrom"
+#endif
+
+#ifndef NSAccessibilitySearchTextStartFromBegin
+// Value for SearchTextStartFrom.
+#define NSAccessibilitySearchTextStartFromBegin @"AXSearchTextStartFromBegin"
+#endif
+
+#ifndef NSAccessibilitySearchTextStartFromSelection
+// Value for SearchTextStartFrom.
+#define NSAccessibilitySearchTextStartFromSelection @"AXSearchTextStartFromSelection"
+#endif
+
+#ifndef NSAccessibilitySearchTextStartFromEnd
+// Value for SearchTextStartFrom.
+#define NSAccessibilitySearchTextStartFromEnd @"AXSearchTextStartFromEnd"
+#endif
+
+#ifndef NSAccessibilitySearchTextDirection
+// NSString specifying the direction of the search: forward, backward, closest, all.
+#define NSAccessibilitySearchTextDirection @"AXSearchTextDirection"
+#endif
+
+#ifndef NSAccessibilitySearchTextDirectionForward
+// Value for SearchTextDirection.
+#define NSAccessibilitySearchTextDirectionForward @"AXSearchTextDirectionForward"
+#endif
+
+#ifndef NSAccessibilitySearchTextDirectionBackward
+// Value for SearchTextDirection.
+#define NSAccessibilitySearchTextDirectionBackward @"AXSearchTextDirectionBackward"
+#endif
+
+#ifndef NSAccessibilitySearchTextDirectionClosest
+// Value for SearchTextDirection.
+#define NSAccessibilitySearchTextDirectionClosest @"AXSearchTextDirectionClosest"
+#endif
+
+#ifndef NSAccessibilitySearchTextDirectionAll
+// Value for SearchTextDirection.
+#define NSAccessibilitySearchTextDirectionAll @"AXSearchTextDirectionAll"
+#endif
+
+// Text operations
+
+#ifndef NSAccessibilityTextOperationParameterizedAttribute
+// Performs an operation on the given text.
+#define NSAccessibilityTextOperationParameterizedAttribute @"AXTextOperation"
+#endif
+
+#ifndef NSAccessibilityTextOperationMarkerRanges
+// Text on which to perform operation.
+#define NSAccessibilityTextOperationMarkerRanges @"AXTextOperationMarkerRanges"
+#endif
+
+#ifndef NSAccessibilityTextOperationType
+// The type of operation to be performed: select, replace, capitalize....
+#define NSAccessibilityTextOperationType @"AXTextOperationType"
+#endif
+
+#ifndef NSAccessibilityTextOperationSelect
+// Value for TextOperationType.
+#define NSAccessibilityTextOperationSelect @"TextOperationSelect"
+#endif
+
+#ifndef NSAccessibilityTextOperationReplace
+// Value for TextOperationType.
+#define NSAccessibilityTextOperationReplace @"TextOperationReplace"
+#endif
+
+#ifndef NSAccessibilityTextOperationCapitalize
+// Value for TextOperationType.
+#define NSAccessibilityTextOperationCapitalize @"Capitalize"
+#endif
+
+#ifndef NSAccessibilityTextOperationLowercase
+// Value for TextOperationType.
+#define NSAccessibilityTextOperationLowercase @"Lowercase"
+#endif
+
+#ifndef NSAccessibilityTextOperationUppercase
+// Value for TextOperationType.
+#define NSAccessibilityTextOperationUppercase @"Uppercase"
+#endif
+
+#ifndef NSAccessibilityTextOperationReplacementString
+// Replacement text for operation replace.
+#define NSAccessibilityTextOperationReplacementString @"AXTextOperationReplacementString"
+#endif
+
</ins><span class="cx"> // Math attributes
</span><span class="cx"> #define NSAccessibilityMathRootRadicandAttribute @"AXMathRootRadicand"
</span><span class="cx"> #define NSAccessibilityMathRootIndexAttribute @"AXMathRootIndex"
</span><span class="lines">@@ -504,39 +610,39 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma mark Select text helpers
</span><span class="cx"> 
</span><del>-static AccessibilitySelectTextCriteria accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute(const NSDictionary *parameterizedAttribute)
</del><ins>+// To be deprecated.
+static std::pair<AccessibilitySearchTextCriteria, AccessibilityTextOperation> accessibilityTextCriteriaForParameterizedAttribute(const NSDictionary *parameterizedAttribute)
</ins><span class="cx"> {
</span><ins>+    AccessibilitySearchTextCriteria criteria;
+    AccessibilityTextOperation operation;
+
</ins><span class="cx">     NSString *activityParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextActivity];
</span><span class="cx">     NSString *ambiguityResolutionParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextAmbiguityResolution];
</span><span class="cx">     NSString *replacementStringParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextReplacementString];
</span><span class="cx">     NSArray *searchStringsParameter = [parameterizedAttribute objectForKey:NSAccessibilitySelectTextSearchStrings];
</span><del>-    
-    AccessibilitySelectTextActivity activity = AccessibilitySelectTextActivity::FindAndSelect;
</del><ins>+
</ins><span class="cx">     if ([activityParameter isKindOfClass:[NSString class]]) {
</span><span class="cx">         if ([activityParameter isEqualToString:NSAccessibilitySelectTextActivityFindAndReplace])
</span><del>-            activity = AccessibilitySelectTextActivity::FindAndReplace;
</del><ins>+            operation.type = AccessibilityTextOperationType::Replace;
</ins><span class="cx">         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndCapitalize])
</span><del>-            activity = AccessibilitySelectTextActivity::FindAndCapitalize;
</del><ins>+            operation.type = AccessibilityTextOperationType::Capitalize;
</ins><span class="cx">         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndLowercase])
</span><del>-            activity = AccessibilitySelectTextActivity::FindAndLowercase;
</del><ins>+            operation.type = AccessibilityTextOperationType::Lowercase;
</ins><span class="cx">         else if ([activityParameter isEqualToString:kAXSelectTextActivityFindAndUppercase])
</span><del>-            activity = AccessibilitySelectTextActivity::FindAndUppercase;
</del><ins>+            operation.type = AccessibilityTextOperationType::Uppercase;
</ins><span class="cx">     }
</span><del>-    
-    AccessibilitySelectTextAmbiguityResolution ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestTo;
</del><ins>+
+    criteria.direction = AccessibilitySearchTextDirection::Closest;
</ins><span class="cx">     if ([ambiguityResolutionParameter isKindOfClass:[NSString class]]) {
</span><span class="cx">         if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestAfterSelection])
</span><del>-            ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestAfter;
</del><ins>+            criteria.direction = AccessibilitySearchTextDirection::Forward;
</ins><span class="cx">         else if ([ambiguityResolutionParameter isEqualToString:NSAccessibilitySelectTextAmbiguityResolutionClosestBeforeSelection])
</span><del>-            ambiguityResolution = AccessibilitySelectTextAmbiguityResolution::ClosestBefore;
</del><ins>+            criteria.direction = AccessibilitySearchTextDirection::Backward;
</ins><span class="cx">     }
</span><del>-    
-    String replacementString;
</del><ins>+
</ins><span class="cx">     if ([replacementStringParameter isKindOfClass:[NSString class]])
</span><del>-        replacementString = replacementStringParameter;
-    
-    AccessibilitySelectTextCriteria criteria(activity, ambiguityResolution, replacementString);
-    
</del><ins>+        operation.replacementText = replacementStringParameter;
+
</ins><span class="cx">     if ([searchStringsParameter isKindOfClass:[NSArray class]]) {
</span><span class="cx">         size_t searchStringsCount = static_cast<size_t>([searchStringsParameter count]);
</span><span class="cx">         criteria.searchStrings.reserveInitialCapacity(searchStringsCount);
</span><span class="lines">@@ -545,10 +651,78 @@
</span><span class="cx">                 criteria.searchStrings.uncheckedAppend(searchString);
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    return std::make_pair(criteria, operation);
+}
+
+static AccessibilitySearchTextCriteria accessibilitySearchTextCriteriaForParameterizedAttribute(const NSDictionary *params)
+{
+    AccessibilitySearchTextCriteria criteria;
+
+    NSArray *searchStrings = [params objectForKey:NSAccessibilitySearchTextSearchStrings];
+    NSString *start = [params objectForKey:NSAccessibilitySearchTextStartFrom];
+    NSString *direction = [params objectForKey:NSAccessibilitySearchTextDirection];
+
+    if ([searchStrings isKindOfClass:[NSArray class]]) {
+        size_t searchStringsCount = static_cast<size_t>([searchStrings count]);
+        criteria.searchStrings.reserveInitialCapacity(searchStringsCount);
+        for (NSString *searchString in searchStrings) {
+            if ([searchString isKindOfClass:[NSString class]])
+                criteria.searchStrings.uncheckedAppend(searchString);
+        }
+    }
+
+    if ([start isKindOfClass:[NSString class]]) {
+        if ([start isEqualToString:NSAccessibilitySearchTextStartFromBegin])
+            criteria.start = AccessibilitySearchTextStartFrom::Begin;
+        else if ([start isEqualToString:NSAccessibilitySearchTextStartFromEnd])
+            criteria.start = AccessibilitySearchTextStartFrom::End;
+    }
+
+    if ([direction isKindOfClass:[NSString class]]) {
+        if ([direction isEqualToString:NSAccessibilitySearchTextDirectionBackward])
+            criteria.direction = AccessibilitySearchTextDirection::Backward;
+        else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionClosest])
+            criteria.direction = AccessibilitySearchTextDirection::Closest;
+        else if ([direction isEqualToString:NSAccessibilitySearchTextDirectionAll])
+            criteria.direction = AccessibilitySearchTextDirection::All;
+    }
+
</ins><span class="cx">     return criteria;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static AccessibilityTextOperation accessibilityTextOperationForParameterizedAttribute(WebAccessibilityObjectWrapper *obj, const NSDictionary *parameterizedAttribute)
+{
+    AccessibilityTextOperation operation;
+
+    NSArray *markerRanges = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationMarkerRanges];
+    NSString *operationType = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationType];
+    NSString *replacementString = [parameterizedAttribute objectForKey:NSAccessibilityTextOperationReplacementString];
+
+    if ([markerRanges isKindOfClass:[NSArray class]]) {
+        size_t count = static_cast<size_t>(markerRanges.count);
+        operation.textRanges.reserveInitialCapacity(count);
+        for (id markerRange : markerRanges)
+            operation.textRanges.append([obj rangeForTextMarkerRange:markerRange]);
+    }
+
+    if ([operationType isKindOfClass:[NSString class]]) {
+        if ([operationType isEqualToString:NSAccessibilityTextOperationReplace])
+            operation.type = AccessibilityTextOperationType::Replace;
+        else if ([operationType isEqualToString:NSAccessibilityTextOperationCapitalize])
+            operation.type = AccessibilityTextOperationType::Capitalize;
+        else if ([operationType isEqualToString:NSAccessibilityTextOperationLowercase])
+            operation.type = AccessibilityTextOperationType::Lowercase;
+        else if ([operationType isEqualToString:NSAccessibilityTextOperationUppercase])
+            operation.type = AccessibilityTextOperationType::Uppercase;
+    }
+
+    if ([replacementString isKindOfClass:[NSString class]])
+        operation.replacementText = replacementString;
+
+    return operation;
+}
+
</ins><span class="cx"> #pragma mark Text Marker helpers
</span><span class="cx"> 
</span><span class="cx"> static BOOL getBytesFromAXTextMarker(CFTypeRef textMarker, void* bytes, size_t length)
</span><span class="lines">@@ -3439,6 +3613,8 @@
</span><span class="cx">             NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute,
</span><span class="cx">             NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute,
</span><span class="cx">             NSAccessibilitySelectTextWithCriteriaParameterizedAttribute,
</span><ins>+            NSAccessibilitySearchTextWithCriteriaParameterizedAttribute,
+            NSAccessibilityTextOperationParameterizedAttribute,
</ins><span class="cx">             nil];
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -3990,10 +4166,41 @@
</span><span class="cx">     
</span><span class="cx">     // dispatch
</span><span class="cx">     if ([attribute isEqualToString:NSAccessibilitySelectTextWithCriteriaParameterizedAttribute]) {
</span><del>-        AccessibilitySelectTextCriteria criteria = accessibilitySelectTextCriteriaForCriteriaParameterizedAttribute(dictionary);
-        return m_object->selectText(&criteria);
</del><ins>+        // To be deprecated.
+        auto criteria = accessibilityTextCriteriaForParameterizedAttribute(dictionary);
+        criteria.second.textRanges = m_object->findTextRanges(criteria.first);
+        ASSERT(criteria.second.textRanges.size() <= 1);
+        Vector<String> result = m_object->performTextOperation(criteria.second);
+        ASSERT(result.size() <= 1);
+        if (result.size() > 0)
+            return result[0];
+        return String();
</ins><span class="cx">     }
</span><del>-    
</del><ins>+
+    if ([attribute isEqualToString:NSAccessibilitySearchTextWithCriteriaParameterizedAttribute]) {
+        auto criteria = accessibilitySearchTextCriteriaForParameterizedAttribute(dictionary);
+        auto ranges = m_object->findTextRanges(criteria);
+        if (ranges.isEmpty())
+            return nil;
+        NSMutableArray *markers = [NSMutableArray arrayWithCapacity:ranges.size()];
+        for (auto range : ranges) {
+            if (id marker = [self textMarkerRangeFromRange:range])
+                [markers addObject:marker];
+        }
+        return markers;
+    }
+
+    if ([attribute isEqualToString:NSAccessibilityTextOperationParameterizedAttribute]) {
+        auto textOperation = accessibilityTextOperationForParameterizedAttribute(self, dictionary);
+        auto operationResult = m_object->performTextOperation(textOperation);
+        if (operationResult.isEmpty())
+            return nil;
+        NSMutableArray *result = [NSMutableArray arrayWithCapacity:operationResult.size()];
+        for (auto str : operationResult)
+            [result addObject:str];
+        return result;
+    }
+
</ins><span class="cx">     if ([attribute isEqualToString:NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute]) {
</span><span class="cx">         AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
</span><span class="cx">         AccessibilityObject::AccessibilityChildrenVector results;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/ChangeLog       2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2019-04-23  Andres Gonzalez  <andresg_22@apple.com>
+
+        Accessibility text search and selection API enhancements.
+        https://bugs.webkit.org/show_bug.cgi?id=197095
+        <rdar://problem/48181791>
+
+        Reviewed by Chris Fleizach.
+
+        Added new API JS binding code for searchTextWithCriteria to both WTR and DRT.
+
+        * DumpRenderTree/AccessibilityTextMarker.h:
+        * DumpRenderTree/AccessibilityUIElement.cpp:
+        (searchTextWithCriteriaCallback):
+        (AccessibilityUIElement::getJSClass):
+        * DumpRenderTree/AccessibilityUIElement.h:
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (convertVectorToObjectArray):
+        (convertNSArrayToVector):
+        (searchTextParameterizedAttributeForCriteria):
+        (AccessibilityUIElement::getLinkedUIElements):
+        (AccessibilityUIElement::getDocumentLinks):
+        (AccessibilityUIElement::getChildren):
+        (AccessibilityUIElement::getChildrenWithRange):
+        (AccessibilityUIElement::rowHeaders const):
+        (AccessibilityUIElement::columnHeaders const):
+        (AccessibilityUIElement::uiElementArrayAttributeValue const):
+        (AccessibilityUIElement::searchTextWithCriteria):
+        (AccessibilityUIElement::attributesOfColumnHeaders):
+        (AccessibilityUIElement::attributesOfRowHeaders):
+        (AccessibilityUIElement::attributesOfColumns):
+        (AccessibilityUIElement::attributesOfRows):
+        (AccessibilityUIElement::attributesOfVisibleCells):
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+        (WTR::convertVectorToObjectArray):
+        (WTR::convertNSArrayToVector):
+        (WTR::searchTextParameterizedAttributeForCriteria):
+        (WTR::AccessibilityUIElement::getLinkedUIElements):
+        (WTR::AccessibilityUIElement::getDocumentLinks):
+        (WTR::AccessibilityUIElement::getUIElementsWithAttribute const):
+        (WTR::AccessibilityUIElement::getChildren):
+        (WTR::AccessibilityUIElement::getChildrenWithRange):
+        (WTR::AccessibilityUIElement::rowHeaders const):
+        (WTR::AccessibilityUIElement::columnHeaders const):
+        (WTR::AccessibilityUIElement::uiElementArrayAttributeValue const):
+        (WTR::AccessibilityUIElement::searchTextWithCriteria):
+        (WTR::AccessibilityUIElement::attributesOfColumnHeaders):
+        (WTR::AccessibilityUIElement::attributesOfRowHeaders):
+        (WTR::AccessibilityUIElement::attributesOfColumns):
+        (WTR::AccessibilityUIElement::attributesOfRows):
+        (WTR::AccessibilityUIElement::attributesOfVisibleCells):
+        (WTR::convertElementsToObjectArray): Deleted.
+
</ins><span class="cx"> 2019-04-23  Guy Lewin  <guy@lewin.co.il>
</span><span class="cx"> 
</span><span class="cx">         Multiple File Input Icon Set Regardless of File List
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeAccessibilityTextMarkerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/AccessibilityTextMarker.h (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/AccessibilityTextMarker.h     2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/DumpRenderTree/AccessibilityTextMarker.h        2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -75,9 +75,10 @@
</span><span class="cx">     
</span><span class="cx">     static JSObjectRef makeJSAccessibilityTextMarkerRange(JSContextRef, const AccessibilityTextMarkerRange&);
</span><span class="cx">     bool isEqual(AccessibilityTextMarkerRange*);
</span><del>-    
</del><ins>+
+    static JSClassRef getJSClass();
+
</ins><span class="cx"> private:
</span><del>-    static JSClassRef getJSClass();
</del><span class="cx"> #if SUPPORTS_AX_TEXTMARKERS && PLATFORM(MAC)
</span><span class="cx">     RetainPtr<PlatformTextMarkerRange> m_textMarkerRange;
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeAccessibilityUIElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp    2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp       2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -279,6 +279,24 @@
</span><span class="cx">     return JSValueMakeString(context, result.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+static JSValueRef searchTextWithCriteriaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    JSValueRef searchStrings = arguments[0];
+    JSRetainPtr<JSStringRef> startFrom;
+    if (argumentCount > 1)
+        startFrom = adopt(JSValueToStringCopy(context, arguments[1], exception));
+    JSRetainPtr<JSStringRef> direction;
+    if (argumentCount > 2)
+        direction = adopt(JSValueToStringCopy(context, arguments[2], exception));
+
+    return toAXElement(thisObject)->searchTextWithCriteria(context, searchStrings, startFrom.get(), direction.get());
+}
+#endif
+
</ins><span class="cx"> static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
</span><span class="cx"> {
</span><span class="cx">     if (argumentCount != 1)
</span><span class="lines">@@ -1896,6 +1914,9 @@
</span><span class="cx">         { "uiElementCountForSearchPredicate", uiElementCountForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span><span class="cx">         { "uiElementForSearchPredicate", uiElementForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span><span class="cx">         { "selectTextWithCriteria", selectTextWithCriteriaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span><ins>+#if PLATFORM(MAC)
+        { "searchTextWithCriteria", searchTextWithCriteriaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+#endif
</ins><span class="cx">         { "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span><span class="cx">         { "linkedUIElementAtIndex", linkedUIElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span><span class="cx">         { "indexOfChild", indexOfChildCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeAccessibilityUIElementh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.h (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.h      2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.h 2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -218,6 +218,10 @@
</span><span class="cx">     unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
</span><span class="cx">     AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
</span><span class="cx">     JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity);
</span><ins>+#if PLATFORM(MAC)
+    JSValueRef searchTextWithCriteria(JSContextRef, JSValueRef searchStrings, JSStringRef StartFrom, JSStringRef direction);
+#endif
+
</ins><span class="cx"> #if PLATFORM(IOS_FAMILY)
</span><span class="cx">     void elementsForRange(unsigned location, unsigned length, Vector<AccessibilityUIElement>& elements);
</span><span class="cx">     JSRetainPtr<JSStringRef> stringForSelection();
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacAccessibilityUIElementMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm      2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm 2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -178,6 +178,18 @@
</span><span class="cx">     return attributesString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template<typename T>
+static JSValueRef convertVectorToObjectArray(JSContextRef context, Vector<T> const& elements)
+{
+    JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
+    JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
+    size_t elementCount = elements.size();
+    for (size_t i = 0; i < elementCount; ++i)
+        JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i].getJSClass(), new T(elements[i])), 0);
+
+    return arrayResult;
+}
+
</ins><span class="cx"> static JSRetainPtr<JSStringRef> concatenateAttributeAndValue(NSString *attribute, NSString *value)
</span><span class="cx"> {
</span><span class="cx">     Vector<UniChar> buffer([attribute length]);
</span><span class="lines">@@ -192,11 +204,15 @@
</span><span class="cx">     return adopt(JSStringCreateWithCharacters(buffer.data(), buffer.size()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void convertNSArrayToVector(NSArray* array, Vector<AccessibilityUIElement>& elementVector)
</del><ins>+template<typename T>
+static Vector<T> convertNSArrayToVector(NSArray *array)
</ins><span class="cx"> {
</span><del>-    NSUInteger count = [array count];
</del><ins>+    Vector<T> v;
+    NSUInteger count = array.count;
+    v.reserveInitialCapacity(count);
</ins><span class="cx">     for (NSUInteger i = 0; i < count; ++i)
</span><del>-        elementVector.append(AccessibilityUIElement([array objectAtIndex:i]));
</del><ins>+        v.append([array objectAtIndex:i]);
+    return v;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static JSRetainPtr<JSStringRef> descriptionOfElements(Vector<AccessibilityUIElement>& elementVector)
</span><span class="lines">@@ -255,11 +271,50 @@
</span><span class="cx">     return parameterizedAttribute;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+static NSDictionary *searchTextParameterizedAttributeForCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction)
+{
+    NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary];
+
+    if (searchStrings) {
+        NSMutableArray *searchStringsParameter = [NSMutableArray array];
+        if (JSValueIsString(context, searchStrings)) {
+            auto searchStringsString = adopt(JSValueToStringCopy(context, searchStrings, nullptr));
+            if (searchStringsString)
+                [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
+        } else if (JSValueIsObject(context, searchStrings)) {
+            JSObjectRef searchStringsArray = JSValueToObject(context, searchStrings, nullptr);
+            unsigned searchStringsArrayLength = 0;
+
+            auto lengthPropertyString = adopt(JSStringCreateWithUTF8CString("length"));
+            JSValueRef searchStringsArrayLengthValue = JSObjectGetProperty(context, searchStringsArray, lengthPropertyString.get(), nullptr);
+            if (searchStringsArrayLengthValue && JSValueIsNumber(context, searchStringsArrayLengthValue))
+                searchStringsArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchStringsArrayLengthValue, nullptr));
+
+            for (unsigned i = 0; i < searchStringsArrayLength; ++i) {
+                auto searchStringsString = adopt(JSValueToStringCopy(context, JSObjectGetPropertyAtIndex(context, searchStringsArray, i, nullptr), nullptr));
+                if (searchStringsString)
+                    [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
+            }
+        }
+        [parameterizedAttribute setObject:searchStringsParameter forKey:@"AXSearchTextSearchStrings"];
+    }
+
+    if (startFrom)
+        [parameterizedAttribute setObject:[NSString stringWithJSStringRef:startFrom] forKey:@"AXSearchTextStartFrom"];
+
+    if (direction)
+        [parameterizedAttribute setObject:[NSString stringWithJSStringRef:direction] forKey:@"AXSearchTextDirection"];
+
+    return parameterizedAttribute;
+}
+#endif
+
</ins><span class="cx"> void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
</span><del>-    convertNSArrayToVector(linkedElements, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<AccessibilityUIElement>(linkedElements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -267,7 +322,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
</span><del>-    convertNSArrayToVector(linkElements, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<AccessibilityUIElement>(linkElements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -275,7 +330,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
</span><del>-    convertNSArrayToVector(children, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<AccessibilityUIElement>(children);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -283,7 +338,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length];
</span><del>-    convertNSArrayToVector(children, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<AccessibilityUIElement>(children);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -492,7 +547,7 @@
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:NSAccessibilityRowHeaderUIElementsAttribute];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
</del><ins>+        elements = convertNSArrayToVector<AccessibilityUIElement>(value);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -501,7 +556,7 @@
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:NSAccessibilityColumnHeaderUIElementsAttribute];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
</del><ins>+        elements = convertNSArrayToVector<AccessibilityUIElement>(value);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -510,7 +565,7 @@
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
</del><ins>+        elements = convertNSArrayToVector<AccessibilityUIElement>(value);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1103,13 +1158,25 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction)
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    NSDictionary *parameterizedAttribute = searchTextParameterizedAttributeForCriteria(context, searchStrings, startFrom, direction);
+    id result = [m_element accessibilityAttributeValue:@"AXSearchTextWithCriteria" forParameter:parameterizedAttribute];
+    if ([result isKindOfClass:[NSArray class]])
+        return convertVectorToObjectArray<AccessibilityTextMarkerRange>(context, convertNSArrayToVector<AccessibilityTextMarkerRange>(result));
+    END_AX_OBJC_EXCEPTIONS
+    return nullptr;
+}
+#endif
+
</ins><span class="cx"> JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
</span><span class="cx"> {
</span><span class="cx">     // not yet defined in AppKit... odd
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
</span><del>-    Vector<AccessibilityUIElement> columnHeadersVector;
-    convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
</del><ins>+    auto columnHeadersVector = convertNSArrayToVector<AccessibilityUIElement>(columnHeadersArray);
</ins><span class="cx">     return descriptionOfElements(columnHeadersVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1120,8 +1187,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
</span><del>-    Vector<AccessibilityUIElement> rowHeadersVector;
-    convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
</del><ins>+    auto rowHeadersVector = convertNSArrayToVector<AccessibilityUIElement>(rowHeadersArray);
</ins><span class="cx">     return descriptionOfElements(rowHeadersVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1132,8 +1198,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
</span><del>-    Vector<AccessibilityUIElement> columnsVector;
-    convertNSArrayToVector(columnsArray, columnsVector);
</del><ins>+    auto columnsVector = convertNSArrayToVector<AccessibilityUIElement>(columnsArray);
</ins><span class="cx">     return descriptionOfElements(columnsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1144,8 +1209,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
</span><del>-    Vector<AccessibilityUIElement> rowsVector;
-    convertNSArrayToVector(rowsArray, rowsVector);
</del><ins>+    auto rowsVector = convertNSArrayToVector<AccessibilityUIElement>(rowsArray);
</ins><span class="cx">     return descriptionOfElements(rowsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1156,8 +1220,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
</span><del>-    Vector<AccessibilityUIElement> cellsVector;
-    convertNSArrayToVector(cellsArray, cellsVector);
</del><ins>+    auto cellsVector = convertNSArrayToVector<AccessibilityUIElement>(cellsArray);
</ins><span class="cx">     return descriptionOfElements(cellsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleAccessibilityUIElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp   2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp      2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -91,6 +91,7 @@
</span><span class="cx"> void AccessibilityUIElement::resetSelectedTextMarkerRange() { }
</span><span class="cx"> void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { }
</span><span class="cx"> void AccessibilityUIElement::setValue(JSStringRef) { }
</span><ins>+JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef, JSValueRef, JSStringRef, JSStringRef) { return nullptr; }
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(COCOA) || !HAVE(ACCESSIBILITY)
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleAccessibilityUIElementh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h     2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h        2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -255,6 +255,7 @@
</span><span class="cx">     unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
</span><span class="cx">     RefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly, bool immediateDescendantsOnly);
</span><span class="cx">     JSRetainPtr<JSStringRef> selectTextWithCriteria(JSContextRef, JSStringRef ambiguityResolution, JSValueRef searchStrings, JSStringRef replacementString, JSStringRef activity);
</span><ins>+    JSValueRef searchTextWithCriteria(JSContextRef, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction);
</ins><span class="cx"> 
</span><span class="cx">     // Text-specific
</span><span class="cx">     JSRetainPtr<JSStringRef> characterAtOffset(int offset);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundleBindingsAccessibilityUIElementidl"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl  2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl     2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -183,6 +183,7 @@
</span><span class="cx">     [PassContext] unsigned long uiElementCountForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
</span><span class="cx">     [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly, boolean immediateDescendantsOnly);
</span><span class="cx">     [PassContext] DOMString selectTextWithCriteria(DOMString ambiguityResolution, object searchStrings, DOMString replacementString, DOMString activity);
</span><ins>+    [PassContext] object searchTextWithCriteria(object searchStrings, DOMString startFrom, DOMString direction);
</ins><span class="cx">     boolean setSelectedTextRange(unsigned long location, unsigned long length);
</span><span class="cx"> 
</span><span class="cx">     // Scroll area attributes.
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerInjectedBundlemacAccessibilityUIElementMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (244560 => 244561)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm     2019-04-23 20:31:02 UTC (rev 244560)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm        2019-04-23 20:31:51 UTC (rev 244561)
</span><span class="lines">@@ -192,7 +192,8 @@
</span><span class="cx">     return attributesString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static JSValueRef convertElementsToObjectArray(JSContextRef context, Vector<RefPtr<AccessibilityUIElement>>& elements)
</del><ins>+template<typename T>
+static JSValueRef convertVectorToObjectArray(JSContextRef context, Vector<T> const& elements)
</ins><span class="cx"> {
</span><span class="cx">     JSValueRef arrayResult = JSObjectMakeArray(context, 0, 0, 0);
</span><span class="cx">     JSObjectRef arrayObj = JSValueToObject(context, arrayResult, 0);
</span><span class="lines">@@ -199,7 +200,7 @@
</span><span class="cx">     size_t elementCount = elements.size();
</span><span class="cx">     for (size_t i = 0; i < elementCount; ++i)
</span><span class="cx">         JSObjectSetPropertyAtIndex(context, arrayObj, i, JSObjectMake(context, elements[i]->wrapperClass(), elements[i].get()), 0);
</span><del>-    
</del><ins>+
</ins><span class="cx">     return arrayResult;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -217,11 +218,15 @@
</span><span class="cx">     return adopt(JSStringCreateWithCharacters(buffer.data(), buffer.size()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void convertNSArrayToVector(NSArray* array, Vector<RefPtr<AccessibilityUIElement> >& elementVector)
</del><ins>+template<typename T>
+static Vector<T> convertNSArrayToVector(NSArray *array)
</ins><span class="cx"> {
</span><del>-    NSUInteger count = [array count];
</del><ins>+    Vector<T> v;
+    NSUInteger count = array.count;
+    v.reserveInitialCapacity(count);
</ins><span class="cx">     for (NSUInteger i = 0; i < count; ++i)
</span><del>-        elementVector.append(AccessibilityUIElement::create([array objectAtIndex:i]));
</del><ins>+        v.append(T::ValueType::create([array objectAtIndex:i]));
+    return v;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static JSRetainPtr<JSStringRef> descriptionOfElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
</span><span class="lines">@@ -281,11 +286,48 @@
</span><span class="cx">     return parameterizedAttribute;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static NSDictionary *searchTextParameterizedAttributeForCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction)
+{
+    NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary];
+
+    if (searchStrings) {
+        NSMutableArray *searchStringsParameter = [NSMutableArray array];
+        if (JSValueIsString(context, searchStrings)) {
+            auto searchStringsString = adopt(JSValueToStringCopy(context, searchStrings, nullptr));
+            if (searchStringsString)
+                [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
+        } else if (JSValueIsObject(context, searchStrings)) {
+            JSObjectRef searchStringsArray = JSValueToObject(context, searchStrings, nullptr);
+            unsigned searchStringsArrayLength = 0;
+
+            auto lengthPropertyString = adopt(JSStringCreateWithUTF8CString("length"));
+            JSValueRef searchStringsArrayLengthValue = JSObjectGetProperty(context, searchStringsArray, lengthPropertyString.get(), nullptr);
+            if (searchStringsArrayLengthValue && JSValueIsNumber(context, searchStringsArrayLengthValue))
+                searchStringsArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchStringsArrayLengthValue, nullptr));
+
+            for (unsigned i = 0; i < searchStringsArrayLength; ++i) {
+                auto searchStringsString = adopt(JSValueToStringCopy(context, JSObjectGetPropertyAtIndex(context, searchStringsArray, i, nullptr), nullptr));
+                if (searchStringsString)
+                    [searchStringsParameter addObject:[NSString stringWithJSStringRef:searchStringsString.get()]];
+            }
+        }
+        [parameterizedAttribute setObject:searchStringsParameter forKey:@"AXSearchTextSearchStrings"];
+    }
+
+    if (startFrom)
+        [parameterizedAttribute setObject:[NSString stringWithJSStringRef:startFrom] forKey:@"AXSearchTextStartFrom"];
+
+    if (direction)
+        [parameterizedAttribute setObject:[NSString stringWithJSStringRef:direction] forKey:@"AXSearchTextDirection"];
+
+    return parameterizedAttribute;
+}
+
</ins><span class="cx"> void AccessibilityUIElement::getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* linkedElements = [m_element accessibilityAttributeValue:NSAccessibilityLinkedUIElementsAttribute];
</span><del>-    convertNSArrayToVector(linkedElements, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(linkedElements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -293,7 +335,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* linkElements = [m_element accessibilityAttributeValue:@"AXLinkUIElements"];
</span><del>-    convertNSArrayToVector(linkElements, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(linkElements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -302,7 +344,7 @@
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:[NSString stringWithJSStringRef:attribute]];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
</del><ins>+        elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -310,7 +352,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* children = [m_element accessibilityAttributeValue:NSAccessibilityChildrenAttribute];
</span><del>-    convertNSArrayToVector(children, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(children);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -318,7 +360,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* children = [m_element accessibilityArrayAttributeValues:NSAccessibilityChildrenAttribute index:location maxCount:length];
</span><del>-    convertNSArrayToVector(children, elementVector);
</del><ins>+    elementVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(children);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -331,8 +373,8 @@
</span><span class="cx">     Vector<RefPtr<AccessibilityUIElement>> elements;
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:NSAccessibilityRowHeaderUIElementsAttribute];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
-    return convertElementsToObjectArray(context, elements);
</del><ins>+        elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value);
+    return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -345,8 +387,8 @@
</span><span class="cx">     Vector<RefPtr<AccessibilityUIElement>> elements;
</span><span class="cx">     id value = [m_element accessibilityAttributeValue:NSAccessibilityColumnHeaderUIElementsAttribute];
</span><span class="cx">     if ([value isKindOfClass:[NSArray class]])
</span><del>-        convertNSArrayToVector(value, elements);
-    return convertElementsToObjectArray(context, elements);
</del><ins>+        elements = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(value);
+    return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements);
</ins><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx"> }
</span><span class="cx">     
</span><span class="lines">@@ -596,7 +638,7 @@
</span><span class="cx">     
</span><span class="cx">     Vector<RefPtr<AccessibilityUIElement>> elements;
</span><span class="cx">     getUIElementsWithAttribute(attribute, elements);
</span><del>-    return convertElementsToObjectArray(context, elements);
</del><ins>+    return convertVectorToObjectArray<RefPtr<AccessibilityUIElement>>(context, elements);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementAttributeValue(JSStringRef attribute) const
</span><span class="lines">@@ -1199,13 +1241,26 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef context, JSValueRef searchStrings, JSStringRef startFrom, JSStringRef direction)
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    NSDictionary *parameterizedAttribute = searchTextParameterizedAttributeForCriteria(context, searchStrings, startFrom, direction);
+    id result = [m_element accessibilityAttributeValue:@"AXSearchTextWithCriteria" forParameter:parameterizedAttribute];
+    if ([result isKindOfClass:[NSArray class]])
+        return convertVectorToObjectArray<RefPtr<AccessibilityTextMarkerRange>>(context, convertNSArrayToVector<RefPtr<AccessibilityTextMarkerRange>>(result));
+    END_AX_OBJC_EXCEPTIONS
+
+    return nullptr;
+}
+#endif
+
</ins><span class="cx"> JSRetainPtr<JSStringRef> AccessibilityUIElement::attributesOfColumnHeaders()
</span><span class="cx"> {
</span><span class="cx">     // not yet defined in AppKit... odd
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* columnHeadersArray = [m_element accessibilityAttributeValue:@"AXColumnHeaderUIElements"];
</span><del>-    Vector<RefPtr<AccessibilityUIElement> > columnHeadersVector;
-    convertNSArrayToVector(columnHeadersArray, columnHeadersVector);
</del><ins>+    auto columnHeadersVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(columnHeadersArray);
</ins><span class="cx">     return descriptionOfElements(columnHeadersVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1216,8 +1271,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* rowHeadersArray = [m_element accessibilityAttributeValue:@"AXRowHeaderUIElements"];
</span><del>-    Vector<RefPtr<AccessibilityUIElement> > rowHeadersVector;
-    convertNSArrayToVector(rowHeadersArray, rowHeadersVector);
</del><ins>+    auto rowHeadersVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(rowHeadersArray);
</ins><span class="cx">     return descriptionOfElements(rowHeadersVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1228,8 +1282,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* columnsArray = [m_element accessibilityAttributeValue:NSAccessibilityColumnsAttribute];
</span><del>-    Vector<RefPtr<AccessibilityUIElement> > columnsVector;
-    convertNSArrayToVector(columnsArray, columnsVector);
</del><ins>+    auto columnsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(columnsArray);
</ins><span class="cx">     return descriptionOfElements(columnsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1240,8 +1293,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* rowsArray = [m_element accessibilityAttributeValue:NSAccessibilityRowsAttribute];
</span><del>-    Vector<RefPtr<AccessibilityUIElement> > rowsVector;
-    convertNSArrayToVector(rowsArray, rowsVector);
</del><ins>+    auto rowsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(rowsArray);
</ins><span class="cx">     return descriptionOfElements(rowsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span><span class="lines">@@ -1252,8 +1304,7 @@
</span><span class="cx"> {
</span><span class="cx">     BEGIN_AX_OBJC_EXCEPTIONS
</span><span class="cx">     NSArray* cellsArray = [m_element accessibilityAttributeValue:@"AXVisibleCells"];
</span><del>-    Vector<RefPtr<AccessibilityUIElement> > cellsVector;
-    convertNSArrayToVector(cellsArray, cellsVector);
</del><ins>+    auto cellsVector = convertNSArrayToVector<RefPtr<AccessibilityUIElement>>(cellsArray);
</ins><span class="cx">     return descriptionOfElements(cellsVector);
</span><span class="cx">     END_AX_OBJC_EXCEPTIONS
</span><span class="cx">     
</span></span></pre>
</div>
</div>

</body>
</html>