@refinitiv-ui/efx-grid 6.0.99 → 6.0.100

Sign up to get free protection for your applications and to get access to all the features.
@@ -327,6 +327,8 @@ declare class Core extends ElementWrapper {
327
327
 
328
328
  public scrollToRow(sectionRef: Core.SectionReference|null, rowIndex: number, topOfView?: boolean|null): void;
329
329
 
330
+ public getVerticalViewInfo(): any;
331
+
330
332
  public getVScrollView(): any;
331
333
 
332
334
  public getScrollTop(): number;
@@ -574,7 +574,7 @@ Core.prototype._hasPendingRowChange = false;
574
574
  * @return {string}
575
575
  */
576
576
  Core.getVersion = function () {
577
- return "5.1.102";
577
+ return "5.1.103";
578
578
  };
579
579
  /** {@link ElementWrapper#dispose}
580
580
  * @override
@@ -3583,33 +3583,24 @@ Core.prototype.getYScrollVal = function (sectionRef, rowIndex, topOfView) {
3583
3583
  }
3584
3584
 
3585
3585
  let rowCount = this._layoutY.getLaneCount();
3586
- let rowIndexOffset = (section) ? section.getRowOffset() : this._sectionStarts[this._startVScrollbarIndex];
3587
-
3588
- if(rowIndexOffset) {
3589
- rowIndex += rowIndexOffset;
3590
- }
3591
3586
  if (rowIndex <= 0) { rowIndex = 0; }
3592
3587
  else if (rowIndex >= rowCount) { rowIndex = rowCount - 1; }
3593
3588
 
3594
- let heightOffset = this._layoutY.getLaneStart(rowIndexOffset);
3595
- let scrollTop = this._vscrollbar.getScrollTop();
3596
- let viewTop = scrollTop + heightOffset;
3597
- let viewTopIndex = section ? section.getFirstIndexInView() : this._layoutY.hitTest(viewTop); // TODO: Make it work in zooming mode
3589
+ let viewInfo = this.getVerticalViewInfo();
3590
+ let viewTopIndex = viewInfo.topRowIndex; // TODO: Make it work in zooming mode
3598
3591
 
3599
3592
  let scrollIndex = -1;
3600
3593
  if (topOfView) {
3601
3594
  scrollIndex = rowIndex;
3602
3595
  } else {
3603
- if(rowIndex <= viewTopIndex) { // Scroll up
3596
+ if(rowIndex < viewTopIndex) { // Scroll up
3604
3597
  scrollIndex = rowIndex - 3; // Have some spaces at the top for more appealing visual
3605
3598
  if(scrollIndex < 0) {
3606
3599
  scrollIndex = 0;
3607
3600
  }
3608
3601
  } else { // Scroll down
3609
- let viewHeight = this._vscrollbar.getHeight();
3610
- let viewBottom = viewTop + viewHeight;
3611
- let viewBottomIndex = section ? section.getLastIndexInView() : this._layoutY.hitTest(viewBottom - 0.1);
3612
- if (rowIndex >= viewBottomIndex) {
3602
+ let viewBottomIndex = viewInfo.bottomRowIndex;
3603
+ if (rowIndex > viewBottomIndex) {
3613
3604
  let viewIndexSize = viewBottomIndex - viewTopIndex;
3614
3605
  scrollIndex = rowIndex - viewIndexSize + 3;
3615
3606
  if(scrollIndex < 0) {
@@ -3619,7 +3610,9 @@ Core.prototype.getYScrollVal = function (sectionRef, rowIndex, topOfView) {
3619
3610
  }
3620
3611
  }
3621
3612
 
3622
- return (scrollIndex >= 0) ? (this._layoutY.getLaneStart(scrollIndex) - heightOffset) : null;
3613
+ let rowIndexOffset = (section) ? section.getRowOffset() : this._sectionStarts[this._startVScrollbarIndex];
3614
+ let heightOffset = this._layoutY.getLaneStart(this._startVScrollbarIndex);
3615
+ return (scrollIndex >= 0) ? (this._layoutY.getLaneStart(scrollIndex + rowIndexOffset) - heightOffset) : null;
3623
3616
  };
3624
3617
  /** Scroll up or down to make specified row visible in the view
3625
3618
  * @public
@@ -3634,6 +3627,21 @@ Core.prototype.scrollToRow = function (sectionRef, rowIndex, topOfView) {
3634
3627
  }
3635
3628
  };
3636
3629
  /** @public
3630
+ * @return {Object}
3631
+ */
3632
+ Core.prototype.getVerticalViewInfo = function() {
3633
+ let rowIndexOffset = this._sectionStarts[this._startVScrollbarIndex];
3634
+ let heightOffset = this._layoutY.getLaneStart(rowIndexOffset);
3635
+ let viewHeight = this._vscrollbar.getHeight();
3636
+ let viewTop = this._vscrollbar.getScrollTop() + heightOffset;
3637
+ let viewBottom = viewTop + viewHeight;
3638
+
3639
+ return {
3640
+ topRowIndex: this._layoutY.hitTest(viewTop) - rowIndexOffset,
3641
+ bottomRowIndex: this._layoutY.hitTest(viewBottom - 0.1) - rowIndexOffset
3642
+ };
3643
+ };
3644
+ /** @public
3637
3645
  * @return {Object} Returns null if vscrollbar does not exists
3638
3646
  */
3639
3647
  Core.prototype.getVScrollView = function () {
package/lib/grid/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import {Grid} from "./lib/efx-grid.js";
2
2
  export {Grid}
3
- window.EFX_GRID = { version: "6.0.99" };
3
+ window.EFX_GRID = { version: "6.0.100" };
@@ -15285,6 +15285,7 @@ PredefinedFormula.remove = function(field) {
15285
15285
  * @property {boolean=} leftPinned=false If enabled, the column will not be part of the scrollable area and is pinned to the left side
15286
15286
  * @property {boolean=} rightPinned=false If enabled, the column will not be part of the scrollable area and is pinned to the right side
15287
15287
  * @property {Object=} info=null For storing any additional information to the column
15288
+ * @property {boolean} focusable=false If enabled, the column will be used to find focusable element when pressing tab key
15288
15289
  */
15289
15290
 
15290
15291
  /** mapping of field type to javascript type
@@ -15493,6 +15494,10 @@ ColumnDefinition.prototype._info = null;
15493
15494
  * @private
15494
15495
  */
15495
15496
  ColumnDefinition.prototype._coreColDef = null;
15497
+ /** @type {boolean}
15498
+ * @private
15499
+ */
15500
+ ColumnDefinition.prototype._focusable = false;
15496
15501
  //#endregion Private Members
15497
15502
 
15498
15503
 
@@ -15637,6 +15642,11 @@ ColumnDefinition.prototype.initialize = function(columnOption) {
15637
15642
  this._sortable = val ? true : false;
15638
15643
  }
15639
15644
 
15645
+ val = columnOption["focusable"];
15646
+ if(val != null) {
15647
+ this._focusable = val ? true : false;
15648
+ }
15649
+
15640
15650
  val = columnOption["className"] || columnOption["class"];
15641
15651
  if(typeof val === "string") {
15642
15652
  this._classes = val.split(" ");
@@ -16020,6 +16030,10 @@ ColumnDefinition.prototype.getConfigObject = function(colOptions) {
16020
16030
  obj["autoGenerated"] = this._autoGenerated;
16021
16031
  }
16022
16032
 
16033
+ if(this._focusable) {
16034
+ obj["focusable"] = true;
16035
+ }
16036
+
16023
16037
  let core = this._eventArg["core"];
16024
16038
  let grid = this._eventArg["grid"];
16025
16039
  let colIndex = grid.getColumnIndex(this);
@@ -16384,6 +16398,12 @@ ColumnDefinition.prototype._setCoreColumnDef = function(obj) {
16384
16398
  this._coreColDef = obj || null;
16385
16399
  };
16386
16400
 
16401
+ /** @public
16402
+ * @return {boolean}
16403
+ */
16404
+ ColumnDefinition.prototype.isFocusable = function() {
16405
+ return this._focusable;
16406
+ };
16387
16407
 
16388
16408
 
16389
16409
  /* harmony default export */ var js_ColumnDefinition = (ColumnDefinition);
@@ -31562,8 +31582,9 @@ DataView.prototype.stallSorting = function(bool) {
31562
31582
  this._dispatchDataChange(data_DataTable._positionChangeArg);
31563
31583
  }
31564
31584
  }
31585
+ return true;
31565
31586
  }
31566
- return true;
31587
+ return false;
31567
31588
  };
31568
31589
 
31569
31590
  /** Automatically and asyncronuosly remove group that has no member or no content. Predefined groups will not be removed in this way.
@@ -34431,12 +34452,12 @@ Virtualizer.prototype.setViewOffset = function (px) {
34431
34452
  };
34432
34453
  /** @public
34433
34454
  * @ignore
34434
- * @param {number} start
34435
- * @param {number} end
34455
+ * @param {number} startItemCount
34456
+ * @param {number} endItemCount
34436
34457
  */
34437
- Virtualizer.prototype.setViewBounds = function (start, end) {
34438
- this._startOffsetCount = start > 0 ? start : 0;
34439
- this._endOffsetCount = end > 0 ? end : 0;
34458
+ Virtualizer.prototype.setViewBounds = function (startItemCount, endItemCount) {
34459
+ this._startOffsetCount = startItemCount > 0 ? startItemCount : 0;
34460
+ this._endOffsetCount = endItemCount > 0 ? endItemCount : 0;
34440
34461
  this.validateVirtualization(); // Everytime row height is changed
34441
34462
  };
34442
34463
  /** @public
@@ -36517,7 +36538,7 @@ Core.prototype._hasPendingRowChange = false;
36517
36538
  * @return {string}
36518
36539
  */
36519
36540
  Core.getVersion = function () {
36520
- return "5.1.98";
36541
+ return "5.1.103";
36521
36542
  };
36522
36543
  /** {@link ElementWrapper#dispose}
36523
36544
  * @override
@@ -37718,6 +37739,16 @@ Core.prototype._moveColumn = function (fromCol, destCol) {
37718
37739
  }
37719
37740
  }
37720
37741
 
37742
+ // The deactivated column may be moved directly or indirectly to the current view. It's necessary to make all columns in view activated.
37743
+ if(!this._frozenLayout) {
37744
+ if(this._colVirtualizer.isEnabled()) {
37745
+ let vBegin = this._colVirtualizer.getFirstIndexInView();
37746
+ if(!((fromCol < vBegin && destCol < vBegin) || (fromCol > vEnd && destCol > vEnd))) { // Columns does not move between hidden columns
37747
+ this._activateColumns(vBegin, vEnd, vBegin, vEnd); // To confirm that all columns in view are activated
37748
+ }
37749
+ }
37750
+ }
37751
+
37721
37752
  // no need to invoke because moving column does not change column-width
37722
37753
  // this._syncLayoutToColumns(minColumn, this.getColumnCount());
37723
37754
 
@@ -39516,33 +39547,24 @@ Core.prototype.getYScrollVal = function (sectionRef, rowIndex, topOfView) {
39516
39547
  }
39517
39548
 
39518
39549
  let rowCount = this._layoutY.getLaneCount();
39519
- let rowIndexOffset = (section) ? section.getRowOffset() : this._sectionStarts[this._startVScrollbarIndex];
39520
-
39521
- if(rowIndexOffset) {
39522
- rowIndex += rowIndexOffset;
39523
- }
39524
39550
  if (rowIndex <= 0) { rowIndex = 0; }
39525
39551
  else if (rowIndex >= rowCount) { rowIndex = rowCount - 1; }
39526
39552
 
39527
- let heightOffset = this._layoutY.getLaneStart(rowIndexOffset);
39528
- let scrollTop = this._vscrollbar.getScrollTop();
39529
- let viewTop = scrollTop + heightOffset;
39530
- let viewTopIndex = section ? section.getFirstIndexInView() : this._layoutY.hitTest(viewTop); // TODO: Make it work in zooming mode
39553
+ let viewInfo = this.getVerticalViewInfo();
39554
+ let viewTopIndex = viewInfo.topRowIndex; // TODO: Make it work in zooming mode
39531
39555
 
39532
39556
  let scrollIndex = -1;
39533
39557
  if (topOfView) {
39534
39558
  scrollIndex = rowIndex;
39535
39559
  } else {
39536
- if(rowIndex <= viewTopIndex) { // Scroll up
39560
+ if(rowIndex < viewTopIndex) { // Scroll up
39537
39561
  scrollIndex = rowIndex - 3; // Have some spaces at the top for more appealing visual
39538
39562
  if(scrollIndex < 0) {
39539
39563
  scrollIndex = 0;
39540
39564
  }
39541
39565
  } else { // Scroll down
39542
- let viewHeight = this._vscrollbar.getHeight();
39543
- let viewBottom = viewTop + viewHeight;
39544
- let viewBottomIndex = section ? section.getLastIndexInView() : this._layoutY.hitTest(viewBottom - 0.1);
39545
- if (rowIndex >= viewBottomIndex) {
39566
+ let viewBottomIndex = viewInfo.bottomRowIndex;
39567
+ if (rowIndex > viewBottomIndex) {
39546
39568
  let viewIndexSize = viewBottomIndex - viewTopIndex;
39547
39569
  scrollIndex = rowIndex - viewIndexSize + 3;
39548
39570
  if(scrollIndex < 0) {
@@ -39552,7 +39574,9 @@ Core.prototype.getYScrollVal = function (sectionRef, rowIndex, topOfView) {
39552
39574
  }
39553
39575
  }
39554
39576
 
39555
- return (scrollIndex >= 0) ? (this._layoutY.getLaneStart(scrollIndex) - heightOffset) : null;
39577
+ let rowIndexOffset = (section) ? section.getRowOffset() : this._sectionStarts[this._startVScrollbarIndex];
39578
+ let heightOffset = this._layoutY.getLaneStart(this._startVScrollbarIndex);
39579
+ return (scrollIndex >= 0) ? (this._layoutY.getLaneStart(scrollIndex + rowIndexOffset) - heightOffset) : null;
39556
39580
  };
39557
39581
  /** Scroll up or down to make specified row visible in the view
39558
39582
  * @public
@@ -39567,6 +39591,21 @@ Core.prototype.scrollToRow = function (sectionRef, rowIndex, topOfView) {
39567
39591
  }
39568
39592
  };
39569
39593
  /** @public
39594
+ * @return {Object}
39595
+ */
39596
+ Core.prototype.getVerticalViewInfo = function() {
39597
+ let rowIndexOffset = this._sectionStarts[this._startVScrollbarIndex];
39598
+ let heightOffset = this._layoutY.getLaneStart(rowIndexOffset);
39599
+ let viewHeight = this._vscrollbar.getHeight();
39600
+ let viewTop = this._vscrollbar.getScrollTop() + heightOffset;
39601
+ let viewBottom = viewTop + viewHeight;
39602
+
39603
+ return {
39604
+ topRowIndex: this._layoutY.hitTest(viewTop) - rowIndexOffset,
39605
+ bottomRowIndex: this._layoutY.hitTest(viewBottom - 0.1) - rowIndexOffset
39606
+ };
39607
+ };
39608
+ /** @public
39570
39609
  * @return {Object} Returns null if vscrollbar does not exists
39571
39610
  */
39572
39611
  Core.prototype.getVScrollView = function () {
@@ -41664,7 +41703,15 @@ Core.prototype._updateScrollbarHeight = function (paneChanged, contentChanged, n
41664
41703
  // HACK: Due to fixed layout size we need to scale view size instead of content size, when zooming
41665
41704
  // TODO: Check if zoom factor is used for virtualization correctly
41666
41705
  this._rowVirtualizer.setViewSize(viewSize / this._zoomFactor);
41667
- this._rowVirtualizer.setViewBounds(this._startVScrollbarIndex, this.getFooterCount());
41706
+
41707
+ let offsetRowCount = this._sectionStarts[this._startVScrollbarIndex];
41708
+ let footerCount = this.getFooterCount();
41709
+ let footerRowCount = 0;
41710
+ if(footerCount) {
41711
+ let sectionCount = this.getSectionCount();
41712
+ footerRowCount = this._sectionStarts[sectionCount] - this._sectionStarts[sectionCount - footerCount];
41713
+ }
41714
+ this._rowVirtualizer.setViewBounds(offsetRowCount, footerRowCount);
41668
41715
  } else {
41669
41716
  this._rowVirtualizer.validateVirtualization(); // Content height may be changed
41670
41717
  }
@@ -43952,6 +43999,17 @@ SortableTitlePlugin.prototype._getPlugin = function(pluginName) {
43952
43999
  let host = this._hosts[0];
43953
44000
  return (host) ? host.getPlugin(pluginName) : null;
43954
44001
  };
44002
+
44003
+ /** @public
44004
+ * @description Click title to sort with mouse event. This is for testing purpose.
44005
+ * @ignore
44006
+ * @param {Core} grid
44007
+ * @param {Object=} mouseEvt
44008
+ */
44009
+ SortableTitlePlugin.prototype.clickTitleByMouse = function (grid, mouseEvt) {
44010
+ this._onClickTitle(grid, mouseEvt);
44011
+ };
44012
+
43955
44013
  /** @private
43956
44014
  * @param {Core} grid
43957
44015
  * @param {MouseEvent} e
@@ -45003,6 +45061,11 @@ let Grid = function(placeholder, config) {
45003
45061
  t._snapshotFillerDataChanged = t._snapshotFillerDataChanged.bind(t);
45004
45062
  t._onPollingInterval = t._onPollingInterval.bind(t);
45005
45063
 
45064
+ t._onKeyDown = t._onKeyDown.bind(t);
45065
+ t._requestScroll = t._requestScroll.bind(t);
45066
+ t._onVScroll = t._onVScroll.bind(t);
45067
+ t._selfScrollToRow = t._selfScrollToRow.bind(t);
45068
+
45006
45069
  t._streamingConflator = new Conflator(50, t._updateStreamingData);
45007
45070
  t._formulaConflator = new Conflator(300, t._onFormulaDataChanged);
45008
45071
  t._chainConflator = new Conflator(100, t._addMemberOfChain);
@@ -45082,6 +45145,10 @@ let Grid = function(placeholder, config) {
45082
45145
  t._grid.listen("postSectionDataBinding", t._onPostSectionDataBinding);
45083
45146
  t._grid.listen("firstRendered", t._dispatch.bind(t, "firstRendered"));
45084
45147
  t._grid.listen("afterContentBinding", t._dispatch.bind(t, "afterContentBinding"));
45148
+ t._grid.listen("keydown", t._onKeyDown);
45149
+
45150
+ t._grid.getVScrollbar().listen("scroll", t._onVScroll);
45151
+ t._hiddenInput = t._grid.getHiddenInput();
45085
45152
 
45086
45153
  t._grid.enableRowHighlighting(true);
45087
45154
 
@@ -45267,7 +45334,14 @@ Grid.prototype._childDataField = "";
45267
45334
  * @private
45268
45335
  */
45269
45336
  Grid.prototype._topSection = true;
45270
-
45337
+ /** @type {Object}
45338
+ * @private
45339
+ */
45340
+ Grid.prototype._focusingArgs = null;
45341
+ /** @type {number}
45342
+ * @private
45343
+ */
45344
+ Grid.prototype._scrolledRow = -1;
45271
45345
  /** @public
45272
45346
  */
45273
45347
  Grid.prototype.dispose = function() {
@@ -45300,6 +45374,11 @@ Grid.prototype.dispose = function() {
45300
45374
  this._subs["dispose"]();
45301
45375
  this._subs = null;
45302
45376
  }
45377
+
45378
+ if(this._focusingArgs && this._focusingArgs.id) {
45379
+ clearTimeout(this._focusingArgs.id);
45380
+ this._focusingArgs = null;
45381
+ }
45303
45382
  };
45304
45383
  /** @public
45305
45384
  * @return {Element}
@@ -47727,6 +47806,13 @@ Grid.prototype.setRicData = function(ric, values) {
47727
47806
  }
47728
47807
  }
47729
47808
  };
47809
+ /** Retrieve all RIC subscriptions. This method is not dependent on the number of rows, the RIC can vary from the current row in the grid.
47810
+ * @public
47811
+ * @return {Array.<string>}
47812
+ */
47813
+ Grid.prototype.getAllRics = function() {
47814
+ return this._connector.getAllRics();
47815
+ };
47730
47816
  /** A shorthand to set row data based on index of the specified row. It is better to keep rowDefinition object for updating data directly as row index can be changed by sorting and filtering.
47731
47817
  * @public
47732
47818
  * @param {Grid~RowReference} rowRef
@@ -48792,6 +48878,199 @@ Grid.prototype.getVScrollView = function () {
48792
48878
  return this._grid.getVScrollView();
48793
48879
  };
48794
48880
 
48881
+ /** @private
48882
+ * @param {Element} el
48883
+ * @return {boolean}
48884
+ */
48885
+ function isValidInput(el) {
48886
+ return el && el.tagName !== "SPAN" && !el.disabled;
48887
+ }
48888
+ /** @private
48889
+ * @param {Element} el
48890
+ * @param {Element} hiddenInput
48891
+ * @return {boolean}
48892
+ */
48893
+ function isValidTarget(el, hiddenInput) {
48894
+ return !el.classList.contains("valigner") && el !== hiddenInput;
48895
+ }
48896
+ /** @private
48897
+ * @param {Object} cell
48898
+ * @return {boolean}
48899
+ */
48900
+ function focusCell(cell) {
48901
+ if(cell) {
48902
+ let cellContent = cell.getContent();
48903
+ if(cellContent && isValidInput(cellContent)) {
48904
+ cellContent.focus();
48905
+ return true;
48906
+ }
48907
+ }
48908
+ return false;
48909
+ }
48910
+ /** @private
48911
+ */
48912
+ Grid.prototype._onVScroll = function() {
48913
+ let args = this._focusingArgs;
48914
+ if(!args) { return; }
48915
+
48916
+ this._focusingArgs = null;
48917
+ let event = args.event;
48918
+ let cell = args.section.getCell(args.colIndex, args.rowIndex);
48919
+ if(focusCell(cell)) {
48920
+ event.preventDefault();
48921
+ } else {
48922
+ if(event.shiftKey) {
48923
+ this._findPrevFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
48924
+ } else {
48925
+ this._findNextFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
48926
+ }
48927
+ }
48928
+ };
48929
+ /** @private
48930
+ */
48931
+ Grid.prototype._selfScrollToRow = function() {
48932
+ let args = this._focusingArgs;
48933
+ if(!args) { return; }
48934
+ args.id = 0;
48935
+ this.scrollToRow(args.rowIndex);
48936
+ };
48937
+ /** @private
48938
+ * @param {Object} e
48939
+ * @param {number} colIndex
48940
+ * @param {number} rowIndex
48941
+ * @param {Array} focusableColIndices
48942
+ * @param {Object} section
48943
+ */
48944
+ Grid.prototype._requestScroll = function(e, colIndex, rowIndex, focusableColIndices, section) {
48945
+ let args = this._focusingArgs;
48946
+ if(args) { return; }
48947
+ if(this._scrolledRow === rowIndex) { return; } // Avoid infinite loop
48948
+
48949
+ this._scrolledRow = rowIndex;
48950
+ args = this._focusingArgs = {
48951
+ event: e,
48952
+ colIndex: colIndex,
48953
+ rowIndex: rowIndex,
48954
+ focusableColIndices: focusableColIndices,
48955
+ section: section
48956
+ };
48957
+
48958
+ args.id = setTimeout(this._selfScrollToRow); // Avoid event loop protection
48959
+ };
48960
+ /** @private
48961
+ * @param {Object} e
48962
+ * @param {number} colIndex
48963
+ * @param {number} rowIndex
48964
+ * @param {Array} focusableColIndices
48965
+ * @param {Element=} content
48966
+ */
48967
+ Grid.prototype._findNextFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
48968
+ let startIdx = focusableColIndices.indexOf(colIndex);
48969
+
48970
+ // Calculate starting row and column index
48971
+ if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
48972
+ rowIndex = 0;
48973
+ startIdx = 0;
48974
+ } else if(isValidInput(content) && startIdx >= 0) {
48975
+ startIdx++;
48976
+ }
48977
+ let grid = this._grid;
48978
+ let section = grid.getSection("content");
48979
+ let viewInfo = grid.getVerticalViewInfo();
48980
+ let bottomRowIndex = viewInfo.bottomRowIndex;
48981
+ let rowCount = this.getRowCount();
48982
+ for(let r = rowIndex; r < rowCount; r++) {
48983
+ for(let i = startIdx; i < focusableColIndices.length; i++) {
48984
+ let c = focusableColIndices[i];
48985
+ if(r > bottomRowIndex) {
48986
+ this._requestScroll(e, c, r, focusableColIndices, section);
48987
+ return;
48988
+ } else {
48989
+ let cell = section.getCell(c, r);
48990
+ if(focusCell(cell)) {
48991
+ e.preventDefault();
48992
+ return;
48993
+ }
48994
+ }
48995
+ }
48996
+ startIdx = 0;
48997
+ }
48998
+ };
48999
+ /** @private
49000
+ * @param {Object} e
49001
+ * @param {number} colIndex
49002
+ * @param {number} rowIndex
49003
+ * @param {Array} focusableColIndices
49004
+ * @param {Element=} content
49005
+ */
49006
+ Grid.prototype._findPrevFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
49007
+ let startIdx = focusableColIndices.indexOf(colIndex);
49008
+ let len = focusableColIndices.length;
49009
+
49010
+ // Calculate starting row and column index
49011
+ if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
49012
+ rowIndex = 0;
49013
+ startIdx = 0;
49014
+ } else if(isValidInput(content) && startIdx >= 0) {
49015
+ startIdx--;
49016
+ }
49017
+
49018
+ let grid = this._grid;
49019
+ let section = grid.getSection("content");
49020
+ let viewInfo = grid.getVerticalViewInfo();
49021
+ let topRowIndex = viewInfo.topRowIndex;
49022
+ for(let r = rowIndex; r >= 0; r--) {
49023
+ for(let i = startIdx; i >= 0; i--) {
49024
+ let c = focusableColIndices[i];
49025
+ if(r < topRowIndex) {
49026
+ this._requestScroll(e, c, r, focusableColIndices, section);
49027
+ return;
49028
+ } else {
49029
+ let cell = section.getCell(c, r);
49030
+ if(focusCell(cell)) {
49031
+ e.preventDefault();
49032
+ return;
49033
+ }
49034
+ }
49035
+ }
49036
+ startIdx = len - 1;
49037
+ }
49038
+ };
49039
+
49040
+ /** @private
49041
+ * @param {Object} e
49042
+ */
49043
+ Grid.prototype._onKeyDown = function(e) {
49044
+ if (e.keyCode !== 9 || e.ctrlKey || e.altKey || e.metaKey) {
49045
+ return;
49046
+ }
49047
+
49048
+ // Find next focusable cell
49049
+ let colDefs = this.getColumnDefinitions();
49050
+ let colCount = colDefs.length;
49051
+
49052
+ let focusableColIndices = [];
49053
+ for(let c = 0; c < colCount; c++) {
49054
+ if(colDefs[c].isFocusable()) {
49055
+ focusableColIndices.push(c);
49056
+ }
49057
+ }
49058
+
49059
+ if(!focusableColIndices.length) {
49060
+ return;
49061
+ }
49062
+
49063
+ this._scrolledRow = -1; // Reset the scroll loop protector
49064
+ let pos = this.getRelativePosition(e);
49065
+ let content = pos["cell"] ? pos["cell"].getContent() : null;
49066
+
49067
+ if(e.shiftKey) {
49068
+ this._findPrevFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
49069
+ } else {
49070
+ this._findNextFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
49071
+ }
49072
+ };
49073
+
48795
49074
 
48796
49075
  /* harmony default export */ var js_Grid = (Grid);
48797
49076