| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * TODO(stoarca): This class has become obsolete except for the shadow table. | 6 * TODO(stoarca): This class has become obsolete except for the shadow table. |
| 7 * Chop most of it away. | 7 * Chop most of it away. |
| 8 * @fileoverview A DOM traversal interface for navigating data in tables. | 8 * @fileoverview A DOM traversal interface for navigating data in tables. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 goog.provide('cvox.TraverseTable'); | 11 goog.provide('cvox.TraverseTable'); |
| 12 | 12 |
| 13 goog.require('cvox.DomPredicates'); | 13 goog.require('cvox.DomPredicates'); |
| 14 goog.require('cvox.DomUtil'); | 14 goog.require('cvox.DomUtil'); |
| 15 goog.require('cvox.SelectionUtil'); | 15 goog.require('cvox.SelectionUtil'); |
| 16 goog.require('cvox.TableUtil'); | 16 goog.require('cvox.TableUtil'); |
| 17 goog.require('cvox.TraverseUtil'); | 17 goog.require('cvox.TraverseUtil'); |
| 18 | 18 |
| 19 | 19 |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * An object that represents an active table cell inside the shadow table. | 22 * An object that represents an active table cell inside the shadow table. |
| 23 * @constructor | 23 * @constructor |
| 24 */ | 24 */ |
| 25 function ShadowTableNode() {} | 25 function ShadowTableNode() { |
| 26 /** |
| 27 * The cells that are row headers of the corresponding active table cell |
| 28 * @type {!Array} |
| 29 */ |
| 30 this.rowHeaderCells = []; |
| 31 |
| 32 /** |
| 33 * The cells that are column headers of the corresponding active table cell |
| 34 * @type {!Array} |
| 35 */ |
| 36 this.colHeaderCells = []; |
| 37 } |
| 26 | 38 |
| 27 | 39 |
| 28 /** | 40 /** |
| 29 * Whether or not the active cell is spanned by a preceding cell. | 41 * Whether or not the active cell is spanned by a preceding cell. |
| 30 * @type {boolean} | 42 * @type {boolean} |
| 31 */ | 43 */ |
| 32 ShadowTableNode.prototype.spanned; | 44 ShadowTableNode.prototype.spanned; |
| 33 | 45 |
| 34 | 46 |
| 35 /** | 47 /** |
| (...skipping 25 matching lines...) Expand all Loading... |
| 61 | 73 |
| 62 | 74 |
| 63 /** | 75 /** |
| 64 * The corresponding <TD> or <TH> node in the active table. | 76 * The corresponding <TD> or <TH> node in the active table. |
| 65 * @type {?Node} | 77 * @type {?Node} |
| 66 */ | 78 */ |
| 67 ShadowTableNode.prototype.activeCell; | 79 ShadowTableNode.prototype.activeCell; |
| 68 | 80 |
| 69 | 81 |
| 70 /** | 82 /** |
| 71 * The cells that are row headers of the corresponding active table cell | |
| 72 * @type {!Array} | |
| 73 */ | |
| 74 ShadowTableNode.prototype.rowHeaderCells = []; | |
| 75 | |
| 76 | |
| 77 /** | |
| 78 * The cells that are column headers of the corresponding active table cell | |
| 79 * @type {!Array} | |
| 80 */ | |
| 81 ShadowTableNode.prototype.colHeaderCells = []; | |
| 82 | |
| 83 | |
| 84 | |
| 85 /** | |
| 86 * Initializes the traversal with the provided table node. | 83 * Initializes the traversal with the provided table node. |
| 87 * | 84 * |
| 88 * @constructor | 85 * @constructor |
| 89 * @param {Node} tableNode The table to be traversed. | 86 * @param {Node} tableNode The table to be traversed. |
| 90 */ | 87 */ |
| 91 cvox.TraverseTable = function(tableNode) { | 88 cvox.TraverseTable = function(tableNode) { |
| 92 | 89 |
| 93 /** | 90 /** |
| 94 * The active table <TABLE> node. In this context, "active" means that this is | 91 * The active table <TABLE> node. In this context, "active" means that this is |
| 95 * the table the TraverseTable object is navigating. | 92 * the table the TraverseTable object is navigating. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 107 * The shadow table will allow us efficient navigation of tables with | 104 * The shadow table will allow us efficient navigation of tables with |
| 108 * rowspans and colspans without needing to repeatedly scan the table. For | 105 * rowspans and colspans without needing to repeatedly scan the table. For |
| 109 * example, if someone requests a cell at (1,3), predecessor cells with | 106 * example, if someone requests a cell at (1,3), predecessor cells with |
| 110 * rowspans/colspans mean the cell you eventually return could actually be | 107 * rowspans/colspans mean the cell you eventually return could actually be |
| 111 * one located at (0,2) that spans out to (1,3). | 108 * one located at (0,2) that spans out to (1,3). |
| 112 * | 109 * |
| 113 * This shadow table will contain a ShadowTableNode with the (0, 2) index at | 110 * This shadow table will contain a ShadowTableNode with the (0, 2) index at |
| 114 * the (1,3) position, eliminating the need to check for predecessor cells | 111 * the (1,3) position, eliminating the need to check for predecessor cells |
| 115 * with rowspan/colspan every time we traverse the table. | 112 * with rowspan/colspan every time we traverse the table. |
| 116 * | 113 * |
| 117 * @type {!Array.<Array.<ShadowTableNode>>} | 114 * @type {!Array<Array<ShadowTableNode>>} |
| 118 * @private | 115 * @private |
| 119 */ | 116 */ |
| 120 this.shadowTable_ = []; | 117 this.shadowTable_ = []; |
| 121 | 118 |
| 122 /** | 119 /** |
| 123 * An array of shadow table nodes that have been determined to contain header | 120 * An array of shadow table nodes that have been determined to contain header |
| 124 * cells or information about header cells. This array is collected at | 121 * cells or information about header cells. This array is collected at |
| 125 * initialization and then only recalculated if the table changes. | 122 * initialization and then only recalculated if the table changes. |
| 126 * This array is used by findHeaderCells() to determine table row headers | 123 * This array is used by findHeaderCells() to determine table row headers |
| 127 * and column headers. | 124 * and column headers. |
| 128 * @type {Array.<ShadowTableNode>} | 125 * @type {Array<ShadowTableNode>} |
| 129 * @private | 126 * @private |
| 130 */ | 127 */ |
| 131 this.candidateHeaders_ = []; | 128 this.candidateHeaders_ = []; |
| 132 | 129 |
| 133 /** | 130 /** |
| 134 * An array that associates cell IDs with their corresponding shadow nodes. | 131 * An array that associates cell IDs with their corresponding shadow nodes. |
| 135 * If there are two shadow nodes for the same cell (i.e. when a cell spans | 132 * If there are two shadow nodes for the same cell (i.e. when a cell spans |
| 136 * other cells) then the first one will be associated with the ID. This means | 133 * other cells) then the first one will be associated with the ID. This means |
| 137 * that shadow nodes that have spanned set to true will not be included in | 134 * that shadow nodes that have spanned set to true will not be included in |
| 138 * this array. | 135 * this array. |
| 139 * @type {Array.<ShadowTableNode>} | 136 * @type {Array<ShadowTableNode>} |
| 140 * @private | 137 * @private |
| 141 */ | 138 */ |
| 142 this.idToShadowNode_ = []; | 139 this.idToShadowNode_ = []; |
| 143 | 140 |
| 144 this.initialize(tableNode); | 141 this.initialize(tableNode); |
| 145 }; | 142 }; |
| 146 | 143 |
| 147 | 144 |
| 148 /** | 145 /** |
| 149 * The cell cursor, represented by an array that stores the row and | 146 * The cell cursor, represented by an array that stores the row and |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 this.attachCursorToNearestCell_(); | 255 this.attachCursorToNearestCell_(); |
| 259 } | 256 } |
| 260 }, this), false); | 257 }, this), false); |
| 261 }; | 258 }; |
| 262 | 259 |
| 263 | 260 |
| 264 /** | 261 /** |
| 265 * Finds the cell cursor containing the specified node within the table. | 262 * Finds the cell cursor containing the specified node within the table. |
| 266 * Returns null if there is no close cell. | 263 * Returns null if there is no close cell. |
| 267 * @param {!Node} node The node for which to find the cursor. | 264 * @param {!Node} node The node for which to find the cursor. |
| 268 * @return {Array.<number>} The table index for the node. | 265 * @return {Array<number>} The table index for the node. |
| 269 */ | 266 */ |
| 270 cvox.TraverseTable.prototype.findNearestCursor = function(node) { | 267 cvox.TraverseTable.prototype.findNearestCursor = function(node) { |
| 271 // TODO (stoarca): The current structure for representing the | 268 // TODO (stoarca): The current structure for representing the |
| 272 // shadow table is not optimal for this query, but it's not urgent | 269 // shadow table is not optimal for this query, but it's not urgent |
| 273 // since this only gets executed at most once per user action. | 270 // since this only gets executed at most once per user action. |
| 274 | 271 |
| 275 // In case node is in a table but above any individual cell, we go down as | 272 // In case node is in a table but above any individual cell, we go down as |
| 276 // deep as we can, being careful to avoid going into nested tables. | 273 // deep as we can, being careful to avoid going into nested tables. |
| 277 var n = node; | 274 var n = node; |
| 278 | 275 |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 | 846 |
| 850 var shadowEntry = | 847 var shadowEntry = |
| 851 this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]]; | 848 this.shadowTable_[this.currentCellCursor[0]][this.currentCellCursor[1]]; |
| 852 | 849 |
| 853 return shadowEntry && shadowEntry.activeCell; | 850 return shadowEntry && shadowEntry.activeCell; |
| 854 }; | 851 }; |
| 855 | 852 |
| 856 | 853 |
| 857 /** | 854 /** |
| 858 * Gets the cell at the specified location. | 855 * Gets the cell at the specified location. |
| 859 * @param {Array.<number>} index The index <i, j> of the required cell. | 856 * @param {Array<number>} index The index <i, j> of the required cell. |
| 860 * @return {?Node} The cell <TD> or <TH> or role='gridcell' node at the | 857 * @return {?Node} The cell <TD> or <TH> or role='gridcell' node at the |
| 861 * specified location. Null if that cell does not exist. | 858 * specified location. Null if that cell does not exist. |
| 862 */ | 859 */ |
| 863 cvox.TraverseTable.prototype.getCellAt = function(index) { | 860 cvox.TraverseTable.prototype.getCellAt = function(index) { |
| 864 if (((index[0] < this.rowCount) && (index[0] >= 0)) && | 861 if (((index[0] < this.rowCount) && (index[0] >= 0)) && |
| 865 ((index[1] < this.colCount) && (index[1] >= 0))) { | 862 ((index[1] < this.colCount) && (index[1] >= 0))) { |
| 866 var shadowEntry = this.shadowTable_[index[0]][index[1]]; | 863 var shadowEntry = this.shadowTable_[index[0]][index[1]]; |
| 867 if (shadowEntry != null) { | 864 if (shadowEntry != null) { |
| 868 return shadowEntry.activeCell; | 865 return shadowEntry.activeCell; |
| 869 } | 866 } |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 } else { | 1210 } else { |
| 1214 this.currentCellCursor = [this.currentCellCursor[0], index]; | 1211 this.currentCellCursor = [this.currentCellCursor[0], index]; |
| 1215 } | 1212 } |
| 1216 return true; | 1213 return true; |
| 1217 }; | 1214 }; |
| 1218 | 1215 |
| 1219 | 1216 |
| 1220 /** | 1217 /** |
| 1221 * Moves to the cell at the specified index <i, j> in the table. Updates the | 1218 * Moves to the cell at the specified index <i, j> in the table. Updates the |
| 1222 * cell cursor. | 1219 * cell cursor. |
| 1223 * @param {Array.<number>} index The index <i, j> of the required cell. | 1220 * @param {Array<number>} index The index <i, j> of the required cell. |
| 1224 * @return {boolean} Either: | 1221 * @return {boolean} Either: |
| 1225 * 1) True if the index is valid and the update has been made. | 1222 * 1) True if the index is valid and the update has been made. |
| 1226 * 2) False if the index is not valid (either less than 0, greater than | 1223 * 2) False if the index is not valid (either less than 0, greater than |
| 1227 * the number of rows or columns in the table, or there is no cell | 1224 * the number of rows or columns in the table, or there is no cell |
| 1228 * at that location). | 1225 * at that location). |
| 1229 */ | 1226 */ |
| 1230 cvox.TraverseTable.prototype.goToCell = function(index) { | 1227 cvox.TraverseTable.prototype.goToCell = function(index) { |
| 1231 if (((index[0] < this.rowCount) && (index[0] >= 0)) && | 1228 if (((index[0] < this.rowCount) && (index[0] >= 0)) && |
| 1232 ((index[1] < this.colCount) && (index[1] >= 0))) { | 1229 ((index[1] < this.colCount) && (index[1] >= 0))) { |
| 1233 var cell = this.shadowTable_[index[0]][index[1]]; | 1230 var cell = this.shadowTable_[index[0]][index[1]]; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 }; | 1300 }; |
| 1304 | 1301 |
| 1305 | 1302 |
| 1306 /** | 1303 /** |
| 1307 * Resets the table cursors. | 1304 * Resets the table cursors. |
| 1308 * | 1305 * |
| 1309 */ | 1306 */ |
| 1310 cvox.TraverseTable.prototype.resetCursor = function() { | 1307 cvox.TraverseTable.prototype.resetCursor = function() { |
| 1311 this.currentCellCursor = null; | 1308 this.currentCellCursor = null; |
| 1312 }; | 1309 }; |
| OLD | NEW |