Expose misspelling ranges for editable content to accessibility clients.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Sep 2019 09:04:42 +0000 (09:04 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Sep 2019 09:04:42 +0000 (09:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201752
<rdar://problem/49556828>

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

Source/WebCore:

Test: accessibility/misspelling-range.html

Added [WebAccessibilityObjectWrapper misspellingTextMarkerRange] and
underlying AccessibilityObject implementation to expose misspellings to
accessibility clients that provide an alternative user interface to
spell checking.
* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::getMisspellingRange const):
* accessibility/AccessibilityObject.h:
* accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
(-[WebAccessibilityObjectWrapper misspellingTextMarkerRange:direction:]):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(accessibilityMisspellingSearchCriteriaForParameterizedAttribute):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):

Tools:

Test code needed for LayoutTests/accessibility/misspelling-range.html.
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
(WTR::AccessibilityUIElement::misspellingTextMarkerRange):
(WTR::AccessibilityUIElement::indexForTextMarker):
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::misspellingSearchParameterizedAttributeForCriteria):
(WTR::AccessibilityUIElement::misspellingTextMarkerRange):

LayoutTests:

* accessibility/misspelling-range-expected.txt: Added.
* accessibility/misspelling-range.html: Added.
* platform/ios-simulator/TestExpectations:

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/misspelling-range-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/misspelling-range.html [new file with mode: 0644]
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/AccessibilityObject.h
Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
Tools/ChangeLog
Tools/DumpRenderTree/AccessibilityUIElement.cpp
Tools/DumpRenderTree/AccessibilityUIElement.h
Tools/DumpRenderTree/ios/AccessibilityUIElementIOS.mm
Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp
Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h
Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl
Tools/WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm
Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm

index 59d543a..0ac2f70 100644 (file)
@@ -1,3 +1,15 @@
+2019-09-16  Andres Gonzalez  <andresg_22@apple.com>
+
+        Expose misspelling ranges for editable content to accessibility clients.
+        https://bugs.webkit.org/show_bug.cgi?id=201752
+        <rdar://problem/49556828>
+
+        Reviewed by Chris Fleizach.
+
+        * accessibility/misspelling-range-expected.txt: Added.
+        * accessibility/misspelling-range.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
 2019-09-15  Chris Dumez  <cdumez@apple.com>
 
         Re-sync HTML web-platform-tests from upstream
diff --git a/LayoutTests/accessibility/misspelling-range-expected.txt b/LayoutTests/accessibility/misspelling-range-expected.txt
new file mode 100644 (file)
index 0000000..455287f
--- /dev/null
@@ -0,0 +1,29 @@
+wrods is misspelled aab lotsi nowadays. euep.
+This tests that misspelling ranges are properly retrieved in the fashion that a spell checker would.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+textMarkerRange start: 0
+textMarkerRange end: 45
+startRange start: 0
+startRange end: 0
+misspelling start: 0
+misspelling end: 5
+PASS text.stringForTextMarkerRange(misspellingRange) is 'wrods'
+misspelling start: 20
+misspelling end: 23
+PASS text.stringForTextMarkerRange(misspellingRange) is 'aab'
+misspelling start: 24
+misspelling end: 29
+PASS text.stringForTextMarkerRange(misspellingRange) is 'lotsi'
+misspelling start: 40
+misspelling end: 44
+PASS text.stringForTextMarkerRange(misspellingRange) is 'euep'
+misspelling start: 24
+misspelling end: 29
+PASS text.stringForTextMarkerRange(misspellingRange) is 'lotsi'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/misspelling-range.html b/LayoutTests/accessibility/misspelling-range.html
new file mode 100644 (file)
index 0000000..279f6b9
--- /dev/null
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../resources/js-test-pre.js"></script>
+<script>
+if (window.testRunner)
+   testRunner.dumpAsText();
+</script>
+</head>
+<body>
+
+<div contenteditable=true id="content" role="textbox">
+wrods is misspelled aab lotsi nowadays. euep.
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+    description("This tests that misspelling ranges are properly retrieved in the fashion that a spell checker would.");
+
+    if (window.accessibilityController) {
+        var content = document.getElementById("content");
+        content.focus();
+
+        var text = accessibilityController.focusedElement;
+
+        var textMarkerRange = text.textMarkerRangeForElement(text);
+        var startMarker = text.startTextMarkerForTextMarkerRange(textMarkerRange);
+        debug("textMarkerRange start: " + text.indexForTextMarker(startMarker));
+        var endMarker = text.endTextMarkerForTextMarkerRange(textMarkerRange);
+        debug("textMarkerRange end: " + text.indexForTextMarker(endMarker));
+
+        // Find the first misspelling, "wrods".
+        var startRange = text.textMarkerRangeForMarkers(startMarker, startMarker);
+        startMarker = text.startTextMarkerForTextMarkerRange(startRange);
+        debug("startRange start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(startRange);
+        debug("startRange end: " + text.indexForTextMarker(endMarker));
+
+        var misspellingRange = text.misspellingTextMarkerRange(startRange, true);
+        startMarker = text.startTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling end: " + text.indexForTextMarker(endMarker));
+        shouldBe("text.stringForTextMarkerRange(misspellingRange)", "'wrods'");
+
+        // Find the next one, "aab".
+        startRange = misspellingRange;
+        misspellingRange = text.misspellingTextMarkerRange(startRange, true);
+        startMarker = text.startTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling end: " + text.indexForTextMarker(endMarker));
+        shouldBe("text.stringForTextMarkerRange(misspellingRange)", "'aab'");
+
+        // Find the next one, "lotsi".
+        startRange = misspellingRange;
+        misspellingRange = text.misspellingTextMarkerRange(startRange, true);
+        startMarker = text.startTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling end: " + text.indexForTextMarker(endMarker));
+        shouldBe("text.stringForTextMarkerRange(misspellingRange)", "'lotsi'");
+
+        // Find the next one, "euep".
+        startRange = misspellingRange;
+        misspellingRange = text.misspellingTextMarkerRange(startRange, true);
+        startMarker = text.startTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling end: " + text.indexForTextMarker(endMarker));
+        shouldBe("text.stringForTextMarkerRange(misspellingRange)", "'euep'");
+
+        // Find the previous one, "lotsi".
+        startRange = misspellingRange;
+        misspellingRange = text.misspellingTextMarkerRange(startRange, false);
+        startMarker = text.startTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling start: " + text.indexForTextMarker(startMarker));
+        endMarker = text.endTextMarkerForTextMarkerRange(misspellingRange);
+        debug("misspelling end: " + text.indexForTextMarker(endMarker));
+        shouldBe("text.stringForTextMarkerRange(misspellingRange)", "'lotsi'");
+    }
+</script>
+
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
+
index 801e546..f1e78ea 100644 (file)
@@ -4,6 +4,7 @@
 #
 
 accessibility/insert-newline.html [ Pass ]
+accessibility/misspelling-range.html [ Pass ]
 css3/font-variant-small-caps-synthesis-coverage.html [ ImageOnlyFailure ]
 fast/frames/sandboxed-iframe-close-top-noclose.html [ Failure ]
 fast/multicol/flexbox-rows.html [ Skip ]
index ea78684..1056448 100644 (file)
@@ -1712,6 +1712,7 @@ webkit.org/b/184676 accessibility/ARIA-reflection.html [ Skip ]
 # Not implemented on Win
 accessibility/insert-newline.html [ Skip ]
 accessibility/media-with-aria-label.html [ Skip ]
+accessibility/misspelling-range.html [ Skip ]
 
 ################################################################################
 #######################   End Accessibility Issues   ###########################
index 2cefb1f..a00fd0d 100644 (file)
@@ -1,3 +1,26 @@
+2019-09-16  Andres Gonzalez  <andresg_22@apple.com>
+
+        Expose misspelling ranges for editable content to accessibility clients.
+        https://bugs.webkit.org/show_bug.cgi?id=201752
+        <rdar://problem/49556828>
+
+        Reviewed by Chris Fleizach.
+
+        Test: accessibility/misspelling-range.html
+
+        Added [WebAccessibilityObjectWrapper misspellingTextMarkerRange] and
+        underlying AccessibilityObject implementation to expose misspellings to
+        accessibility clients that provide an alternative user interface to
+        spell checking.
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::getMisspellingRange const):
+        * accessibility/AccessibilityObject.h:
+        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
+        (-[WebAccessibilityObjectWrapper misspellingTextMarkerRange:direction:]):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (accessibilityMisspellingSearchCriteriaForParameterizedAttribute):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
 2019-09-15  Andy Estes  <aestes@apple.com>
 
         [WebIDL] Derived dictionaries should inherit their inherited dictionaries' partials
index 0e68445..254e9b2 100644 (file)
@@ -463,6 +463,55 @@ bool AccessibilityObject::hasMisspelling() const
     return isMisspelled;
 }
 
+RefPtr<Range> AccessibilityObject::getMisspellingRange(RefPtr<Range> const& start, AccessibilitySearchDirection direction) const
+{
+    auto node = this->node();
+    if (!node)
+        return nullptr;
+
+    Frame* frame = node->document().frame();
+    if (!frame)
+        return nullptr;
+
+    if (!unifiedTextCheckerEnabled(frame))
+        return nullptr;
+
+    Editor& editor = frame->editor();
+
+    TextCheckerClient* textChecker = editor.textChecker();
+    if (!textChecker)
+        return nullptr;
+
+    Vector<TextCheckingResult> misspellings;
+    checkTextOfParagraph(*textChecker, stringValue(), TextCheckingType::Spelling, misspellings, frame->selection().selection());
+
+    // The returned misspellings are assumed to be ordered in the document
+    // logical order, which should be matched by Range::compareBoundaryPoints.
+    // So iterate forward or backwards depending on the desired search
+    // direction to find the closest misspelling in that direction.
+    if (direction == AccessibilitySearchDirection::Next) {
+        for (auto misspelling : misspellings) {
+            auto misspellingRange = editor.rangeForTextCheckingResult(misspelling);
+            if (!misspellingRange)
+                continue;
+
+            if (misspellingRange->compareBoundaryPoints(Range::END_TO_END, *start).releaseReturnValue() > 0)
+                return misspellingRange;
+        }
+    } else if (direction == AccessibilitySearchDirection::Previous) {
+        for (auto rit = misspellings.rbegin(); rit != misspellings.rend(); ++rit) {
+            auto misspellingRange = editor.rangeForTextCheckingResult(*rit);
+            if (!misspellingRange)
+                continue;
+
+            if (misspellingRange->compareBoundaryPoints(Range::START_TO_START, *start).releaseReturnValue() < 0)
+                return misspellingRange;
+        }
+    }
+
+    return nullptr;
+}
+
 unsigned AccessibilityObject::blockquoteLevel() const
 {
     unsigned level = 0;
index 04b0a09..3ff0c36 100644 (file)
@@ -485,6 +485,7 @@ public:
     virtual bool hasBoldFont() const { return false; }
     virtual bool hasItalicFont() const { return false; }
     bool hasMisspelling() const;
+    RefPtr<Range> getMisspellingRange(RefPtr<Range> const& start, AccessibilitySearchDirection) const;
     virtual bool hasPlainText() const { return false; }
     virtual bool hasSameFont(RenderObject*) const { return false; }
     virtual bool hasSameFontColor(RenderObject*) const { return false; }
index 3c50193..1934925 100644 (file)
@@ -2655,6 +2655,20 @@ static void AXAttributedStringAppendText(NSMutableAttributedString* attrString,
     return [WebAccessibilityTextMarker textMarkerWithVisiblePosition:lineStart cache:m_object->axObjectCache()];
 }
 
+- (NSArray *)misspellingTextMarkerRange:(NSArray *)startTextMarkerRange forward:(BOOL)forward
+{
+    if (![self _prepareAccessibilityCall])
+        return nil;
+
+    RefPtr<Range> startRange = [self rangeForTextMarkers:startTextMarkerRange];
+    if (!startRange)
+        return nil;
+
+    RefPtr<Range> misspellingRange = m_object->getMisspellingRange(startRange,
+        forward ? AccessibilitySearchDirection::Next : AccessibilitySearchDirection::Previous);
+    return [self textMarkersForRange:misspellingRange];
+}
+
 - (WebAccessibilityTextMarker *)nextMarkerForMarker:(WebAccessibilityTextMarker *)marker
 {
     if (![self _prepareAccessibilityCall])
index 0af18b5..89e1d90 100644 (file)
@@ -323,6 +323,10 @@ using namespace HTMLNames;
 #define NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute @"AXLineTextMarkerRangeForTextMarker"
 #endif
 
+#ifndef NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute
+#define NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute @"AXMisspellingTextMarkerRange"
+#endif
+
 // Text selection
 #ifndef NSAccessibilitySelectTextActivity
 #define NSAccessibilitySelectTextActivity @"AXSelectTextActivity"
@@ -727,6 +731,21 @@ static AccessibilityTextOperation accessibilityTextOperationForParameterizedAttr
     return operation;
 }
 
+static std::pair<RefPtr<Range>, AccessibilitySearchDirection> accessibilityMisspellingSearchCriteriaForParameterizedAttribute(WebAccessibilityObjectWrapper *object, const NSDictionary *params)
+{
+    std::pair<RefPtr<Range>, AccessibilitySearchDirection> criteria;
+
+    criteria.first = [object rangeForTextMarkerRange:[params objectForKey:@"AXStartTextMarkerRange"]];
+
+    NSNumber *forward = [params objectForKey:NSAccessibilitySearchTextDirection];
+    if ([forward isKindOfClass:[NSNumber class]])
+        criteria.second = [forward boolValue] ? AccessibilitySearchDirection::Next : AccessibilitySearchDirection::Previous;
+    else
+        criteria.second = AccessibilitySearchDirection::Next;
+
+    return criteria;
+}
+
 #pragma mark Text Marker helpers
 
 static BOOL getBytesFromAXTextMarker(CFTypeRef textMarker, void* bytes, size_t length)
@@ -4206,7 +4225,7 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         m_object->findMatchingObjects(&criteria, results);
         return convertToNSArray(results);
     }
-    
+
     if ([attribute isEqualToString:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute]) {
         IntRect webCoreRect = [self screenToContents:enclosingIntRect(rect)];
         CharacterOffset characterOffset = cache->characterOffsetForBounds(webCoreRect, false);
@@ -4223,7 +4242,14 @@ ALLOW_DEPRECATED_IMPLEMENTATIONS_END
         VisiblePositionRange visiblePositionRange = m_object->lineRangeForPosition(visiblePosition);
         return [self textMarkerRangeFromVisiblePositions:visiblePositionRange.start endPosition:visiblePositionRange.end];
     }
-    
+
+    if ([attribute isEqualToString:NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute]) {
+        auto criteria = accessibilityMisspellingSearchCriteriaForParameterizedAttribute(self, dictionary);
+        if (auto misspellingRange = m_object->getMisspellingRange(criteria.first, criteria.second))
+            return [self textMarkerRangeFromRange:misspellingRange];
+        return nil;
+    }
+
     if ([attribute isEqualToString:NSAccessibilityTextMarkerIsValidParameterizedAttribute]) {
         VisiblePosition pos = [self visiblePositionForTextMarker:textMarker];
         return [NSNumber numberWithBool:!pos.isNull()];
index 5ef623e..56f178a 100644 (file)
@@ -1,3 +1,21 @@
+2019-09-16  Andres Gonzalez  <andresg_22@apple.com>
+
+        Expose misspelling ranges for editable content to accessibility clients.
+        https://bugs.webkit.org/show_bug.cgi?id=201752
+        <rdar://problem/49556828>
+
+        Reviewed by Chris Fleizach.
+
+        Test code needed for LayoutTests/accessibility/misspelling-range.html.
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+        * WebKitTestRunner/InjectedBundle/ios/AccessibilityUIElementIOS.mm:
+        (WTR::AccessibilityUIElement::misspellingTextMarkerRange):
+        (WTR::AccessibilityUIElement::indexForTextMarker):
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+        (WTR::misspellingSearchParameterizedAttributeForCriteria):
+        (WTR::AccessibilityUIElement::misspellingTextMarkerRange):
+
 2019-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         REGRESSION(r249142): [GTK] Epiphany delayed page loads continue indefinitely
index dece230..b34b401 100644 (file)
@@ -804,6 +804,19 @@ static JSValueRef lineTextMarkerRangeForTextMarkerCallback(JSContextRef context,
     return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->lineTextMarkerRangeForTextMarker(textMarker));
 }
 
+static JSValueRef misspellingTextMarkerRangeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    AccessibilityTextMarkerRange* startRange = nullptr;
+    bool forward = true;
+
+    if (argumentCount >= 1)
+        startRange = toTextMarkerRange(JSValueToObject(context, arguments[0], exception));
+    if (argumentCount >= 2)
+        forward = JSValueToBoolean(context, arguments[1]);
+
+    return AccessibilityTextMarkerRange::makeJSAccessibilityTextMarkerRange(context, toAXElement(thisObject)->misspellingTextMarkerRange(startRange, forward));
+}
+
 static JSValueRef textMarkerRangeForElementCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     AccessibilityUIElement* uiElement = 0;
@@ -1639,6 +1652,11 @@ AccessibilityTextMarkerRange AccessibilityUIElement::lineTextMarkerRangeForTextM
     return nullptr;
 }
 
+AccessibilityTextMarkerRange AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange*, bool)
+{
+    return nullptr;
+}
+
 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement*)
 {
     return 0;
@@ -1986,6 +2004,7 @@ JSClassRef AccessibilityUIElement::getJSClass()
         { "addSelection", addSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "removeSelection", removeSelectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "lineTextMarkerRangeForTextMarker", lineTextMarkerRangeForTextMarkerCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "misspellingTextMarkerRange", misspellingTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "textMarkerRangeForElement", textMarkerRangeForElementCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "selectedTextMarkerRange", selectedTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "resetSelectedTextMarkerRange", resetSelectedTextMarkerRangeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
index 3c0dc9d..ca2255c 100644 (file)
@@ -257,7 +257,8 @@ public:
 
     // Text markers.
     AccessibilityTextMarkerRange lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
-    AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement*);    
+    AccessibilityTextMarkerRange misspellingTextMarkerRange(AccessibilityTextMarkerRange* start, bool forward);
+    AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement*);
     AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
     AccessibilityTextMarker startTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
     AccessibilityTextMarker endTextMarkerForTextMarkerRange(AccessibilityTextMarkerRange*);
index 98474cd..c510bc4 100644 (file)
@@ -118,6 +118,7 @@ AccessibilityUIElement::~AccessibilityUIElement()
 - (id)accessibilityObjectForTextMarker:(id)marker;
 - (id)lineStartMarkerForMarker:(id)marker;
 - (id)lineEndMarkerForMarker:(id)marker;
+- (NSArray *)misspellingTextMarkerRange:(NSArray *)startTextMarkerRange forward:(BOOL)forward;
 - (NSArray *)textMarkerRangeFromMarkers:(NSArray *)markers withText:(NSString *)text;
 @end
 
@@ -469,6 +470,12 @@ AccessibilityTextMarkerRange AccessibilityUIElement::lineTextMarkerRangeForTextM
     return AccessibilityTextMarkerRange(textMarkerRange);
 }
 
+AccessibilityTextMarkerRange AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange* startRange, bool forward)
+{
+    id misspellingRange = [m_element misspellingTextMarkerRange:(id)startRange->platformTextMarkerRange() forward:forward];
+    return AccessibilityTextMarkerRange(misspellingRange);
+}
+
 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
 {
     id textMarkerRange = [element->platformUIElement() textMarkerRange];
index 32a07a3..9e106da 100644 (file)
@@ -1673,6 +1673,19 @@ AccessibilityTextMarkerRange AccessibilityUIElement::lineTextMarkerRangeForTextM
     return nullptr;
 }
 
+AccessibilityTextMarkerRange AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange* start, bool forward)
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
+    [parameters setObject:(__bridge id)start->platformTextMarkerRange() forKey:@"AXStartTextMarkerRange"];
+    [parameters setObject:[NSNumber numberWithBool:forward] forKey:@"AXSearchTextDirection"];
+    id textMarkerRange = [m_element accessibilityAttributeValue:@"AXMisspellingTextMarkerRange" forParameter:parameters];
+    return AccessibilityTextMarkerRange((__bridge CFTypeRef)textMarkerRange);
+    END_AX_OBJC_EXCEPTIONS
+
+    return nullptr;
+}
+
 AccessibilityTextMarkerRange AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
 {
     BEGIN_AX_OBJC_EXCEPTIONS
index 95dcefb..2a237d3 100644 (file)
@@ -109,6 +109,7 @@ RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousParagraphStartTe
 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::sentenceTextMarkerRangeForTextMarker(AccessibilityTextMarker*) { return nullptr; }
 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::nextSentenceEndTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
 RefPtr<AccessibilityTextMarker> AccessibilityUIElement::previousSentenceStartTextMarkerForTextMarker(AccessibilityTextMarker*) { return nullptr; }
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange*, bool) { return nullptr; }
 #endif
 
 } // namespace WTR
index 8d92df7..35fb370 100644 (file)
@@ -278,6 +278,7 @@ public:
     
     // Text markers.
     RefPtr<AccessibilityTextMarkerRange> lineTextMarkerRangeForTextMarker(AccessibilityTextMarker*);
+    RefPtr<AccessibilityTextMarkerRange> misspellingTextMarkerRange(AccessibilityTextMarkerRange* start, bool forward);
     RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForElement(AccessibilityUIElement*);
     RefPtr<AccessibilityTextMarkerRange> textMarkerRangeForMarkers(AccessibilityTextMarker* startMarker, AccessibilityTextMarker* endMarker);
     RefPtr<AccessibilityTextMarkerRange> selectedTextMarkerRange();
index e26be90..ef5a6a0 100644 (file)
 
     // Text markers.
     AccessibilityTextMarkerRange lineTextMarkerRangeForTextMarker(AccessibilityTextMarker textMarker);
-    AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement element);    
+    AccessibilityTextMarkerRange misspellingTextMarkerRange(AccessibilityTextMarkerRange start, boolean forward);
+    AccessibilityTextMarkerRange textMarkerRangeForElement(AccessibilityUIElement element);
     AccessibilityTextMarkerRange textMarkerRangeForMarkers(AccessibilityTextMarker startMarker, AccessibilityTextMarker endMarker);
     AccessibilityTextMarkerRange selectedTextMarkerRange();
     void resetSelectedTextMarkerRange();
index 8270cb3..813bca7 100644 (file)
@@ -97,11 +97,13 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
 - (NSString *)stringForTextMarkers:(NSArray *)markers;
 - (id)startOrEndTextMarkerForTextMarkers:(NSArray*)textMarkers isStart:(BOOL)isStart;
 - (NSArray *)textMarkerRangeForMarkers:(NSArray *)textMarkers;
+- (NSInteger)positionForTextMarker:(id)marker;
 - (id)nextMarkerForMarker:(id)marker;
 - (id)previousMarkerForMarker:(id)marker;
 - (id)accessibilityObjectForTextMarker:(id)marker;
 - (id)lineStartMarkerForMarker:(id)marker;
 - (id)lineEndMarkerForMarker:(id)marker;
+- (NSArray *)misspellingTextMarkerRange:(NSArray *)startTextMarkerRange forward:(BOOL)forward;
 - (NSArray *)textMarkerRangeFromMarkers:(NSArray *)markers withText:(NSString *)text;
 - (BOOL)_accessibilityIsInTableCell;
 @end
@@ -1102,6 +1104,12 @@ RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRange
     return AccessibilityTextMarkerRange::create(textMarkerRange);
 }
 
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange* start, bool forward)
+{
+    id misspellingRange = [m_element misspellingTextMarkerRange:(id)start->platformTextMarkerRange() forward:forward];
+    return AccessibilityTextMarkerRange::create(misspellingRange);
+}
+
 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
 {
     id textMarkerRange = [element->platformUIElement() textMarkerRange];
@@ -1205,7 +1213,7 @@ bool AccessibilityUIElement::attributedStringForTextMarkerRangeContainsAttribute
 
 int AccessibilityUIElement::indexForTextMarker(AccessibilityTextMarker* marker)
 {
-    return -1;
+    return [m_element positionForTextMarker:(__bridge id)marker->platformTextMarker()];
 }
 
 bool AccessibilityUIElement::isTextMarkerValid(AccessibilityTextMarker* textMarker)
index e0bd6b0..532408d 100644 (file)
@@ -324,6 +324,16 @@ static NSDictionary *searchTextParameterizedAttributeForCriteria(JSContextRef co
     return parameterizedAttribute;
 }
 
+static NSDictionary *misspellingSearchParameterizedAttributeForCriteria(AccessibilityTextMarkerRange* start, bool forward)
+{
+    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
+
+    [parameters setObject:(__bridge id)start->platformTextMarkerRange() forKey:@"AXStartTextMarkerRange"];
+    [parameters setObject:[NSNumber numberWithBool:forward] forKey:@"AXSearchTextDirection"];
+
+    return parameters;
+}
+
 void AccessibilityUIElement::getLinkedUIElements(Vector<RefPtr<AccessibilityUIElement> >& elementVector)
 {
     BEGIN_AX_OBJC_EXCEPTIONS
@@ -1753,6 +1763,17 @@ RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::lineTextMarkerRange
     return nullptr;
 }
 
+RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::misspellingTextMarkerRange(AccessibilityTextMarkerRange* start, bool forward)
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    NSDictionary *parameters = misspellingSearchParameterizedAttributeForCriteria(start, forward);
+    id textMarkerRange = [m_element accessibilityAttributeValue:@"AXMisspellingTextMarkerRange" forParameter:parameters];
+    return AccessibilityTextMarkerRange::create((__bridge CFTypeRef)textMarkerRange);
+    END_AX_OBJC_EXCEPTIONS
+
+    return nullptr;
+}
+
 RefPtr<AccessibilityTextMarkerRange> AccessibilityUIElement::textMarkerRangeForElement(AccessibilityUIElement* element)
 {
     BEGIN_AX_OBJC_EXCEPTIONS