Commit cfa41a00 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Complete jump commands in Docs

- treat the Docs content editable as a root (note that the role=textbox has a parent that is also richly editable; the only way to distinguish is based on focus. Could have used role as well, but focused state seems more relevant). This means that jumping to the next link while ChromeVox range is inside of a content editable wraps inside the content editable. Also, control duplicate/overlapping output by suppressing the usual output in navigation when the node is richly editable.
- fix an issue where we were clearing text edit handler state on focus. We actually set focus after every jump command, so this resulted in us speaking "deleted" after every jump command.
- handle another state transition in AutomationRichEditableText. This one is non-overlapping selections from prev to cur. These occur as a result of jump commands among other possibilities.
TEST=jump around in a complex document.

Bug: 
Change-Id: I1f5b555e143a2998576b746671761eeb0705ede1
Reviewed-on: https://chromium-review.googlesource.com/574787Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487187}
parent 5297f870
...@@ -296,7 +296,7 @@ AutomationPredicate.root = function(node) { ...@@ -296,7 +296,7 @@ AutomationPredicate.root = function(node) {
case Role.ROOT_WEB_AREA: case Role.ROOT_WEB_AREA:
return !node.parent || node.parent.root.role == Role.DESKTOP; return !node.parent || node.parent.root.role == Role.DESKTOP;
default: default:
return false; return node.state.richlyEditable && node.state.focused;
} }
}; };
......
...@@ -487,6 +487,10 @@ Background.prototype = { ...@@ -487,6 +487,10 @@ Background.prototype = {
if (!lca || lca.state[StateType.EDITABLE] || if (!lca || lca.state[StateType.EDITABLE] ||
!range.start.node.state[StateType.EDITABLE]) !range.start.node.state[StateType.EDITABLE])
range.select(); range.select();
// Richly editable output gets handled by editing.js.
if (lca && lca.state.richlyEditable)
return;
} }
o.withRichSpeechAndBraille( o.withRichSpeechAndBraille(
......
...@@ -738,7 +738,13 @@ CommandHandler.onCommand = function(command) { ...@@ -738,7 +738,13 @@ CommandHandler.onCommand = function(command) {
current = cursors.Range.fromNode(node); current = cursors.Range.fromNode(node);
} else { } else {
cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP); cvox.ChromeVox.earcons.playEarcon(cvox.Earcon.WRAP);
var root = AutomationUtil.getTopLevelRoot(bound) || bound.root; var root = bound;
while (root && !AutomationPredicate.root(root))
root = root.parent;
if (!root)
root = bound.root;
if (dir == Dir.FORWARD) { if (dir == Dir.FORWARD) {
bound = root; bound = root;
} else { } else {
......
...@@ -295,7 +295,8 @@ DesktopAutomationHandler.prototype = { ...@@ -295,7 +295,8 @@ DesktopAutomationHandler.prototype = {
*/ */
onFocus: function(evt) { onFocus: function(evt) {
// Invalidate any previous editable text handler state. // Invalidate any previous editable text handler state.
this.textEditHandler_ = null; if (!this.createTextEditHandlerIfNeeded_(evt.target))
this.textEditHandler_ = null;
var node = evt.target; var node = evt.target;
......
...@@ -311,6 +311,14 @@ AutomationRichEditableText.prototype = { ...@@ -311,6 +311,14 @@ AutomationRichEditableText.prototype = {
return; return;
} }
// TODO(dtseng): base/extent and anchor/focus are ordered
// (i.e. anchor/base always comes before focus/extent) in Blink
// accessibility. However, in other parts of Blink, they are
// unordered (i.e. anchor is where the selection starts and focus
// where it ends). The latter is correct. Change this once Blink
// ax gets fixed.
var curBase = baseLineOnStart ? focusLine : anchorLine;
if (cur.text == '') { if (cur.text == '') {
// This line has no text content. Describe the DOM selection. // This line has no text content. Describe the DOM selection.
new Output() new Output()
...@@ -318,13 +326,13 @@ AutomationRichEditableText.prototype = { ...@@ -318,13 +326,13 @@ AutomationRichEditableText.prototype = {
new Range(cur.start_, cur.end_), new Range(cur.start_, cur.end_),
new Range(prev.start_, prev.end_), Output.EventType.NAVIGATE) new Range(prev.start_, prev.end_), Output.EventType.NAVIGATE)
.go(); .go();
} else if (!cur.hasCollapsedSelection()) { } else if (
// This is a selection. !cur.hasCollapsedSelection() &&
(curBase.isSameLine(prevAnchorLine) ||
curBase.isSameLine(prevFocusLine))) {
// This is a selection that gets extended from the same anchor.
// Speech requires many more states than braille. // Speech requires many more states than braille.
// TODO(dtseng): base/extent and anchor/focus are mismatched in AX. Swap
// once this works.
var curBase = baseLineOnStart ? focusLine : anchorLine;
var curExtent = baseLineOnStart ? anchorLine : focusLine; var curExtent = baseLineOnStart ? anchorLine : focusLine;
var text = ''; var text = '';
var suffixMsg = ''; var suffixMsg = '';
...@@ -380,9 +388,12 @@ AutomationRichEditableText.prototype = { ...@@ -380,9 +388,12 @@ AutomationRichEditableText.prototype = {
cvox.ChromeVox.tts.speak(Msgs.getMsg(suffixMsg), cvox.QueueMode.QUEUE); cvox.ChromeVox.tts.speak(Msgs.getMsg(suffixMsg), cvox.QueueMode.QUEUE);
this.brailleCurrentRichLine_(); this.brailleCurrentRichLine_();
} else { } else {
// A catch-all for any other transitions.
// Describe the current line. This accounts for previous/current // Describe the current line. This accounts for previous/current
// selections and picking the line edge boundary that changed (as computed // selections and picking the line edge boundary that changed (as computed
// above). This is also the code path for describing paste. // above). This is also the code path for describing paste. It also covers
// jump commands which are non-overlapping selections from prev to cur.
this.speakCurrentRichLine_(prev); this.speakCurrentRichLine_(prev);
this.brailleCurrentRichLine_(); this.brailleCurrentRichLine_();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment