Add new certificateProvider extension API.
[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.
11  */
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}
26  */
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
37  */
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);
46   }
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;
61   }
62   return retSel;
65 /**
66  * @override
67  */
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);
90         }
91       }
93       // node has no visible children; it's therefore the deepest visible node.
94       if (!child) {
95         break;
96       }
97     }
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;
105     }
106   }
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;
120   }
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;
130   }
131   return newSel;
135  * @override
136  */
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
148  */
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
158   });