Title: [258673] trunk/Source/WebCore
Revision
258673
Author
[email protected]
Date
2020-03-18 19:09:44 -0700 (Wed, 18 Mar 2020)

Log Message

Several TextMarker attributes need to run on the main thread.
https://bugs.webkit.org/show_bug.cgi?id=209247

Reviewed by Chris Fleizach.

- Dispatch several TextMarker parameterized attributes to the main
thread.
- Added helper methods to return TextMarkers and TextMarkerRanges for
diffferent units of text such as word or sentence.
- Added a helper function, retainWrapper to make code a bit more
readable in lambda definitions.

* accessibility/mac/AXObjectCacheMac.mm:
(WebCore::textMarkerForVisiblePosition):
(WebCore::textMarkerRangeFromVisiblePositions):
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(retainWrapper):
(-[WebAccessibilityObjectWrapper attachmentView]):
(-[WebAccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:spellCheck:]):
(-[WebAccessibilityObjectWrapper textMarkerRangeFromVisiblePositions:endPosition:]):
(-[WebAccessibilityObjectWrapper associatedPluginParent]):
(-[WebAccessibilityObjectWrapper windowElement:]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
(-[WebAccessibilityObjectWrapper accessibilityShowContextMenu]):
(-[WebAccessibilityObjectWrapper textMarkerRangeAtTextMarker:forUnit:]):
(-[WebAccessibilityObjectWrapper lineTextMarkerRangeForTextMarker:forUnit:]):
(-[WebAccessibilityObjectWrapper textMarkerForTextMarker:atUnit:]):
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (258672 => 258673)


--- trunk/Source/WebCore/ChangeLog	2020-03-19 01:26:16 UTC (rev 258672)
+++ trunk/Source/WebCore/ChangeLog	2020-03-19 02:09:44 UTC (rev 258673)
@@ -1,3 +1,34 @@
+2020-03-18  Andres Gonzalez  <[email protected]>
+
+        Several TextMarker attributes need to run on the main thread.
+        https://bugs.webkit.org/show_bug.cgi?id=209247
+
+        Reviewed by Chris Fleizach.
+
+        - Dispatch several TextMarker parameterized attributes to the main
+        thread.
+        - Added helper methods to return TextMarkers and TextMarkerRanges for
+        diffferent units of text such as word or sentence.
+        - Added a helper function, retainWrapper to make code a bit more
+        readable in lambda definitions.
+
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::textMarkerForVisiblePosition):
+        (WebCore::textMarkerRangeFromVisiblePositions):
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (retainWrapper):
+        (-[WebAccessibilityObjectWrapper attachmentView]):
+        (-[WebAccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:spellCheck:]):
+        (-[WebAccessibilityObjectWrapper textMarkerRangeFromVisiblePositions:endPosition:]):
+        (-[WebAccessibilityObjectWrapper associatedPluginParent]):
+        (-[WebAccessibilityObjectWrapper windowElement:]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+        (-[WebAccessibilityObjectWrapper accessibilityShowContextMenu]):
+        (-[WebAccessibilityObjectWrapper textMarkerRangeAtTextMarker:forUnit:]):
+        (-[WebAccessibilityObjectWrapper lineTextMarkerRangeForTextMarker:forUnit:]):
+        (-[WebAccessibilityObjectWrapper textMarkerForTextMarker:atUnit:]):
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
+
 2020-03-18  Zalan Bujtas  <[email protected]>
 
         [MultiColumn] Ignore spanner boxes inside <legend>

Modified: trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm (258672 => 258673)


--- trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm	2020-03-19 01:26:16 UTC (rev 258672)
+++ trunk/Source/WebCore/accessibility/mac/AXObjectCacheMac.mm	2020-03-19 02:09:44 UTC (rev 258673)
@@ -567,6 +567,7 @@
 
 id textMarkerForVisiblePosition(AXObjectCache* cache, const VisiblePosition& visiblePos)
 {
+    ASSERT(isMainThread());
     ASSERT(cache);
     if (!cache)
         return nil;
@@ -580,6 +581,7 @@
 
 id textMarkerRangeFromVisiblePositions(AXObjectCache* cache, const VisiblePosition& startPosition, const VisiblePosition& endPosition)
 {
+    ASSERT(isMainThread());
     if (!cache)
         return nil;
 

Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (258672 => 258673)


--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2020-03-19 01:26:16 UTC (rev 258672)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2020-03-19 02:09:44 UTC (rev 258673)
@@ -553,11 +553,16 @@
     [super detach];
 }
 
+static inline RetainPtr<WebAccessibilityObjectWrapper> retainWrapper(WebAccessibilityObjectWrapper* wrapper)
+{
+    return RetainPtr<WebAccessibilityObjectWrapper>(wrapper);
+}
+
 - (id)attachmentView
 {
     ASSERT(self.axBackingObject->isAttachment());
 
-    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
         auto* widget = protectedSelf.get().axBackingObject->widgetForAttachmentView();
         if (!widget)
             return nil;
@@ -1247,7 +1252,7 @@
 
 - (NSAttributedString*)doAXAttributedStringForTextMarkerRange:(id)textMarkerRange spellCheck:(BOOL)spellCheck
 {
-    return Accessibility::retrieveValueFromMainThread<NSAttributedString *>([&textMarkerRange, &spellCheck, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSAttributedString * {
+    return Accessibility::retrieveValueFromMainThread<NSAttributedString *>([&textMarkerRange, &spellCheck, protectedSelf = retainWrapper(self)] () -> NSAttributedString * {
         auto* backingObject = protectedSelf.get().axBackingObject;
         if (!backingObject)
             return nil;
@@ -1293,11 +1298,13 @@
 
 - (id)textMarkerRangeFromVisiblePositions:(const VisiblePosition&)startPosition endPosition:(const VisiblePosition&)endPosition
 {
-    auto* backingObject = self.axBackingObject;
-    if (!backingObject)
-        return nil;
+    return Accessibility::retrieveValueFromMainThread<NSAttributedString *>([&startPosition, &endPosition, protectedSelf = retainWrapper(self)] () -> id {
+        auto* backingObject = protectedSelf.get().axBackingObject;
+        if (!backingObject)
+            return nil;
 
-    return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), startPosition, endPosition);
+        return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), startPosition, endPosition);
+    });
 }
 
 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
@@ -1912,7 +1919,7 @@
 
 - (id)associatedPluginParent
 {
-    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
         auto* backingObject = protectedSelf.get().axBackingObject;
         if (!backingObject || !backingObject->hasApplePDFAnnotationAttribute())
             return nil;
@@ -2282,7 +2289,7 @@
 
 - (id)windowElement:(NSString*)attributeName
 {
-    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([attributeName, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([attributeName, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
         id remoteParent = [protectedSelf remoteAccessibilityParentObject];
         if (remoteParent) {
             ALLOW_DEPRECATED_DECLARATIONS_BEGIN
@@ -2817,13 +2824,13 @@
         return NSAccessibilityVerticalOrientationValue;
 
     if ([attributeName isEqualToString:@"AXSelectedTextMarkerRange"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             return [protectedSelf textMarkerRangeForSelection];
         });
     }
 
     if ([attributeName isEqualToString:@"AXStartTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             if (auto* backingObject = protectedSelf.get().axBackingObject)
                 return [protectedSelf textMarkerForVisiblePosition:startOfDocument(backingObject->document())];
             return nil;
@@ -2831,7 +2838,7 @@
     }
 
     if ([attributeName isEqualToString:@"AXEndTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             if (auto* backingObject = protectedSelf.get().axBackingObject)
                 return [protectedSelf textMarkerForVisiblePosition:endOfDocument(backingObject->document())];
             return nil;
@@ -3399,7 +3406,7 @@
 
 - (void)accessibilityShowContextMenu
 {
-    Accessibility::performFunctionOnMainThread([protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] {
+    Accessibility::performFunctionOnMainThread([protectedSelf = retainWrapper(self)] {
         [protectedSelf _accessibilityShowContextMenu];
     });
 }
@@ -3756,6 +3763,140 @@
 }
 #endif
 
+enum class TextUnit {
+    LeftWord = 1,
+    RightWord,
+    NextWordEnd,
+    PreviousWordStart,
+    Sentence,
+    NextSentenceEnd,
+    PreviousSentenceStart,
+    Paragraph,
+    NextParagraphEnd,
+    PreviousParagraphStart,
+    Line,
+    LeftLine,
+    RightLine,
+    NextLineEnd,
+    PreviousLineStart,
+};
+
+- (id)textMarkerRangeAtTextMarker:(id)textMarker forUnit:(TextUnit)textUnit
+{
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, &textUnit, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+        auto* backingObject = protectedSelf.get().axBackingObject;
+        if (!backingObject)
+            return nil;
+
+        auto* cache = backingObject->axObjectCache();
+        if (!cache)
+            return nil;
+
+        auto characterOffset = characterOffsetForTextMarker(cache, textMarker);
+        RefPtr<Range> range;
+        switch (textUnit) {
+        case TextUnit::LeftWord:
+            range = cache->leftWordRange(characterOffset);
+            break;
+        case TextUnit::RightWord:
+            range = cache->rightWordRange(characterOffset);
+            break;
+        case TextUnit::Sentence:
+            range = cache->sentenceForCharacterOffset(characterOffset);
+            break;
+        case TextUnit::Paragraph:
+            range = cache->paragraphForCharacterOffset(characterOffset);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+
+        return textMarkerRangeFromRange(cache, range);
+    });
+}
+
+- (id)lineTextMarkerRangeForTextMarker:(id)textMarker forUnit:(TextUnit)textUnit
+{
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, &textUnit, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+        auto* backingObject = protectedSelf.get().axBackingObject;
+        if (!backingObject)
+            return nil;
+
+        auto* cache = backingObject->axObjectCache();
+        if (!cache)
+            return nil;
+
+        auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
+        VisiblePositionRange visiblePositionRange;
+        switch (textUnit) {
+        case TextUnit::Line:
+            visiblePositionRange = backingObject->lineRangeForPosition(visiblePosition);
+            break;
+        case TextUnit::LeftLine:
+            visiblePositionRange = backingObject->leftLineVisiblePositionRange(visiblePosition);
+            break;
+        case TextUnit::RightLine:
+            visiblePositionRange = backingObject->rightLineVisiblePositionRange(visiblePosition);
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+
+        return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), visiblePositionRange.start, visiblePositionRange.end);
+    });
+}
+
+- (id)textMarkerForTextMarker:(id)textMarker atUnit:(TextUnit)textUnit
+{
+    return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, &textUnit, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+        auto* backingObject = protectedSelf.get().axBackingObject;
+        if (!backingObject)
+            return nil;
+
+        auto* cache = backingObject->axObjectCache();
+        if (!cache)
+            return nil;
+
+        CharacterOffset oldOffset = characterOffsetForTextMarker(cache, textMarker);
+        CharacterOffset newOffset;
+        switch (textUnit) {
+        case TextUnit::NextWordEnd:
+            newOffset = cache->nextWordEndCharacterOffset(oldOffset);
+            break;
+        case TextUnit::PreviousWordStart:
+            newOffset = cache->previousWordStartCharacterOffset(oldOffset);
+            break;
+        case TextUnit::NextSentenceEnd:
+            newOffset = cache->nextSentenceEndCharacterOffset(oldOffset);
+            break;
+        case TextUnit::PreviousSentenceStart:
+            newOffset = cache->previousSentenceStartCharacterOffset(oldOffset);
+            break;
+        case TextUnit::NextParagraphEnd:
+            newOffset = cache->nextParagraphEndCharacterOffset(oldOffset);
+            break;
+        case TextUnit::PreviousParagraphStart:
+            newOffset = cache->previousParagraphStartCharacterOffset(oldOffset);
+            break;
+        case TextUnit::NextLineEnd: {
+            auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
+            return textMarkerForVisiblePosition(cache, backingObject->nextLineEndPosition(visiblePosition));
+        }
+        case TextUnit::PreviousLineStart: {
+            auto visiblePosition = visiblePositionForTextMarker(cache, textMarker);
+            return textMarkerForVisiblePosition(cache, backingObject->previousLineStartPosition(visiblePosition));
+        }
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+
+        return textMarkerForCharacterOffset(cache, newOffset);
+    });
+}
+
 ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
 - (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
 ALLOW_DEPRECATED_IMPLEMENTATIONS_END
@@ -3811,7 +3952,7 @@
     // dispatch
     if ([attribute isEqualToString:NSAccessibilitySelectTextWithCriteriaParameterizedAttribute]) {
         // To be deprecated.
-        auto result = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> Vector<String> {
+        auto result = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = retainWrapper(self)] () -> Vector<String> {
             auto* backingObject = protectedSelf.get().axBackingObject;
             if (!backingObject)
                 return Vector<String>();
@@ -3829,7 +3970,7 @@
 
     if ([attribute isEqualToString:NSAccessibilitySearchTextWithCriteriaParameterizedAttribute]) {
         auto criteria = accessibilitySearchTextCriteriaForParameterizedAttribute(dictionary);
-        return Accessibility::retrieveValueFromMainThread<NSArray *>([&criteria, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSArray * {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<NSArray *>([&criteria, protectedSelf = retainWrapper(self)] () -> RetainPtr<NSArray> {
             auto* backingObject = protectedSelf.get().axBackingObject;
             if (!backingObject)
                 return nil;
@@ -3847,7 +3988,7 @@
     }
 
     if ([attribute isEqualToString:NSAccessibilityTextOperationParameterizedAttribute]) {
-        auto operationResult = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> Vector<String> {
+        auto operationResult = Accessibility::retrieveValueFromMainThread<Vector<String>>([dictionary, protectedSelf = retainWrapper(self)] () -> Vector<String> {
             auto* backingObject = protectedSelf.get().axBackingObject;
             if (!backingObject)
                 return Vector<String>();
@@ -3878,8 +4019,12 @@
     }
 
     if ([attribute isEqualToString:NSAccessibilityEndTextMarkerForBoundsParameterizedAttribute]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
                 return nil;
 
@@ -3890,8 +4035,12 @@
     }
 
     if ([attribute isEqualToString:NSAccessibilityStartTextMarkerForBoundsParameterizedAttribute]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&rect, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
                 return nil;
 
@@ -3901,41 +4050,57 @@
         });
     }
 
-    if ([attribute isEqualToString:NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute]) {
-        VisiblePosition visiblePosition = [self visiblePositionForTextMarker:textMarker];
-        VisiblePositionRange visiblePositionRange = backingObject->lineRangeForPosition(visiblePosition);
-        return [self textMarkerRangeFromVisiblePositions:visiblePositionRange.start endPosition:visiblePositionRange.end];
-    }
+    if ([attribute isEqualToString:NSAccessibilityLineTextMarkerRangeForTextMarkerParameterizedAttribute])
+        return [self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::Line];
 
     if ([attribute isEqualToString:NSAccessibilityMisspellingTextMarkerRangeParameterizedAttribute]) {
         auto criteria = accessibilityMisspellingSearchCriteriaForParameterizedAttribute(self, dictionary);
-        if (auto misspellingRange = backingObject->getMisspellingRange(criteria.first, criteria.second))
-            return [self textMarkerRangeFromRange:misspellingRange];
-        return nil;
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&criteria, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            if (auto misspellingRange = backingObject->getMisspellingRange(criteria.first, criteria.second))
+                return [protectedSelf textMarkerRangeFromRange:misspellingRange];
+            return nil;
+        });
     }
 
     if ([attribute isEqualToString:NSAccessibilityTextMarkerIsValidParameterizedAttribute]) {
-        VisiblePosition pos = [self visiblePositionForTextMarker:textMarker];
-        return [NSNumber numberWithBool:!pos.isNull()];
+        bool result = Accessibility::retrieveValueFromMainThread<bool>([&textMarker, protectedSelf = retainWrapper(self)] () -> bool {
+            VisiblePosition pos = [protectedSelf visiblePositionForTextMarker:textMarker];
+            return !pos.isNull();
+        });
+        return [NSNumber numberWithBool:result];
     }
+
     if ([attribute isEqualToString:NSAccessibilityIndexForTextMarkerParameterizedAttribute]) {
-        return [NSNumber numberWithInteger:[self _indexForTextMarker:textMarker]];
+        auto result = Accessibility::retrieveValueFromMainThread<NSInteger>([&textMarker, protectedSelf = retainWrapper(self)] () -> NSInteger {
+            return [protectedSelf _indexForTextMarker:textMarker];
+        });
+        return [NSNumber numberWithInteger:result];
     }
+
     if ([attribute isEqualToString:NSAccessibilityTextMarkerForIndexParameterizedAttribute]) {
-        return [self _textMarkerForIndex:[number integerValue]];
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&number, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            return [protectedSelf _textMarkerForIndex:[number integerValue]];
+        });
     }
 
     if ([attribute isEqualToString:@"AXUIElementForTextMarker"]) {
-        AccessibilityObject* axObject = [self accessibilityObjectForTextMarker:textMarker];
-        if (!axObject)
-            return nil;
-        if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
-            return [axObject->wrapper() attachmentView];
-        return axObject->wrapper();
+        // FIXME: we need to return an IsolatedObject if this is called on the AX thread.
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* axObject = [protectedSelf accessibilityObjectForTextMarker:textMarker];
+            if (!axObject)
+                return nil;
+            if (axObject->isAttachment() && [axObject->wrapper() attachmentView])
+                return [axObject->wrapper() attachmentView];
+            return axObject->wrapper();
+        });
     }
 
     if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&uiElement, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&uiElement, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             RefPtr<Range> range = uiElement.get()->elementRange();
             return [protectedSelf textMarkerRangeFromRange:range];
         });
@@ -3942,19 +4107,29 @@
     }
 
     if ([attribute isEqualToString:@"AXLineForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [NSNumber numberWithUnsignedInt:backingObject->lineForPosition(visiblePos)];
+        int result = Accessibility::retrieveValueFromMainThread<int>([&textMarker, protectedSelf = retainWrapper(self)] () -> int {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return -1;
+
+            VisiblePosition visiblePos = [protectedSelf visiblePositionForTextMarker:textMarker];
+            return backingObject->lineForPosition(visiblePos);
+        });
+        return [NSNumber numberWithInt:result];
     }
 
     if ([attribute isEqualToString:@"AXTextMarkerRangeForLine"]) {
-        VisiblePositionRange vpRange;
-        if ([number unsignedIntegerValue] != NSNotFound)
-            vpRange = backingObject->visiblePositionRangeForLine([number unsignedIntValue]);
-        return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&number, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            VisiblePositionRange vpRange;
+            if (backingObject && [number unsignedIntegerValue] != NSNotFound)
+                vpRange = backingObject->visiblePositionRangeForLine([number unsignedIntValue]);
+            return [protectedSelf textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
+        });
     }
 
     if ([attribute isEqualToString:@"AXStringForTextMarkerRange"]) {
-        return Accessibility::retrieveValueFromMainThread<String>([&textMarkerRange, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> String {
+        return Accessibility::retrieveValueFromMainThread<String>([&textMarkerRange, protectedSelf = retainWrapper(self)] () -> String {
             RefPtr<Range> range = [protectedSelf rangeForTextMarkerRange:textMarkerRange];
             auto* backingObject = protectedSelf.get().axBackingObject;
             return backingObject ? backingObject->stringForRange(range) : String();
@@ -3966,25 +4141,35 @@
         if (!pointSet)
             return nil;
 
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&webCorePoint, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&webCorePoint, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
                 return nil;
 
-            CharacterOffset characterOffset = cache->characterOffsetForPoint(webCorePoint, protectedSelf.get().axBackingObject);
+            CharacterOffset characterOffset = cache->characterOffsetForPoint(webCorePoint, backingObject);
             return [protectedSelf textMarkerForCharacterOffset:characterOffset];
         });
     }
 
     if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
-        RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        auto bounds = FloatRect(backingObject->boundsForRange(range));
-        NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
+        NSRect rect = Accessibility::retrieveValueFromMainThread<NSRect>([&textMarkerRange, protectedSelf = retainWrapper(self)] () -> NSRect {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return CGRectZero;
+
+            RefPtr<Range> range = [protectedSelf rangeForTextMarkerRange:textMarkerRange];
+            auto bounds = FloatRect(backingObject->boundsForRange(range));
+            return [protectedSelf convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
+        });
         return [NSValue valueWithRect:rect];
     }
 
     if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
-        NSRect rect = Accessibility::retrieveValueFromMainThread<NSRect>([&range, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSRect {
+        NSRect rect = Accessibility::retrieveValueFromMainThread<NSRect>([&range, protectedSelf = retainWrapper(self)] () -> NSRect {
             auto* backingObject = protectedSelf.get().axBackingObject;
             if (!backingObject)
                 return CGRectZero;
@@ -4011,18 +4196,22 @@
             return backingObject->doAXStringForRange(plainTextRange);
         }
 
-        return Accessibility::retrieveValueFromMainThread<NSString *>([&range, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> NSString * {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+        return Accessibility::retrieveValueFromMainThread<String>([&range, protectedSelf = retainWrapper(self)] () -> String {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return String();
+
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
-                return nil;
+                return String();
 
-            CharacterOffset start = cache->characterOffsetForIndex(range.location, protectedSelf.get().axBackingObject);
-            CharacterOffset end = cache->characterOffsetForIndex(range.location + range.length, protectedSelf.get().axBackingObject);
+            CharacterOffset start = cache->characterOffsetForIndex(range.location, backingObject);
+            CharacterOffset end = cache->characterOffsetForIndex(range.location + range.length, backingObject);
             if (start.isNull() || end.isNull())
-                return nil;
+                return String();
 
             RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(start, end);
-            return protectedSelf.get().axBackingObject->stringForRange(range);
+            return backingObject->stringForRange(range);
         });
     }
 
@@ -4055,8 +4244,12 @@
         if (!AXObjectIsTextMarker(textMarker1) || !AXObjectIsTextMarker(textMarker2))
             return nil;
 
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker1, textMarker2, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker1, &textMarker2, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return nil;
+
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
                 return nil;
 
@@ -4068,166 +4261,86 @@
     }
 
     if ([attribute isEqualToString:@"AXNextTextMarkerForTextMarker"]) {
-        CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
-        return [self nextTextMarkerForCharacterOffset:characterOffset];
-    }
-
-    if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
-        CharacterOffset characterOffset = [self characterOffsetForTextMarker:textMarker];
-        return [self previousTextMarkerForCharacterOffset:characterOffset];
-    }
-
-    if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
-
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            RefPtr<Range> range = cache->leftWordRange(characterOffset);
-            return [protectedSelf textMarkerRangeFromRange:range];
+            return [protectedSelf nextTextMarkerForCharacterOffset:characterOffset];
         });
     }
 
-    if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
-
+    if ([attribute isEqualToString:@"AXPreviousTextMarkerForTextMarker"]) {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
             CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            RefPtr<Range> range = cache->rightWordRange(characterOffset);
-            return [protectedSelf textMarkerRangeFromRange:range];
+            return [protectedSelf previousTextMarkerForCharacterOffset:characterOffset];
         });
     }
 
-    if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = backingObject->leftLineVisiblePositionRange(visiblePos);
-        return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
-    }
+    if ([attribute isEqualToString:@"AXLeftWordTextMarkerRangeForTextMarker"])
+        return [self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::LeftWord];
 
-    if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = backingObject->rightLineVisiblePositionRange(visiblePos);
-        return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
-    }
+    if ([attribute isEqualToString:@"AXRightWordTextMarkerRangeForTextMarker"])
+        return [self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::RightWord];
 
-    if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXLeftLineTextMarkerRangeForTextMarker"])
+        return [self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::LeftLine];
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            RefPtr<Range> range = cache->sentenceForCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerRangeFromRange:range];
-        });
-    }
+    if ([attribute isEqualToString:@"AXRightLineTextMarkerRangeForTextMarker"])
+        return [self lineTextMarkerRangeForTextMarker:textMarker forUnit:TextUnit::RightLine];
 
-    if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXSentenceTextMarkerRangeForTextMarker"])
+        return [self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::Sentence];
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            RefPtr<Range> range = cache->paragraphForCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerRangeFromRange:range];
-        });
-    }
+    if ([attribute isEqualToString:@"AXParagraphTextMarkerRangeForTextMarker"])
+        return [self textMarkerRangeAtTextMarker:textMarker forUnit:TextUnit::Paragraph];
 
-    if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXNextWordEndTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextWordEnd];
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset nextEnd = cache->nextWordEndCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:nextEnd];
-        });
-    }
+    if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousWordStart];
 
-    if ([attribute isEqualToString:@"AXPreviousWordStartTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextLineEnd];
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset previousStart = cache->previousWordStartCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:previousStart];
-        });
-    }
+    if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousLineStart];
 
-    if ([attribute isEqualToString:@"AXNextLineEndTextMarkerForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [self textMarkerForVisiblePosition:backingObject->nextLineEndPosition(visiblePos)];
-    }
+    if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextSentenceEnd];
 
-    if ([attribute isEqualToString:@"AXPreviousLineStartTextMarkerForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        return [self textMarkerForVisiblePosition:backingObject->previousLineStartPosition(visiblePos)];
-    }
+    if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousSentenceStart];
 
-    if ([attribute isEqualToString:@"AXNextSentenceEndTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::NextParagraphEnd];
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset nextEnd = cache->nextSentenceEndCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:nextEnd];
-        });
-    }
+    if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"])
+        return [self textMarkerForTextMarker:textMarker atUnit:TextUnit::PreviousParagraphStart];
 
-    if ([attribute isEqualToString:@"AXPreviousSentenceStartTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
+    if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarker, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
                 return nil;
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset previousStart = cache->previousSentenceStartCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:previousStart];
-        });
-    }
-
-    if ([attribute isEqualToString:@"AXNextParagraphEndTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
+            auto* cache = backingObject->axObjectCache();
             if (!cache)
                 return nil;
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset nextEnd = cache->nextParagraphEndCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:nextEnd];
+        VisiblePosition visiblePos = visiblePositionForTextMarker(cache, textMarker);
+        VisiblePositionRange vpRange = backingObject->styleRangeForPosition(visiblePos);
+        return [protectedSelf textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
         });
     }
 
-    if ([attribute isEqualToString:@"AXPreviousParagraphStartTextMarkerForTextMarker"]) {
-        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([textMarker, protectedSelf = RetainPtr<WebAccessibilityObjectWrapper>(self)] () -> RetainPtr<id> {
-            auto* cache = protectedSelf.get().axBackingObject->axObjectCache();
-            if (!cache)
-                return nil;
+    if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
+        int length = Accessibility::retrieveValueFromMainThread<int>([&textMarkerRange, protectedSelf = retainWrapper(self)] () -> int {
+            auto* backingObject = protectedSelf.get().axBackingObject;
+            if (!backingObject)
+                return 0;
 
-            CharacterOffset characterOffset = [protectedSelf characterOffsetForTextMarker:textMarker];
-            CharacterOffset previousStart = cache->previousParagraphStartCharacterOffset(characterOffset);
-            return [protectedSelf textMarkerForCharacterOffset:previousStart];
+            RefPtr<Range> range = [protectedSelf rangeForTextMarkerRange:textMarkerRange];
+            return AXObjectCache::lengthForRange(range.get());
         });
-    }
-
-    if ([attribute isEqualToString:@"AXStyleTextMarkerRangeForTextMarker"]) {
-        VisiblePosition visiblePos = [self visiblePositionForTextMarker:(textMarker)];
-        VisiblePositionRange vpRange = backingObject->styleRangeForPosition(visiblePos);
-        return [self textMarkerRangeFromVisiblePositions:vpRange.start endPosition:vpRange.end];
-    }
-
-    if ([attribute isEqualToString:@"AXLengthForTextMarkerRange"]) {
-        RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        int length = AXObjectCache::lengthForRange(range.get());
         if (length < 0)
             return nil;
         return [NSNumber numberWithInt:length];
@@ -4235,13 +4348,17 @@
 
     // Used only by DumpRenderTree (so far).
     if ([attribute isEqualToString:@"AXStartTextMarkerForTextMarkerRange"]) {
-        RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        return [self startOrEndTextMarkerForRange:range isStart:YES];
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarkerRange, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            RefPtr<Range> range = [protectedSelf rangeForTextMarkerRange:textMarkerRange];
+            return [protectedSelf startOrEndTextMarkerForRange:range isStart:YES];
+        });
     }
 
     if ([attribute isEqualToString:@"AXEndTextMarkerForTextMarkerRange"]) {
-        RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
-        return [self startOrEndTextMarkerForRange:range isStart:NO];
+        return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([&textMarkerRange, protectedSelf = retainWrapper(self)] () -> RetainPtr<id> {
+            RefPtr<Range> range = [protectedSelf rangeForTextMarkerRange:textMarkerRange];
+            return [protectedSelf startOrEndTextMarkerForRange:range isStart:NO];
+        });
     }
 
 #if ENABLE(TREE_DEBUGGING)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to