| Index: chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
|
| diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
|
| index b19fb53548fa3932d691b4df9002be96e59215cc..e3c8e7f454e4cd8ec81ebc51eb829339ac6f8ea5 100644
|
| --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
|
| +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
|
| @@ -133,6 +133,21 @@ cursors.Cursor.prototype = {
|
| return lNode === rNode && lNode != undefined;
|
| },
|
|
|
| + /**
|
| + * Compares this cursor with |rhs|.
|
| + * @param {cursors.Cursor} rhs
|
| + * @return Dir.BACKWARD if |rhs| comes before this cursor in
|
| + * document order. Forward otherwise.
|
| + */
|
| + compare: function(rhs) {
|
| + if (!this.node || !rhs.node)
|
| + return Dir.FORWARD;
|
| +
|
| + if (rhs.node == this.node)
|
| + return rhs.index < this.index ? Dir.BACKWARD : Dir.FORWARD;
|
| + return AutomationUtil.getDirection(this.node, rhs.node);
|
| + },
|
| +
|
| /**
|
| * Returns the node. If the node is invalid since the last time it
|
| * was accessed, moves the cursor to the nearest valid ancestor first.
|
| @@ -364,7 +379,10 @@ cursors.Cursor.prototype = {
|
| }
|
| break;
|
| case Unit.LINE:
|
| - newIndex = 0;
|
| + var deepEquivalent = this.deepEquivalent;
|
| + newNode = deepEquivalent.node || newNode;
|
| + newIndex = deepEquivalent.index || 0;
|
| +
|
| switch (movement) {
|
| case Movement.BOUND:
|
| newNode = AutomationUtil.findNodeUntil(newNode, dir,
|
| @@ -387,6 +405,44 @@ cursors.Cursor.prototype = {
|
| return new cursors.Cursor(newNode, newIndex);
|
| },
|
|
|
| + /**
|
| + * Returns the deepest equivalent cursor.
|
| + * @return {cursors.Cursor}
|
| + */
|
| + get deepEquivalent() {
|
| + var newNode = this.node;
|
| + var newIndex = this.index_;
|
| + while (newNode.firstChild) {
|
| + if (newNode.role == RoleType.STATIC_TEXT) {
|
| + // Text offset.
|
| + // Re-interpret the index as an offset into an inlineTextBox.
|
| + var target = newNode.firstChild;
|
| + var length = 0;
|
| + while (target && length < newIndex) {
|
| + if (length <= newIndex && newIndex < (length + target.name.length))
|
| + break;
|
| + length += target.name.length;
|
| + target = target.nextSibling;
|
| + }
|
| + if (target) {
|
| + newNode = target;
|
| + newIndex = newIndex - length;
|
| + }
|
| + break;
|
| + } else if (newNode.role != RoleType.INLINE_TEXT_BOX &&
|
| + newNode.children[newIndex]) {
|
| + // Valid node offset.
|
| + newNode = newNode.children[newIndex];
|
| + newIndex = 0;
|
| + } else {
|
| + // Invalid offset.
|
| + break;
|
| + }
|
| + }
|
| +
|
| + return new cursors.Cursor(newNode, newIndex);
|
| + },
|
| +
|
| /**
|
| * Returns whether this cursor points to a valid position.
|
| * @return {boolean}
|
|
|