• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 DOM utility functions to aid in table navigation.
7 */
8
9goog.provide('cvox.TableUtil');
10
11goog.require('cvox.XpathUtil');
12
13
14/**
15 * Utility function to check if a particular table cell is a candidate
16 * header cell.
17 * @param {Node} cell The table cell.
18 * @return {boolean} Whether or not the table cell is acting as a header cell.
19 */
20cvox.TableUtil.checkIfHeader = function(cell) {
21  /*
22   * Headers are defined here as <TH> or <TD> elements. <TD> elements when
23   * serving as header cells must have either:
24   *  - The scope attribute defined
25   *  - Their IDs referenced in the header content attribute of another <TD> or
26   *  <TH> element.
27   * This function does not check whether this cell is referenced by another
28   * <TD>. So this function by itself will not be able to gather all possible
29   * header cells when applied across all table cells.
30   *
31   * Please Note:
32   * The HTML5 spec specifies that only header <TH> elements can be headers
33   * ( http://dev.w3.org/html5/spec/tabular-data.html#row-header ) but the
34   * HTML4 spec says that <TD> elements can act as headers if they have a
35   * scope attribute defined
36   * ( http://www.w3.org/TR/html401/struct/tables.html#h-11.2.6 ). In the
37   * interest of providing meaningful header information for all tables, here
38   * we take the position that <TD> elements can act as headers.
39   */
40  return ((cell.tagName == 'TH') ||
41      cell.hasAttribute('scope') || (cell.hasAttribute('role') &&
42          ((cell.getAttribute('role') == 'rowheader') ||
43              (cell.getAttribute('role') == 'columnheader'))));
44};
45
46
47/**
48 * Utility function to determine colgroup structure. Builds an array that
49 * associates a column number to a particular col group.
50 * @param {Array} colGroups An array of all the colgroup elements in a
51 * particular table.
52 * @return {Array} An array that maps indexes representing table columns
53 * to indexes into the colGroups array.
54 */
55cvox.TableUtil.determineColGroups = function(colGroups) {
56  var colToColGroup = [];
57
58  if (colGroups.length == 0) {
59    return colToColGroup;
60  }
61  // A colgroup has either a series of col element children or a span
62  // attribute. If it has col children, ignore the span attribute
63  for (var colGroupCtr = 0; colGroupCtr < colGroups.length;
64       colGroupCtr++) {
65
66    var currentColGroup = colGroups[colGroupCtr];
67
68    var childCols = cvox.TableUtil.getColNodes(currentColGroup);
69    if (childCols.length > 0) {
70      for (var colNodeCtr = 0; colNodeCtr < childCols.length;
71          colNodeCtr++) {
72        var colElement = childCols[colNodeCtr];
73
74        if (colElement.hasAttribute('span')) {
75          var span = parseInt(colElement.getAttribute('span'), 10);
76
77          for (var s = 0; s < span; s++) {
78            colToColGroup.push(colGroupCtr);
79          }
80        } else {
81          colToColGroup.push(colGroupCtr);
82        }
83      }
84    } else {
85      // No children of the current colgroup. Does it have a span attribute?
86      if (currentColGroup.hasAttribute('span')) {
87        var span = parseInt(currentColGroup.getAttribute('span'), 10);
88
89        for (var s = 0; s < span; s++) {
90          colToColGroup.push(colGroupCtr);
91        }
92      } else {
93        // Default span value is 1
94        colToColGroup.push(colGroupCtr);
95      }
96    }
97  }
98  return colToColGroup;
99
100};
101
102
103/**
104 * Utility function to push an element into a given array only if that element
105 * is not already contained in the array.
106 * @param {Array} givenArray The given array.
107 * @param {Node} givenElement The given element.
108 */
109cvox.TableUtil.pushIfNotContained = function(givenArray, givenElement) {
110  if (givenArray.indexOf(givenElement) == -1) {
111    givenArray.push(givenElement);
112  }
113};
114
115
116/**
117 * Returns a JavaScript array of all the non-nested rows in the given table.
118 *
119 * @param {Node} table A table node.
120 * @return {Array} An array of all the child rows of the active table.
121 */
122cvox.TableUtil.getChildRows = function(table) {
123  return cvox.XpathUtil.evalXPath('child::tbody/tr | child::thead/tr | ' +
124      'child::*[attribute::role="row"]', table);
125};
126
127
128/**
129 * Returns a JavaScript array of all the child cell <TD> or <TH> or
130 * role='gridcell' nodes of the given row.
131 *
132 * @param {Node} rowNode The specified row node.
133 * @return {Array} An array of all the child cells of the given row node.
134 */
135cvox.TableUtil.getChildCells = function(rowNode) {
136  return cvox.XpathUtil.evalXPath('child::td | child::th | ' +
137      'child::*[attribute::role="gridcell"] |' +
138      'child::*[attribute::role="rowheader"] |' +
139      'child::*[attribute::role="columnheader"]', rowNode);
140};
141
142
143/**
144 * Returns a JavaScript array containing the cell in the active table
145 * with the given ID.
146 *
147 * @param {Node} table A table node.
148 * @param {string} cellID The specified ID.
149 * @return {Array} An array containing the cell with the specified ID.
150 */
151cvox.TableUtil.getCellWithID = function(table, cellID) {
152  return cvox.XpathUtil.evalXPath('id(\'' + cellID + '\')', table);
153};
154
155
156/**
157 * Returns a Javascript array containing the colgroup elements in the
158 * active table.
159 *
160 * @param {Node} table A table node.
161 * @return {Array} An array of all the colgroup elements in the active table.
162 */
163cvox.TableUtil.getColGroups = function(table) {
164  return cvox.XpathUtil.evalXPath('child::colgroup', table);
165};
166
167
168/**
169 * Returns a Javascript array containing the child col elements of the given
170 * colgroup element.
171 *
172 * @param {Node} colGroupNode The specified <COLGROUP> element.
173 * @return {Array} An array of all of the child col elements of the given
174 * colgroup element.
175 */
176cvox.TableUtil.getColNodes = function(colGroupNode) {
177  return cvox.XpathUtil.evalXPath('child::col', colGroupNode);
178};
179
180