Title: [264037] trunk
Revision
264037
Author
[email protected]
Date
2020-07-07 12:49:55 -0700 (Tue, 07 Jul 2020)

Log Message

Web content process hangs in AccessibilityRenderObject::setSelectedVisiblePositionRange in some corner cases.
https://bugs.webkit.org/show_bug.cgi?id=214017
Source/WebCore:

<rdar://problem/63000006>

Reviewed by Chris Fleizach.

Ensures that in the case of collapsed ranges, the VisiblePosition that
the selection is being set to, is contained in the Element object.

Test: accessibility/mac/selected-visible-position-range.html

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange const):

LayoutTests:

Reviewed by Chris Fleizach.

* accessibility/mac/resources/accessibility-helper.js:
(selectTextInNode):
* accessibility/mac/selected-visible-position-range-expected.txt: Added.
* accessibility/mac/selected-visible-position-range.html: Added.
* accessibility/mac/text-marker-p-tags.html:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (264036 => 264037)


--- trunk/LayoutTests/ChangeLog	2020-07-07 19:45:53 UTC (rev 264036)
+++ trunk/LayoutTests/ChangeLog	2020-07-07 19:49:55 UTC (rev 264037)
@@ -1,3 +1,16 @@
+2020-07-07  Andres Gonzalez  <[email protected]>
+
+        Web content process hangs in AccessibilityRenderObject::setSelectedVisiblePositionRange in some corner cases.
+        https://bugs.webkit.org/show_bug.cgi?id=214017
+
+        Reviewed by Chris Fleizach.
+
+        * accessibility/mac/resources/accessibility-helper.js:
+        (selectTextInNode):
+        * accessibility/mac/selected-visible-position-range-expected.txt: Added.
+        * accessibility/mac/selected-visible-position-range.html: Added.
+        * accessibility/mac/text-marker-p-tags.html:
+
 2020-07-07  Simon Fraser  <[email protected]>
 
         Unable to scroll elcomerico.pe page until the page finishes loading

Modified: trunk/LayoutTests/accessibility/mac/resources/accessibility-helper.js (264036 => 264037)


--- trunk/LayoutTests/accessibility/mac/resources/accessibility-helper.js	2020-07-07 19:45:53 UTC (rev 264036)
+++ trunk/LayoutTests/accessibility/mac/resources/accessibility-helper.js	2020-07-07 19:49:55 UTC (rev 264037)
@@ -21,3 +21,21 @@
 function setCaretBrowsingEnabled(webArea, value) {
     webArea.setBoolAttributeValue("AXCaretBrowsingEnabled", value);
 }
+
+function selectTextInNode(nodeId) {
+    var node = document.getElementById(nodeId);
+
+    if (document.body.createTextRange) {
+        const range = document.body.createTextRange();
+        range.moveToElementText(node);
+        range.select();
+    } else if (window.getSelection) {
+        const selection = window.getSelection();
+        const range = document.createRange();
+        range.selectNodeContents(node);
+        selection.removeAllRanges();
+        selection.addRange(range);
+    } else {
+        console.warn("Could not select text in node: Unsupported browser.");
+    }
+}

Added: trunk/LayoutTests/accessibility/mac/selected-visible-position-range-expected.txt (0 => 264037)


--- trunk/LayoutTests/accessibility/mac/selected-visible-position-range-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/accessibility/mac/selected-visible-position-range-expected.txt	2020-07-07 19:49:55 UTC (rev 264037)
@@ -0,0 +1,19 @@
+First paragraph.
+
+Last paragraph.
+
+This tests getting and setting the selected VisiblePosition range.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS selectedString is 'Last paragraph.'
+selectedString must be the text of the first paragraph: First paragraph.
+
+
+selectedString must be an empty string: 
+selectedString must be an empty string: 
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/accessibility/mac/selected-visible-position-range.html (0 => 264037)


--- trunk/LayoutTests/accessibility/mac/selected-visible-position-range.html	                        (rev 0)
+++ trunk/LayoutTests/accessibility/mac/selected-visible-position-range.html	2020-07-07 19:49:55 UTC (rev 264037)
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<div id="content" contenteditable=true>
+    <p id="p1">First paragraph.</p>
+    <p id="p2">Last paragraph.</p>
+</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+    description("This tests getting and setting the selected VisiblePosition range.");
+
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
+
+        // Select the last paragraph using DOM API.
+        selectTextInNode("p2");
+
+        // Get current selection range via accessibility API.
+        var content = accessibilityController.accessibleElementById("content");
+        var selectedRange = content.selectedTextMarkerRange();
+        var selectedString = content.stringForTextMarkerRange(selectedRange);
+        shouldBe("selectedString", "'Last paragraph.'");
+
+        // Set the selection to the first paragraph via accessibility API.
+        var startTextMarker = content.startTextMarkerForTextMarkerRange(selectedRange);
+        var previousParagraphStart = content.previousParagraphStartTextMarkerForTextMarker(startTextMarker);
+        var paragraphRange = content.textMarkerRangeForMarkers(previousParagraphStart, startTextMarker);
+        content.setSelectedVisibleTextRange(paragraphRange);
+        setTimeout(function() {
+            selectedRange = content.selectedTextMarkerRange();
+            selectedString = content.stringForTextMarkerRange(selectedRange);
+            debug("selectedString must be the text of the first paragraph: " + selectedString);
+
+            // Set the selection range to a collapsed range at the start position of the last paragraph.
+            var nullRange = content.textMarkerRangeForMarkers(startTextMarker, startTextMarker);
+            content.setSelectedVisibleTextRange(nullRange);
+            setTimeout(function() {
+                selectedRange = content.selectedTextMarkerRange();
+                selectedString = content.stringForTextMarkerRange(selectedRange);
+                debug("selectedString must be an empty string: " + selectedString);
+
+                // Set the selection range to a collapsed range at the start position of the first paragraph.
+                nullRange = content.textMarkerRangeForMarkers(previousParagraphStart, previousParagraphStart);
+                content.setSelectedVisibleTextRange(nullRange);
+                setTimeout(function() {
+                    selectedRange = content.selectedTextMarkerRange();
+                    selectedString = content.stringForTextMarkerRange(selectedRange);
+                    debug("selectedString must be an empty string: " + selectedString);
+
+                    finishJSTest();
+                }, 10);
+            }, 10);
+        }, 10);
+    }
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/accessibility/mac/text-marker-p-tags.html (264036 => 264037)


--- trunk/LayoutTests/accessibility/mac/text-marker-p-tags.html	2020-07-07 19:45:53 UTC (rev 264036)
+++ trunk/LayoutTests/accessibility/mac/text-marker-p-tags.html	2020-07-07 19:49:55 UTC (rev 264037)
@@ -2,6 +2,7 @@
 <html>
 <head>
 <script src=""
+<script src=""
 </head>
 <body id="body">
 
@@ -19,7 +20,7 @@
     if (window.accessibilityController) {
 
         // select text
-        selectText('p2');
+        selectTextInNode('p2');
         var p2 = accessibilityController.accessibleElementById("p2");
         var selectedRange = p2.selectedTextMarkerRange();
         var selectedString = p2.stringForTextMarkerRange(selectedRange);
@@ -41,25 +42,6 @@
         var paragraphString = p2.stringForTextMarkerRange(paragraphRange);
         debug("Previous paragraph: " + paragraphString);
     }
-
-    function selectText(node) {
-        node = document.getElementById(node);
-
-        if (document.body.createTextRange) {
-            const range = document.body.createTextRange();
-            range.moveToElementText(node);
-            range.select();
-        } else if (window.getSelection) {
-            const selection = window.getSelection();
-            const range = document.createRange();
-            range.selectNodeContents(node);
-            selection.removeAllRanges();
-            selection.addRange(range);
-        } else {
-            console.warn("Could not select text in node: Unsupported browser.");
-        }
-    }
-    
 </script>
 
 <script src=""

Modified: trunk/Source/WebCore/ChangeLog (264036 => 264037)


--- trunk/Source/WebCore/ChangeLog	2020-07-07 19:45:53 UTC (rev 264036)
+++ trunk/Source/WebCore/ChangeLog	2020-07-07 19:49:55 UTC (rev 264037)
@@ -1,3 +1,19 @@
+2020-07-07  Andres Gonzalez  <[email protected]>
+
+        Web content process hangs in AccessibilityRenderObject::setSelectedVisiblePositionRange in some corner cases.
+        https://bugs.webkit.org/show_bug.cgi?id=214017
+        <rdar://problem/63000006>
+
+        Reviewed by Chris Fleizach.
+
+        Ensures that in the case of collapsed ranges, the VisiblePosition that
+        the selection is being set to, is contained in the Element object.
+
+        Test: accessibility/mac/selected-visible-position-range.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange const):
+
 2020-07-07  Youenn Fablet  <[email protected]>
 
         Fix potential pixel buffer leak in ImageRotationSessionVT::rotate

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (264036 => 264037)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2020-07-07 19:45:53 UTC (rev 264036)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2020-07-07 19:49:55 UTC (rev 264037)
@@ -2219,26 +2219,31 @@
 {
     if (range.start.isNull() || range.end.isNull())
         return;
-    
+
     // In WebKit1, when the top web area sets the selection to be an input element in an iframe, the caret will disappear.
     // FrameSelection::setSelectionWithoutUpdatingAppearance is setting the selection on the new frame in this case, and causing this behavior.
-    if (isWebArea() && parentObject() && parentObject()->isAttachment()) {
-        if (isVisiblePositionRangeInDifferentDocument(range))
-            return;
-    }
+    if (isWebArea() && parentObject() && parentObject()->isAttachment()
+        && isVisiblePositionRangeInDifferentDocument(range))
+        return;
 
     // 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);
-        m_renderer->frame().selection().moveTo(range.start, UserTriggered);
-        clearTextSelectionIntent(axObjectCache());
-    }
-    else {
+
+        auto elementRange = this->elementRange();
+        auto start = range.start;
+        if (elementRange && !elementRange->contains(start))
+            start = VisiblePosition(elementRange->startPosition());
+
+        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());
-        clearTextSelectionIntent(axObjectCache());
     }
+
+    clearTextSelectionIntent(axObjectCache());
 }
 
 VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to