Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 const nsIDOMKeyEvent = Components.interfaces.nsIDOMKeyEvent;
3 /**
4 * Create grid object based on HTML table.
5 */
6 function grid(aTableIdentifier)
7 {
8 this.getRowCount = function getRowCount()
9 {
10 return this.table.rows.length - (this.table.tHead ? 1 : 0);
11 }
12 this.getColsCount = function getColsCount()
13 {
14 return this.table.rows[0].cells.length;
15 }
17 this.getRowAtIndex = function getRowAtIndex(aIndex)
18 {
19 return this.table.rows[this.table.tHead ? aIndex + 1 : aIndex];
20 }
22 this.getMaxIndex = function getMaxIndex()
23 {
24 return this.getRowCount() * this.getColsCount() - 1;
25 }
27 this.getCellAtIndex = function getCellAtIndex(aIndex)
28 {
29 var rowCount = this.getRowCount();
30 var colsCount = this.getColsCount();
32 var rowIdx = Math.floor(aIndex / colsCount);
33 var colIdx = aIndex % colsCount;
35 var row = this.getRowAtIndex(rowIdx);
36 return row.cells[colIdx];
37 }
39 this.getIndexByCell = function getIndexByCell(aCell)
40 {
41 var colIdx = aCell.cellIndex;
43 var rowIdx = aCell.parentNode.rowIndex;
44 if (this.table.tHead)
45 rowIdx -= 1;
47 var colsCount = this.getColsCount();
48 return rowIdx * colsCount + colIdx;
49 }
51 this.getCurrentCell = function getCurrentCell()
52 {
53 var rowCount = this.table.rows.length;
54 var colsCount = this.getColsCount();
55 for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
56 for (var colIdx = 0; colIdx < colsCount; colIdx++) {
57 var cell = this.table.rows[rowIdx].cells[colIdx];
58 if (cell.hasAttribute("tabindex"))
59 return cell;
60 }
61 }
62 return null;
63 }
65 this.initGrid = function initGrid()
66 {
67 this.table.addEventListener("keypress", this, false);
68 this.table.addEventListener("click", this, false);
69 }
71 this.handleEvent = function handleEvent(aEvent)
72 {
73 if (aEvent instanceof nsIDOMKeyEvent)
74 this.handleKeyEvent(aEvent);
75 else
76 this.handleClickEvent(aEvent);
77 }
79 this.handleKeyEvent = function handleKeyEvent(aEvent)
80 {
81 if (aEvent.target.localName != "td")
82 return;
84 var cell = aEvent.target;
85 switch(aEvent.keyCode) {
86 case nsIDOMKeyEvent.DOM_VK_UP:
87 var colsCount = this.getColsCount();
88 var idx = this.getIndexByCell(cell);
89 var upidx = idx - colsCount;
90 if (upidx >= 0) {
91 cell.removeAttribute("tabindex");
92 var upcell = this.getCellAtIndex(upidx);
93 upcell.setAttribute("tabindex", "0");
94 upcell.focus();
95 }
96 break;
98 case nsIDOMKeyEvent.DOM_VK_DOWN:
99 var colsCount = this.getColsCount();
100 var idx = this.getIndexByCell(cell);
101 var downidx = idx + colsCount;
102 if (downidx <= this.getMaxIndex()) {
103 cell.removeAttribute("tabindex");
104 var downcell = this.getCellAtIndex(downidx);
105 downcell.setAttribute("tabindex", "0");
106 downcell.focus();
107 }
108 break;
110 case nsIDOMKeyEvent.DOM_VK_LEFT:
111 var idx = this.getIndexByCell(cell);
112 if (idx > 0) {
113 cell.removeAttribute("tabindex");
114 var prevcell = this.getCellAtIndex(idx - 1);
115 prevcell.setAttribute("tabindex", "0");
116 prevcell.focus();
117 }
118 break;
120 case nsIDOMKeyEvent.DOM_VK_RIGHT:
121 var idx = this.getIndexByCell(cell);
122 if (idx < this.getMaxIndex()) {
123 cell.removeAttribute("tabindex");
124 var nextcell = this.getCellAtIndex(idx + 1);
125 nextcell.setAttribute("tabindex", "0");
126 nextcell.focus();
127 }
128 break;
129 }
130 }
132 this.handleClickEvent = function handleClickEvent(aEvent)
133 {
134 if (aEvent.target.localName != "td")
135 return;
137 var curCell = this.getCurrentCell();
138 var cell = aEvent.target;
140 if (cell != curCell) {
141 curCell.removeAttribute("tabindex");
142 cell.setAttribute("tabindex", "0");
143 cell.focus();
144 }
145 }
147 this.table = getNode(aTableIdentifier);
148 this.initGrid();
149 }