Diff
Modified: branches/safari-612-branch/LayoutTests/ChangeLog (282929 => 282930)
--- branches/safari-612-branch/LayoutTests/ChangeLog 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/LayoutTests/ChangeLog 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1,5 +1,55 @@
2021-09-22 Alan Coon <alanc...@apple.com>
+ Cherry-pick r281691. rdar://problem/83429796
+
+ Make AXCoreObject::setSelectedVisiblePositionRange work in native text controls on MacOS.
+ https://bugs.webkit.org/show_bug.cgi?id=229529
+
+ Reviewed by Chris Fleizach.
+
+ Source/WebCore:
+
+ Test: accessibility/mac/native-text-control-set-selected-textmarker-range.html
+
+ Trying to set the selection in native text controls using the atribute
+ AXSelectedTextMarkerRange didn't work for MacOS AX clients. This patch
+ implements this functionality by properly handling native text controls
+ in AccessibilityRenderObject::setSelectedVisiblePositionRange.
+
+ * accessibility/AccessibilityObject.h:
+ * accessibility/AccessibilityObjectInterface.h:
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::documentBasedSelectedTextRange const):
+ (WebCore::AccessibilityRenderObject::selectedVisiblePositionRange const): Added.
+ (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange const):
+ * accessibility/AccessibilityRenderObject.h:
+ * accessibility/isolatedtree/AXIsolatedObject.cpp:
+ (WebCore::AXIsolatedObject::selectedVisiblePositionRange const):
+ * accessibility/isolatedtree/AXIsolatedObject.h:
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[WebAccessibilityObjectWrapper textMarkerRangeForSelection]): Renamed selectedTextMarkerRange for consistency.
+
+ LayoutTests:
+
+ * accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt: Added.
+ * accessibility/mac/native-text-control-set-selected-textmarker-range.html: Added.
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@281691 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-08-27 Andres Gonzalez <andresg...@apple.com>
+
+ Make AXCoreObject::setSelectedVisiblePositionRange work in native text controls on MacOS.
+ https://bugs.webkit.org/show_bug.cgi?id=229529
+
+ Reviewed by Chris Fleizach.
+
+ * accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt: Added.
+ * accessibility/mac/native-text-control-set-selected-textmarker-range.html: Added.
+
+2021-09-22 Alan Coon <alanc...@apple.com>
+
Cherry-pick r281613. rdar://problem/83429969
Crash in GraphicsContextGLOpenGL::reshapeDisplayBufferBacking
Added: branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt (0 => 282930)
--- branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt (rev 0)
+++ branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt 2021-09-23 05:13:42 UTC (rev 282930)
@@ -0,0 +1,15 @@
+Test for setting the selected TextMarkerRange in a native text control: textarea and text field.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+selected text "This is a textarea."
+selected text "This is a "
+selected text " is a "
+selected text "This is a text field."
+selected text "This is a "
+selected text " is a text"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range.html (0 => 282930)
--- branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range.html (rev 0)
+++ branches/safari-612-branch/LayoutTests/accessibility/mac/native-text-control-set-selected-textmarker-range.html 2021-09-23 05:13:42 UTC (rev 282930)
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<textarea id="textarea">This is a textarea.</textarea>
+
+<input type="text" id="textfield" value="This is a text field." />
+
+<script>
+ description("Test for setting the selected TextMarkerRange in a native text control: textarea and text field.");
+
+ if (window.accessibilityController) {
+ window.jsTestIsAsync = true;
+
+ let elementID = "textarea";
+
+ let p = accessibilityController.accessibleElementById(elementID);
+ let range = p.textMarkerRangeForElement(p);
+
+ setTimeout(async () => {
+ // Select all text.
+ p.setSelectedTextMarkerRange(range);
+ let selectedRange = null;
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 19;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ // Select the first 10 characters.
+ let start = p.startTextMarkerForTextMarkerRange(range);
+ end = start;
+ for (let i = 0; i < 10; ++i)
+ end = p.nextTextMarker(end);
+ range = p.textMarkerRangeForMarkers(start, end);
+ p.setSelectedTextMarkerRange(range);
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 10;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ // Select some characters in the middle.
+ for (let i = 0; i < 4; ++i)
+ start = p.nextTextMarker(start);
+ range = p.textMarkerRangeForMarkers(start, end);
+ p.setSelectedTextMarkerRange(range);
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 6;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ elementID = "textfield";
+
+ p = accessibilityController.accessibleElementById(elementID);
+ range = p.textMarkerRangeForElement(p);
+
+ // Select all text.
+ p.setSelectedTextMarkerRange(range);
+ selectedRange = null;
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 21;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ // Select the first 10 characters.
+ start = p.startTextMarkerForTextMarkerRange(range);
+ end = start;
+ for (let i = 0; i < 10; ++i)
+ end = p.nextTextMarker(end);
+ range = p.textMarkerRangeForMarkers(start, end);
+ p.setSelectedTextMarkerRange(range);
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 10;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ // Select some characters in the middle.
+ for (let i = 0; i < 4; ++i)
+ start = p.nextTextMarker(start);
+ for (let i = 0; i < 4; ++i)
+ end = p.nextTextMarker(end);
+ range = p.textMarkerRangeForMarkers(start, end);
+ p.setSelectedTextMarkerRange(range);
+ await waitFor(() => {
+ selectedRange = p.selectedTextMarkerRange();
+ return p.textMarkerRangeLength(selectedRange) == 10;
+ });
+ debug(`selected text "${p.stringForTextMarkerRange(selectedRange)}"`);
+
+ finishJSTest();
+ }, 0);
+ }
+</script>
+</body>
+</html>
Modified: branches/safari-612-branch/Source/WebCore/ChangeLog (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/ChangeLog 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/ChangeLog 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1,5 +1,73 @@
2021-09-22 Alan Coon <alanc...@apple.com>
+ Cherry-pick r281691. rdar://problem/83429796
+
+ Make AXCoreObject::setSelectedVisiblePositionRange work in native text controls on MacOS.
+ https://bugs.webkit.org/show_bug.cgi?id=229529
+
+ Reviewed by Chris Fleizach.
+
+ Source/WebCore:
+
+ Test: accessibility/mac/native-text-control-set-selected-textmarker-range.html
+
+ Trying to set the selection in native text controls using the atribute
+ AXSelectedTextMarkerRange didn't work for MacOS AX clients. This patch
+ implements this functionality by properly handling native text controls
+ in AccessibilityRenderObject::setSelectedVisiblePositionRange.
+
+ * accessibility/AccessibilityObject.h:
+ * accessibility/AccessibilityObjectInterface.h:
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::documentBasedSelectedTextRange const):
+ (WebCore::AccessibilityRenderObject::selectedVisiblePositionRange const): Added.
+ (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange const):
+ * accessibility/AccessibilityRenderObject.h:
+ * accessibility/isolatedtree/AXIsolatedObject.cpp:
+ (WebCore::AXIsolatedObject::selectedVisiblePositionRange const):
+ * accessibility/isolatedtree/AXIsolatedObject.h:
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[WebAccessibilityObjectWrapper textMarkerRangeForSelection]): Renamed selectedTextMarkerRange for consistency.
+
+ LayoutTests:
+
+ * accessibility/mac/native-text-control-set-selected-textmarker-range-expected.txt: Added.
+ * accessibility/mac/native-text-control-set-selected-textmarker-range.html: Added.
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@281691 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2021-08-27 Andres Gonzalez <andresg...@apple.com>
+
+ Make AXCoreObject::setSelectedVisiblePositionRange work in native text controls on MacOS.
+ https://bugs.webkit.org/show_bug.cgi?id=229529
+
+ Reviewed by Chris Fleizach.
+
+ Test: accessibility/mac/native-text-control-set-selected-textmarker-range.html
+
+ Trying to set the selection in native text controls using the atribute
+ AXSelectedTextMarkerRange didn't work for MacOS AX clients. This patch
+ implements this functionality by properly handling native text controls
+ in AccessibilityRenderObject::setSelectedVisiblePositionRange.
+
+ * accessibility/AccessibilityObject.h:
+ * accessibility/AccessibilityObjectInterface.h:
+ * accessibility/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::documentBasedSelectedTextRange const):
+ (WebCore::AccessibilityRenderObject::selectedVisiblePositionRange const): Added.
+ (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange const):
+ * accessibility/AccessibilityRenderObject.h:
+ * accessibility/isolatedtree/AXIsolatedObject.cpp:
+ (WebCore::AXIsolatedObject::selectedVisiblePositionRange const):
+ * accessibility/isolatedtree/AXIsolatedObject.h:
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[WebAccessibilityObjectWrapper textMarkerRangeForSelection]): Renamed selectedTextMarkerRange for consistency.
+
+2021-09-22 Alan Coon <alanc...@apple.com>
+
Cherry-pick r281613. rdar://problem/83429969
Crash in GraphicsContextGLOpenGL::reshapeDisplayBufferBacking
Modified: branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObject.h (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObject.h 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObject.h 2021-09-23 05:13:42 UTC (rev 282930)
@@ -536,6 +536,7 @@
VisiblePositionRange styleRangeForPosition(const VisiblePosition&) const override;
VisiblePositionRange visiblePositionRangeForRange(const PlainTextRange&) const override;
VisiblePositionRange lineRangeForPosition(const VisiblePosition&) const override;
+ VisiblePositionRange selectedVisiblePositionRange() const override { return { }; }
std::optional<SimpleRange> rangeForPlainTextRange(const PlainTextRange&) const override;
#if PLATFORM(MAC)
Modified: branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObjectInterface.h (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1274,6 +1274,7 @@
virtual VisiblePositionRange styleRangeForPosition(const VisiblePosition&) const = 0;
virtual VisiblePositionRange visiblePositionRangeForRange(const PlainTextRange&) const = 0;
virtual VisiblePositionRange lineRangeForPosition(const VisiblePosition&) const = 0;
+ virtual VisiblePositionRange selectedVisiblePositionRange() const = 0;
virtual std::optional<SimpleRange> rangeForPlainTextRange(const PlainTextRange&) const = 0;
#if PLATFORM(MAC)
Modified: branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.cpp 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1617,17 +1617,12 @@
PlainTextRange AccessibilityRenderObject::documentBasedSelectedTextRange() const
{
- Node* node = m_renderer->node();
- if (!node)
- return PlainTextRange();
+ auto selectedVisiblePositionRange = this->selectedVisiblePositionRange();
+ if (selectedVisiblePositionRange.isNull())
+ return { };
- auto visibleSelection = selection();
- auto selectionRange = visibleSelection.firstRange();
- if (!selectionRange || !intersects<ComposedTree>(*selectionRange, *node))
- return PlainTextRange();
-
- int start = indexForVisiblePosition(visibleSelection.start());
- int end = indexForVisiblePosition(visibleSelection.end());
+ int start = indexForVisiblePosition(selectedVisiblePositionRange.start);
+ int end = indexForVisiblePosition(selectedVisiblePositionRange.end);
return PlainTextRange(start, end - start);
}
@@ -2284,6 +2279,17 @@
return false;
}
+VisiblePositionRange AccessibilityRenderObject::selectedVisiblePositionRange() const
+{
+ if (!m_renderer)
+ return { };
+
+ auto selection = m_renderer->frame().selection().selection();
+ if (selection.isNone())
+ return { };
+ return selection;
+}
+
void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const
{
if (range.isNull())
@@ -2298,22 +2304,50 @@
if (auto client = m_renderer->document().editor().client())
client->willChangeSelectionForAccessibility();
- // make selection and tell the document to use it. if it's zero length, then move to that position
- if (range.start == range.end) {
- setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionMove);
+ if (isNativeTextControl()) {
+ // isNativeTextControl returns true only if this->node() is<HTMLTextAreaElement> or is<HTMLInputElement>.
+ // Since both HTMLTextAreaElement and HTMLInputElement derive from HTMLTextFormControlElement, it is safe to downcast here.
+ auto* textControl = downcast<HTMLTextFormControlElement>(node());
+ int start = textControl->indexForVisiblePosition(range.start);
+ int end = textControl->indexForVisiblePosition(range.end);
- auto start = range.start;
- if (auto elementRange = this->elementRange()) {
- if (!contains<ComposedTree>(*elementRange, makeBoundaryPoint(start)))
- start = makeContainerOffsetPosition(elementRange->start);
+ // For ranges entirely contained in textControl, the start or end position may not be inside textControl.innerTextElement.
+ // This would cause that the above indexes will be 0, leading to an incorrect selected range
+ // (see HTMLTextFormControlElement::indexForVisiblePosition). This is
+ // the case when range is obtained from AXObjectCache::rangeForNodeContents
+ // for the HTMLTextFormControlElement.
+ // Thus, the following corrects the start and end indexes in such a case..
+ if (range.start.deepEquivalent().anchorNode() == range.end.deepEquivalent().anchorNode()
+ && range.start.deepEquivalent().anchorNode() == textControl) {
+ if (auto innerText = textControl->innerTextElement()) {
+ auto innerRange = makeVisiblePositionRange(AXObjectCache::rangeForNodeContents(*innerText));
+ if (range.start < innerRange.start)
+ start = 0;
+ if (range.end >= innerRange.end)
+ end = textControl->value().length();
+ }
}
- m_renderer->frame().selection().moveTo(start, UserTriggered);
+ setTextSelectionIntent(axObjectCache(), start == end ? AXTextStateChangeTypeSelectionMove : AXTextStateChangeTypeSelectionExtend);
+ textControl->setSelectionRange(start, end);
} else {
- setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionExtend);
+ // Make selection and tell the document to use it. If it's zero length, then move to that position.
+ if (range.start == range.end) {
+ setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionMove);
- VisibleSelection newSelection = VisibleSelection(range.start, range.end);
- m_renderer->frame().selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(UserTriggered));
+ auto start = range.start;
+ if (auto elementRange = this->elementRange()) {
+ if (!contains<ComposedTree>(*elementRange, makeBoundaryPoint(start)))
+ start = makeContainerOffsetPosition(elementRange->start);
+ }
+
+ m_renderer->frame().selection().moveTo(start, UserTriggered);
+ } else {
+ setTextSelectionIntent(axObjectCache(), AXTextStateChangeTypeSelectionExtend);
+
+ VisibleSelection newSelection = VisibleSelection(range.start, range.end);
+ m_renderer->frame().selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(UserTriggered));
+ }
}
clearTextSelectionIntent(axObjectCache());
Modified: branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.h (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.h 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/AccessibilityRenderObject.h 2021-09-23 05:13:42 UTC (rev 282930)
@@ -165,6 +165,7 @@
VisiblePositionRange visiblePositionRangeForLine(unsigned) const override;
IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const override;
IntRect boundsForRange(const SimpleRange&) const override;
+ VisiblePositionRange selectedVisiblePositionRange() const override;
void setSelectedVisiblePositionRange(const VisiblePositionRange&) const override;
bool isVisiblePositionRangeInDifferentDocument(const VisiblePositionRange&) const;
bool hasPopup() const override;
Modified: branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1435,6 +1435,15 @@
return object ? object->selection() : VisibleSelection();
}
+VisiblePositionRange AXIsolatedObject::selectedVisiblePositionRange() const
+{
+ ASSERT(isMainThread());
+
+ if (auto* axObject = associatedAXObject())
+ return axObject->selectedVisiblePositionRange();
+ return { };
+}
+
void AXIsolatedObject::setSelectedVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const
{
ASSERT(isMainThread());
Modified: branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2021-09-23 05:13:42 UTC (rev 282930)
@@ -384,6 +384,7 @@
unsigned doAXLineForIndex(unsigned) override;
VisibleSelection selection() const override;
+ VisiblePositionRange selectedVisiblePositionRange() const override;
void setSelectedVisiblePositionRange(const VisiblePositionRange&) const override;
// TODO: Text ranges and selection.
Modified: branches/safari-612-branch/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (282929 => 282930)
--- branches/safari-612-branch/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2021-09-23 05:13:37 UTC (rev 282929)
+++ branches/safari-612-branch/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2021-09-23 05:13:42 UTC (rev 282930)
@@ -1683,7 +1683,7 @@
}
}
-- (AXTextMarkerRangeRef)textMarkerRangeForSelection
+- (AXTextMarkerRangeRef)selectedTextMarkerRange
{
return Accessibility::retrieveAutoreleasedValueFromMainThread<AXTextMarkerRangeRef>([protectedSelf = retainPtr(self)] () -> RetainPtr<AXTextMarkerRangeRef> {
auto* backingObject = protectedSelf.get().axBackingObject;
@@ -1690,11 +1690,10 @@
if (!backingObject)
return nil;
- VisibleSelection selection = backingObject->selection();
- if (selection.isNone())
+ auto selectedVisiblePositionRange = backingObject->selectedVisiblePositionRange();
+ if (selectedVisiblePositionRange.isNull())
return nil;
-
- return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), selection.visibleStart(), selection.visibleEnd());
+ return textMarkerRangeFromVisiblePositions(backingObject->axObjectCache(), selectedVisiblePositionRange.start, selectedVisiblePositionRange.end);
});
}
@@ -2614,7 +2613,7 @@
return NSAccessibilityVerticalOrientationValue;
if ([attributeName isEqualToString:@"AXSelectedTextMarkerRange"])
- return (id)[self textMarkerRangeForSelection];
+ return (id)[self selectedTextMarkerRange];
if ([attributeName isEqualToString:@"AXStartTextMarker"]) {
return Accessibility::retrieveAutoreleasedValueFromMainThread<id>([protectedSelf = retainPtr(self)] () -> RetainPtr<id> {