cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / walkers / abstract_selection_walker.js
blobe56b5d7a6a81f7b16b52733c52a33e92917677e7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6 * @fileoverview An abstract class for walking at the sub-element level.
7 * For example, walking at the sentence, word, or character level.
8 * This class is an adapter around TraverseContent which exposes the interface
9 * required by walkers. Subclasses must override the this.grain attribute
10 * on initialization.
14 goog.provide('cvox.AbstractSelectionWalker');
16 goog.require('cvox.AbstractWalker');
17 goog.require('cvox.BareObjectWalker');
18 goog.require('cvox.DescriptionUtil');
19 goog.require('cvox.DomUtil');
20 goog.require('cvox.Spannable');
21 goog.require('cvox.TraverseContent');
23 /**
24 * @constructor
25 * @extends {cvox.AbstractWalker}
27 cvox.AbstractSelectionWalker = function() {
28 cvox.AbstractWalker.call(this);
29 this.objWalker_ = new cvox.BareObjectWalker();
30 this.tc_ = cvox.TraverseContent.getInstance();
31 this.grain /** @protected */ = ''; // child must override
33 goog.inherits(cvox.AbstractSelectionWalker, cvox.AbstractWalker);
35 /**
36 * @override
38 cvox.AbstractSelectionWalker.prototype.next = function(sel) {
39 var r = sel.isReversed();
40 this.tc_.syncToCursorSelection(sel.clone().setReversed(false));
41 var ret = r ? this.tc_.prevElement(this.grain) :
42 this.tc_.nextElement(this.grain);
43 if (ret == null) {
44 // Unfortunately, we can't trust TraverseContent; fall back to ObjectWalker.
45 return this.objWalker_.next(sel);
47 var retSel = this.tc_.getCurrentCursorSelection().setReversed(r);
48 var objSel = this.objWalker_.next(sel);
49 objSel = objSel ? objSel.setReversed(r) : null;
51 // ObjectWalker wins when there's a discrepancy between it and
52 // TraverseContent. The only exception is with an end cursor on a text node.
53 // In all other cases, this makes sure we visit the same selections as
54 // object walker.
55 if (objSel &&
56 (retSel.end.node.constructor.name != 'Text' ||
57 objSel.end.node.constructor.name != 'Text') &&
58 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, sel.end.node) &&
59 !cvox.DomUtil.isDescendantOfNode(retSel.end.node, objSel.end.node)) {
60 return objSel;
62 return retSel;
65 /**
66 * @override
68 cvox.AbstractSelectionWalker.prototype.sync = function(sel) {
69 var r = sel.isReversed();
70 var newSel = null;
71 if (sel.start.equals(sel.end) && sel.start.node.constructor.name != 'Text') {
72 var node = sel.start.node;
74 // Find the deepest visible node; written specifically here because we want
75 // to move across siblings if necessary and take the deepest node which can
76 // be BODY.
77 while (node &&
78 cvox.DomUtil.directedFirstChild(node, r) &&
79 !cvox.TraverseUtil.treatAsLeafNode(node)) {
80 var child = cvox.DomUtil.directedFirstChild(node, r);
82 // Find the first visible child.
83 while (child) {
84 if (cvox.DomUtil.isVisible(child,
85 {checkAncestors: false, checkDescendants: false})) {
86 node = child;
87 break;
88 } else {
89 child = cvox.DomUtil.directedNextSibling(child, r);
93 // node has no visible children; it's therefore the deepest visible node.
94 if (!child) {
95 break;
98 newSel = cvox.CursorSelection.fromNode(node);
99 } else {
100 newSel = sel.clone();
101 if (r) {
102 newSel.start = newSel.end;
103 } else {
104 newSel.end = newSel.start;
108 // This.next places us at the correct initial position (except below).
109 newSel = this.next(newSel.setReversed(false));
111 // ObjectWalker wins when there's a discrepancy between it and
112 // TraverseContent. The only exception is with an end cursor on a text node.
113 // In all other cases, this makes sure we visit the same selections as
114 // object walker.
115 var objSel = this.objWalker_.sync(sel);
116 objSel = objSel ? objSel.setReversed(r) : null;
118 if (!newSel) {
119 return objSel;
122 newSel.setReversed(r);
124 if (objSel &&
125 (newSel.end.node.constructor.name != 'Text' ||
126 objSel.end.node.constructor.name != 'Text') &&
127 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, sel.end.node) &&
128 !cvox.DomUtil.isDescendantOfNode(newSel.end.node, objSel.end.node)) {
129 return objSel;
131 return newSel;
135 * @override
137 cvox.AbstractSelectionWalker.prototype.getDescription = function(prevSel, sel) {
138 var description = cvox.DescriptionUtil.getDescriptionFromAncestors(
139 cvox.DomUtil.getUniqueAncestors(prevSel.end.node, sel.start.node),
140 true,
141 cvox.ChromeVox.verbosity);
142 description.text = sel.getText() || description.text;
143 return [description];
147 * @override
149 cvox.AbstractSelectionWalker.prototype.getBraille = function(prevSel, sel) {
150 var node = sel.absStart().node;
151 var text = cvox.TraverseUtil.getNodeText(node);
152 var spannable = new cvox.Spannable(text);
153 spannable.setSpan(node, 0, text.length);
154 return new cvox.NavBraille({
155 text: spannable,
156 startIndex: sel.absStart().index,
157 endIndex: sel.absEnd().index