AX: Add AXUIElementCountForSearchPredicate parameterized attribute.

    https://bugs.webkit.org/show_bug.cgi?id=124561

    Reviewed by Chris Fleizach.

    Added test to verify that NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute
    works as it should and updated existing test that has exposes this new attribute.

    * platform/mac/accessibility/bounds-for-range-expected.txt:
    * platform/mac/accessibility/search-predicate-element-count-expected.txt: Added.
    * platform/mac/accessibility/search-predicate-element-count.html: Added.

    Added ability to fetch the number of elements that match a specific criteria. This will enable VoiceOver
    to interface with WebKit much more dynamically. We can now get an idea of how many interesting elements
    exist on a page, and then fetch them in chunks as needed.

    Test: platform/mac/accessibility/search-predicate-element-count.html

    * accessibility/AccessibilityObject.cpp:
    (WebCore::AccessibilityObject::isAccessibilityTextSearchMatch):
    * accessibility/AccessibilityObject.h:
    (WebCore::AccessibilitySearchCriteria::AccessibilitySearchCriteria):
    * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
    (accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute):
    (-[WebAccessibilityObjectWrapper accessibilityParameterizedAttributeNames]):
    (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):

    Added function to verify that NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute works as it should.

    * DumpRenderTree/AccessibilityUIElement.cpp:
    (uiElementCountForSearchPredicateCallback):
    (uiElementForSearchPredicateCallback):
    (AccessibilityUIElement::getJSClass):
    * DumpRenderTree/AccessibilityUIElement.h:
    * DumpRenderTree/atk/AccessibilityUIElementAtk.cpp:
    (AccessibilityUIElement::uiElementCountForSearchPredicate):
    * DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
    (AccessibilityUIElement::uiElementCountForSearchPredicate):
    * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
    (searchPredicateParameterizedAttributeForSearchCriteria):
    (AccessibilityUIElement::uiElementCountForSearchPredicate):
    (AccessibilityUIElement::uiElementForSearchPredicate):
    * DumpRenderTree/win/AccessibilityUIElementWin.cpp:
    (AccessibilityUIElement::uiElementCountForSearchPredicate):
    * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
    (WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
    * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
    * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
    * WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp:
    (WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
    * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
    (WTR::searchPredicateParameterizedAttributeForSearchCriteria):
    (WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
    (WTR::AccessibilityUIElement::uiElementForSearchPredicate):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159980 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent fa49c82a
2013-12-02 Samuel White <samuel_white@apple.com>
AX: Add AXUIElementCountForSearchPredicate parameterized attribute.
https://bugs.webkit.org/show_bug.cgi?id=124561
Reviewed by Chris Fleizach.
Added test to verify that NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute
works as it should and updated existing test that has exposes this new attribute.
* platform/mac/accessibility/bounds-for-range-expected.txt:
* platform/mac/accessibility/search-predicate-element-count-expected.txt: Added.
* platform/mac/accessibility/search-predicate-element-count.html: Added.
2013-12-02 Bem Jones-Bey <bjonesbe@adobe.com>
[css shapes] Layout support for new circle shape syntax
......
......@@ -55,6 +55,7 @@ AXStyleTextMarkerRangeForTextMarker
AXLengthForTextMarkerRange
AXBoundsForRange
AXStringForRange
AXUIElementCountForSearchPredicate
AXUIElementsForSearchPredicate
AXEndTextMarkerForBounds
AXStartTextMarkerForBounds
......
This tests that search predicate based element count results are accurate.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS elementCount is 2
PASS elementCount is 3
PASS elementCount is 4
PASS elementCount is 5
PASS elementCount is 6
PASS elementCount is 6
PASS elementCount is 4
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
<style>
.offscreen {
position:relative;
top:9999px;
}
</style>
<title>Search Predicate Element Count</title>
</head>
<body>
<div id="container">
<p id="start">Start</p>
<!-- Tables. -->
<table border="1">
<tr><th>A</th><th>B</th></tr>
<tr><td>C</td><td>D</td></tr>
</table>
<table border="1">
<tr><th>W</th><th>X</th></tr>
<tr><td>Y</td><td>Z</td></tr>
</table>
<br>
<!-- Links. -->
<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
<br>
<!-- Images. -->
<img alt="Cake" src="resources/cake.png">
<img alt="Cake" src="resources/cake.png">
<img alt="Cake" src="resources/cake.png">
<img alt="Cake" src="resources/cake.png">
<br>
<!-- Inputs. -->
<input type="submit" value="Submit">
<input type="submit" value="Submit">
<input type="submit" value="Submit">
<input type="submit" value="Submit">
<input type="submit" value="Submit">
<br>
<!-- Headings. -->
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5 class="offscreen">Heading 5</h5>
<h6 class="offscreen">Heading 6</h6>
</div>
<p id="description"></p>
<div id="console"></div>
<script>
description("This tests that search predicate based element count results are accurate.");
if (window.accessibilityController) {
document.getElementById("container").focus();
var containerElement = accessibilityController.focusedElement;
var elementCount = 0;
var startElement = accessibilityController.accessibleElementById("start");
// Tables.
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXTableSearchKey", "", false);
shouldBe("elementCount", "2");
// Links.
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXLinkSearchKey", "", false);
shouldBe("elementCount", "3");
// Images.
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXGraphicSearchKey", "", false);
shouldBe("elementCount", "4");
// Inputs.
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
shouldBe("elementCount", "5");
// Headings.
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", false);
shouldBe("elementCount", "6");
// Onscreen
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", false);
shouldBe("elementCount", "6");
// Offscreen
elementCount = containerElement.uiElementCountForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", true);
shouldBe("elementCount", "4");
// Hide superfluous text.
document.getElementById("container").style.display = "none";
}
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
2013-12-02 Samuel White <samuel_white@apple.com>
AX: Add AXUIElementCountForSearchPredicate parameterized attribute.
https://bugs.webkit.org/show_bug.cgi?id=124561
Reviewed by Chris Fleizach.
Added ability to fetch the number of elements that match a specific criteria. This will enable VoiceOver
to interface with WebKit much more dynamically. We can now get an idea of how many interesting elements
exist on a page, and then fetch them in chunks as needed.
Test: platform/mac/accessibility/search-predicate-element-count.html
* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::isAccessibilityTextSearchMatch):
* accessibility/AccessibilityObject.h:
(WebCore::AccessibilitySearchCriteria::AccessibilitySearchCriteria):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute):
(-[WebAccessibilityObjectWrapper accessibilityParameterizedAttributeNames]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
2013-12-02 Bem Jones-Bey <bjonesbe@adobe.com>
[css shapes] Layout support for new circle shape syntax
......@@ -263,7 +263,7 @@ bool AccessibilityObject::isAccessibilityTextSearchMatch(AccessibilityObject* ax
if (!axObject || !criteria)
return false;
return axObject->accessibilityObjectContainsText(criteria->searchText);
return axObject->accessibilityObjectContainsText(&criteria->searchText);
}
bool AccessibilityObject::accessibilityObjectContainsText(String* text) const
......
......@@ -339,16 +339,16 @@ struct AccessibilitySearchCriteria {
AccessibilityObject* startObject;
AccessibilitySearchDirection searchDirection;
Vector<AccessibilitySearchKey> searchKeys;
String* searchText;
String searchText;
unsigned resultsLimit;
bool visibleOnly;
AccessibilitySearchCriteria(AccessibilityObject* o, AccessibilitySearchDirection d, String* t, unsigned l, bool v)
: startObject(o)
, searchDirection(d)
, searchText(t)
, resultsLimit(l)
, visibleOnly(v)
AccessibilitySearchCriteria(AccessibilityObject* startObject, AccessibilitySearchDirection searchDirection, String searchText, unsigned resultsLimit, bool visibleOnly)
: startObject(startObject)
, searchDirection(searchDirection)
, searchText(searchText)
, resultsLimit(resultsLimit)
, visibleOnly(visibleOnly)
{ }
};
......
......@@ -190,6 +190,10 @@ using namespace HTMLNames;
#endif
// Search
#ifndef NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute
#define NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute @"AXUIElementCountForSearchPredicate"
#endif
#ifndef NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute
#define NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute @"AXUIElementsForSearchPredicate"
#endif
......@@ -536,6 +540,52 @@ static AccessibilitySearchKey accessibilitySearchKeyForString(const String& valu
return searchKey ? searchKey : AnyTypeSearchKey;
}
static AccessibilitySearchCriteria accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(const NSDictionary *parameterizedAttribute)
{
NSString *directionParameter = [parameterizedAttribute objectForKey:@"AXDirection"];
NSNumber *resultsLimitParameter = [parameterizedAttribute objectForKey:@"AXResultsLimit"];
NSString *searchTextParameter = [parameterizedAttribute objectForKey:@"AXSearchText"];
WebAccessibilityObjectWrapper *startElementParameter = [parameterizedAttribute objectForKey:@"AXStartElement"];
NSNumber *visibleOnlyParameter = [parameterizedAttribute objectForKey:@"AXVisibleOnly"];
id searchKeyParameter = [parameterizedAttribute objectForKey:@"AXSearchKey"];
AccessibilitySearchDirection direction = SearchDirectionNext;
if ([directionParameter isKindOfClass:[NSString class]])
direction = [directionParameter isEqualToString:@"AXDirectionNext"] ? SearchDirectionNext : SearchDirectionPrevious;
unsigned resultsLimit = 0;
if ([resultsLimitParameter isKindOfClass:[NSNumber class]])
resultsLimit = [resultsLimitParameter unsignedIntValue];
String searchText;
if ([searchTextParameter isKindOfClass:[NSString class]])
searchText = searchTextParameter;
AccessibilityObject *startElement = nullptr;
if ([startElementParameter isKindOfClass:[WebAccessibilityObjectWrapper class]])
startElement = [startElementParameter accessibilityObject];
BOOL visibleOnly = NO;
if ([visibleOnlyParameter isKindOfClass:[NSNumber class]])
visibleOnly = [visibleOnlyParameter boolValue];
AccessibilitySearchCriteria criteria = AccessibilitySearchCriteria(startElement, direction, searchText, resultsLimit, visibleOnly);
if ([searchKeyParameter isKindOfClass:[NSString class]])
criteria.searchKeys.append(accessibilitySearchKeyForString(searchKeyParameter));
else if ([searchKeyParameter isKindOfClass:[NSArray class]]) {
size_t searchKeyCount = static_cast<size_t>([searchKeyParameter count]);
criteria.searchKeys.reserveInitialCapacity(searchKeyCount);
for (size_t i = 0; i < searchKeyCount; ++i) {
NSString *searchKey = [searchKeyParameter objectAtIndex:i];
if ([searchKey isKindOfClass:[NSString class]])
criteria.searchKeys.uncheckedAppend(accessibilitySearchKeyForString(searchKey));
}
}
return criteria;
}
#pragma mark Text Marker helpers
static id textMarkerForVisiblePosition(AXObjectCache* cache, const VisiblePosition& visiblePos)
......@@ -2865,6 +2915,7 @@ static NSString* roleValueToNSString(AccessibilityRole value)
@"AXLengthForTextMarkerRange",
NSAccessibilityBoundsForRangeParameterizedAttribute,
NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute,
NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute,
NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute,
NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute,
......@@ -3254,45 +3305,17 @@ static RenderObject* rendererForView(NSView* view)
}
// dispatch
if ([attribute isEqualToString:NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute]) {
AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
AccessibilityObject::AccessibilityChildrenVector results;
m_object->findMatchingObjects(&criteria, results);
return @(results.size());
}
if ([attribute isEqualToString:NSAccessibilityUIElementsForSearchPredicateParameterizedAttribute]) {
AccessibilityObject* startObject = 0;
if ([[dictionary objectForKey:@"AXStartElement"] isKindOfClass:[WebAccessibilityObjectWrapper self]])
startObject = [(WebAccessibilityObjectWrapper*)[dictionary objectForKey:@"AXStartElement"] accessibilityObject];
AccessibilitySearchDirection searchDirection = SearchDirectionNext;
if ([[dictionary objectForKey:@"AXDirection"] isKindOfClass:[NSString self]])
searchDirection = ([(NSString*)[dictionary objectForKey:@"AXDirection"] isEqualToString:@"AXDirectionNext"]) ? SearchDirectionNext : SearchDirectionPrevious;
String searchText;
if ([[dictionary objectForKey:@"AXSearchText"] isKindOfClass:[NSString self]])
searchText = (CFStringRef)[dictionary objectForKey:@"AXSearchText"];
unsigned resultsLimit = 0;
if ([[dictionary objectForKey:@"AXResultsLimit"] isKindOfClass:[NSNumber self]])
resultsLimit = [(NSNumber*)[dictionary objectForKey:@"AXResultsLimit"] unsignedIntValue];
BOOL visibleOnly = NO;
if ([[dictionary objectForKey:@"AXVisibleOnly"] isKindOfClass:[NSNumber self]])
visibleOnly = [(NSNumber*)[dictionary objectForKey:@"AXVisibleOnly"] boolValue];
AccessibilitySearchCriteria criteria = AccessibilitySearchCriteria(startObject, searchDirection, &searchText, resultsLimit, visibleOnly);
id searchKeyEntry = [dictionary objectForKey:@"AXSearchKey"];
if ([searchKeyEntry isKindOfClass:[NSString class]])
criteria.searchKeys.append(accessibilitySearchKeyForString((CFStringRef)searchKeyEntry));
else if ([searchKeyEntry isKindOfClass:[NSArray class]]) {
size_t length = static_cast<size_t>([(NSArray *)searchKeyEntry count]);
criteria.searchKeys.reserveInitialCapacity(length);
for (size_t i = 0; i < length; ++i) {
id searchKey = [(NSArray *)searchKeyEntry objectAtIndex:i];
if ([searchKey isKindOfClass:[NSString class]])
criteria.searchKeys.append(accessibilitySearchKeyForString((CFStringRef)searchKey));
}
}
AccessibilitySearchCriteria criteria = accessibilitySearchCriteriaForSearchPredicateParameterizedAttribute(dictionary);
AccessibilityObject::AccessibilityChildrenVector results;
m_object->findMatchingObjects(&criteria, results);
return convertToNSArray(results);
}
......
2013-12-02 Samuel White <samuel_white@apple.com>
AX: Add AXUIElementCountForSearchPredicate parameterized attribute.
https://bugs.webkit.org/show_bug.cgi?id=124561
Reviewed by Chris Fleizach.
Added function to verify that NSAccessibilityUIElementCountForSearchPredicateParameterizedAttribute works as it should.
* DumpRenderTree/AccessibilityUIElement.cpp:
(uiElementCountForSearchPredicateCallback):
(uiElementForSearchPredicateCallback):
(AccessibilityUIElement::getJSClass):
* DumpRenderTree/AccessibilityUIElement.h:
* DumpRenderTree/atk/AccessibilityUIElementAtk.cpp:
(AccessibilityUIElement::uiElementCountForSearchPredicate):
* DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
(AccessibilityUIElement::uiElementCountForSearchPredicate):
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(searchPredicateParameterizedAttributeForSearchCriteria):
(AccessibilityUIElement::uiElementCountForSearchPredicate):
(AccessibilityUIElement::uiElementForSearchPredicate):
* DumpRenderTree/win/AccessibilityUIElementWin.cpp:
(AccessibilityUIElement::uiElementCountForSearchPredicate):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp:
(WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::searchPredicateParameterizedAttributeForSearchCriteria):
(WTR::AccessibilityUIElement::uiElementCountForSearchPredicate):
(WTR::AccessibilityUIElement::uiElementForSearchPredicate):
2013-12-02 Dániel Bátyai <Batyai.Daniel@stud.u-szeged.hu>
Instead of a large 'if' block, each failure class should write it's own result in test_result_writer.py
......
......@@ -202,32 +202,52 @@ static JSValueRef attributedStringRangeIsMisspelledCallback(JSContextRef context
return JSValueMakeBoolean(context, toAXElement(thisObject)->attributedStringRangeIsMisspelled(location, length));
}
static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
static JSValueRef uiElementCountForSearchPredicateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityUIElement* startElement = 0;
AccessibilityUIElement* startElement = nullptr;
bool isDirectionNext = true;
JSValueRef searchKey = nullptr;
JSRetainPtr<JSStringRef> searchText = nullptr;
bool visibleOnly = false;
JSValueRef searchKey = 0;
JSStringRef searchText = 0;
if (argumentCount == 5) {
JSObjectRef startElementObject = JSValueToObject(context, arguments[0], exception);
if (startElementObject)
startElement = toAXElement(startElementObject);
isDirectionNext = JSValueToBoolean(context, arguments[1]);
if (JSValueIsObject(context, arguments[0]))
startElement = toAXElement(JSValueToObject(context, arguments[0], exception));
isDirectionNext = JSValueToBoolean(context, arguments[1]);
searchKey = arguments[2];
if (JSValueIsString(context, arguments[3]))
searchText = JSValueToStringCopy(context, arguments[3], exception);
searchText.adopt(JSValueToStringCopy(context, arguments[3], exception));
visibleOnly = JSValueToBoolean(context, arguments[4]);
}
JSObjectRef resultObject = AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText, visibleOnly));
return JSValueMakeNumber(context, toAXElement(thisObject)->uiElementCountForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly));
}
if (searchText)
JSStringRelease(searchText);
static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
AccessibilityUIElement* startElement = nullptr;
bool isDirectionNext = true;
JSValueRef searchKey = nullptr;
JSRetainPtr<JSStringRef> searchText = nullptr;
bool visibleOnly = false;
if (argumentCount == 5) {
if (JSValueIsObject(context, arguments[0]))
startElement = toAXElement(JSValueToObject(context, arguments[0], exception));
isDirectionNext = JSValueToBoolean(context, arguments[1]);
searchKey = arguments[2];
if (JSValueIsString(context, arguments[3]))
searchText.adopt(JSValueToStringCopy(context, arguments[3], exception));
visibleOnly = JSValueToBoolean(context, arguments[4]);
}
return resultObject;
return AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText.get(), visibleOnly));
}
static JSValueRef indexOfChildCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
......@@ -1390,6 +1410,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
{ "stringForRange", stringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "attributedStringForRange", attributedStringForRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "attributedStringRangeIsMisspelled", attributedStringRangeIsMisspelledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "uiElementCountForSearchPredicate", uiElementCountForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeReadOnly },
{ "uiElementForSearchPredicate", uiElementForSearchPredicateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "childAtIndex", childAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "linkedUIElementAtIndex", linkedUIElementAtIndexCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
......
......@@ -203,6 +203,7 @@ public:
JSStringRef stringForRange(unsigned location, unsigned length);
JSStringRef attributedStringForRange(unsigned location, unsigned length);
bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
unsigned uiElementCountForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
#if PLATFORM(IOS)
void elementsForRange(unsigned location, unsigned length, Vector<AccessibilityUIElement>& elements);
......
......@@ -1092,6 +1092,12 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
return false;
}
unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
// FIXME: implement
return 0;
}
AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
// FIXME: implement
......
......@@ -797,6 +797,12 @@ void AccessibilityUIElement::removeSelection()
// FIXME: implement
}
unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
// FIXME: implement
return 0;
}
AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
// FIXME: implement
......
......@@ -195,6 +195,56 @@ static JSStringRef descriptionOfElements(Vector<AccessibilityUIElement>& element
return [allElementString createJSStringRef];
}
static NSDictionary *searchPredicateParameterizedAttributeForSearchCriteria(JSContextRef context, AccessibilityUIElement *startElement, bool isDirectionNext, unsigned resultsLimit, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
NSMutableDictionary *parameterizedAttribute = [NSMutableDictionary dictionary];
if (startElement && startElement->platformUIElement())
[parameterizedAttribute setObject:(id)startElement->platformUIElement() forKey:@"AXStartElement"];
[parameterizedAttribute setObject:(isDirectionNext) ? @"AXDirectionNext" : @"AXDirectionPrevious" forKey:@"AXDirection"];
[parameterizedAttribute setObject:@(resultsLimit) forKey:@"AXResultsLimit"];
if (searchKey) {
id searchKeyParameter = nil;
if (JSValueIsString(context, searchKey)) {
JSRetainPtr<JSStringRef> searchKeyString(Adopt, JSValueToStringCopy(context, searchKey, nullptr));
if (searchKeyString)
searchKeyParameter = [NSString stringWithJSStringRef:searchKeyString.get()];
}
else if (JSValueIsObject(context, searchKey)) {
JSObjectRef searchKeyArray = JSValueToObject(context, searchKey, nullptr);
unsigned searchKeyArrayLength = 0;
JSRetainPtr<JSStringRef> lengthPropertyString(Adopt, JSStringCreateWithUTF8CString("length"));
JSValueRef searchKeyArrayLengthValue = JSObjectGetProperty(context, searchKeyArray, lengthPropertyString.get(), nullptr);
if (searchKeyArrayLengthValue && JSValueIsNumber(context, searchKeyArrayLengthValue))
searchKeyArrayLength = static_cast<unsigned>(JSValueToNumber(context, searchKeyArrayLengthValue, nullptr));
for (unsigned i = 0; i < searchKeyArrayLength; ++i) {
JSValueRef searchKeyValue = JSObjectGetPropertyAtIndex(context, searchKeyArray, i, nullptr);
JSStringRef searchKeyString = JSValueToStringCopy(context, searchKeyValue, nullptr);
if (searchKeyString) {
if (!searchKeyParameter)
searchKeyParameter = [NSMutableArray array];
[searchKeyParameter addObject:[NSString stringWithJSStringRef:searchKeyString]];
JSStringRelease(searchKeyString);
}
}
}
if (searchKeyParameter)
[parameterizedAttribute setObject:searchKeyParameter forKey:@"AXSearchKey"];
}
if (searchText && JSStringGetLength(searchText))
[parameterizedAttribute setObject:[NSString stringWithJSStringRef:searchText] forKey:@"AXSearchText"];
[parameterizedAttribute setObject:@(visibleOnly) forKey:@"AXVisibleOnly"];
return parameterizedAttribute;
}
void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elementVector)
{
BEGIN_AX_OBJC_EXCEPTIONS
......@@ -960,60 +1010,25 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
return false;
}
AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
unsigned AccessibilityUIElement::uiElementCountForSearchPredicate(JSContextRef context, AccessibilityUIElement *startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
{
BEGIN_AX_OBJC_EXCEPTIONS
NSMutableDictionary* parameter = [NSMutableDictionary dictionary];
[parameter setObject:(isDirectionNext) ? @"AXDirectionNext" : @"AXDirectionPrevious" forKey:@"AXDirection"];
if (visibleOnly)
[parameter setObject:[NSNumber numberWithBool:YES] forKey:@"AXVisibleOnly"];
[parameter setObject:[NSNumber numberWithInt:1] forKey:@"AXResultsLimit"];
if (startElement && startElement->platformUIElement())
[parameter setObject:(id)startElement->platformUIElement() forKey:@"AXStartElement"];
if (searchKey) {
if (JSValueIsString(context, searchKey)) {
NSString *searchKeyParameter = nil;
JSStringRef singleSearchKey = JSValueToStringCopy(context, searchKey, 0);
if (singleSearchKey) {
searchKeyParameter = [NSString stringWithJSStringRef:singleSearchKey];
JSStringRelease(singleSearchKey);
if (searchKeyParameter)
[parameter setObject:searchKeyParameter forKey:@"AXSearchKey"];
}
}
else if (JSValueIsObject(context, searchKey)) {
NSMutableArray *searchKeyParameter = nil;
JSObjectRef array = const_cast<JSObjectRef>(searchKey);
unsigned arrayLength = 0;
JSRetainPtr<JSStringRef> arrayLengthString(Adopt, JSStringCreateWithUTF8CString("length"));
JSValueRef arrayLengthValue = JSObjectGetProperty(context, array, arrayLengthString.get(), 0);
if (arrayLengthValue && JSValueIsNumber(context, arrayLengthValue))
arrayLength = static_cast<unsigned>(JSValueToNumber(context, arrayLengthValue, 0));
for (unsigned i = 0; i < arrayLength; ++i) {
JSValueRef exception = 0;
JSValueRef value = JSObjectGetPropertyAtIndex(context, array, i, &exception);
if (exception)
break;
JSStringRef singleSearchKey = JSValueToStringCopy(context, value, &exception);
if (exception)
break;
if (singleSearchKey) {
if (!searchKeyParameter)
searchKeyParameter = [NSMutableArray array];
[searchKeyParameter addObject:[NSString stringWithJSStringRef:singleSearchKey]];
JSStringRelease(singleSearchKey);
}
}
if (searchKeyParameter)