@everymatrix/stage-mm-verification-report 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/chunk-A3NTIEMP.js +1 -0
  2. package/chunk-CAY35YP7.js +7 -0
  3. package/chunk-H3QHLLCN.js +1 -0
  4. package/chunk-KE4BCZO4.js +851 -0
  5. package/chunk-OHPEWN32.js +1198 -0
  6. package/chunk-WSQOM5HU.js +1 -0
  7. package/component-lib.js +1 -0
  8. package/index.html +12 -0
  9. package/main.js +3264 -0
  10. package/modules/angular/LICENSE.md +21 -0
  11. package/modules/angular/README.md +67 -0
  12. package/modules/angular/angular-csp.css +25 -0
  13. package/modules/angular/angular.js +36600 -0
  14. package/modules/angular/angular.min.js +352 -0
  15. package/modules/angular/angular.min.js.gzip +0 -0
  16. package/modules/angular/angular.min.js.map +8 -0
  17. package/modules/angular/bower.json +9 -0
  18. package/modules/angular/index.js +2 -0
  19. package/modules/angular/package.json +25 -0
  20. package/modules/angular-ui-grid/CHANGELOG.md +1973 -0
  21. package/modules/angular-ui-grid/README.md +59 -0
  22. package/modules/angular-ui-grid/css/ui-grid.cellnav.css +25 -0
  23. package/modules/angular-ui-grid/css/ui-grid.cellnav.min.css +1 -0
  24. package/modules/angular-ui-grid/css/ui-grid.core.css +866 -0
  25. package/modules/angular-ui-grid/css/ui-grid.core.min.css +5 -0
  26. package/modules/angular-ui-grid/css/ui-grid.edit.css +23 -0
  27. package/modules/angular-ui-grid/css/ui-grid.edit.min.css +1 -0
  28. package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.css +6 -0
  29. package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.min.css +1 -0
  30. package/modules/angular-ui-grid/css/ui-grid.expandable.css +16 -0
  31. package/modules/angular-ui-grid/css/ui-grid.expandable.min.css +1 -0
  32. package/modules/angular-ui-grid/css/ui-grid.exporter.css +0 -0
  33. package/modules/angular-ui-grid/css/ui-grid.exporter.min.css +0 -0
  34. package/modules/angular-ui-grid/css/ui-grid.grouping.css +3 -0
  35. package/modules/angular-ui-grid/css/ui-grid.grouping.min.css +1 -0
  36. package/modules/angular-ui-grid/css/ui-grid.importer.css +0 -0
  37. package/modules/angular-ui-grid/css/ui-grid.importer.min.css +0 -0
  38. package/modules/angular-ui-grid/css/ui-grid.move-columns.css +9 -0
  39. package/modules/angular-ui-grid/css/ui-grid.move-columns.min.css +1 -0
  40. package/modules/angular-ui-grid/css/ui-grid.pagination.css +299 -0
  41. package/modules/angular-ui-grid/css/ui-grid.pagination.min.css +1 -0
  42. package/modules/angular-ui-grid/css/ui-grid.pinning.css +67 -0
  43. package/modules/angular-ui-grid/css/ui-grid.pinning.min.css +1 -0
  44. package/modules/angular-ui-grid/css/ui-grid.resize-columns.css +38 -0
  45. package/modules/angular-ui-grid/css/ui-grid.resize-columns.min.css +1 -0
  46. package/modules/angular-ui-grid/css/ui-grid.row-edit.css +9 -0
  47. package/modules/angular-ui-grid/css/ui-grid.row-edit.min.css +1 -0
  48. package/modules/angular-ui-grid/css/ui-grid.selection.css +25 -0
  49. package/modules/angular-ui-grid/css/ui-grid.selection.min.css +1 -0
  50. package/modules/angular-ui-grid/css/ui-grid.tree-base.css +4 -0
  51. package/modules/angular-ui-grid/css/ui-grid.tree-base.min.css +1 -0
  52. package/modules/angular-ui-grid/css/ui-grid.tree-view.css +6 -0
  53. package/modules/angular-ui-grid/css/ui-grid.tree-view.min.css +1 -0
  54. package/modules/angular-ui-grid/css/ui-grid.validate.css +3 -0
  55. package/modules/angular-ui-grid/css/ui-grid.validate.min.css +1 -0
  56. package/modules/angular-ui-grid/fonts/ui-grid.eot +0 -0
  57. package/modules/angular-ui-grid/fonts/ui-grid.svg +56 -0
  58. package/modules/angular-ui-grid/fonts/ui-grid.ttf +0 -0
  59. package/modules/angular-ui-grid/fonts/ui-grid.woff +0 -0
  60. package/modules/angular-ui-grid/less/animation.less +85 -0
  61. package/modules/angular-ui-grid/less/body.less +84 -0
  62. package/modules/angular-ui-grid/less/cell.less +46 -0
  63. package/modules/angular-ui-grid/less/cellnav.less +29 -0
  64. package/modules/angular-ui-grid/less/core.less +11 -0
  65. package/modules/angular-ui-grid/less/edit.less +27 -0
  66. package/modules/angular-ui-grid/less/elements.less +156 -0
  67. package/modules/angular-ui-grid/less/emptyBaseLayer.less +8 -0
  68. package/modules/angular-ui-grid/less/expandable.less +29 -0
  69. package/modules/angular-ui-grid/less/exporter.less +4 -0
  70. package/modules/angular-ui-grid/less/footer.less +76 -0
  71. package/modules/angular-ui-grid/less/grid.less +86 -0
  72. package/modules/angular-ui-grid/less/grouping.less +5 -0
  73. package/modules/angular-ui-grid/less/header.less +250 -0
  74. package/modules/angular-ui-grid/less/icons.less +151 -0
  75. package/modules/angular-ui-grid/less/importer.less +4 -0
  76. package/modules/angular-ui-grid/less/main.less +2 -0
  77. package/modules/angular-ui-grid/less/menu.less +91 -0
  78. package/modules/angular-ui-grid/less/moveColumns.less +12 -0
  79. package/modules/angular-ui-grid/less/pagination.less +297 -0
  80. package/modules/angular-ui-grid/less/pinning.less +86 -0
  81. package/modules/angular-ui-grid/less/resizeColumns.less +53 -0
  82. package/modules/angular-ui-grid/less/rowEdit.less +19 -0
  83. package/modules/angular-ui-grid/less/rtl.less +67 -0
  84. package/modules/angular-ui-grid/less/selection.less +29 -0
  85. package/modules/angular-ui-grid/less/sorting.less +16 -0
  86. package/modules/angular-ui-grid/less/treeBase.less +6 -0
  87. package/modules/angular-ui-grid/less/treeView.less +8 -0
  88. package/modules/angular-ui-grid/less/validate.less +5 -0
  89. package/modules/angular-ui-grid/less/variables.less +90 -0
  90. package/modules/angular-ui-grid/package.json +144 -0
  91. package/modules/angular-ui-grid/ui-grid.auto-resize.js +69 -0
  92. package/modules/angular-ui-grid/ui-grid.auto-resize.min.js +6 -0
  93. package/modules/angular-ui-grid/ui-grid.cellnav.js +1181 -0
  94. package/modules/angular-ui-grid/ui-grid.cellnav.min.js +6 -0
  95. package/modules/angular-ui-grid/ui-grid.core.js +12737 -0
  96. package/modules/angular-ui-grid/ui-grid.core.min.js +6 -0
  97. package/modules/angular-ui-grid/ui-grid.css +3208 -0
  98. package/modules/angular-ui-grid/ui-grid.edit.js +1325 -0
  99. package/modules/angular-ui-grid/ui-grid.edit.min.js +6 -0
  100. package/modules/angular-ui-grid/ui-grid.empty-base-layer.js +178 -0
  101. package/modules/angular-ui-grid/ui-grid.empty-base-layer.min.js +6 -0
  102. package/modules/angular-ui-grid/ui-grid.expandable.js +651 -0
  103. package/modules/angular-ui-grid/ui-grid.expandable.min.js +6 -0
  104. package/modules/angular-ui-grid/ui-grid.exporter.js +1777 -0
  105. package/modules/angular-ui-grid/ui-grid.exporter.min.js +6 -0
  106. package/modules/angular-ui-grid/ui-grid.grouping.js +1291 -0
  107. package/modules/angular-ui-grid/ui-grid.grouping.min.js +6 -0
  108. package/modules/angular-ui-grid/ui-grid.importer.js +791 -0
  109. package/modules/angular-ui-grid/ui-grid.importer.min.js +6 -0
  110. package/modules/angular-ui-grid/ui-grid.infinite-scroll.js +552 -0
  111. package/modules/angular-ui-grid/ui-grid.infinite-scroll.min.js +6 -0
  112. package/modules/angular-ui-grid/ui-grid.js +30867 -0
  113. package/modules/angular-ui-grid/ui-grid.language.all.js +3214 -0
  114. package/modules/angular-ui-grid/ui-grid.language.all.min.js +6 -0
  115. package/modules/angular-ui-grid/ui-grid.language.ar.js +118 -0
  116. package/modules/angular-ui-grid/ui-grid.language.ar.min.js +6 -0
  117. package/modules/angular-ui-grid/ui-grid.language.bg.js +115 -0
  118. package/modules/angular-ui-grid/ui-grid.language.bg.min.js +6 -0
  119. package/modules/angular-ui-grid/ui-grid.language.cs.js +96 -0
  120. package/modules/angular-ui-grid/ui-grid.language.cs.min.js +6 -0
  121. package/modules/angular-ui-grid/ui-grid.language.da.js +90 -0
  122. package/modules/angular-ui-grid/ui-grid.language.da.min.js +6 -0
  123. package/modules/angular-ui-grid/ui-grid.language.de.js +133 -0
  124. package/modules/angular-ui-grid/ui-grid.language.de.min.js +6 -0
  125. package/modules/angular-ui-grid/ui-grid.language.es-ct.js +133 -0
  126. package/modules/angular-ui-grid/ui-grid.language.es-ct.min.js +6 -0
  127. package/modules/angular-ui-grid/ui-grid.language.es.js +106 -0
  128. package/modules/angular-ui-grid/ui-grid.language.es.min.js +6 -0
  129. package/modules/angular-ui-grid/ui-grid.language.fa.js +93 -0
  130. package/modules/angular-ui-grid/ui-grid.language.fa.min.js +6 -0
  131. package/modules/angular-ui-grid/ui-grid.language.fi.js +76 -0
  132. package/modules/angular-ui-grid/ui-grid.language.fi.min.js +6 -0
  133. package/modules/angular-ui-grid/ui-grid.language.fr.js +128 -0
  134. package/modules/angular-ui-grid/ui-grid.language.fr.min.js +6 -0
  135. package/modules/angular-ui-grid/ui-grid.language.he.js +71 -0
  136. package/modules/angular-ui-grid/ui-grid.language.he.min.js +6 -0
  137. package/modules/angular-ui-grid/ui-grid.language.hy.js +76 -0
  138. package/modules/angular-ui-grid/ui-grid.language.hy.min.js +6 -0
  139. package/modules/angular-ui-grid/ui-grid.language.is.js +118 -0
  140. package/modules/angular-ui-grid/ui-grid.language.is.min.js +6 -0
  141. package/modules/angular-ui-grid/ui-grid.language.it.js +112 -0
  142. package/modules/angular-ui-grid/ui-grid.language.it.min.js +6 -0
  143. package/modules/angular-ui-grid/ui-grid.language.ja.js +118 -0
  144. package/modules/angular-ui-grid/ui-grid.language.ja.min.js +6 -0
  145. package/modules/angular-ui-grid/ui-grid.language.ko.js +77 -0
  146. package/modules/angular-ui-grid/ui-grid.language.ko.min.js +6 -0
  147. package/modules/angular-ui-grid/ui-grid.language.nl.js +91 -0
  148. package/modules/angular-ui-grid/ui-grid.language.nl.min.js +6 -0
  149. package/modules/angular-ui-grid/ui-grid.language.no.js +115 -0
  150. package/modules/angular-ui-grid/ui-grid.language.no.min.js +6 -0
  151. package/modules/angular-ui-grid/ui-grid.language.pl.js +126 -0
  152. package/modules/angular-ui-grid/ui-grid.language.pl.min.js +6 -0
  153. package/modules/angular-ui-grid/ui-grid.language.pt-br.js +133 -0
  154. package/modules/angular-ui-grid/ui-grid.language.pt-br.min.js +6 -0
  155. package/modules/angular-ui-grid/ui-grid.language.pt.js +133 -0
  156. package/modules/angular-ui-grid/ui-grid.language.pt.min.js +6 -0
  157. package/modules/angular-ui-grid/ui-grid.language.ro.js +112 -0
  158. package/modules/angular-ui-grid/ui-grid.language.ro.min.js +6 -0
  159. package/modules/angular-ui-grid/ui-grid.language.rs-lat.js +126 -0
  160. package/modules/angular-ui-grid/ui-grid.language.rs-lat.min.js +6 -0
  161. package/modules/angular-ui-grid/ui-grid.language.ru.js +115 -0
  162. package/modules/angular-ui-grid/ui-grid.language.ru.min.js +6 -0
  163. package/modules/angular-ui-grid/ui-grid.language.sk.js +127 -0
  164. package/modules/angular-ui-grid/ui-grid.language.sk.min.js +6 -0
  165. package/modules/angular-ui-grid/ui-grid.language.sv.js +126 -0
  166. package/modules/angular-ui-grid/ui-grid.language.sv.min.js +6 -0
  167. package/modules/angular-ui-grid/ui-grid.language.ta.js +87 -0
  168. package/modules/angular-ui-grid/ui-grid.language.ta.min.js +6 -0
  169. package/modules/angular-ui-grid/ui-grid.language.tr.js +112 -0
  170. package/modules/angular-ui-grid/ui-grid.language.tr.min.js +6 -0
  171. package/modules/angular-ui-grid/ui-grid.language.ua.js +112 -0
  172. package/modules/angular-ui-grid/ui-grid.language.ua.min.js +6 -0
  173. package/modules/angular-ui-grid/ui-grid.language.zh-cn.js +112 -0
  174. package/modules/angular-ui-grid/ui-grid.language.zh-cn.min.js +6 -0
  175. package/modules/angular-ui-grid/ui-grid.language.zh-tw.js +77 -0
  176. package/modules/angular-ui-grid/ui-grid.language.zh-tw.min.js +6 -0
  177. package/modules/angular-ui-grid/ui-grid.min.css +5 -0
  178. package/modules/angular-ui-grid/ui-grid.min.js +6 -0
  179. package/modules/angular-ui-grid/ui-grid.move-columns.js +582 -0
  180. package/modules/angular-ui-grid/ui-grid.move-columns.min.js +6 -0
  181. package/modules/angular-ui-grid/ui-grid.pagination.js +510 -0
  182. package/modules/angular-ui-grid/ui-grid.pagination.min.js +6 -0
  183. package/modules/angular-ui-grid/ui-grid.pinning.js +281 -0
  184. package/modules/angular-ui-grid/ui-grid.pinning.min.js +6 -0
  185. package/modules/angular-ui-grid/ui-grid.resize-columns.js +574 -0
  186. package/modules/angular-ui-grid/ui-grid.resize-columns.min.js +6 -0
  187. package/modules/angular-ui-grid/ui-grid.row-edit.js +717 -0
  188. package/modules/angular-ui-grid/ui-grid.row-edit.min.js +6 -0
  189. package/modules/angular-ui-grid/ui-grid.saveState.js +831 -0
  190. package/modules/angular-ui-grid/ui-grid.saveState.min.js +6 -0
  191. package/modules/angular-ui-grid/ui-grid.selection.js +1196 -0
  192. package/modules/angular-ui-grid/ui-grid.selection.min.js +6 -0
  193. package/modules/angular-ui-grid/ui-grid.tree-base.js +1743 -0
  194. package/modules/angular-ui-grid/ui-grid.tree-base.min.js +6 -0
  195. package/modules/angular-ui-grid/ui-grid.tree-view.js +218 -0
  196. package/modules/angular-ui-grid/ui-grid.tree-view.min.js +6 -0
  197. package/modules/angular-ui-grid/ui-grid.validate.js +589 -0
  198. package/modules/angular-ui-grid/ui-grid.validate.min.js +6 -0
  199. package/package.json +8 -0
  200. package/polyfills.js +2 -0
  201. package/styles.css +1 -0
@@ -0,0 +1,1181 @@
1
+ /*!
2
+ * ui-grid - v4.12.7 - 2024-04-12
3
+ * http://ui-grid.info/
4
+ * Copyright (c) 2024 ; License: MIT
5
+ */
6
+
7
+ (function () {
8
+ 'use strict';
9
+
10
+ /**
11
+ * @ngdoc overview
12
+ * @name ui.grid.cellNav
13
+ *
14
+ * @description
15
+
16
+ #ui.grid.cellNav
17
+
18
+ <div class="alert alert-success" role="alert"><strong>Stable</strong> This feature is stable. There should no longer be breaking api changes without a deprecation warning.</div>
19
+
20
+ This module provides cell navigation functionality to UI-Grid.
21
+ */
22
+ var module = angular.module('ui.grid.cellNav', ['ui.grid']);
23
+
24
+ /**
25
+ * @ngdoc object
26
+ * @name ui.grid.cellNav.constant:uiGridCellNavConstants
27
+ *
28
+ * @description constants available in cellNav
29
+ */
30
+ module.constant('uiGridCellNavConstants', {
31
+ FEATURE_NAME: 'gridCellNav',
32
+ CELL_NAV_EVENT: 'cellNav',
33
+ direction: {LEFT: 0, RIGHT: 1, UP: 2, DOWN: 3, PG_UP: 4, PG_DOWN: 5},
34
+ EVENT_TYPE: {
35
+ KEYDOWN: 0,
36
+ CLICK: 1,
37
+ CLEAR: 2
38
+ }
39
+ });
40
+
41
+
42
+ module.factory('uiGridCellNavFactory', ['uiGridCellNavConstants', 'GridRowColumn',
43
+ function (uiGridCellNavConstants, GridRowColumn) {
44
+ /**
45
+ * @ngdoc object
46
+ * @name ui.grid.cellNav.object:CellNav
47
+ * @description returns a CellNav prototype function
48
+ * @param {object} rowContainer container for rows
49
+ * @param {object} colContainer parent column container
50
+ * @param {object} leftColContainer column container to the left of parent
51
+ * @param {object} rightColContainer column container to the right of parent
52
+ */
53
+ var UiGridCellNav = function UiGridCellNav(rowContainer, colContainer, leftColContainer, rightColContainer) {
54
+ this.rows = rowContainer.visibleRowCache;
55
+ this.columns = colContainer.visibleColumnCache;
56
+ this.leftColumns = leftColContainer ? leftColContainer.visibleColumnCache : [];
57
+ this.rightColumns = rightColContainer ? rightColContainer.visibleColumnCache : [];
58
+ this.bodyContainer = rowContainer;
59
+ };
60
+
61
+ /** returns focusable columns of all containers */
62
+ UiGridCellNav.prototype.getFocusableCols = function () {
63
+ var allColumns = this.leftColumns.concat(this.columns, this.rightColumns);
64
+
65
+ return allColumns.filter(function (col) {
66
+ return col.colDef.allowCellFocus;
67
+ });
68
+ };
69
+
70
+ /**
71
+ * @ngdoc object
72
+ * @name ui.grid.cellNav.api:GridRow
73
+ *
74
+ * @description GridRow settings for cellNav feature, these are available to be
75
+ * set only internally (for example, by other features)
76
+ */
77
+
78
+ /**
79
+ * @ngdoc object
80
+ * @name allowCellFocus
81
+ * @propertyOf ui.grid.cellNav.api:GridRow
82
+ * @description Enable focus on a cell within this row. If set to false then no cells
83
+ * in this row can be focused - group header rows as an example would set this to false.
84
+ * <br/>Defaults to true
85
+ */
86
+ /** returns focusable rows */
87
+ UiGridCellNav.prototype.getFocusableRows = function () {
88
+ return this.rows.filter(function(row) {
89
+ return row.allowCellFocus !== false;
90
+ });
91
+ };
92
+
93
+ UiGridCellNav.prototype.getNextRowCol = function (direction, curRow, curCol) {
94
+ switch (direction) {
95
+ case uiGridCellNavConstants.direction.LEFT:
96
+ return this.getRowColLeft(curRow, curCol);
97
+ case uiGridCellNavConstants.direction.RIGHT:
98
+ return this.getRowColRight(curRow, curCol);
99
+ case uiGridCellNavConstants.direction.UP:
100
+ return this.getRowColUp(curRow, curCol);
101
+ case uiGridCellNavConstants.direction.DOWN:
102
+ return this.getRowColDown(curRow, curCol);
103
+ case uiGridCellNavConstants.direction.PG_UP:
104
+ return this.getRowColPageUp(curRow, curCol);
105
+ case uiGridCellNavConstants.direction.PG_DOWN:
106
+ return this.getRowColPageDown(curRow, curCol);
107
+ }
108
+ };
109
+
110
+ UiGridCellNav.prototype.initializeSelection = function () {
111
+ var focusableCols = this.getFocusableCols();
112
+ var focusableRows = this.getFocusableRows();
113
+ if (focusableCols.length === 0 || focusableRows.length === 0) {
114
+ return null;
115
+ }
116
+
117
+ return new GridRowColumn(focusableRows[0], focusableCols[0]); // return same row
118
+ };
119
+
120
+ UiGridCellNav.prototype.getRowColLeft = function (curRow, curCol) {
121
+ var focusableCols = this.getFocusableCols();
122
+ var focusableRows = this.getFocusableRows();
123
+ var curColIndex = focusableCols.indexOf(curCol);
124
+ var curRowIndex = focusableRows.indexOf(curRow);
125
+
126
+ // could not find column in focusable Columns so set it to 1
127
+ if (curColIndex === -1) {
128
+ curColIndex = 1;
129
+ }
130
+
131
+ var nextColIndex = curColIndex === 0 ? focusableCols.length - 1 : curColIndex - 1;
132
+
133
+ // get column to left
134
+ if (nextColIndex >= curColIndex) {
135
+ // On the first row
136
+ // if (curRowIndex === 0 && curColIndex === 0) {
137
+ // return null;
138
+ // }
139
+ if (curRowIndex === 0) {
140
+ return new GridRowColumn(curRow, focusableCols[nextColIndex]); // return same row
141
+ }
142
+ else {
143
+ // up one row and far right column
144
+ return new GridRowColumn(focusableRows[curRowIndex - 1], focusableCols[nextColIndex]);
145
+ }
146
+ }
147
+ else {
148
+ return new GridRowColumn(curRow, focusableCols[nextColIndex]);
149
+ }
150
+ };
151
+
152
+
153
+
154
+ UiGridCellNav.prototype.getRowColRight = function (curRow, curCol) {
155
+ var focusableCols = this.getFocusableCols();
156
+ var focusableRows = this.getFocusableRows();
157
+ var curColIndex = focusableCols.indexOf(curCol);
158
+ var curRowIndex = focusableRows.indexOf(curRow);
159
+
160
+ // could not find column in focusable Columns so set it to 0
161
+ if (curColIndex === -1) {
162
+ curColIndex = 0;
163
+ }
164
+ var nextColIndex = curColIndex === focusableCols.length - 1 ? 0 : curColIndex + 1;
165
+
166
+ if (nextColIndex <= curColIndex) {
167
+ if (curRowIndex === focusableRows.length - 1) {
168
+ return new GridRowColumn(curRow, focusableCols[nextColIndex]); // return same row
169
+ }
170
+ else {
171
+ // down one row and far left column
172
+ return new GridRowColumn(focusableRows[curRowIndex + 1], focusableCols[nextColIndex]);
173
+ }
174
+ }
175
+ else {
176
+ return new GridRowColumn(curRow, focusableCols[nextColIndex]);
177
+ }
178
+ };
179
+
180
+ UiGridCellNav.prototype.getRowColDown = function (curRow, curCol) {
181
+ var focusableCols = this.getFocusableCols();
182
+ var focusableRows = this.getFocusableRows();
183
+ var curColIndex = focusableCols.indexOf(curCol);
184
+ var curRowIndex = focusableRows.indexOf(curRow);
185
+
186
+ // could not find column in focusable Columns so set it to 0
187
+ if (curColIndex === -1) {
188
+ curColIndex = 0;
189
+ }
190
+
191
+ if (curRowIndex === focusableRows.length - 1) {
192
+ return new GridRowColumn(curRow, focusableCols[curColIndex]); // return same row
193
+ }
194
+ else {
195
+ // down one row
196
+ return new GridRowColumn(focusableRows[curRowIndex + 1], focusableCols[curColIndex]);
197
+ }
198
+ };
199
+
200
+ UiGridCellNav.prototype.getRowColPageDown = function (curRow, curCol) {
201
+ var focusableCols = this.getFocusableCols();
202
+ var focusableRows = this.getFocusableRows();
203
+ var curColIndex = focusableCols.indexOf(curCol);
204
+ var curRowIndex = focusableRows.indexOf(curRow);
205
+
206
+ // could not find column in focusable Columns so set it to 0
207
+ if (curColIndex === -1) {
208
+ curColIndex = 0;
209
+ }
210
+
211
+ var pageSize = this.bodyContainer.minRowsToRender();
212
+ if (curRowIndex >= focusableRows.length - pageSize) {
213
+ return new GridRowColumn(focusableRows[focusableRows.length - 1], focusableCols[curColIndex]); // return last row
214
+ }
215
+ else {
216
+ // down one page
217
+ return new GridRowColumn(focusableRows[curRowIndex + pageSize], focusableCols[curColIndex]);
218
+ }
219
+ };
220
+
221
+ UiGridCellNav.prototype.getRowColUp = function (curRow, curCol) {
222
+ var focusableCols = this.getFocusableCols();
223
+ var focusableRows = this.getFocusableRows();
224
+ var curColIndex = focusableCols.indexOf(curCol);
225
+ var curRowIndex = focusableRows.indexOf(curRow);
226
+
227
+ // could not find column in focusable Columns so set it to 0
228
+ if (curColIndex === -1) {
229
+ curColIndex = 0;
230
+ }
231
+
232
+ if (curRowIndex === 0) {
233
+ return new GridRowColumn(curRow, focusableCols[curColIndex]); // return same row
234
+ }
235
+ else {
236
+ // up one row
237
+ return new GridRowColumn(focusableRows[curRowIndex - 1], focusableCols[curColIndex]);
238
+ }
239
+ };
240
+
241
+ UiGridCellNav.prototype.getRowColPageUp = function (curRow, curCol) {
242
+ var focusableCols = this.getFocusableCols();
243
+ var focusableRows = this.getFocusableRows();
244
+ var curColIndex = focusableCols.indexOf(curCol);
245
+ var curRowIndex = focusableRows.indexOf(curRow);
246
+
247
+ // could not find column in focusable Columns so set it to 0
248
+ if (curColIndex === -1) {
249
+ curColIndex = 0;
250
+ }
251
+
252
+ var pageSize = this.bodyContainer.minRowsToRender();
253
+ if (curRowIndex - pageSize < 0) {
254
+ return new GridRowColumn(focusableRows[0], focusableCols[curColIndex]); // return first row
255
+ }
256
+ else {
257
+ // up one page
258
+ return new GridRowColumn(focusableRows[curRowIndex - pageSize], focusableCols[curColIndex]);
259
+ }
260
+ };
261
+ return UiGridCellNav;
262
+ }]);
263
+
264
+ /**
265
+ * @ngdoc service
266
+ * @name ui.grid.cellNav.service:uiGridCellNavService
267
+ *
268
+ * @description Services for cell navigation features. If you don't like the key maps we use,
269
+ * or the direction cells navigation, override with a service decorator (see angular docs)
270
+ */
271
+ module.service('uiGridCellNavService', ['uiGridConstants', 'uiGridCellNavConstants', '$q', 'uiGridCellNavFactory',
272
+ function (uiGridConstants, uiGridCellNavConstants, $q, UiGridCellNav) {
273
+
274
+ var service = {
275
+
276
+ initializeGrid: function (grid) {
277
+ grid.registerColumnBuilder(service.cellNavColumnBuilder);
278
+
279
+
280
+ /**
281
+ * @ngdoc object
282
+ * @name ui.grid.cellNav.Grid:cellNav
283
+ * @description cellNav properties added to grid class
284
+ */
285
+ grid.cellNav = {};
286
+ grid.cellNav.lastRowCol = null;
287
+ grid.cellNav.focusedCells = [];
288
+
289
+ service.defaultGridOptions(grid.options);
290
+
291
+ /**
292
+ * @ngdoc object
293
+ * @name ui.grid.cellNav.api:PublicApi
294
+ *
295
+ * @description Public Api for cellNav feature
296
+ */
297
+ var publicApi = {
298
+ events: {
299
+ cellNav: {
300
+ /**
301
+ * @ngdoc event
302
+ * @name navigate
303
+ * @eventOf ui.grid.cellNav.api:PublicApi
304
+ * @description raised when the active cell is changed
305
+ * <pre>
306
+ * gridApi.cellNav.on.navigate(scope,function(newRowcol, oldRowCol) {})
307
+ * </pre>
308
+ * @param {object} newRowCol new position
309
+ * @param {object} oldRowCol old position
310
+ */
311
+ navigate: function (newRowCol, oldRowCol) {},
312
+ /**
313
+ * @ngdoc event
314
+ * @name viewPortKeyDown
315
+ * @eventOf ui.grid.cellNav.api:PublicApi
316
+ * @description is raised when the viewPort receives a keyDown event. Cells never get focus in uiGrid
317
+ * due to the difficulties of setting focus on a cell that is not visible in the viewport. Use this
318
+ * event whenever you need a keydown event on a cell
319
+ * <br/>
320
+ * @param {object} event keydown event
321
+ * @param {object} rowCol current rowCol position
322
+ */
323
+ viewPortKeyDown: function (event, rowCol) {},
324
+
325
+ /**
326
+ * @ngdoc event
327
+ * @name viewPortKeyPress
328
+ * @eventOf ui.grid.cellNav.api:PublicApi
329
+ * @description is raised when the viewPort receives a keyPress event. Cells never get focus in uiGrid
330
+ * due to the difficulties of setting focus on a cell that is not visible in the viewport. Use this
331
+ * event whenever you need a keypress event on a cell
332
+ * <br/>
333
+ * @param {object} event keypress event
334
+ * @param {object} rowCol current rowCol position
335
+ */
336
+ viewPortKeyPress: function (event, rowCol) {}
337
+ }
338
+ },
339
+ methods: {
340
+ cellNav: {
341
+ /**
342
+ * @ngdoc function
343
+ * @name scrollToFocus
344
+ * @methodOf ui.grid.cellNav.api:PublicApi
345
+ * @description brings the specified row and column into view, and sets focus
346
+ * to that cell
347
+ * @param {object} rowEntity gridOptions.data[] array instance to make visible and set focus
348
+ * @param {object} colDef to make visible and set focus
349
+ * @returns {promise} a promise that is resolved after any scrolling is finished
350
+ */
351
+ scrollToFocus: function (rowEntity, colDef) {
352
+ return service.scrollToFocus(grid, rowEntity, colDef);
353
+ },
354
+
355
+ /**
356
+ * @ngdoc function
357
+ * @name getFocusedCell
358
+ * @methodOf ui.grid.cellNav.api:PublicApi
359
+ * @description returns the current (or last if Grid does not have focus) focused row and column
360
+ * <br> value is null if no selection has occurred
361
+ */
362
+ getFocusedCell: function () {
363
+ return grid.cellNav.lastRowCol;
364
+ },
365
+
366
+ /**
367
+ * @ngdoc function
368
+ * @name getCurrentSelection
369
+ * @methodOf ui.grid.cellNav.api:PublicApi
370
+ * @description returns an array containing the current selection
371
+ * <br> array is empty if no selection has occurred
372
+ */
373
+ getCurrentSelection: function () {
374
+ return grid.cellNav.focusedCells;
375
+ },
376
+
377
+ /**
378
+ * @ngdoc function
379
+ * @name rowColSelectIndex
380
+ * @methodOf ui.grid.cellNav.api:PublicApi
381
+ * @description returns the index in the order in which the GridRowColumn was selected, returns -1 if the GridRowColumn
382
+ * isn't selected
383
+ * @param {object} rowCol the rowCol to evaluate
384
+ */
385
+ rowColSelectIndex: function (rowCol) {
386
+ // return gridUtil.arrayContainsObjectWithProperty(grid.cellNav.focusedCells, 'col.uid', rowCol.col.uid) &&
387
+ var index = -1;
388
+ for (var i = 0; i < grid.cellNav.focusedCells.length; i++) {
389
+ if (grid.cellNav.focusedCells[i].col.uid === rowCol.col.uid &&
390
+ grid.cellNav.focusedCells[i].row.uid === rowCol.row.uid) {
391
+ index = i;
392
+ break;
393
+ }
394
+ }
395
+ return index;
396
+ }
397
+ }
398
+ }
399
+ };
400
+
401
+ grid.api.registerEventsFromObject(publicApi.events);
402
+
403
+ grid.api.registerMethodsFromObject(publicApi.methods);
404
+ },
405
+
406
+ defaultGridOptions: function (gridOptions) {
407
+ /**
408
+ * @ngdoc object
409
+ * @name ui.grid.cellNav.api:GridOptions
410
+ *
411
+ * @description GridOptions for cellNav feature, these are available to be
412
+ * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
413
+ */
414
+
415
+ /**
416
+ * @ngdoc object
417
+ * @name modifierKeysToMultiSelectCells
418
+ * @propertyOf ui.grid.cellNav.api:GridOptions
419
+ * @description Enable multiple cell selection only when using the ctrlKey or shiftKey.
420
+ * <br/>Defaults to false
421
+ */
422
+ gridOptions.modifierKeysToMultiSelectCells = gridOptions.modifierKeysToMultiSelectCells === true;
423
+
424
+ /**
425
+ * @ngdoc array
426
+ * @name keyDownOverrides
427
+ * @propertyOf ui.grid.cellNav.api:GridOptions
428
+ * @description An array of event objects to override on keydown. If an event is overridden, the viewPortKeyDown event will
429
+ * be raised with the overridden events, allowing custom keydown behavior.
430
+ * <br/>Defaults to []
431
+ */
432
+ gridOptions.keyDownOverrides = gridOptions.keyDownOverrides || [];
433
+
434
+ },
435
+
436
+ /**
437
+ * @ngdoc service
438
+ * @name decorateRenderContainers
439
+ * @methodOf ui.grid.cellNav.service:uiGridCellNavService
440
+ * @description decorates grid renderContainers with cellNav functions
441
+ */
442
+ decorateRenderContainers: function (grid) {
443
+
444
+ var rightContainer = grid.hasRightContainer() ? grid.renderContainers.right : null;
445
+ var leftContainer = grid.hasLeftContainer() ? grid.renderContainers.left : null;
446
+
447
+ if (leftContainer !== null) {
448
+ grid.renderContainers.left.cellNav = new UiGridCellNav(grid.renderContainers.body, leftContainer, rightContainer, grid.renderContainers.body);
449
+ }
450
+ if (rightContainer !== null) {
451
+ grid.renderContainers.right.cellNav = new UiGridCellNav(grid.renderContainers.body, rightContainer, grid.renderContainers.body, leftContainer);
452
+ }
453
+
454
+ grid.renderContainers.body.cellNav = new UiGridCellNav(grid.renderContainers.body, grid.renderContainers.body, leftContainer, rightContainer);
455
+ },
456
+
457
+ /**
458
+ * @ngdoc service
459
+ * @name getDirection
460
+ * @methodOf ui.grid.cellNav.service:uiGridCellNavService
461
+ * @description determines which direction to for a given keyDown event
462
+ * @returns {uiGridCellNavConstants.direction} direction
463
+ */
464
+ getDirection: function (evt) {
465
+ if (evt.keyCode === uiGridConstants.keymap.LEFT ||
466
+ (evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey)) {
467
+ return uiGridCellNavConstants.direction.LEFT;
468
+ }
469
+ if (evt.keyCode === uiGridConstants.keymap.RIGHT ||
470
+ evt.keyCode === uiGridConstants.keymap.TAB) {
471
+ return uiGridCellNavConstants.direction.RIGHT;
472
+ }
473
+
474
+ if (evt.keyCode === uiGridConstants.keymap.UP ||
475
+ (evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey) ) {
476
+ return uiGridCellNavConstants.direction.UP;
477
+ }
478
+
479
+ if (evt.keyCode === uiGridConstants.keymap.PG_UP) {
480
+ return uiGridCellNavConstants.direction.PG_UP;
481
+ }
482
+
483
+ if (evt.keyCode === uiGridConstants.keymap.DOWN ||
484
+ evt.keyCode === uiGridConstants.keymap.ENTER && !(evt.ctrlKey || evt.altKey)) {
485
+ return uiGridCellNavConstants.direction.DOWN;
486
+ }
487
+
488
+ if (evt.keyCode === uiGridConstants.keymap.PG_DOWN) {
489
+ return uiGridCellNavConstants.direction.PG_DOWN;
490
+ }
491
+
492
+ return null;
493
+ },
494
+
495
+ /**
496
+ * @ngdoc service
497
+ * @name cellNavColumnBuilder
498
+ * @methodOf ui.grid.cellNav.service:uiGridCellNavService
499
+ * @description columnBuilder function that adds cell navigation properties to grid column
500
+ * @returns {promise} promise that will load any needed templates when resolved
501
+ */
502
+ cellNavColumnBuilder: function (colDef, col, gridOptions) {
503
+ var promises = [];
504
+
505
+ /**
506
+ * @ngdoc object
507
+ * @name ui.grid.cellNav.api:ColumnDef
508
+ *
509
+ * @description Column Definitions for cellNav feature, these are available to be
510
+ * set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
511
+ */
512
+
513
+ /**
514
+ * @ngdoc object
515
+ * @name allowCellFocus
516
+ * @propertyOf ui.grid.cellNav.api:ColumnDef
517
+ * @description Enable focus on a cell within this column.
518
+ * <br/>Defaults to true
519
+ */
520
+ colDef.allowCellFocus = colDef.allowCellFocus === undefined ? true : colDef.allowCellFocus;
521
+
522
+ return $q.all(promises);
523
+ },
524
+
525
+ /**
526
+ * @ngdoc method
527
+ * @methodOf ui.grid.cellNav.service:uiGridCellNavService
528
+ * @name scrollToFocus
529
+ * @description Scroll the grid such that the specified
530
+ * row and column is in view, and set focus to the cell in that row and column
531
+ * @param {Grid} grid the grid you'd like to act upon, usually available
532
+ * from gridApi.grid
533
+ * @param {object} rowEntity gridOptions.data[] array instance to make visible and set focus to
534
+ * @param {object} colDef to make visible and set focus to
535
+ * @returns {promise} a promise that is resolved after any scrolling is finished
536
+ */
537
+ scrollToFocus: function (grid, rowEntity, colDef) {
538
+ var gridRow = null, gridCol = null;
539
+
540
+ if (typeof(rowEntity) !== 'undefined' && rowEntity !== null) {
541
+ gridRow = grid.getRow(rowEntity);
542
+ }
543
+
544
+ if (typeof(colDef) !== 'undefined' && colDef !== null) {
545
+ gridCol = grid.getColumn(colDef.name ? colDef.name : colDef.field);
546
+ }
547
+ return grid.api.core.scrollToIfNecessary(gridRow, gridCol).then(function () {
548
+ var rowCol = { row: gridRow, col: gridCol };
549
+
550
+ // Broadcast the navigation
551
+ if (gridRow !== null && gridCol !== null) {
552
+ grid.cellNav.broadcastCellNav(rowCol, null, null);
553
+ }
554
+ });
555
+ },
556
+
557
+
558
+ /**
559
+ * @ngdoc method
560
+ * @methodOf ui.grid.cellNav.service:uiGridCellNavService
561
+ * @name getLeftWidth
562
+ * @description Get the current drawn width of the columns in the
563
+ * grid up to the numbered column, and add an apportionment for the
564
+ * column that we're on. So if we are on column 0, we want to scroll
565
+ * 0% (i.e. exclude this column from calc). If we're on the last column
566
+ * we want to scroll to 100% (i.e. include this column in the calc). So
567
+ * we include (thisColIndex / totalNumberCols) % of this column width
568
+ * @param {Grid} grid the grid you'd like to act upon, usually available
569
+ * from gridApi.grid
570
+ * @param {GridColumn} upToCol the column to total up to and including
571
+ */
572
+ getLeftWidth: function (grid, upToCol) {
573
+ var width = 0;
574
+
575
+ if (!upToCol) {
576
+ return width;
577
+ }
578
+
579
+ var lastIndex = grid.renderContainers.body.visibleColumnCache.indexOf( upToCol );
580
+
581
+ // total column widths up-to but not including the passed in column
582
+ grid.renderContainers.body.visibleColumnCache.forEach( function( col, index ) {
583
+ if ( index < lastIndex ) {
584
+ width += col.drawnWidth;
585
+ }
586
+ });
587
+
588
+ // pro-rata the final column based on % of total columns.
589
+ var percentage = lastIndex === 0 ? 0 : (lastIndex + 1) / grid.renderContainers.body.visibleColumnCache.length;
590
+ width += upToCol.drawnWidth * percentage;
591
+
592
+ return width;
593
+ }
594
+ };
595
+
596
+ return service;
597
+ }]);
598
+
599
+ /**
600
+ * @ngdoc directive
601
+ * @name ui.grid.cellNav.directive:uiCellNav
602
+ * @element div
603
+ * @restrict EA
604
+ *
605
+ * @description Adds cell navigation features to the grid columns
606
+ *
607
+ * @example
608
+ <example module="app">
609
+ <file name="app.js">
610
+ var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);
611
+
612
+ app.controller('MainCtrl', ['$scope', function ($scope) {
613
+ $scope.data = [
614
+ { name: 'Bob', title: 'CEO' },
615
+ { name: 'Frank', title: 'Lowly Developer' }
616
+ ];
617
+
618
+ $scope.columnDefs = [
619
+ {name: 'name'},
620
+ {name: 'title'}
621
+ ];
622
+ }]);
623
+ </file>
624
+ <file name="index.html">
625
+ <div ng-controller="MainCtrl">
626
+ <div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-cellnav></div>
627
+ </div>
628
+ </file>
629
+ </example>
630
+ */
631
+ module.directive('uiGridCellnav', ['uiGridCellNavService', 'uiGridCellNavConstants', 'uiGridConstants', 'GridRowColumn', '$compile', 'i18nService',
632
+ function (uiGridCellNavService, uiGridCellNavConstants, uiGridConstants, GridRowColumn, $compile, i18nService) {
633
+ return {
634
+ replace: true,
635
+ priority: -150,
636
+ require: '^uiGrid',
637
+ scope: false,
638
+ controller: function () {},
639
+ compile: function () {
640
+ return {
641
+ pre: function ($scope, $elm, $attrs, uiGridCtrl) {
642
+ var _scope = $scope;
643
+
644
+ var grid = uiGridCtrl.grid;
645
+ uiGridCellNavService.initializeGrid(grid);
646
+
647
+ uiGridCtrl.cellNav = {};
648
+
649
+ // Ensure that the object has all of the methods we expect it to
650
+ uiGridCtrl.cellNav.makeRowCol = function (obj) {
651
+ if (!(obj instanceof GridRowColumn)) {
652
+ obj = new GridRowColumn(obj.row, obj.col);
653
+ }
654
+ return obj;
655
+ };
656
+
657
+ uiGridCtrl.cellNav.getActiveCell = function () {
658
+ var elms = $elm[0].getElementsByClassName('ui-grid-cell-focus');
659
+ if (elms.length > 0) {
660
+ return elms[0];
661
+ }
662
+
663
+ return undefined;
664
+ };
665
+
666
+ uiGridCtrl.cellNav.broadcastCellNav = grid.cellNav.broadcastCellNav = function (newRowCol, modifierDown, originEvt) {
667
+ modifierDown = !(modifierDown === undefined || !modifierDown);
668
+
669
+ newRowCol = uiGridCtrl.cellNav.makeRowCol(newRowCol);
670
+
671
+ uiGridCtrl.cellNav.broadcastFocus(newRowCol, modifierDown, originEvt);
672
+ _scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT, newRowCol, modifierDown, originEvt);
673
+ };
674
+
675
+ uiGridCtrl.cellNav.clearFocus = grid.cellNav.clearFocus = function () {
676
+ grid.cellNav.focusedCells = [];
677
+ _scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT);
678
+ };
679
+
680
+ uiGridCtrl.cellNav.broadcastFocus = function (rowCol, modifierDown, originEvt) {
681
+ modifierDown = !(modifierDown === undefined || !modifierDown);
682
+
683
+ rowCol = uiGridCtrl.cellNav.makeRowCol(rowCol);
684
+
685
+ var row = rowCol.row,
686
+ col = rowCol.col;
687
+
688
+ var rowColSelectIndex = uiGridCtrl.grid.api.cellNav.rowColSelectIndex(rowCol);
689
+
690
+ if (grid.cellNav.lastRowCol === null || rowColSelectIndex === -1 || (grid.cellNav.lastRowCol.col === col && grid.cellNav.lastRowCol.row === row)) {
691
+ var newRowCol = new GridRowColumn(row, col);
692
+
693
+ if (grid.cellNav.lastRowCol === null || grid.cellNav.lastRowCol.row !== newRowCol.row || grid.cellNav.lastRowCol.col !== newRowCol.col || grid.options.enableCellEditOnFocus) {
694
+ grid.api.cellNav.raise.navigate(newRowCol, grid.cellNav.lastRowCol, originEvt);
695
+ grid.cellNav.lastRowCol = newRowCol;
696
+ }
697
+ if (uiGridCtrl.grid.options.modifierKeysToMultiSelectCells && modifierDown) {
698
+ grid.cellNav.focusedCells.push(rowCol);
699
+ } else {
700
+ grid.cellNav.focusedCells = [rowCol];
701
+ }
702
+ } else if (grid.options.modifierKeysToMultiSelectCells && modifierDown &&
703
+ rowColSelectIndex >= 0) {
704
+
705
+ grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
706
+ }
707
+ };
708
+
709
+ uiGridCtrl.cellNav.handleKeyDown = function (evt) {
710
+ var direction = uiGridCellNavService.getDirection(evt);
711
+ if (direction === null) {
712
+ return null;
713
+ }
714
+
715
+ var containerId = 'body';
716
+ if (evt.uiGridTargetRenderContainerId) {
717
+ containerId = evt.uiGridTargetRenderContainerId;
718
+ }
719
+
720
+ // Get the last-focused row+col combo
721
+ var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
722
+ if (lastRowCol) {
723
+ // Figure out which new row+combo we're navigating to
724
+ var rowCol = uiGridCtrl.grid.renderContainers[containerId].cellNav.getNextRowCol(direction, lastRowCol.row, lastRowCol.col);
725
+ var focusableCols = uiGridCtrl.grid.renderContainers[containerId].cellNav.getFocusableCols();
726
+ var rowColSelectIndex = uiGridCtrl.grid.api.cellNav.rowColSelectIndex(rowCol);
727
+ // Shift+tab on top-left cell should exit cellnav on render container
728
+ if (
729
+ // Navigating left
730
+ direction === uiGridCellNavConstants.direction.LEFT &&
731
+ // New col is last col (i.e. wrap around)
732
+ rowCol.col === focusableCols[focusableCols.length - 1] &&
733
+ // Staying on same row, which means we're at first row
734
+ rowCol.row === lastRowCol.row &&
735
+ evt.keyCode === uiGridConstants.keymap.TAB &&
736
+ evt.shiftKey
737
+ ) {
738
+ grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
739
+ uiGridCtrl.cellNav.clearFocus();
740
+ return true;
741
+ }
742
+ // Tab on bottom-right cell should exit cellnav on render container
743
+ else if (
744
+ direction === uiGridCellNavConstants.direction.RIGHT &&
745
+ // New col is first col (i.e. wrap around)
746
+ rowCol.col === focusableCols[0] &&
747
+ // Staying on same row, which means we're at first row
748
+ rowCol.row === lastRowCol.row &&
749
+ evt.keyCode === uiGridConstants.keymap.TAB &&
750
+ !evt.shiftKey
751
+ ) {
752
+ grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
753
+ uiGridCtrl.cellNav.clearFocus();
754
+ return true;
755
+ }
756
+
757
+ // Scroll to the new cell, if it's not completely visible within the render container's viewport
758
+ grid.scrollToIfNecessary(rowCol.row, rowCol.col).then(function () {
759
+ uiGridCtrl.cellNav.broadcastCellNav(rowCol, null, evt);
760
+ });
761
+
762
+
763
+ evt.stopPropagation();
764
+ evt.preventDefault();
765
+
766
+ return false;
767
+ }
768
+ };
769
+ },
770
+ post: function ($scope, $elm, $attrs, uiGridCtrl) {
771
+ var grid = uiGridCtrl.grid;
772
+ var usesAria = true;
773
+
774
+ // Detect whether we are using ngAria
775
+ // (if ngAria module is not used then the stuff inside addAriaLiveRegion
776
+ // is not used and provides extra fluff)
777
+ try {
778
+ angular.module('ngAria');
779
+ }
780
+ catch (err) {
781
+ usesAria = false;
782
+ }
783
+
784
+ function addAriaLiveRegion() {
785
+ // Thanks to google docs for the inspiration behind how to do this
786
+ // XXX: Why is this entire mess nessasary?
787
+ // Because browsers take a lot of coercing to get them to read out live regions
788
+ // http://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
789
+ var ariaNotifierDomElt = '<div ' +
790
+ 'id="' + grid.id +'-aria-speakable" ' +
791
+ 'class="ui-grid-a11y-ariascreenreader-speakable ui-grid-offscreen" ' +
792
+ 'aria-live="assertive" ' +
793
+ 'role="alert" ' +
794
+ 'aria-atomic="true" ' +
795
+ 'aria-hidden="false" ' +
796
+ 'aria-relevant="additions" ' +
797
+ '>' +
798
+ '&nbsp;' +
799
+ '</div>';
800
+
801
+ var ariaNotifier = $compile(ariaNotifierDomElt)($scope);
802
+ $elm.prepend(ariaNotifier);
803
+ $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function (evt, rowCol, modifierDown, originEvt) {
804
+ /*
805
+ * If the cell nav event was because of a focus event then we don't want to
806
+ * change the notifier text.
807
+ * Reasoning: Voice Over fires a focus events when moving arround the grid.
808
+ * If the screen reader is handing the grid nav properly then we don't need to
809
+ * use the alert to notify the user of the movement.
810
+ * In all other cases we do want a notification event.
811
+ */
812
+ if (originEvt && originEvt.type === 'focus') {return;}
813
+
814
+ function setNotifyText(text) {
815
+ if (text === ariaNotifier.text().trim()) {return;}
816
+ ariaNotifier[0].style.clip = 'rect(0px,0px,0px,0px)';
817
+ /*
818
+ * This is how google docs handles clearing the div. Seems to work better than setting the text of the div to ''
819
+ */
820
+ ariaNotifier[0].innerHTML = "";
821
+ ariaNotifier[0].style.visibility = 'hidden';
822
+ ariaNotifier[0].style.visibility = 'visible';
823
+ if (text !== '') {
824
+ ariaNotifier[0].style.clip = 'auto';
825
+ /*
826
+ * The space after the text is something that google docs does.
827
+ */
828
+ ariaNotifier[0].appendChild(document.createTextNode(text + " "));
829
+ ariaNotifier[0].style.visibility = 'hidden';
830
+ ariaNotifier[0].style.visibility = 'visible';
831
+ }
832
+ }
833
+
834
+ function getAppendedColumnHeaderText(col) {
835
+ return ', ' + i18nService.getSafeText('headerCell.aria.column') + ' ' + col.displayName;
836
+ }
837
+
838
+ function getCellDisplayValue(currentRowColumn) {
839
+ var prefix = '';
840
+
841
+ if (currentRowColumn.col.field === 'selectionRowHeaderCol') {
842
+ // This is the case when the 'selection' feature is used in the grid and the user has moved
843
+ // to or inside of the left grid container which holds the checkboxes for selecting rows.
844
+ // This is necessary for Accessibility. Without this a screen reader cannot determine if the row
845
+ // is or is not currently selected.
846
+ prefix = (currentRowColumn.row.isSelected ? i18nService.getSafeText('search.aria.selected') : i18nService.getSafeText('search.aria.notSelected')) + ', ';
847
+ }
848
+ return prefix + grid.getCellDisplayValue(currentRowColumn.row, currentRowColumn.col);
849
+ }
850
+
851
+ var values = [];
852
+ var currentSelection = grid.api.cellNav.getCurrentSelection();
853
+ for (var i = 0; i < currentSelection.length; i++) {
854
+ var cellDisplayValue = getCellDisplayValue(currentSelection[i]) + getAppendedColumnHeaderText(currentSelection[i].col);
855
+ values.push(cellDisplayValue);
856
+ }
857
+ setNotifyText(values.toString());
858
+ });
859
+ }
860
+ // Only add the ngAria stuff it will be used
861
+ if (usesAria) {
862
+ addAriaLiveRegion();
863
+ }
864
+ }
865
+ };
866
+ }
867
+ };
868
+ }]);
869
+
870
+ module.directive('uiGridRenderContainer', ['$timeout', 'gridUtil', 'uiGridCellNavService', '$compile','uiGridCellNavConstants',
871
+ function ($timeout, gridUtil, uiGridCellNavService, $compile, uiGridCellNavConstants) {
872
+ return {
873
+ replace: true,
874
+ priority: -99999, // this needs to run very last
875
+ require: ['^uiGrid', 'uiGridRenderContainer', '?^uiGridCellnav'],
876
+ scope: false,
877
+ compile: function () {
878
+ return {
879
+ post: function ($scope, $elm, $attrs, controllers) {
880
+ var uiGridCtrl = controllers[0],
881
+ renderContainerCtrl = controllers[1],
882
+ uiGridCellnavCtrl = controllers[2];
883
+
884
+ // Skip attaching cell-nav specific logic if the directive is not attached above us
885
+ if (!uiGridCtrl.grid.api.cellNav) { return; }
886
+
887
+ var containerId = renderContainerCtrl.containerId;
888
+
889
+ var grid = uiGridCtrl.grid;
890
+
891
+ // run each time a render container is created
892
+ uiGridCellNavService.decorateRenderContainers(grid);
893
+
894
+ // focusser only created for body
895
+ if (containerId !== 'body') {
896
+ return;
897
+ }
898
+
899
+ if (uiGridCtrl.grid.options.modifierKeysToMultiSelectCells) {
900
+ $elm.attr('aria-multiselectable', true);
901
+ }
902
+ else {
903
+ $elm.attr('aria-multiselectable', false);
904
+ }
905
+
906
+ // add an element with no dimensions that can be used to set focus and capture keystrokes
907
+ var focuser = $compile('<div class="ui-grid-focuser" role="region" aria-live="assertive" aria-atomic="false" tabindex="0" aria-controls="' + grid.id +'-aria-speakable '+ grid.id + '-grid-container' +'" aria-owns="' + grid.id + '-grid-container' + '"></div>')($scope);
908
+ $elm.append(focuser);
909
+
910
+ focuser.on('focus', function (evt) {
911
+ evt.uiGridTargetRenderContainerId = containerId;
912
+ var rowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
913
+ if (rowCol === null) {
914
+ rowCol = uiGridCtrl.grid.renderContainers[containerId].cellNav.getNextRowCol(uiGridCellNavConstants.direction.DOWN, null, null);
915
+ if (rowCol.row && rowCol.col) {
916
+ uiGridCtrl.cellNav.broadcastCellNav(rowCol);
917
+ }
918
+ }
919
+ });
920
+
921
+ uiGridCellnavCtrl.setAriaActivedescendant = function(id) {
922
+ $elm.attr('aria-activedescendant', id);
923
+ };
924
+
925
+ uiGridCellnavCtrl.removeAriaActivedescendant = function(id) {
926
+ if ($elm.attr('aria-activedescendant') === id) {
927
+ $elm.attr('aria-activedescendant', '');
928
+ }
929
+ };
930
+
931
+
932
+ uiGridCtrl.focus = function () {
933
+ gridUtil.focus.byElement(focuser[0]);
934
+ // allow for first time grid focus
935
+ };
936
+
937
+ var viewPortKeyDownWasRaisedForRowCol = null;
938
+ // Bind to keydown events in the render container
939
+ focuser.on('keydown', function (evt) {
940
+ evt.uiGridTargetRenderContainerId = containerId;
941
+ var rowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
942
+ var raiseViewPortKeyDown = uiGridCtrl.grid.options.keyDownOverrides.some(function (override) {
943
+ return Object.keys(override).every( function (property) {
944
+ return override[property] === evt[property];
945
+ });
946
+ });
947
+ var result = raiseViewPortKeyDown ? null : uiGridCtrl.cellNav.handleKeyDown(evt);
948
+ if (result === null) {
949
+ uiGridCtrl.grid.api.cellNav.raise.viewPortKeyDown(evt, rowCol, uiGridCtrl.cellNav.handleKeyDown);
950
+ viewPortKeyDownWasRaisedForRowCol = rowCol;
951
+ }
952
+ });
953
+ // Bind to keypress events in the render container
954
+ // keypress events are needed by edit function so the key press
955
+ // that initiated an edit is not lost
956
+ // must fire the event in a timeout so the editor can
957
+ // initialize and subscribe to the event on another event loop
958
+ focuser.on('keypress', function (evt) {
959
+ if (viewPortKeyDownWasRaisedForRowCol) {
960
+ $timeout(function () {
961
+ uiGridCtrl.grid.api.cellNav.raise.viewPortKeyPress(evt, viewPortKeyDownWasRaisedForRowCol);
962
+ }, 4);
963
+
964
+ viewPortKeyDownWasRaisedForRowCol = null;
965
+ }
966
+ });
967
+
968
+ $scope.$on('$destroy', function() {
969
+ // Remove all event handlers associated with this focuser.
970
+ focuser.off();
971
+ });
972
+ }
973
+ };
974
+ }
975
+ };
976
+ }]);
977
+
978
+ module.directive('uiGridViewport',
979
+ function () {
980
+ return {
981
+ replace: true,
982
+ priority: -99999, // this needs to run very last
983
+ require: ['^uiGrid', '^uiGridRenderContainer', '?^uiGridCellnav'],
984
+ scope: false,
985
+ compile: function () {
986
+ return {
987
+ pre: function ($scope, $elm, $attrs, uiGridCtrl) {
988
+ },
989
+ post: function ($scope, $elm, $attrs, controllers) {
990
+ var uiGridCtrl = controllers[0],
991
+ renderContainerCtrl = controllers[1];
992
+
993
+ // Skip attaching cell-nav specific logic if the directive is not attached above us
994
+ if (!uiGridCtrl.grid.api.cellNav) { return; }
995
+
996
+ var containerId = renderContainerCtrl.containerId;
997
+ // no need to process for other containers
998
+ if (containerId !== 'body') {
999
+ return;
1000
+ }
1001
+
1002
+ var grid = uiGridCtrl.grid;
1003
+
1004
+ grid.api.core.on.scrollBegin($scope, function () {
1005
+
1006
+ // Skip if there's no currently-focused cell
1007
+ var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
1008
+ if (lastRowCol === null) {
1009
+ return;
1010
+ }
1011
+
1012
+ // if not in my container, move on
1013
+ // todo: worry about horiz scroll
1014
+ if (!renderContainerCtrl.colContainer.containsColumn(lastRowCol.col)) {
1015
+ return;
1016
+ }
1017
+
1018
+ uiGridCtrl.cellNav.clearFocus();
1019
+
1020
+ });
1021
+
1022
+ grid.api.core.on.scrollEnd($scope, function (args) {
1023
+ // Skip if there's no currently-focused cell
1024
+ var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
1025
+ if (lastRowCol === null) {
1026
+ return;
1027
+ }
1028
+
1029
+ // if not in my container, move on
1030
+ // todo: worry about horiz scroll
1031
+ if (!renderContainerCtrl.colContainer.containsColumn(lastRowCol.col)) {
1032
+ return;
1033
+ }
1034
+
1035
+ uiGridCtrl.cellNav.broadcastCellNav(lastRowCol);
1036
+ });
1037
+
1038
+ grid.api.cellNav.on.navigate($scope, function () {
1039
+ // focus again because it can be lost
1040
+ uiGridCtrl.focus();
1041
+ });
1042
+ }
1043
+ };
1044
+ }
1045
+ };
1046
+ });
1047
+
1048
+ /**
1049
+ * @ngdoc directive
1050
+ * @name ui.grid.cellNav.directive:uiGridCell
1051
+ * @element div
1052
+ * @restrict A
1053
+ * @description Stacks on top of ui.grid.uiGridCell to provide cell navigation
1054
+ */
1055
+ module.directive('uiGridCell', ['uiGridCellNavConstants', 'uiGridConstants', 'GridRowColumn',
1056
+ function (uiGridCellNavConstants, uiGridConstants, GridRowColumn) {
1057
+ return {
1058
+ priority: -150, // run after default uiGridCell directive and ui.grid.edit uiGridCell
1059
+ restrict: 'A',
1060
+ require: ['^uiGrid', '?^uiGridCellnav'],
1061
+ scope: false,
1062
+ link: function ($scope, $elm, $attrs, controllers) {
1063
+ var uiGridCtrl = controllers[0],
1064
+ uiGridCellnavCtrl = controllers[1];
1065
+ // Skip attaching cell-nav specific logic if the directive is not attached above us
1066
+ if (!uiGridCtrl.grid.api.cellNav) { return; }
1067
+
1068
+ if (!$scope.col.colDef.allowCellFocus) {
1069
+ return;
1070
+ }
1071
+
1072
+ // Convinience local variables
1073
+ var grid = uiGridCtrl.grid;
1074
+ $scope.focused = false;
1075
+
1076
+ // Make this cell focusable but only with javascript/a mouse click
1077
+ $elm.attr('tabindex', -1);
1078
+
1079
+ // When a cell is clicked, broadcast a cellNav event saying that this row+col combo is now focused
1080
+ $elm.find('div').on('click', function (evt) {
1081
+ uiGridCtrl.cellNav.broadcastCellNav(new GridRowColumn($scope.row, $scope.col), evt.ctrlKey || evt.metaKey, evt);
1082
+
1083
+ evt.stopPropagation();
1084
+ $scope.$apply();
1085
+ });
1086
+
1087
+
1088
+ /*
1089
+ * XXX Hack for screen readers.
1090
+ * This allows the grid to focus using only the screen reader cursor.
1091
+ * Since the focus event doesn't include key press information we can't use it
1092
+ * as our primary source of the event.
1093
+ */
1094
+ $elm.on('mousedown', preventMouseDown);
1095
+
1096
+ // turn on and off for edit events
1097
+ if (uiGridCtrl.grid.api.edit) {
1098
+ uiGridCtrl.grid.api.edit.on.beginCellEdit($scope, function () {
1099
+ $elm.off('mousedown', preventMouseDown);
1100
+ });
1101
+
1102
+ uiGridCtrl.grid.api.edit.on.afterCellEdit($scope, function () {
1103
+ $elm.on('mousedown', preventMouseDown);
1104
+ });
1105
+
1106
+ uiGridCtrl.grid.api.edit.on.cancelCellEdit($scope, function () {
1107
+ $elm.on('mousedown', preventMouseDown);
1108
+ });
1109
+ }
1110
+
1111
+ // In case we created a new row, and we are the new created row by ngRepeat
1112
+ // then this cell content might have been selected previously
1113
+ refreshCellFocus();
1114
+
1115
+ function preventMouseDown(evt) {
1116
+ // Prevents the foucus event from firing if the click event is already going to fire.
1117
+ // If both events fire it will cause bouncing behavior.
1118
+ evt.preventDefault();
1119
+ }
1120
+
1121
+ // You can only focus on elements with a tabindex value
1122
+ $elm.on('focus', function (evt) {
1123
+ uiGridCtrl.cellNav.broadcastCellNav(new GridRowColumn($scope.row, $scope.col), false, evt);
1124
+ evt.stopPropagation();
1125
+ $scope.$apply();
1126
+ });
1127
+
1128
+ // This event is fired for all cells. If the cell matches, then focus is set
1129
+ $scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, refreshCellFocus);
1130
+
1131
+ // Refresh cell focus when a new row id added to the grid
1132
+ var dataChangeDereg = uiGridCtrl.grid.registerDataChangeCallback(function (grid) {
1133
+ // Clear the focus if it's set to avoid the wrong cell getting focused during
1134
+ // a short period of time (from now until $timeout function executed)
1135
+ clearFocus();
1136
+
1137
+ $scope.$applyAsync(refreshCellFocus);
1138
+ }, [uiGridConstants.dataChange.ROW]);
1139
+
1140
+ function refreshCellFocus() {
1141
+ var isFocused = grid.cellNav.focusedCells.some(function (focusedRowCol, index) {
1142
+ return (focusedRowCol.row === $scope.row && focusedRowCol.col === $scope.col);
1143
+ });
1144
+ if (isFocused) {
1145
+ setFocused();
1146
+ } else {
1147
+ clearFocus();
1148
+ }
1149
+ }
1150
+
1151
+ function setFocused() {
1152
+ if (!$scope.focused) {
1153
+ var div = $elm.find('div');
1154
+ div.addClass('ui-grid-cell-focus');
1155
+ $elm.attr('aria-selected', true);
1156
+ uiGridCellnavCtrl.setAriaActivedescendant($elm.attr('id'));
1157
+ $scope.focused = true;
1158
+ }
1159
+ }
1160
+
1161
+ function clearFocus() {
1162
+ if ($scope.focused) {
1163
+ var div = $elm.find('div');
1164
+ div.removeClass('ui-grid-cell-focus');
1165
+ $elm.attr('aria-selected', false);
1166
+ uiGridCellnavCtrl.removeAriaActivedescendant($elm.attr('id'));
1167
+ $scope.focused = false;
1168
+ }
1169
+ }
1170
+
1171
+ $scope.$on('$destroy', function () {
1172
+ dataChangeDereg();
1173
+
1174
+ // .off withouth paramaters removes all handlers
1175
+ $elm.find('div').off();
1176
+ $elm.off();
1177
+ });
1178
+ }
1179
+ };
1180
+ }]);
1181
+ })();