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.
6 * @fileoverview DOM utility functions to aid in table navigation.
9 goog
.provide('cvox.TableUtil');
11 goog
.require('cvox.XpathUtil');
15 * Utility function to check if a particular table cell is a candidate
17 * @param {Node} cell The table cell.
18 * @return {boolean} Whether or not the table cell is acting as a header cell.
20 cvox
.TableUtil
.checkIfHeader = function(cell
) {
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
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.
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.
40 return ((cell
.tagName
== 'TH') ||
41 cell
.hasAttribute('scope') || (cell
.hasAttribute('role') &&
42 ((cell
.getAttribute('role') == 'rowheader') ||
43 (cell
.getAttribute('role') == 'columnheader'))));
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
52 * @return {Array} An array that maps indexes representing table columns
53 * to indexes into the colGroups array.
55 cvox
.TableUtil
.determineColGroups = function(colGroups
) {
56 var colToColGroup
= [];
58 if (colGroups
.length
== 0) {
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
;
66 var currentColGroup
= colGroups
[colGroupCtr
];
68 var childCols
= cvox
.TableUtil
.getColNodes(currentColGroup
);
69 if (childCols
.length
> 0) {
70 for (var colNodeCtr
= 0; colNodeCtr
< childCols
.length
;
72 var colElement
= childCols
[colNodeCtr
];
74 if (colElement
.hasAttribute('span')) {
75 var span
= parseInt(colElement
.getAttribute('span'), 10);
77 for (var s
= 0; s
< span
; s
++) {
78 colToColGroup
.push(colGroupCtr
);
81 colToColGroup
.push(colGroupCtr
);
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);
89 for (var s
= 0; s
< span
; s
++) {
90 colToColGroup
.push(colGroupCtr
);
93 // Default span value is 1
94 colToColGroup
.push(colGroupCtr
);
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.
109 cvox
.TableUtil
.pushIfNotContained = function(givenArray
, givenElement
) {
110 if (givenArray
.indexOf(givenElement
) == -1) {
111 givenArray
.push(givenElement
);
117 * Returns a JavaScript array of all the non-nested rows in the given table.
119 * @param {Node} table A table node.
120 * @return {Array} An array of all the child rows of the active table.
122 cvox
.TableUtil
.getChildRows = function(table
) {
123 return cvox
.XpathUtil
.evalXPath('child::tbody/tr | child::thead/tr | ' +
124 'child::*[attribute::role="row"]', table
);
129 * Returns a JavaScript array of all the child cell <TD> or <TH> or
130 * role='gridcell' nodes of the given row.
132 * @param {Node} rowNode The specified row node.
133 * @return {Array} An array of all the child cells of the given row node.
135 cvox
.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
);
144 * Returns a JavaScript array containing the cell in the active table
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.
151 cvox
.TableUtil
.getCellWithID = function(table
, cellID
) {
152 return cvox
.XpathUtil
.evalXPath('id(\'' + cellID
+ '\')', table
);
157 * Returns a Javascript array containing the colgroup elements in the
160 * @param {Node} table A table node.
161 * @return {Array} An array of all the colgroup elements in the active table.
163 cvox
.TableUtil
.getColGroups = function(table
) {
164 return cvox
.XpathUtil
.evalXPath('child::colgroup', table
);
169 * Returns a Javascript array containing the child col elements of the given
172 * @param {Node} colGroupNode The specified <COLGROUP> element.
173 * @return {Array} An array of all of the child col elements of the given
176 cvox
.TableUtil
.getColNodes = function(colGroupNode
) {
177 return cvox
.XpathUtil
.evalXPath('child::col', colGroupNode
);