@refinitiv-ui/efx-grid 6.0.119 → 6.0.121

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 (52) hide show
  1. package/README.md +1 -1
  2. package/lib/column-dragging/es6/ColumnDragging.js +7 -4
  3. package/lib/core/dist/core.js +104 -10
  4. package/lib/core/dist/core.min.js +1 -1
  5. package/lib/core/es6/data/DataView.js +7 -5
  6. package/lib/core/es6/grid/Core.js +3 -3
  7. package/lib/core/es6/grid/components/Cell.d.ts +2 -0
  8. package/lib/core/es6/grid/components/Cell.js +89 -0
  9. package/lib/core/es6/grid/components/HScrollbar.d.ts +1 -1
  10. package/lib/core/es6/grid/components/HScrollbar.js +5 -2
  11. package/lib/filter-dialog/themes/base-checkbox.less +1 -1
  12. package/lib/filter-dialog/themes/base.less +8 -3
  13. package/lib/filter-dialog/themes/elemental/dark/checkbox-list.js +1 -1
  14. package/lib/filter-dialog/themes/elemental/dark/es5/all-elements.js +2 -2
  15. package/lib/filter-dialog/themes/elemental/dark/filter-dialog.js +1 -1
  16. package/lib/filter-dialog/themes/elemental/light/checkbox-list.js +1 -1
  17. package/lib/filter-dialog/themes/elemental/light/es5/all-elements.js +2 -2
  18. package/lib/filter-dialog/themes/elemental/light/filter-dialog.js +1 -1
  19. package/lib/filter-dialog/themes/halo/dark/checkbox-list.js +1 -1
  20. package/lib/filter-dialog/themes/halo/dark/es5/all-elements.js +2 -2
  21. package/lib/filter-dialog/themes/halo/dark/filter-dialog.js +1 -1
  22. package/lib/filter-dialog/themes/halo/light/checkbox-list.js +1 -1
  23. package/lib/filter-dialog/themes/halo/light/es5/all-elements.js +2 -2
  24. package/lib/filter-dialog/themes/halo/light/filter-dialog.js +1 -1
  25. package/lib/filter-dialog/themes/solar/charcoal/checkbox-list.js +1 -1
  26. package/lib/filter-dialog/themes/solar/charcoal/es5/all-elements.js +2 -2
  27. package/lib/filter-dialog/themes/solar/charcoal/filter-dialog.js +1 -1
  28. package/lib/filter-dialog/themes/solar/pearl/checkbox-list.js +1 -1
  29. package/lib/filter-dialog/themes/solar/pearl/es5/all-elements.js +2 -2
  30. package/lib/filter-dialog/themes/solar/pearl/filter-dialog.js +1 -1
  31. package/lib/grid/index.js +1 -1
  32. package/lib/rt-grid/dist/rt-grid.js +240 -104
  33. package/lib/rt-grid/dist/rt-grid.min.js +1 -1
  34. package/lib/rt-grid/es6/ColumnDefinition.js +7 -0
  35. package/lib/rt-grid/es6/Grid.js +108 -81
  36. package/lib/rt-grid/es6/RowDefinition.d.ts +1 -1
  37. package/lib/rt-grid/es6/RowDefinition.js +28 -17
  38. package/lib/tr-grid-auto-tooltip/es6/AutoTooltip.js +18 -15
  39. package/lib/tr-grid-checkbox/es6/Checkbox.js +4 -0
  40. package/lib/tr-grid-column-grouping/es6/ColumnGrouping.js +6 -1
  41. package/lib/tr-grid-filter-input/es6/FilterInput.js +1 -0
  42. package/lib/tr-grid-row-dragging/es6/RowDragging.d.ts +0 -2
  43. package/lib/tr-grid-row-dragging/es6/RowDragging.js +82 -77
  44. package/lib/tr-grid-row-selection/es6/RowSelection.js +155 -35
  45. package/lib/types/es6/Core/grid/components/Cell.d.ts +2 -0
  46. package/lib/types/es6/Core/grid/components/HScrollbar.d.ts +1 -1
  47. package/lib/types/es6/RealtimeGrid/RowDefinition.d.ts +1 -1
  48. package/lib/types/es6/RowDragging.d.ts +0 -2
  49. package/lib/utils/index.d.ts +1 -1
  50. package/lib/utils/index.js +1 -1
  51. package/lib/versions.json +8 -8
  52. package/package.json +1 -1
@@ -12941,7 +12941,7 @@ DataTable._proto = DataTable.prototype;
12941
12941
  * @property {boolean=} hidden=true When this row is hidden
12942
12942
  * @property {boolean=} realTime=true Realtime row, able to request for JET/RTK
12943
12943
  * @property {Object=} info=null For storing any additional information to the row
12944
- * @property {string=} rowId Row identifier used for referencing the row
12944
+ * @property {string=} rowId Row identifier used for referencing the row. The value cannot be in "_x_" format.
12945
12945
  */
12946
12946
 
12947
12947
  /** @typedef {Object} RowDefinition~RowTypes
@@ -12972,6 +12972,12 @@ const ROW_TYPES = {
12972
12972
  GROUP_MEMBER: "GROUP_MEMBER"
12973
12973
  };
12974
12974
 
12975
+ /** @type {RegExp}
12976
+ * @private
12977
+ * @const
12978
+ */
12979
+ const ROW_ID_PATTERN = /^_[^_]+_$/;
12980
+
12975
12981
  /** @constructor
12976
12982
  * @param {RowDefinition~Options=} rowOptions
12977
12983
  */
@@ -13160,8 +13166,12 @@ RowDefinition.prototype.initialize = function(rowOptions) {
13160
13166
  if(!this._autoGenerated) {
13161
13167
  let userRowId = rowOptions["rowId"];
13162
13168
  if(userRowId && typeof userRowId === "string") {
13163
- this._rowId = this._dataId = userRowId;
13164
- this._userId = true;
13169
+ if(userRowId.match(ROW_ID_PATTERN)) {
13170
+ console.warn("Please change the rowId format to avoid duplicated rows' id causing unexpected behavior.");
13171
+ } else {
13172
+ this._rowId = this._dataId = userRowId;
13173
+ this._userId = true;
13174
+ }
13165
13175
  }
13166
13176
  }
13167
13177
 
@@ -13915,14 +13925,20 @@ RowDefinition.prototype.resetUpdates = function() {
13915
13925
 
13916
13926
  /** @public
13917
13927
  * @param {DataView} view
13918
- * @param {string=} rowId
13928
+ * @param {string=} destRowId Destination position where the row will be placed BEFORE the specified position.
13919
13929
  */
13920
- RowDefinition.prototype.registerToView = function(view, rowId) {
13930
+ RowDefinition.prototype.registerToView = function(view, destRowId) {
13921
13931
  if(!view || this._view === view) {
13922
13932
  return; // Already in the view
13923
13933
  }
13924
13934
  this._view = view;
13925
13935
 
13936
+ let rowId = this.getRowId();
13937
+ if(view.getRowData(rowId)) {
13938
+ console.warn("Duplicated rows' id.");
13939
+ return;
13940
+ }
13941
+
13926
13942
  let rowData = null;
13927
13943
  if(this._subSegment) {
13928
13944
  rowData = this._view.getRowData(this.getRowId());
@@ -13937,32 +13953,27 @@ RowDefinition.prototype.registerToView = function(view, rowId) {
13937
13953
 
13938
13954
  let parentRowId = "";
13939
13955
  let isSegment = this._isChain || this._asSegment;
13940
- if(rowId) {
13941
- parentRowId = view.getSegmentParentRowId(rowId);
13956
+ if(destRowId) {
13957
+ parentRowId = view.getSegmentParentRowId(destRowId);
13942
13958
  if(parentRowId) {
13943
13959
  if(isSegment) { // A chain or a segment cannot be put inside another segment
13944
- rowId = _getEndOfSegmentRowId(view, rowId);
13960
+ destRowId = _getEndOfSegmentRowId(view, destRowId);
13945
13961
  } // else { // Normal row is inserted into a segment
13946
13962
  }
13947
13963
  }
13948
13964
 
13949
13965
  let stalledSorting = _stallSorting(view, isSegment, false);
13950
-
13951
- let newRowId = view.insertRow(rowId, rowData, this.getRowId());
13952
- if(newRowId !== this._rowId) {
13953
- this._rowId = newRowId; // In case there is some duplicate row id
13954
- this._userId = false;
13955
- }
13966
+ view.insertRow(destRowId, rowData, rowId);
13956
13967
 
13957
13968
  if(isSegment) {
13958
- view.setSegmentSeparator(newRowId);
13969
+ view.setSegmentSeparator(rowId);
13959
13970
  _stallSorting(view, false, stalledSorting);
13960
13971
  if(this._collapsed != null) {
13961
- view.collapseSegment(newRowId, this._collapsed);
13972
+ view.collapseSegment(rowId, this._collapsed);
13962
13973
  this._collapsed = null;
13963
13974
  }
13964
13975
  } else if(!this._parent && parentRowId) { // Constituent cannot be added to another segment
13965
- view.addSegmentChild(parentRowId, newRowId, this._dataId);
13976
+ view.addSegmentChild(parentRowId, rowId, this._dataId);
13966
13977
  }
13967
13978
  };
13968
13979
  /** @private
@@ -15522,6 +15533,13 @@ ColumnDefinition.getDataType = function(field) {
15522
15533
  return "";
15523
15534
  };
15524
15535
  /** @public
15536
+ * @ignore
15537
+ * @return {boolean|string|null}
15538
+ */
15539
+ ColumnDefinition.prototype.getTooltipValue = function() {
15540
+ return this._tooltip;
15541
+ };
15542
+ /** @public
15525
15543
  * @return {string}
15526
15544
  */
15527
15545
  ColumnDefinition.prototype.getTooltip = function() {
@@ -18274,6 +18292,10 @@ Cell.prototype._floatingPanel = null;
18274
18292
  * @type {CellFloatingPanel}
18275
18293
  */
18276
18294
  Cell.prototype._frontIcon = null;
18295
+ /** @type {Object}
18296
+ * @private
18297
+ */
18298
+ Cell.prototype._tooltipInfo = null;
18277
18299
 
18278
18300
  //#region ElementWrapper
18279
18301
  /** {@link ElementWrapper#getContent}
@@ -18866,6 +18888,91 @@ Cell.prototype.getClientWidth = function () {
18866
18888
  Cell.prototype.getClientHeight = function () {
18867
18889
  return (this._element) ? this._element.clientHeight : this.getHeight();
18868
18890
  };
18891
+
18892
+ /** To remove the tooltip, pass str as an empty string. To allow cell calculation for the correct tooltip, set str to null.
18893
+ * @public
18894
+ * @param {string|null} str
18895
+ */
18896
+ Cell.prototype.setTooltip = function(str) {
18897
+ this.setTooltipInfo("userTooltip", str);
18898
+ this.updateTooltip();
18899
+ };
18900
+ /** @public
18901
+ * @ignore
18902
+ * @param {string} type
18903
+ * @param {*=} tooltip
18904
+ */
18905
+ Cell.prototype.setTooltipInfo = function(type, tooltip) {
18906
+ let tooltipInfo = this._tooltipInfo;
18907
+ if(!tooltipInfo) {
18908
+ tooltipInfo = this._tooltipInfo = {};
18909
+ }
18910
+
18911
+ tooltipInfo[type] = tooltip;
18912
+ };
18913
+ /** @public
18914
+ * @ignore
18915
+ */
18916
+ Cell.prototype.updateTooltip = function() {
18917
+ let tooltipInfo = this._tooltipInfo;
18918
+ if(!tooltipInfo) {
18919
+ return;
18920
+ }
18921
+
18922
+ let defaultTooltip = "";
18923
+ let customizedTooltip = null;
18924
+
18925
+ // Clipped text tooltip takes precedence over default group header and column tooltip
18926
+ if(tooltipInfo["clippedText"]) { // boolean
18927
+ defaultTooltip = customizedTooltip = tooltipInfo["clippedTextTooltip"];
18928
+ }
18929
+
18930
+ if(tooltipInfo["groupHeaderTooltip"] == null) {
18931
+ if(tooltipInfo["columnDefault"] !== false) {
18932
+ if(tooltipInfo["columnDefault"] != null) { // true, "", string
18933
+ customizedTooltip = tooltipInfo["columnTooltip"];
18934
+ } else { // null
18935
+ defaultTooltip = tooltipInfo["columnTooltip"];
18936
+ }
18937
+ }
18938
+ } else { // Group header tooltip takes precedence over column tooltip
18939
+ if(tooltipInfo["groupHeaderDefault"] !== false) {
18940
+ if(tooltipInfo["groupHeaderDefault"] != null) {
18941
+ customizedTooltip = tooltipInfo["groupHeaderTooltip"];
18942
+ } else {
18943
+ defaultTooltip = tooltipInfo["groupHeaderTooltip"];
18944
+ }
18945
+ }
18946
+ }
18947
+
18948
+ // User tooltip take the highest precedence
18949
+ if(tooltipInfo["userTooltip"] != null) { // "", string
18950
+ customizedTooltip = tooltipInfo["userTooltip"];
18951
+ }
18952
+
18953
+ if(customizedTooltip == null) {
18954
+ customizedTooltip = defaultTooltip;
18955
+ }
18956
+
18957
+ if(customizedTooltip) {
18958
+ if(this.getAttribute("title") !== customizedTooltip) {
18959
+ this.setAttribute("title", customizedTooltip);
18960
+ }
18961
+ } else if(this.getAttribute("title") != null) {
18962
+ this.removeAttribute("title");
18963
+ }
18964
+ };
18965
+ /** @public
18966
+ * @ignore
18967
+ * @param {string} type
18968
+ * @return {*}
18969
+ */
18970
+ Cell.prototype.getTooltipInfo = function(type) {
18971
+ if(this._tooltipInfo) {
18972
+ return this._tooltipInfo[type];
18973
+ }
18974
+ return null;
18975
+ };
18869
18976
  //#region Internal Public Methods
18870
18977
 
18871
18978
  //#region Private Methods
@@ -32017,7 +32124,7 @@ DataView.prototype._updateRowIds = function(opt_rowIds) {
32017
32124
 
32018
32125
  this._excludedRids = {};
32019
32126
  let exclusionCount = 0;
32020
- exclusionCount += DataView._copyObjectKeys(this._excludedRids, this._hiddenRids);
32127
+ exclusionCount += DataView._copyValidObjectKeys(this._excludedRids, this._hiddenRids);
32021
32128
 
32022
32129
  // Segment separators should not be filtered out (hidden)
32023
32130
  let segments = this._dt._getSegmentSeparators();
@@ -32037,7 +32144,7 @@ DataView.prototype._updateRowIds = function(opt_rowIds) {
32037
32144
  }
32038
32145
  this._collapsedRids = segments.getCollapsedRows();
32039
32146
  // Children of collapsed segments must be filtered out (hidden)
32040
- exclusionCount += DataView._copyObjectKeys(this._excludedRids, this._collapsedRids);
32147
+ exclusionCount += DataView._copyValidObjectKeys(this._excludedRids, this._collapsedRids);
32041
32148
  }
32042
32149
 
32043
32150
  if(this._groupLevel > 0 && !opt_rowIds) { // WARNING: The line below is quite slow
@@ -32567,13 +32674,15 @@ DataView._removeArrayItems = function(ary, items) {
32567
32674
  * @param {Object} masterObj
32568
32675
  * @returns {number}
32569
32676
  */
32570
- DataView._copyObjectKeys = function(baseObj, masterObj) {
32677
+ DataView._copyValidObjectKeys = function(baseObj, masterObj) {
32571
32678
  if(masterObj) {
32572
32679
  let count = 0;
32573
32680
 
32574
32681
  for(let key in masterObj) {
32575
- baseObj[key] = 1;
32576
- ++count; // WARNING: duplicated key can be counted more than once
32682
+ if(masterObj[key]) {
32683
+ baseObj[key] = 1;
32684
+ ++count; // WARNING: duplicated key can be counted more than once
32685
+ }
32577
32686
  }
32578
32687
  return count;
32579
32688
  }
@@ -36467,7 +36576,7 @@ Core.prototype._hasPendingRowChange = false;
36467
36576
  * @return {string}
36468
36577
  */
36469
36578
  Core.getVersion = function () {
36470
- return "5.1.117";
36579
+ return "5.1.121";
36471
36580
  };
36472
36581
  /** {@link ElementWrapper#dispose}
36473
36582
  * @override
@@ -45043,11 +45152,11 @@ let _hasFieldOrId = function(colDef, str) {
45043
45152
  };
45044
45153
 
45045
45154
  /** Compare the difference in the 'id' property.
45046
- * @private
45047
- * @param {Object} obj1
45048
- * @param {Object} obj2
45049
- * @returns {boolean} If the id property of two objects is equal, the return will be true, otherwise it will be false.
45050
- */
45155
+ * @private
45156
+ * @param {Object} obj1
45157
+ * @param {Object} obj2
45158
+ * @returns {boolean} If the id property of two objects is equal, the return will be true, otherwise it will be false.
45159
+ */
45051
45160
  let _hasMatchingId = function(obj1, obj2) {
45052
45161
  if(!obj1 || !obj2 || !obj1.id || !obj2.id) { // Handle nullable, if the object or id have null, it's means difference value
45053
45162
  return false;
@@ -45055,6 +45164,25 @@ let _hasMatchingId = function(obj1, obj2) {
45055
45164
  return obj1.id === obj2.id;
45056
45165
  };
45057
45166
 
45167
+ /** @private
45168
+ * @param {Object} e
45169
+ */
45170
+ let _preventDefault = function(e) {
45171
+ if(e) {
45172
+ e.preventDefault();
45173
+ }
45174
+ };
45175
+ /** @private
45176
+ * @param {number=} id
45177
+ * @returns {number} Always return 0
45178
+ */
45179
+ let _clearTimeout = function(id) {
45180
+ if(id) {
45181
+ clearTimeout(id);
45182
+ }
45183
+ return 0;
45184
+ };
45185
+
45058
45186
  /** @constructor
45059
45187
  * @extends {EventDispatcher}
45060
45188
  * @param {(Element|null)=} placeholder
@@ -45365,10 +45493,6 @@ Grid.prototype._topSection = true;
45365
45493
  * @private
45366
45494
  */
45367
45495
  Grid.prototype._focusingArgs = null;
45368
- /** @type {number}
45369
- * @private
45370
- */
45371
- Grid.prototype._scrolledRow = -1;
45372
45496
  /** @type {boolean}
45373
45497
  * @private
45374
45498
  */
@@ -45383,10 +45507,8 @@ Grid.prototype.dispose = function() {
45383
45507
  clearInterval(this._autoLayoutTimer);
45384
45508
  this._autoLayoutTimer = 0;
45385
45509
  }
45386
- if(this._pollingTimerId) {
45387
- clearTimeout(this._pollingTimerId);
45388
- this._pollingTimerId = 0;
45389
- }
45510
+ this._pollingTimerId = _clearTimeout(this._pollingTimerId);
45511
+
45390
45512
  this.removeAllColumns(); // Some conflators are reset
45391
45513
  this.removeAllRows(); // Some conflators are reset
45392
45514
  this._sorter.dispose();
@@ -45409,9 +45531,8 @@ Grid.prototype.dispose = function() {
45409
45531
  }
45410
45532
 
45411
45533
  if(this._focusingArgs) {
45412
- if(this._focusingArgs.id) {
45413
- clearTimeout(this._focusingArgs.id);
45414
- }
45534
+ _clearTimeout(this._focusingArgs.id);
45535
+ _clearTimeout(this._focusingArgs.timeoutId);
45415
45536
  this._focusingArgs = null;
45416
45537
  }
45417
45538
  };
@@ -45716,6 +45837,7 @@ Grid.prototype.initialize = function(gridOption) {
45716
45837
  this.addListener(gridOption, "beforeContentBinding");
45717
45838
  this.addListener(gridOption, "firstRendered");
45718
45839
  this.addListener(gridOption, "afterContentBinding");
45840
+ this.addListener(gridOption, "tabNavigation");
45719
45841
 
45720
45842
  if(gridOption["autoDateConversion"]) {
45721
45843
  t._autoDateConversion = true;
@@ -48232,12 +48354,15 @@ Grid.prototype._renderColumnHeader = function(colIndex, arg) {
48232
48354
  let colName = colDef.getName();
48233
48355
  let colTooltip = colDef.getTooltip();
48234
48356
  let headerAlignment = colDef.getHeaderAlignment();
48357
+ let tooltipValue = colDef.getTooltipValue();
48235
48358
 
48236
48359
  for(let r = 0; r < rowCount; ++r) {
48237
48360
  let tCell = tSection.getCell(colIndex, r, false);
48238
48361
  // Default behaviors
48239
48362
  tCell.setContent(colName);
48240
- tCell.setTooltip(colTooltip);
48363
+ tCell.setTooltipInfo("columnDefault", tooltipValue);
48364
+ tCell.setTooltipInfo("columnTooltip", colTooltip);
48365
+ tCell.updateTooltip();
48241
48366
  tCell.setStyle("textAlign", headerAlignment);
48242
48367
 
48243
48368
  if(customRenderer) {
@@ -48865,6 +48990,8 @@ Grid.prototype._logData = function(rowDefs, options) {
48865
48990
 
48866
48991
  /** @public
48867
48992
  * @description Replace existing row by a new row. Row Id is always changed, after the row is replaced.
48993
+ * If the rowId of the new row is identical to that of the replacing row. Grid will do nothing because
48994
+ * similar rowIds indicate that they are the same row.
48868
48995
  * @param {Grid~RowReference} rowRef Reference (i.e. row index, row id, or row definition) of the insert position
48869
48996
  * @param {(RowDefinition~Options|string)=} rowOption
48870
48997
  * @returns {RowDefinition} Returns null, if the row is not replaced. Otherwise, a newly created row is returned
@@ -48985,38 +49112,49 @@ Grid.prototype.getVScrollView = function () {
48985
49112
  return this._grid.getVScrollView();
48986
49113
  };
48987
49114
 
48988
- /** @private
48989
- * @param {Element} el
48990
- * @return {boolean}
48991
- */
48992
- function isFocusableContent(el) {
48993
- if(el) {
48994
- return (el.tagName !== "SPAN" && !el.disabled);
48995
- }
48996
- return false;
48997
- }
48998
49115
  /** @private
48999
49116
  * @param {Object} cell
49117
+ * @param {Object} args
49000
49118
  * @return {boolean}
49001
49119
  */
49002
- function focusCell(cell) {
49120
+ Grid.prototype._focusCell = function(cell, args) {
49003
49121
  if(cell) {
49004
49122
  let cellContent = cell.getContent();
49005
- if(cellContent && isFocusableContent(cellContent)) {
49006
- cellContent.focus();
49007
- return true;
49123
+ if(cellContent) {
49124
+ let nfe = null;
49125
+ if(this.hasListener("tabNavigation")) {
49126
+ let tabNavArg = {
49127
+ "shiftKey": args.shiftKey,
49128
+ "activeElement": args.activeElement,
49129
+ "cellContent": cellContent,
49130
+ "cell": cell,
49131
+ "colIndex": args.colIndex,
49132
+ "rowIndex": args.rowIndex,
49133
+ "field": args.fields ? args.fields[args.colIndex] : ""
49134
+ };
49135
+ this._dispatch("tabNavigation", tabNavArg);
49136
+ nfe = tabNavArg.nextFocusableElement;
49137
+ } else if(cellContent.tagName !== "SPAN") {
49138
+ nfe = cellContent;
49139
+ }
49140
+
49141
+ if(nfe && nfe !== args.activeElement && !nfe.disabled) {
49142
+ nfe.focus();
49143
+ return true;
49144
+ }
49008
49145
  }
49009
49146
  }
49010
49147
  return false;
49011
- }
49148
+ };
49012
49149
  /** @private
49013
49150
  */
49014
49151
  Grid.prototype._onVScroll = function() {
49015
49152
  let args = this._focusingArgs;
49016
49153
  if(args) {
49154
+ args.timeoutId = _clearTimeout(args.timeoutId);
49017
49155
  this._focusingArgs = null;
49018
49156
  let cell = this._grid.getCell("content", args.colIndex, args.rowIndex);
49019
- if(!focusCell(cell)) {
49157
+ if(!this._focusCell(cell, args)) {
49020
49158
  if(args.shiftKey) {
49021
49159
  this._focusPrevCellContent(args);
49022
49160
  } else {
@@ -49027,6 +49165,11 @@ Grid.prototype._onVScroll = function() {
49027
49165
  };
49028
49166
  /** @private
49029
49167
  */
49168
+ Grid.prototype._onScrollTimeout = function() {
49169
+ this._focusingArgs = null;
49170
+ };
49171
+ /** @private
49172
+ */
49030
49173
  Grid.prototype._selfScrollToRow = function() {
49031
49174
  let args = this._focusingArgs;
49032
49175
  if(args) {
@@ -49036,20 +49179,14 @@ Grid.prototype._selfScrollToRow = function() {
49036
49179
  };
49037
49180
  /** @private
49038
49181
  * @param {Object} args
49039
- * @param {number} colIndex
49040
- * @param {number} rowIndex
49041
49182
  */
49042
- Grid.prototype._requestScroll = function(args, colIndex, rowIndex) {
49043
- if(this._focusingArgs || this._scrolledRow === args.rowIndex) {
49044
- return; // Avoid infinite loop
49183
+ Grid.prototype._requestScroll = function(args) {
49184
+ if(!this._focusingArgs) {
49185
+ this._focusingArgs = args;
49186
+ args.event = null; // The event is invalid after the scroll
49187
+ args.id = setTimeout(this._selfScrollToRow, 0); // Avoid event loop protection
49188
+ args.timeoutId = setTimeout(this._onScrollTimeout, 100); // To avoid a fail case where scroll cannot be performed
49045
49189
  }
49046
-
49047
- this._scrolledRow = args.rowIndex;
49048
- this._focusingArgs = args;
49049
- args.colIndex = colIndex;
49050
- args.rowIndex = rowIndex;
49051
- args.event = null; // The event is invalid after the scroll
49052
- args.id = setTimeout(this._selfScrollToRow); // Avoid event loop protection
49053
49190
  };
49054
49191
  /** @private
49055
49192
  * @param {Object} args
@@ -49073,28 +49210,27 @@ Grid.prototype._focusNextCellContent = function(args) {
49073
49210
  startIdx = i;
49074
49211
  }
49075
49212
  }
49076
- // If the current focus is on a valid content, starts on the next cell
49077
- if(args.event && args.validContent) {
49078
- startIdx++;
49079
- }
49080
49213
 
49081
49214
  let grid = this._grid;
49082
49215
  let section = grid.getSection("content");
49083
49216
  let viewInfo = grid.getVerticalViewInfo();
49084
49217
  let lastFullRow = viewInfo.lastFullRow;
49085
49218
  let rowCount = this.getRowCount();
49219
+
49220
+ args.fields = grid.getColumnFields();
49086
49221
  for(let r = rowIndex; r < rowCount; r++) {
49222
+ args.rowIndex = r;
49087
49223
  for(i = startIdx; i < len; i++) {
49088
49224
  let c = focusableColIndices[i];
49225
+ args.colIndex = c;
49089
49226
  if(r > lastFullRow) {
49090
- this._requestScroll(args, c, r);
49227
+ _preventDefault(args.event);
49228
+ this._requestScroll(args);
49091
49229
  return;
49092
49230
  } else {
49093
49231
  let cell = section.getCell(c, r);
49094
- if(focusCell(cell)) {
49095
- if(args.event) {
49096
- args.event.preventDefault();
49097
- }
49232
+ if(this._focusCell(cell, args)) {
49233
+ _preventDefault(args.event);
49098
49234
  return;
49099
49235
  }
49100
49236
  }
@@ -49102,9 +49238,8 @@ Grid.prototype._focusNextCellContent = function(args) {
49102
49238
  startIdx = 0;
49103
49239
  }
49104
49240
 
49105
- if(args.validContent) { // The current focus on the last focusable content
49106
- this._grid.getHiddenInput().focus();
49107
- }
49241
+ // The current focus on the last focusable content
49242
+ this._grid.getHiddenInput().focus();
49108
49243
  };
49109
49244
  /** @private
49110
49245
  * @param {Object} args
@@ -49128,27 +49263,26 @@ Grid.prototype._focusPrevCellContent = function(args) {
49128
49263
  startIdx = i;
49129
49264
  }
49130
49265
  }
49131
- // If the current focus is on a valid content, starts on the next cell
49132
- if(args.event && args.validContent) {
49133
- --startIdx;
49134
- }
49135
49266
 
49136
49267
  let grid = this._grid;
49137
49268
  let section = grid.getSection("content");
49138
49269
  let viewInfo = grid.getVerticalViewInfo();
49139
49270
  let firstFullRow = viewInfo.firstFullRow;
49271
+
49272
+ args.fields = this.getColumnFields();
49140
49273
  for(let r = rowIndex; r >= 0; r--) {
49274
+ args.rowIndex = r;
49141
49275
  for(i = startIdx; i >= 0; i--) {
49142
49276
  let c = focusableColIndices[i];
49277
+ args.colIndex = c;
49143
49278
  if(r < firstFullRow) {
49144
- this._requestScroll(args, c, r);
49279
+ _preventDefault(args.event);
49280
+ this._requestScroll(args);
49145
49281
  return;
49146
49282
  } else {
49147
49283
  let cell = section.getCell(c, r);
49148
- if(focusCell(cell)) {
49149
- if(args.event) {
49150
- args.event.preventDefault();
49151
- }
49284
+ if(this._focusCell(cell, args)) {
49285
+ _preventDefault(args.event);
49152
49286
  return;
49153
49287
  }
49154
49288
  }
@@ -49156,15 +49290,18 @@ Grid.prototype._focusPrevCellContent = function(args) {
49156
49290
  startIdx = len - 1;
49157
49291
  }
49158
49292
 
49159
- if(args.validContent) { // The current focus on the last focusable content
49160
- this._grid.getHiddenInput(true).focus();
49161
- }
49293
+ // The current focus on the last focusable content
49294
+ this._grid.getHiddenInput(true).focus();
49162
49295
  };
49163
49296
 
49164
49297
  /** @private
49165
49298
  * @param {Object} e
49166
49299
  */
49167
49300
  Grid.prototype._onTabNavigation = function(e) {
49301
+ if(this._focusingArgs) {
49302
+ return; // Cannot do another tab navigation while waiting for scrolling
49303
+ }
49304
+
49168
49305
  let colDefs = this.getColumnDefinitions();
49169
49306
  let colCount = colDefs.length;
49170
49307
 
@@ -49179,19 +49316,8 @@ Grid.prototype._onTabNavigation = function(e) {
49179
49316
  return;
49180
49317
  }
49181
49318
 
49182
- this._scrolledRow = -1; // Reset the scroll loop protector
49183
49319
  let keyEvt = e.event;
49184
49320
  let pos = this.getRelativePosition(keyEvt);
49185
- let validContent = true;
49186
- let activeElement = e.activeElement;
49187
- if(activeElement) {
49188
- validContent = !activeElement.classList.contains("valigner");
49189
- }
49190
-
49191
- if(validContent) {
49192
- let content = pos["cell"] ? pos["cell"].getContent() : null;
49193
- validContent = isFocusableContent(content);
49194
- }
49195
49321
  let startingRowIndex = pos["rowIndex"];
49196
49322
  if(e.onTheEdge) {
49197
49323
  let viewInfo = this._grid.getVerticalViewInfo();
@@ -49203,7 +49329,7 @@ Grid.prototype._onTabNavigation = function(e) {
49203
49329
  colIndex: pos["colIndex"],
49204
49330
  rowIndex: startingRowIndex,
49205
49331
  focusableColIndices: focusableColIndices,
49206
- validContent: validContent
49332
+ activeElement: e.activeElement
49207
49333
  };
49208
49334
 
49209
49335
  if(keyEvt.shiftKey) {
@@ -49213,6 +49339,16 @@ Grid.prototype._onTabNavigation = function(e) {
49213
49339
  }
49214
49340
  };
49215
49341
 
49342
+ /** @public
49343
+ * @ignore
49344
+ * @return {!Object}
49345
+ */
49346
+ Grid.prototype._getEventHandlers = function() {
49347
+ return {
49348
+ "tabNavigation": this._onTabNavigation
49349
+ };
49350
+ };
49351
+
49216
49352
 
49217
49353
  /* harmony default export */ var js_Grid = (Grid);
49218
49354