Add "VisibleOnly" key to search predicate
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Jun 2013 19:21:59 +0000 (19:21 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 4 Jun 2013 19:21:59 +0000 (19:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=115491

Patch by Greg Hughes <ghughes@apple.com> on 2013-06-04
Reviewed by Chris Fleizach.

Source/WebCore:

Added support for accessibility clients to use the search predicate to find only visible elements

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

Tools:

Added support for accessibility clients to use the search predicate to find only visible elements

* DumpRenderTree/AccessibilityUIElement.cpp:
(uiElementForSearchPredicateCallback):
* DumpRenderTree/AccessibilityUIElement.h:
(AccessibilityUIElement):
* DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
(AccessibilityUIElement::uiElementForSearchPredicate):
* DumpRenderTree/mac/AccessibilityUIElementMac.mm:
(AccessibilityUIElement::uiElementForSearchPredicate):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::uiElementForSearchPredicate):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
(AccessibilityUIElement):
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElement::uiElementForSearchPredicate):

LayoutTests:

Added tests support for visibleOnly search predicate.

* platform/mac/accessibility/search-predicate-expected.txt:
* platform/mac/accessibility/search-predicate.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@151179 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/accessibility/attributed-string-includes-highlighting.html
LayoutTests/platform/mac/accessibility/search-predicate-expected.txt
LayoutTests/platform/mac/accessibility/search-predicate.html
LayoutTests/platform/mac/accessibility/search-when-element-starts-in-table.html
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
Tools/ChangeLog
Tools/DumpRenderTree/AccessibilityUIElement.cpp
Tools/DumpRenderTree/AccessibilityUIElement.h
Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp
Tools/DumpRenderTree/ios/AccessibilityUIElementIOS.mm
Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
Tools/DumpRenderTree/win/AccessibilityUIElementWin.cpp
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm

index 0be20d1..c891c55 100644 (file)
@@ -1,3 +1,15 @@
+2013-06-04  Greg Hughes  <ghughes@apple.com>
+
+        Add "VisibleOnly" key to search predicate
+        https://bugs.webkit.org/show_bug.cgi?id=115491
+
+        Reviewed by Chris Fleizach.
+
+        Added tests support for visibleOnly search predicate.
+
+        * platform/mac/accessibility/search-predicate-expected.txt:
+        * platform/mac/accessibility/search-predicate.html:
+
 2013-06-04  Roger Fong  <roger_fong@apple.com>
 
         Unreviewed. Rollout of r151146. Broke some tests.
index e1e8622..54c1559 100644 (file)
@@ -29,7 +29,7 @@
         // Search for a highlighted element from the top of the webpage.
         document.getElementById("body").focus();
         var body = accessibilityController.focusedElement;
-        var resultElement = body.uiElementForSearchPredicate("", true, "AXHighlightedSearchKey", "");
+        var resultElement = body.uiElementForSearchPredicate("", true, "AXHighlightedSearchKey", "", false);
         shouldBeTrue("resultElement.isEqual(item1.childAtIndex(0))");
     }
 
index 1a8c72c..1e667fd 100644 (file)
@@ -33,6 +33,20 @@ first table heading level 1
 first table body level 1
 second table heading level 1
 second table body level 1
+isVisible test start
+
+test button 1
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test test test test 
+test button 2
+test button 3
 This tests the ability to search for accessible elements by key or text.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -109,6 +123,29 @@ PASS resultElement.role is 'AXRole: AXLink'
 PASS resultElement.childAtIndex(0).stringValue is 'AXValue: link'
 PASS resultElement.role is 'AXRole: AXHeading'
 PASS resultElement.childAtIndex(0).stringValue is 'AXValue: heading level 2'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 3'
+PASS resultElement.role is 'AXRole: AXHeading'
+PASS resultElement.childAtIndex(0).stringValue is 'AXValue: isVisible test start'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 1'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 2'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 3'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 1'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 3'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 2'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 3'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: test button 2'
+PASS resultElement.role is 'AXRole: AXButton'
+PASS resultElement.title is 'AXTitle: Submit'
+PASS resultElement.role is 'AXRole: '
 PASS successfullyParsed is true
 
 TEST COMPLETE
index f896ae5..35308c7 100644 (file)
 <tbody><tr><td>second table body level 1</td></tr></tbody>
 </table>
 
+<h1>isVisible test start</h1>
+<div id="group" style="overflow: scroll; width:100px; height:100px;">
+    <button id="button">test button 1</button><BR>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    test test test test <br>
+    <button id="button">test button 2</button>
+</div>
+<button id="button">test button 3</button>
+
+    
 <p id="description"></p>
 <div id="console"></div>
 
         var containerElement = accessibilityController.focusedElement;
         var startElement;
         var resultElement;
-        
+        var testButton2;
+
         // Any element.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXAnyTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Same level blockquote.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSameLevelSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
         
         // Blockquote.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
         
         // Bold font.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBoldFontSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBoldFontSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Button.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXButton'");
         
         // Check box.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
         
         // Control.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
         
         // Different type element.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXDifferentTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXDifferentTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Font change.
         startElement = accessibilityController.focusedElement.childAtIndex(2);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontChangeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Font color change.
         startElement = accessibilityController.focusedElement.childAtIndex(2);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontColorChangeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontColorChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Graphic.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXGraphicSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXGraphicSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXImage'");
         
         // Heading level 1.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel1SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel1SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
         
         // Heading level 2.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel2SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel2SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
         
         // Heading level 3.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel3SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel3SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 3'");
         
         // Heading level 4.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel4SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel4SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 4'");
         
         // Heading level 5.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel5SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel5SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 5'");
         
         // Heading level 6.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel6SearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel6SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 6'");
         
         // Same level heading.
         startElement = accessibilityController.focusedElement.childAtIndex(6);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSameLevelSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second heading level 1'");
         
         // Heading.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
         
         // Italic font.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXItalicFontSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXItalicFontSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Landmark.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLandmarkSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLandmarkSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.subrole", "'AXSubrole: AXLandmarkBanner'");
         
         // Link.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLinkSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLinkSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXLink'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
         
         // List.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXListSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXListSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXList'");
         
         // Live Region.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLiveRegionSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLiveRegionSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.stringAttributeValue('AXARIALive')", "'polite'");
         
         
         // Plain text.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXPlainTextSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXPlainTextSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Radio group.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXRadioGroupSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXRadioGroupSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXRadioGroup'");
         
         // Same type element.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXSameTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXSameTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
         
         // Static text.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStaticTextSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStaticTextSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Style change.
         startElement = accessibilityController.focusedElement.childAtIndex(2);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStyleChangeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStyleChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Same level table.
         startElement = accessibilityController.focusedElement.childAtIndex(18);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSameLevelSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTable'");
         shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: second table heading level 1'");
         
         // Table.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTable'");
         shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: first table heading level 1'");
         
         // Text field.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTextFieldSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTextFieldSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTextField'");
         
         // Underline.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnderlineSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnderlineSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Unvisited link.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnvisitedLinkSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnvisitedLinkSearchKey", "", false);
         shouldBe("resultElement.boolAttributeValue('AXVisited')", "false");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
         
         // Visited link.
         accessibilityController.focusedElement.childAtIndex(14).childAtIndex(0).press();
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXVisitedLinkSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXVisitedLinkSearchKey", "", false);
         shouldBe("resultElement.boolAttributeValue('AXVisited')", "true");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
         
         // Previous text search.
         startElement = accessibilityController.focusedElement.childAtIndex(10);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, false, "", "sans-serif black bold text with underline");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, false, "", "sans-serif black bold text with underline", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Execute a search for the next heading level 2 or the next link.
         startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "");
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
         
         // After finding the heading, execute the search again and we should find the link.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
         shouldBe("resultElement.role", "'AXRole: AXLink'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
 
         // From the link, execute the search in reverse and we should land back on the heading.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
+               
+        // Now, we need to test isVisible. Save off the first object
+        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        
+        // Scroll all the way to the bottom of the content
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "test button 3", false);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+        resultElement.scrollToMakeVisible();
+        
+        // find the start of the isVisible test section
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "isVisible test start", false);
+        shouldBe("resultElement.role", "'AXRole: AXHeading'");
+        shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: isVisible test start'");       
+        
+        // save away the "isVisible test start" heading as the start element
+        startElement = resultElement;
+        
+        // If we don't care about visible only, then we should easily find 3 buttons
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 1'");
+        
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 2'");
+        
+        // save away testButton2 so we can make it visible later
+        testButton2 = resultElement;
+
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+
+        // if we care about visible only, then we should not find "test button 2"
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 1'");
+        
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+        
+        // now, scroll to the second button, and confirm that we don't see the first button
+        testButton2.scrollToMakeVisible();
+
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 2'");
+        
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+        
+        // Now since the page is scrolled to the bottom, the first visible button should be #2
+        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: test button 2'");
+        
+        // lets scroll to the top of the page and ensure that the submit button is visible
+        startElement.scrollToMakeVisible();
+        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: AXButton'");
+        shouldBe("resultElement.title", "'AXTitle: Submit'");
+        
+        // there should be no more visible buttons
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
+        shouldBe("resultElement.role", "'AXRole: '");
+        
     }
     
 </script>
index 068980e..e69ae15 100644 (file)
         var heading = accessibilityController.focusedElement;
 
         // The next heading should be outside the table
-        resultElement = containerElement.uiElementForSearchPredicate(heading, true, "AXHeadingSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(heading, true, "AXHeadingSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.title", "'AXTitle: outside heading'");        
 
         // A search for the previous heading should return nothing.
-        resultElement = containerElement.uiElementForSearchPredicate(heading, false, "AXHeadingSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(heading, false, "AXHeadingSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: '");
 
         // When asking the child of the heading for the previous element, it should return the heading.
-        resultElement = containerElement.uiElementForSearchPredicate(heading.childAtIndex(0), false, "AXAnyTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(heading.childAtIndex(0), false, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
 
         // When asking the heading for the previous element, it should return the cell.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCell'");
 
         // When asking the cell for the previous element, it should return the row.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXRow'");
 
         // Now when trying to find the previous static text, it should go into the table's children to find the text in the first cell.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXStaticTextSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXStaticTextSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: Column'");
 
         // When asking the text for the previous element it should return the first cell of the table.
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "");
+        resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCell'");
         shouldBe("resultElement.rowIndexRange()", "'{0, 1}'");
         shouldBe("resultElement.columnIndexRange()", "'{0, 1}'");
index 7e54a66..52c9d79 100644 (file)
@@ -1,3 +1,23 @@
+2013-06-04  Greg Hughes  <ghughes@apple.com>
+
+        Add "VisibleOnly" key to search predicate
+        https://bugs.webkit.org/show_bug.cgi?id=115491
+
+        Reviewed by Chris Fleizach.
+
+        Added support for accessibility clients to use the search predicate to find only visible elements
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::isAccessibilityObjectSearchMatch):
+        (WebCore::AccessibilityObject::isOnscreen):
+        (WebCore):
+        * accessibility/AccessibilityObject.h:
+        (AccessibilitySearchCriteria):
+        (WebCore::AccessibilitySearchCriteria::AccessibilitySearchCriteria):
+        (AccessibilityObject):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
 2013-06-04  Roger Fong  <roger_fong@apple.com>
 
         Unreviewed. Rollout of r151146. Broke some tests.
index 9d21faa..7f56cd4 100644 (file)
@@ -248,8 +248,11 @@ bool AccessibilityObject::isAccessibilityObjectSearchMatch(AccessibilityObject*
     
     size_t length = criteria->searchKeys.size();
     for (size_t i = 0; i < length; ++i) {
-        if (isAccessibilityObjectSearchMatchAtIndex(axObject, criteria, i))
+        if (isAccessibilityObjectSearchMatchAtIndex(axObject, criteria, i)) {
+            if (criteria->visibleOnly && !axObject->isOnscreen())
+                return false;
             return true;
+        }
     }
     return false;
 }
@@ -1721,6 +1724,39 @@ static int computeBestScrollOffset(int currentScrollOffset,
     return currentScrollOffset;
 }
 
+bool AccessibilityObject::isOnscreen() const
+{   
+    bool isOnscreen = true;
+
+    // To figure out if the element is onscreen, we start by building of a stack starting with the
+    // element, and then include every scrollable parent in the hierarchy.
+    Vector<const AccessibilityObject*> objects;
+    
+    objects.append(this);
+    for (AccessibilityObject* parentObject = this->parentObject(); parentObject; parentObject = parentObject->parentObject()) {
+        if (parentObject->getScrollableAreaIfScrollable())
+            objects.append(parentObject);
+    }
+
+    // Now, go back through that chain and make sure each inner object is within the
+    // visible bounds of the outer object.
+    size_t levels = objects.size() - 1;
+    
+    for (size_t i = levels; i >= 1; i--) {
+        const AccessibilityObject* outer = objects[i];
+        const AccessibilityObject* inner = objects[i - 1];
+        const IntRect outerRect = i < levels ? pixelSnappedIntRect(outer->boundingBoxRect()) : outer->getScrollableAreaIfScrollable()->visibleContentRect();
+        const IntRect innerRect = pixelSnappedIntRect(inner->isAccessibilityScrollView() ? inner->parentObject()->boundingBoxRect() : inner->boundingBoxRect());
+        
+        if (!outerRect.intersects(innerRect)) {
+            isOnscreen = false;
+            break;
+        }
+    }
+    
+    return isOnscreen;
+}
+
 void AccessibilityObject::scrollToMakeVisible() const
 {
     IntRect objectRect = pixelSnappedIntRect(boundingBoxRect());
index 2424fca..8348a83 100644 (file)
@@ -315,12 +315,14 @@ struct AccessibilitySearchCriteria {
     Vector<AccessibilitySearchKey> searchKeys;
     String* searchText;
     unsigned resultsLimit;
+    bool visibleOnly;
     
-    AccessibilitySearchCriteria(AccessibilityObject* o, AccessibilitySearchDirection d, String* t, unsigned l)
+    AccessibilitySearchCriteria(AccessibilityObject* o, AccessibilitySearchDirection d, String* t, unsigned l, bool v)
     : startObject(o)
     , searchDirection(d)
     , searchText(t)
     , resultsLimit(l)
+    , visibleOnly(v)
     { }
 };
 
@@ -873,7 +875,8 @@ protected:
     static bool objectMatchesSearchCriteriaWithResultLimit(AccessibilityObject*, AccessibilitySearchCriteria*, AccessibilityChildrenVector&);
     virtual AccessibilityRole buttonRoleType() const;
     bool ariaIsHidden() const;
-
+    bool isOnscreen() const;
+    
 #if PLATFORM(GTK) || (PLATFORM(EFL) && HAVE(ACCESSIBILITY))
     bool allowsTextRanges() const;
     unsigned getLengthForTextRange() const;
index 7b17394..e951852 100644 (file)
@@ -3286,7 +3286,11 @@ static RenderObject* rendererForView(NSView* view)
         if ([[dictionary objectForKey:@"AXResultsLimit"] isKindOfClass:[NSNumber self]])
             resultsLimit = [(NSNumber*)[dictionary objectForKey:@"AXResultsLimit"] unsignedIntValue];
         
-        AccessibilitySearchCriteria criteria = AccessibilitySearchCriteria(startObject, searchDirection, &searchText, resultsLimit);
+        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]])
index f383dfd..5e69b7c 100644 (file)
@@ -1,3 +1,28 @@
+2013-06-04  Greg Hughes  <ghughes@apple.com>
+
+        Add "VisibleOnly" key to search predicate
+        https://bugs.webkit.org/show_bug.cgi?id=115491
+
+        Reviewed by Chris Fleizach.
+
+        Added support for accessibility clients to use the search predicate to find only visible elements
+
+        * DumpRenderTree/AccessibilityUIElement.cpp:
+        (uiElementForSearchPredicateCallback):
+        * DumpRenderTree/AccessibilityUIElement.h:
+        (AccessibilityUIElement):
+        * DumpRenderTree/ios/AccessibilityUIElementIOS.mm:
+        (AccessibilityUIElement::uiElementForSearchPredicate):
+        * DumpRenderTree/mac/AccessibilityUIElementMac.mm:
+        (AccessibilityUIElement::uiElementForSearchPredicate):
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
+        (WTR::AccessibilityUIElement::uiElementForSearchPredicate):
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+        (AccessibilityUIElement):
+        * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+        (WTR::AccessibilityUIElement::uiElementForSearchPredicate):
+
 2013-06-04  Brent Fulgham  <bfulgham@apple.com>
 
         [Windows] Unreviewed build fix.  The last check-in lost CR/LF endings on the batch file,
index d67ea44..77d11a2 100644 (file)
@@ -206,9 +206,10 @@ static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSOb
 {
     AccessibilityUIElement* startElement = 0;
     bool isDirectionNext = true;
+    bool visibleOnly = false;
     JSValueRef searchKey = 0;
     JSStringRef searchText = 0;
-    if (argumentCount == 4) {
+    if (argumentCount == 5) {
         JSObjectRef startElementObject = JSValueToObject(context, arguments[0], exception);
         if (startElementObject)
             startElement = toAXElement(startElementObject);
@@ -218,8 +219,10 @@ static JSValueRef uiElementForSearchPredicateCallback(JSContextRef context, JSOb
         
         if (JSValueIsString(context, arguments[3]))
             searchText = JSValueToStringCopy(context, arguments[3], exception);
+        
+        visibleOnly = JSValueToBoolean(context, arguments[4]);
     }
-    JSObjectRef resultObject = AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText));
+    JSObjectRef resultObject = AccessibilityUIElement::makeJSAccessibilityUIElement(context, toAXElement(thisObject)->uiElementForSearchPredicate(context, startElement, isDirectionNext, searchKey, searchText, visibleOnly));
 
     if (searchText)
         JSStringRelease(searchText);
index ac849fa..ebbf7f3 100644 (file)
@@ -200,7 +200,7 @@ public:
     JSStringRef stringForRange(unsigned location, unsigned length);
     JSStringRef attributedStringForRange(unsigned location, unsigned length);
     bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
-    AccessibilityUIElement uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText);
+    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);
     JSStringRef stringForSelection();
index 10e3767..db894b5 100644 (file)
@@ -773,7 +773,7 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
     return false;
 }
 
-AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
 {
     // FIXME: implement
     return 0;
index afd054a..4608984 100644 (file)
@@ -795,7 +795,7 @@ void AccessibilityUIElement::removeSelection()
     // FIXME: implement
 }
 
-AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
 {
     // FIXME: implement
     return 0;
index b097876..046bc73 100644 (file)
@@ -912,11 +912,13 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
     return false;
 }
 
-AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(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"];
index a26c1b0..759efdc 100644 (file)
@@ -498,7 +498,7 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigne
     return false;
 }
 
-AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
 {
     return 0;
 }
index 16710a4..5f149e0 100644 (file)
@@ -159,7 +159,7 @@ void AccessibilityUIElement::setSelectedTextRange(unsigned, unsigned) { }
 JSRetainPtr<JSStringRef> AccessibilityUIElement::stringForRange(unsigned, unsigned) { return 0; }
 JSRetainPtr<JSStringRef> AccessibilityUIElement::attributedStringForRange(unsigned, unsigned) { return 0; }
 bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned, unsigned) { return false; }
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef) { return 0; }
+PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement*, bool, JSValueRef, JSStringRef, bool) { return 0; }
 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::cellForColumnAndRow(unsigned, unsigned) { return 0; }
 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::horizontalScrollbar() const { return 0; }
 PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::verticalScrollbar() const { return 0; }
index 71a949b..67f7fa2 100644 (file)
@@ -203,7 +203,7 @@ public:
     JSRetainPtr<JSStringRef> stringForRange(unsigned location, unsigned length);
     JSRetainPtr<JSStringRef> attributedStringForRange(unsigned location, unsigned length);
     bool attributedStringRangeIsMisspelled(unsigned location, unsigned length);
-    PassRefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText);
+    PassRefPtr<AccessibilityUIElement> uiElementForSearchPredicate(JSContextRef, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly);
     
     // Table-specific
     PassRefPtr<AccessibilityUIElement> cellForColumnAndRow(unsigned column, unsigned row);
index 623444b..48f76f2 100644 (file)
@@ -141,7 +141,7 @@ interface AccessibilityUIElement {
     DOMString stringForRange(unsigned long location, unsigned long length);
     DOMString attributedStringForRange(unsigned long location, unsigned long length);
     boolean attributedStringRangeIsMisspelled(unsigned long location, unsigned long length);
-    [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText);
+    [PassContext] AccessibilityUIElement uiElementForSearchPredicate(AccessibilityUIElement startElement, boolean isDirectionNext, object searchKey, DOMString searchText, boolean visibleOnly);
     void setSelectedTextRange(unsigned long location, unsigned long length);
 
     // Scroll area attributes.
index c8fa446..456b132 100644 (file)
@@ -870,7 +870,7 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
     return false;
 }
 
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
 {
     // FIXME: implement
     return 0;
index 337391c..cd45487 100644 (file)
@@ -922,11 +922,13 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location
     return false;
 }
 
-PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText)
+PassRefPtr<AccessibilityUIElement> AccessibilityUIElement::uiElementForSearchPredicate(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"];