AX: iOS: Can't navigate inside ContentEditable fields with voiceover enabled
authorcfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Mar 2016 00:42:32 +0000 (00:42 +0000)
committercfleizach@apple.com <cfleizach@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Mar 2016 00:42:32 +0000 (00:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155942

Reviewed by Joanmarie Diggs.

Source/WebCore:

The code to set the selected text range on a non-native text control (like a contenteditable) was either
wrong or broke at some point. It assumed that creating a Position with the contenteditable node with the right
offset would make a valid Position, but it almost never did.

Instead we can use this helper method to create a valid Position.

Test: accessibility/set-selected-text-range-contenteditable.html

* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::setSelectedTextRange):

LayoutTests:

* accessibility/set-selected-text-range-contenteditable-expected.txt: Added.
* accessibility/set-selected-text-range-contenteditable.html: Added.
* platform/efl/TestExpectations:
* platform/gtk/TestExpectations:

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

LayoutTests/ChangeLog
LayoutTests/accessibility/set-selected-text-range-contenteditable-expected.txt [new file with mode: 0644]
LayoutTests/accessibility/set-selected-text-range-contenteditable.html [new file with mode: 0644]
LayoutTests/platform/efl/TestExpectations
LayoutTests/platform/gtk/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityRenderObject.cpp

index 5568d04..832ee3a 100644 (file)
@@ -1,3 +1,15 @@
+2016-03-28  Chris Fleizach  <cfleizach@apple.com>
+
+        AX: iOS: Can't navigate inside ContentEditable fields with voiceover enabled
+        https://bugs.webkit.org/show_bug.cgi?id=155942
+
+        Reviewed by Joanmarie Diggs.
+
+        * accessibility/set-selected-text-range-contenteditable-expected.txt: Added.
+        * accessibility/set-selected-text-range-contenteditable.html: Added.
+        * platform/efl/TestExpectations:
+        * platform/gtk/TestExpectations:
+
 2016-03-28  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
 
         Unreviewed EFL gardening on 29th Mar.
diff --git a/LayoutTests/accessibility/set-selected-text-range-contenteditable-expected.txt b/LayoutTests/accessibility/set-selected-text-range-contenteditable-expected.txt
new file mode 100644 (file)
index 0000000..038e142
--- /dev/null
@@ -0,0 +1,29 @@
+hello world test
+This tests that selected text ranges can be set on a contenteditable element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Initial selected range: {1, 0}
+
+Set range: {3, 0}
+PASS content.selectedTextRange became '{3, 0}'
+
+Set range: {100, 0}
+PASS content.selectedTextRange became '{16, 0}'
+
+Set range: {0, 0}
+PASS content.selectedTextRange became '{0, 0}'
+
+Set range: {1, 12}
+PASS content.selectedTextRange became '{1, 12}'
+
+Set range: {-1, 0}
+PASS content.selectedTextRange became '{0, 0}'
+
+Set range: {7, 3}
+PASS content.selectedTextRange became '{7, 3}'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/accessibility/set-selected-text-range-contenteditable.html b/LayoutTests/accessibility/set-selected-text-range-contenteditable.html
new file mode 100644 (file)
index 0000000..31ea934
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../resources/js-test-pre.js"></script>
+</head>
+<body id="body">
+
+<div contenteditable id="content" tabindex="0">hello <b>world</b> test</div>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+
+    description("This tests that selected text ranges can be set on a contenteditable element.");
+
+
+    if (window.accessibilityController) {
+        window.jsTestIsAsync = true;
+
+        document.getElementById("content").focus();
+        var sel = window.getSelection();
+        var range = document.createRange();
+        range.setStart(sel.anchorNode, 1);
+        range.setEnd(sel.anchorNode, 1);
+        sel.removeAllRanges();
+        sel.addRange(range);
+
+        var content = accessibilityController.accessibleElementById("content");
+        debug("Initial selected range: " + content.selectedTextRange);
+
+        debug("\nSet range: {3, 0}");
+        content.setSelectedTextRange(3, 0);
+        shouldBecomeEqual("content.selectedTextRange", "'{3, 0}'", function() {
+            debug("\nSet range: {100, 0}");
+            content.setSelectedTextRange(100, 0);
+            shouldBecomeEqual("content.selectedTextRange", "'{16, 0}'", function() {
+                debug("\nSet range: {0, 0}");
+                content.setSelectedTextRange(0, 0);
+                shouldBecomeEqual("content.selectedTextRange", "'{0, 0}'", function() {
+                    debug("\nSet range: {1, 12}");
+                    content.setSelectedTextRange(1, 12);
+                    shouldBecomeEqual("content.selectedTextRange", "'{1, 12}'", function() {
+                        debug("\nSet range: {-1, 0}");
+                        content.setSelectedTextRange(-1, 0);
+                        shouldBecomeEqual("content.selectedTextRange", "'{0, 0}'", function() {
+                            debug("\nSet range: {7, 3}");
+                            content.setSelectedTextRange(7, 3);
+                            shouldBecomeEqual("content.selectedTextRange", "'{7, 3}'", finishJSTest);
+                        });
+                    });
+                });
+            });
+        }); 
+    }
+
+</script>
+
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
index 713c8c3..b76dc5d 100644 (file)
@@ -2103,6 +2103,7 @@ webkit.org/b/112012 accessibility/svg-bounds.html [ Failure ]
 webkit.org/b/112014 accessibility/textarea-insertion-point-line-number.html [ Failure ]
 webkit.org/b/112018 accessibility/th-as-title-ui.html [ Failure ]
 webkit.org/b/112021 accessibility/visible-elements.html [ Failure Crash ]
+webkit.org/b/133148 accessibility/set-selected-text-range-contenteditable.html [ Skip ]
 
 # New accessibility test added in r151079 that is failing for EFL.
 webkit.org/b/117182 accessibility/text-role-with-aria-hidden-inside.html [ Failure ]
index 8bf57a6..7113f6b 100644 (file)
@@ -88,6 +88,7 @@ webkit.org/b/98348 accessibility/internal-link-anchors2.html [ Skip ]
 webkit.org/b/98348 accessibility/radio-button-group-members.html [ Skip ]
 webkit.org/b/141074 accessibility/auto-filled-value.html [ Skip ]
 webkit.org/b/133148 accessibility/content-editable-as-textarea.html [ Skip ]
+webkit.org/b/133148 accessibility/set-selected-text-range-contenteditable.html [ Skip ]
 
 # Feature disabled, see: https://bugs.webkit.org/show_bug.cgi?id=85425
 webkit.org/b/98925 fast/viewport/viewport-legacy-handheldfriendly.html [ Skip ]
index 7ef631f..b31647d 100644 (file)
@@ -1,3 +1,21 @@
+2016-03-28  Chris Fleizach  <cfleizach@apple.com>
+
+        AX: iOS: Can't navigate inside ContentEditable fields with voiceover enabled
+        https://bugs.webkit.org/show_bug.cgi?id=155942
+
+        Reviewed by Joanmarie Diggs.
+
+        The code to set the selected text range on a non-native text control (like a contenteditable) was either
+        wrong or broke at some point. It assumed that creating a Position with the contenteditable node with the right
+        offset would make a valid Position, but it almost never did.
+
+        Instead we can use this helper method to create a valid Position.
+
+        Test: accessibility/set-selected-text-range-contenteditable.html
+
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::setSelectedTextRange):
+
 2016-03-28  Alex Christensen  <achristensen@webkit.org>
 
         Fix Ninja build on Mac
index 553a44a..8a58886 100644 (file)
@@ -1499,18 +1499,17 @@ static void clearTextSelectionIntent(AXObjectCache* cache)
 
 void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
 {
+    setTextSelectionIntent(axObjectCache(), range.length ? AXTextStateChangeTypeSelectionExtend : AXTextStateChangeTypeSelectionMove);
+
     if (isNativeTextControl()) {
-        setTextSelectionIntent(axObjectCache(), range.length ? AXTextStateChangeTypeSelectionExtend : AXTextStateChangeTypeSelectionMove);
         HTMLTextFormControlElement& textControl = downcast<RenderTextControl>(*m_renderer).textFormControlElement();
         textControl.setSelectionRange(range.start, range.start + range.length);
-        clearTextSelectionIntent(axObjectCache());
-        return;
+    } else {
+        VisiblePosition start = visiblePositionForIndexUsingCharacterIterator(node(), range.start);
+        VisiblePosition end = visiblePositionForIndexUsingCharacterIterator(node(), range.start + range.length);
+        m_renderer->frame().selection().setSelection(VisibleSelection(start, end), FrameSelection::defaultSetSelectionOptions(UserTriggered));
     }
-
-    Node* node = m_renderer->node();
-    VisibleSelection newSelection(Position(node, range.start, Position::PositionIsOffsetInAnchor), Position(node, range.start + range.length, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
-    setTextSelectionIntent(axObjectCache(), range.length ? AXTextStateChangeTypeSelectionExtend : AXTextStateChangeTypeSelectionMove);
-    m_renderer->frame().selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions());
+    
     clearTextSelectionIntent(axObjectCache());
 }
 
@@ -2848,7 +2847,6 @@ bool AccessibilityRenderObject::canSetExpandedAttribute() const
 
 bool AccessibilityRenderObject::canSetValueAttribute() const
 {
-
     // In the event of a (Boolean)@readonly and (True/False/Undefined)@aria-readonly
     // value mismatch, the host language native attribute value wins.    
     if (isNativeTextControl())