Commit 5fcbbaa5 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Enhance ChromeVox selection

- backward selections were previously not implemented/supported. Add that feature in this change.
- suppress hints during selection.

chromevox_tests --gtest_filter=BackgroundTest.Selection

Test: manually select forwards and backwards in all possible granularities.
Bug: 854872
Change-Id: Ic26a9e2d1426e8fcea31323c33c42c3476b1bc4c
Reviewed-on: https://chromium-review.googlesource.com/1115913Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570865}
parent add11c4c
......@@ -230,16 +230,8 @@ Background.prototype = {
var msg;
if (this.pageSel_ && this.pageSel_.isValid() && range.isValid()) {
// Compute the direction of the endpoints of each range.
// Casts are ok because isValid checks node start and end nodes are
// non-null; Closure just doesn't eval enough to see it.
var startDir = AutomationUtil.getDirection(
this.pageSel_.start.node,
/** @type {!AutomationNode} */ (range.start.node));
var endDir = AutomationUtil.getDirection(
this.pageSel_.end.node,
/** @type {!AutomationNode} */ (range.end.node));
// Suppress hints.
o.withoutHints();
// Selection across roots isn't supported.
var pageRootStart = this.pageSel_.start.node.root;
......@@ -248,21 +240,32 @@ Background.prototype = {
var curRootEnd = range.end.node.root;
// Disallow crossing over the start of the page selection and roots.
if (startDir == Dir.BACKWARD || pageRootStart != pageRootEnd ||
pageRootStart != curRootStart || pageRootEnd != curRootEnd) {
if (pageRootStart != pageRootEnd || pageRootStart != curRootStart ||
pageRootEnd != curRootEnd) {
o.format('@end_selection');
this.pageSel_ = null;
} else {
// Expand or shrink requires different feedback.
if (endDir == Dir.FORWARD &&
(this.pageSel_.end.node != range.end.node ||
this.pageSel_.end.index <= range.end.index)) {
// Page sel is the only place in ChromeVox where we used directed
// selections. It is important to keep track of the directedness in
// places, but when comparing to other ranges, take the undirected
// range.
var dir = this.pageSel_.normalize().compare(range);
if (dir) {
// Directed expansion.
msg = '@selected';
} else {
// Directed shrink.
msg = '@unselected';
selectedRange = prevRange;
}
this.pageSel_ = new cursors.Range(this.pageSel_.start, range.end);
var wasBackwardSel =
this.pageSel_.start.compare(this.pageSel_.end) == Dir.BACKWARD ||
dir == Dir.BACKWARD;
this.pageSel_ = new cursors.Range(
this.pageSel_.start, wasBackwardSel ? range.start : range.end);
if (this.pageSel_)
this.pageSel_.select();
}
......
......@@ -779,8 +779,13 @@ cursors.Range.prototype = {
* Select the text contained within this range.
*/
select: function() {
var startNode = this.start.selectionNode_;
var endNode = this.end.selectionNode_;
var start = this.start_, end = this.end_;
if (this.start.compare(this.end) == Dir.BACKWARD) {
start = this.end;
end = this.start;
}
var startNode = start.selectionNode_;
var endNode = end.selectionNode_;
if (!startNode || !endNode)
return;
......@@ -790,10 +795,10 @@ cursors.Range.prototype = {
startNode.root == endNode.root) {
// We want to adjust to select the entire node for node offsets;
// otherwise, use the plain character offset.
var startIndex = this.start.selectionIndex_;
var endIndex = this.end.index_ == cursors.NODE_INDEX ?
this.end.selectionIndex_ + 1 :
this.end.selectionIndex_;
var startIndex = start.selectionIndex_;
var endIndex = end.index_ == cursors.NODE_INDEX ?
end.selectionIndex_ + 1 :
end.selectionIndex_;
// Richly editables should always set a caret, but not select. This makes
// it possible to navigate through content editables using ChromeVox keys
......@@ -827,6 +832,33 @@ cursors.Range.prototype = {
*/
isValid: function() {
return this.start.isValid() && this.end.isValid();
},
/**
* Compares this range with |rhs|.
* @param {cursors.Range} rhs
* @return {Dir|undefined} Dir.BACKWARD if |rhs| comes before this range in
* document order. Dir.FORWARD if |rhs| comes after this range. Undefined
* otherwise.
*/
compare: function(rhs) {
var startDir = this.start.compare(rhs.start);
var endDir = this.end.compare(rhs.end);
if (startDir != endDir)
return undefined;
return startDir;
},
/**
* Returns an undirected version of this range.
* @return {!cursors.Range}
*/
normalize: function() {
if (this.start.compare(this.end) == Dir.BACKWARD) {
return new cursors.Range(this.end, this.start);
}
return this;
}
};
......
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