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.
4
5/**
6 * @fileoverview Walkers to traverse a table.
7 */
8
9
10goog.provide('cvox.TableShifter');
11
12goog.require('cvox.AbstractShifter');
13goog.require('cvox.ColumnWalker');
14goog.require('cvox.CursorSelection');
15goog.require('cvox.DomPredicates');
16goog.require('cvox.DomUtil');
17goog.require('cvox.NavBraille');
18goog.require('cvox.RowWalker');
19
20
21/**
22 * @constructor
23 * @extends {cvox.AbstractShifter}
24 */
25cvox.TableShifter = function() {
26  this.rowWalker_ = new cvox.RowWalker();
27  this.columnWalker_ = new cvox.ColumnWalker();
28  this.currentWalker_ = this.rowWalker_;
29  this.bumpedEdge_ = false;
30  this.begin_ = true;
31  goog.base(this);
32};
33goog.inherits(cvox.TableShifter, cvox.AbstractShifter);
34
35
36/**
37 * @override
38 */
39cvox.TableShifter.prototype.next = function(sel) {
40  var nextSel = this.currentWalker_.next(sel);
41  if (!nextSel) {
42    // Bumped edge.
43    this.bumpedEdge_ = true;
44    return sel;
45  }
46  return nextSel;
47};
48
49
50/**
51 * @override
52 */
53cvox.TableShifter.prototype.sync = function(sel) {
54  if (sel.start.node.tagName == 'TABLE') {
55    return sel.isReversed() ? this.currentWalker_.goToLastCell(sel) :
56        this.currentWalker_.goToFirstCell(sel);
57  }
58  return this.currentWalker_.sync(sel);
59};
60
61
62/**
63 * @override
64 */
65cvox.TableShifter.prototype.getName = function() {
66  return cvox.ChromeVox.msgs.getMsg('table_shifter');
67};
68
69
70/**
71 * @override
72 * @suppress {checkTypes} actual parameter 2 of
73 * cvox.Msgs.prototype.getMsg does not match formal parameter
74 * found   : Array.<number>
75 * required: (Array.<string>|null|undefined)
76 */
77cvox.TableShifter.prototype.getDescription = function(prevSel, sel) {
78  var descs = this.currentWalker_.getDescription(prevSel, sel);
79  if (descs.length > 0) {
80    if (this.bumpedEdge_) {
81      descs[0].pushEarcon(cvox.AbstractEarcons.WRAP_EDGE);
82      this.bumpedEdge_ = false;
83    }
84    if (this.begin_) {
85      var len = descs.length;
86      var summaryText = this.currentWalker_.tt.summaryText();
87      var locationInfo = this.currentWalker_.getLocationInfo(sel);
88      if (locationInfo != null) {
89        descs.push(new cvox.NavDescription({
90          context: cvox.ChromeVox.msgs.getMsg('table_location', locationInfo),
91          text: '',
92          annotation: summaryText ? summaryText + ' ' : ''
93        }));
94      }
95      if (this.currentWalker_.tt.isSpanned()) {
96        descs.push(new cvox.NavDescription({
97          text: '',
98          annotation: cvox.ChromeVox.msgs.getMsg('spanned')
99        }));
100      }
101      this.begin_ = false;
102    }
103  }
104  return descs;
105};
106
107
108/**
109 * @override
110 */
111cvox.TableShifter.prototype.getBraille = function(prevSel, sel) {
112  return this.currentWalker_.getBraille(prevSel, sel);
113};
114
115
116/**
117 * @override
118 */
119cvox.TableShifter.prototype.getGranularityMsg = function() {
120  return this.currentWalker_.getGranularityMsg();
121};
122
123
124/**
125 * @override
126 */
127cvox.TableShifter.prototype.makeLessGranular = function() {
128  goog.base(this, 'makeLessGranular');
129  this.currentWalker_ = this.rowWalker_;
130};
131
132
133/**
134 * @override
135 */
136cvox.TableShifter.prototype.makeMoreGranular = function() {
137  goog.base(this, 'makeMoreGranular');
138  this.currentWalker_ = this.columnWalker_;
139};
140
141
142/**
143 * @override
144 */
145cvox.TableShifter.create = function(sel) {
146  var ancestors = cvox.DomUtil.getAncestors(sel.start.node);
147  if (cvox.DomPredicates.tablePredicate(ancestors) &&
148      !cvox.DomPredicates.captionPredicate(ancestors)) {
149    return new cvox.TableShifter();
150  }
151  return null;
152};
153