@refinitiv-ui/efx-grid 6.0.30 → 6.0.32

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 (42) hide show
  1. package/lib/core/dist/core.js +310 -117
  2. package/lib/core/dist/core.min.js +1 -1
  3. package/lib/core/es6/grid/Core.js +53 -28
  4. package/lib/core/es6/grid/ILayoutGrid.js +3 -3
  5. package/lib/core/es6/grid/LayoutGrid.js +67 -23
  6. package/lib/core/es6/grid/VirtualizedLayoutGrid.js +92 -55
  7. package/lib/core/es6/grid/components/Scrollbar.js +19 -1
  8. package/lib/core/es6/grid/util/SelectionList.d.ts +6 -2
  9. package/lib/core/es6/grid/util/SelectionList.js +76 -7
  10. package/lib/filter-dialog/lib/filter-dialog.js +11 -8
  11. package/lib/filter-dialog/themes/base.less +7 -3
  12. package/lib/filter-dialog/themes/elemental/dark/es5/all-elements.js +1 -1
  13. package/lib/filter-dialog/themes/elemental/dark/filter-dialog.js +1 -1
  14. package/lib/filter-dialog/themes/elemental/light/es5/all-elements.js +1 -1
  15. package/lib/filter-dialog/themes/elemental/light/filter-dialog.js +1 -1
  16. package/lib/filter-dialog/themes/halo/dark/es5/all-elements.js +1 -1
  17. package/lib/filter-dialog/themes/halo/dark/filter-dialog.js +1 -1
  18. package/lib/filter-dialog/themes/halo/light/es5/all-elements.js +1 -1
  19. package/lib/filter-dialog/themes/halo/light/filter-dialog.js +1 -1
  20. package/lib/filter-dialog/themes/solar/charcoal/es5/all-elements.js +1 -1
  21. package/lib/filter-dialog/themes/solar/charcoal/filter-dialog.js +1 -1
  22. package/lib/filter-dialog/themes/solar/pearl/es5/all-elements.js +1 -1
  23. package/lib/filter-dialog/themes/solar/pearl/filter-dialog.js +1 -1
  24. package/lib/grid/index.js +1 -1
  25. package/lib/statistics-row/es6/StatisticsRow.d.ts +25 -25
  26. package/lib/statistics-row/es6/StatisticsRow.js +9 -4
  27. package/lib/tr-grid-column-selection/es6/ColumnSelection.d.ts +2 -0
  28. package/lib/tr-grid-column-selection/es6/ColumnSelection.js +14 -0
  29. package/lib/tr-grid-content-wrap/es6/ContentWrap.d.ts +4 -4
  30. package/lib/tr-grid-content-wrap/es6/ContentWrap.js +116 -70
  31. package/lib/tr-grid-row-dragging/es6/RowDragging.d.ts +23 -1
  32. package/lib/tr-grid-row-dragging/es6/RowDragging.js +339 -40
  33. package/lib/tr-grid-util/es6/DragUI.d.ts +2 -0
  34. package/lib/tr-grid-util/es6/DragUI.js +39 -9
  35. package/lib/tr-grid-util/es6/Popup.d.ts +3 -1
  36. package/lib/tr-grid-util/es6/Popup.js +57 -23
  37. package/lib/types/es6/ContentWrap.d.ts +4 -4
  38. package/lib/types/es6/RealtimeGrid/ColumnDefinition.d.ts +2 -0
  39. package/lib/types/es6/RealtimeGrid/FieldDefinition.d.ts +4 -0
  40. package/lib/types/es6/RealtimeGrid/Grid.d.ts +1 -0
  41. package/lib/versions.json +6 -6
  42. package/package.json +1 -1
@@ -4693,11 +4693,11 @@ ILayoutGrid.prototype.getHorizontalLayout = function () {};
4693
4693
  ILayoutGrid.prototype.calculateColumnBounds = function (lftIdx, rgtIdx, outPositions, outNoBorders) {};
4694
4694
  /** @public
4695
4695
  * @ignore
4696
- * @param {!Array.<number>} positions Left and right bound positions in pixel
4697
- * @param {!Array.<boolean>} noBorders Boolean values indicating existence of left and right CSS borders
4696
+ * @param {!Array.<Array>} posAry Left and right bound positions in pixel
4697
+ * @param {!Array.<Array>} noBorderAry Boolean values indicating existence of left and right CSS borders
4698
4698
  * @param {number=} topPx Top position of bound
4699
4699
  */
4700
- ILayoutGrid.prototype.updateColumnBounds = function (positions, noBorders, topPx) {};
4700
+ ILayoutGrid.prototype.updateColumnBounds = function (posAry, noBorderAry, topPx) {};
4701
4701
 
4702
4702
  /* harmony default export */ const grid_ILayoutGrid = (ILayoutGrid);
4703
4703
 
@@ -6263,6 +6263,34 @@ SelectionList.prototype.deselect = function (at) {
6263
6263
  }
6264
6264
  return false;
6265
6265
  };
6266
+ /** Deselect all selections starting from the specified index
6267
+ * @public
6268
+ * @param {number} at
6269
+ * @return {boolean}
6270
+ */
6271
+ SelectionList.prototype.deselectFrom = function (at) {
6272
+ if(this._lastIndex < at) {
6273
+ return false;
6274
+ }
6275
+ if(this._firstIndex >= at) {
6276
+ this.clearAllSelections();
6277
+ return true;
6278
+ }
6279
+
6280
+ var lastIndex = this._lastIndex;
6281
+ var sels = this._selections;
6282
+ for(var i = at; i <= lastIndex; ++i) {
6283
+ if (sels[i]) {
6284
+ sels[at] = false;
6285
+ --this._count;
6286
+ }
6287
+ }
6288
+ if (this._anchor >= at) {
6289
+ this._anchor = -1; // No anchor
6290
+ }
6291
+ this._lastIndex = this._findPrevSelection(at);
6292
+ return true;
6293
+ };
6266
6294
  /** @public
6267
6295
  * @param {number} at
6268
6296
  */
@@ -6459,14 +6487,16 @@ SelectionList.prototype.getLastSelectedIndex = function() {
6459
6487
 
6460
6488
  /** WARNING: It will creates a new(EXPENSIVE) defragmented array of selected Index. The selected indices will always be sorted in ascending order
6461
6489
  * @public
6462
- * @return {Array.<number>}
6490
+ * @return {!Array.<number>}
6463
6491
  */
6464
6492
  SelectionList.prototype.getAllSelections = function() {
6465
6493
  if(this._count > 0) {
6466
6494
  var ary = new Array(this._count); // Fastest way to create an array
6467
6495
  var count = 0;
6468
- for(var i = this._firstIndex; i <= this._lastIndex; ++i) {
6469
- if(this._selections[i]) {
6496
+ var sels = this._selections;
6497
+ var lastIdx = this._lastIndex;
6498
+ for(var i = this._firstIndex; i <= lastIdx; ++i) {
6499
+ if(sels[i]) {
6470
6500
  ary[count++] = i;
6471
6501
  }
6472
6502
  }
@@ -6474,6 +6504,45 @@ SelectionList.prototype.getAllSelections = function() {
6474
6504
  }
6475
6505
  return [];
6476
6506
  };
6507
+ /** Get array of connected selection ranges. For intances, if indices 1, 2, 5, and 5 are selected, array of [1, 2] and [5, 5] are returned.
6508
+ * @public
6509
+ * @param {number=} from
6510
+ * @param {number=} to EXCLUSIVE
6511
+ * @return {!Array.<Array.<number>>}
6512
+ */
6513
+ SelectionList.prototype.getConnectedRanges = function(from, to) {
6514
+ if(this._count > 0) {
6515
+ var ary = [];
6516
+ if(from == null || from < this._firstIndex) {
6517
+ from = this._firstIndex;
6518
+ }
6519
+ if(to == null || to > this._lastIndex) {
6520
+ to = this._lastIndex + 1;
6521
+ }
6522
+
6523
+ var pair = null;
6524
+ for(var i = from; i < to; ++i) {
6525
+ if(this._selections[i]) {
6526
+ if(!pair) {
6527
+ pair = [i, -1];
6528
+ }
6529
+ } else if(pair) {
6530
+ pair[1] = i - 1;
6531
+ ary.push(pair);
6532
+ pair = null;
6533
+ }
6534
+ }
6535
+
6536
+ if(pair) {
6537
+ pair[1] = this._lastIndex;
6538
+ ary.push(pair);
6539
+ pair = null;
6540
+ }
6541
+ return ary;
6542
+ }
6543
+ return [];
6544
+ };
6545
+
6477
6546
  /**
6478
6547
  * @public
6479
6548
  * @return {Array.<boolean>}
@@ -6501,13 +6570,13 @@ SelectionList.prototype.clearAllSelections = function() {
6501
6570
  * @public
6502
6571
  * @param {SelectionList} srcSelections
6503
6572
  * @param {number} fromSrcIndex
6504
- * @param {number} offsetIndex
6573
+ * @param {number} offset Offset from the source index to map to destination index of this SelectionList. Use 0 if there is no shifting.
6505
6574
  * @param {number} forLength Positive value only. negative valie is not allowed
6506
6575
  */
6507
- SelectionList.prototype.copyFrom = function (srcSelections, fromSrcIndex, offsetIndex, forLength) {
6576
+ SelectionList.prototype.copyFrom = function (srcSelections, fromSrcIndex, offset, forLength) {
6508
6577
  if (forLength <= 0) { return; }
6509
6578
 
6510
- var toThisIndex = fromSrcIndex + offsetIndex;
6579
+ var toThisIndex = fromSrcIndex + offset;
6511
6580
  if (srcSelections == null) {
6512
6581
  this.deselectRange(toThisIndex, forLength);
6513
6582
  return;
@@ -6528,7 +6597,7 @@ SelectionList.prototype.copyFrom = function (srcSelections, fromSrcIndex, offset
6528
6597
  this._anchor = -1;
6529
6598
  if (srcSelections._anchor >= 0) {
6530
6599
  if (srcSelections._anchor >= fromSrcIndex && srcSelections._anchor < (fromSrcIndex + forLength)) {
6531
- this._anchor = srcSelections._anchor + offsetIndex;
6600
+ this._anchor = srcSelections._anchor + offset;
6532
6601
  }
6533
6602
  }
6534
6603
  };
@@ -6747,7 +6816,8 @@ var Scrollbar = function () {
6747
6816
  t._element.appendChild(t._trackContent); // WARNING: trackContent is not registered as ElementWrapper's content
6748
6817
 
6749
6818
  t.disableKeyboardInput(false); // Enable keyboard input by default
6750
- Scrollbar._queryNativeTrackThickness(t._dispatch.bind(t, "thicknessChanged"));
6819
+ t._onThicknessChanged = t._dispatch.bind(t, "thicknessChanged");
6820
+ Scrollbar._queryNativeTrackThickness(t._onThicknessChanged);
6751
6821
 
6752
6822
  if(!t._updateEffectiveArea()) {
6753
6823
  t.listen("thicknessChanged", t._updateEffectiveArea);
@@ -6917,6 +6987,12 @@ Scrollbar.prototype._wheelScrolling = "";
6917
6987
  * @ignore
6918
6988
  */
6919
6989
  Scrollbar.prototype._mouseWheelLogic = null;
6990
+ /** @type {Function}
6991
+ * @private
6992
+ * @ignore
6993
+ */
6994
+ Scrollbar.prototype._onThicknessChanged = null;
6995
+
6920
6996
 
6921
6997
  /** @type {number}
6922
6998
  * @private
@@ -7024,6 +7100,7 @@ Scrollbar._retrieveNativeTrackThinkness = function () {
7024
7100
  outer.style.overflow = 'scroll';
7025
7101
  var w2 = inner.offsetWidth;
7026
7102
 
7103
+ // Sometimes, w1 may be equal to w2 on certain browsers or devices, such as a Macbook when opened on the built-in screen. In such cases, the outer.style.overflow scroll may not change the offsetWidth, and the outer.clientWidth will be the same as the inner offsetWidth. As a result, the native track thickness may not be found
7027
7104
  if(w1 == w2) {
7028
7105
  w2 = outer.clientWidth;
7029
7106
  }
@@ -7063,6 +7140,16 @@ Scrollbar.updateTrackThickness = function () {
7063
7140
 
7064
7141
  /** @override */
7065
7142
  Scrollbar.prototype.dispose = function () {
7143
+
7144
+ var sbListeners = Scrollbar._listeners;
7145
+ if(sbListeners) {
7146
+ var idx = sbListeners.indexOf(this._onThicknessChanged);
7147
+ if(idx >= 0 ) {
7148
+ sbListeners.splice(idx, 1);
7149
+ this._onThicknessChanged = null;
7150
+ }
7151
+ }
7152
+
7066
7153
  this.unlistenAll();
7067
7154
  if(this._smoothingId) {
7068
7155
  clearInterval(this._smoothingId);
@@ -8584,10 +8671,18 @@ LayoutGrid.prototype._ctxRows;
8584
8671
  * @private
8585
8672
  */
8586
8673
  LayoutGrid.prototype._boundLayer = null;
8587
- /** @type {Element}
8674
+ /** @type {Array.<Element>}
8675
+ * @private
8676
+ */
8677
+ LayoutGrid.prototype._colBounds = null;
8678
+ /** @type {Array.<Element>}
8588
8679
  * @private
8589
8680
  */
8590
- LayoutGrid.prototype._columnBound = null;
8681
+ LayoutGrid.prototype._colBoundCache = null;
8682
+ /** @type {boolean}
8683
+ * @private
8684
+ */
8685
+ LayoutGrid.prototype._colSelDirty = false;
8591
8686
  /** @type {HScrollbar}
8592
8687
  * @private
8593
8688
  */
@@ -8611,6 +8706,8 @@ LayoutGrid.prototype.dispose = function () {
8611
8706
  }
8612
8707
 
8613
8708
  this._colCount = this._rowCount = this._activeRowEnd = this._availableRowCount = 0;
8709
+ this._colBounds = this._colBoundCache = null;
8710
+ this._colSelDirty = false;
8614
8711
 
8615
8712
  this._highlightedCells.length = 0;
8616
8713
  this._ctx = null;
@@ -10552,16 +10649,15 @@ LayoutGrid.prototype.getContextRow = function (rowIndex) {
10552
10649
  LayoutGrid.prototype.selectColumn = function (colIndex, selected) {
10553
10650
  this.enableColumnClass(colIndex, "selected-column", selected);
10554
10651
 
10555
- var columnBound = this._columnBound;
10556
- if(!columnBound) {
10557
- columnBound = this._columnBound = document.createElement("div");
10558
- columnBound.className = "selection-bound column-bound";
10559
- }
10560
- var boundLayer = this._boundLayer;
10561
- if(!boundLayer) {
10562
- boundLayer = this._boundLayer = document.createElement("div");
10563
- boundLayer.className = "cover-layer";
10564
- this._updateLayers();
10652
+ if(selected) {
10653
+ this._colSelDirty = true;
10654
+
10655
+ var boundLayer = this._boundLayer;
10656
+ if(!boundLayer) {
10657
+ boundLayer = this._boundLayer = document.createElement("div");
10658
+ boundLayer.className = "cover-layer";
10659
+ this._updateLayers();
10660
+ }
10565
10661
  }
10566
10662
  };
10567
10663
  /** @public
@@ -10664,24 +10760,56 @@ LayoutGrid.prototype.calculateColumnBounds = function (lftIdx, rgtIdx, outPositi
10664
10760
  };
10665
10761
  /** @public
10666
10762
  * @ignore
10667
- * @param {!Array.<number>} positions Left and right bound positions in pixel
10668
- * @param {!Array.<boolean>} noBorders Boolean values indicating existence of left and right CSS borders
10763
+ * @param {!Array.<Array>} posAry Left and right bound positions in pixel
10764
+ * @param {!Array.<Array>} noBorderAry Boolean values indicating existence of left and right CSS borders
10669
10765
  * @param {number=} topPx Top position of bound
10670
10766
  */
10671
- LayoutGrid.prototype.updateColumnBounds = function (positions, noBorders, topPx) {
10672
- var columnBound = this._columnBound;
10673
- if(!columnBound) {
10767
+ LayoutGrid.prototype.updateColumnBounds = function (posAry, noBorderAry, topPx) {
10768
+ if(!this._colSelDirty) {
10674
10769
  return;
10675
10770
  }
10676
10771
 
10677
- var lftPx = positions[0];
10678
- var rgtPx = positions[1];
10679
- if(lftPx >= rgtPx) {
10680
- var pn = columnBound.parentNode;
10772
+ var cbs = this._colBounds;
10773
+ var cbc = this._colBoundCache;
10774
+ if(!cbs) {
10775
+ cbs = this._colBounds = [];
10776
+ }
10777
+ if(!cbc) {
10778
+ cbc = this._colBoundCache = [];
10779
+ }
10780
+
10781
+ var rangeCount = posAry.length;
10782
+ var i;
10783
+ var pn = null; // parentNode
10784
+ var columnBound = null;
10785
+
10786
+ // Remove unused bounds from document
10787
+ var activeCount = cbs.length;
10788
+ for(i = rangeCount; i < activeCount; ++i) {
10789
+ columnBound = cbs[i];
10790
+ pn = columnBound.parentNode;
10681
10791
  if(pn) {
10682
10792
  pn.removeChild(columnBound);
10683
10793
  }
10684
- } else {
10794
+ }
10795
+ cbs.length = activeCount = rangeCount;
10796
+
10797
+ if(!rangeCount) {
10798
+ this._colSelDirty = false;
10799
+ return;
10800
+ }
10801
+
10802
+ for(i = 0; i < rangeCount; ++i) {
10803
+ var positions = posAry[i];
10804
+ var noBorders = noBorderAry[i];
10805
+ var lftPx = /** @type{number} */(positions[0]);
10806
+ var rgtPx = /** @type{number} */(positions[1]);
10807
+
10808
+ columnBound = cbc[i];
10809
+ if(!columnBound) {
10810
+ columnBound = cbc[i] = document.createElement("div");
10811
+ columnBound.className = "selection-bound column-bound";
10812
+ }
10685
10813
  columnBound.style.left = lftPx + "px";
10686
10814
  columnBound.style.width = (rgtPx - lftPx) + "px";
10687
10815
 
@@ -10691,7 +10819,10 @@ LayoutGrid.prototype.updateColumnBounds = function (positions, noBorders, topPx)
10691
10819
  columnBound.classList.toggle("no-left-bound", noBorders[0]);
10692
10820
  columnBound.classList.toggle("no-right-bound", noBorders[1]);
10693
10821
  if(this._boundLayer) {
10694
- this._boundLayer.appendChild(columnBound);
10822
+ if(!cbs[i]) {
10823
+ cbs[i] = columnBound;
10824
+ this._boundLayer.appendChild(columnBound);
10825
+ }
10695
10826
  }
10696
10827
  }
10697
10828
  };
@@ -23703,10 +23834,18 @@ VirtualizedLayoutGrid.prototype._selectionList = null;
23703
23834
  * @private
23704
23835
  */
23705
23836
  VirtualizedLayoutGrid.prototype._reverter = null;
23706
- /** @type {Element}
23837
+ /** @type {Array.<Element>}
23838
+ * @private
23839
+ */
23840
+ VirtualizedLayoutGrid.prototype._rowBounds = null;
23841
+ /** @type {Array.<Element>}
23842
+ * @private
23843
+ */
23844
+ VirtualizedLayoutGrid.prototype._rowBoundCache = null;
23845
+ /** @type {boolean}
23707
23846
  * @private
23708
23847
  */
23709
- VirtualizedLayoutGrid.prototype._rowBound = null;
23848
+ VirtualizedLayoutGrid.prototype._rowSelDirty = false;
23710
23849
  /** @type {Element}
23711
23850
  * @private
23712
23851
  */
@@ -23772,6 +23911,9 @@ VirtualizedLayoutGrid.prototype.dispose = function () {
23772
23911
  this._grid.dispose();
23773
23912
  this._dispose();
23774
23913
  this._reverter.dispose();
23914
+
23915
+ this._rowBounds = this._rowBoundCache = null;
23916
+ this._rowSelDirty = false;
23775
23917
  if(this._rowBoundTimer) {
23776
23918
  clearTimeout(this._rowBoundTimer);
23777
23919
  this._rowBoundTimer = 0;
@@ -24223,9 +24365,10 @@ VirtualizedLayoutGrid.prototype.setSelectedRow = function (rowIndex, opt_selecte
24223
24365
  this._grid.setSelectedRow(rowIndex - this._firstIndex, selected);
24224
24366
 
24225
24367
  if(selected) {
24226
- this._initRowBounds();
24368
+ this._rowSelDirty = true;
24369
+ this._initBoundLayer();
24227
24370
  }
24228
- this._updateRowBounds();
24371
+ this._requestUpdatingRowBounds();
24229
24372
  };
24230
24373
 
24231
24374
  /** @inheritDoc */
@@ -24238,14 +24381,15 @@ VirtualizedLayoutGrid.prototype.selectSingleRow = function (rowIndex) {
24238
24381
  VirtualizedLayoutGrid.prototype.selectRowRange = function (rowIndex, length) {
24239
24382
  this._selectionList.selectRange(rowIndex, length);
24240
24383
  this._updateRowSelection();
24241
- this._initRowBounds();
24242
- this._updateRowBounds();
24384
+ this._rowSelDirty = true;
24385
+ this._initBoundLayer();
24386
+ this._requestUpdatingRowBounds();
24243
24387
  };
24244
24388
  /** @inheritDoc */
24245
24389
  VirtualizedLayoutGrid.prototype.clearSelectedRows = function () {
24246
24390
  var count = this._selectionList.clearAllSelections();
24247
24391
  this._grid.clearSelectedRows();
24248
- this._updateRowBounds();
24392
+ this._requestUpdatingRowBounds(); // WARNING: Row bounds are not removed from the document immediately
24249
24393
  return count;
24250
24394
  };
24251
24395
  /** @inheritDoc */
@@ -24687,12 +24831,12 @@ VirtualizedLayoutGrid.prototype._updateCellBounds = function () {
24687
24831
  };
24688
24832
  /** @public
24689
24833
  * @ignore
24690
- * @param {!Array.<number>} positions Left and right bound positions in pixel
24691
- * @param {!Array.<boolean>} noBorders Boolean values indicating existence of left and right CSS borders
24834
+ * @param {!Array.<Array>} posAry Left and right bound positions in pixel
24835
+ * @param {!Array.<Array>} noBorderAry Boolean values indicating existence of left and right CSS borders
24692
24836
  * @param {number=} topPx Top position of bound
24693
24837
  */
24694
- VirtualizedLayoutGrid.prototype.updateColumnBounds = function (positions, noBorders, topPx) {
24695
- this._grid.updateColumnBounds(positions, noBorders, topPx);
24838
+ VirtualizedLayoutGrid.prototype.updateColumnBounds = function (posAry, noBorderAry, topPx) {
24839
+ this._grid.updateColumnBounds(posAry, noBorderAry, topPx);
24696
24840
  this._updateRowBounds();
24697
24841
  };
24698
24842
  /** @private
@@ -24707,16 +24851,6 @@ VirtualizedLayoutGrid.prototype._initBoundLayer = function () {
24707
24851
  };
24708
24852
  /** @private
24709
24853
  */
24710
- VirtualizedLayoutGrid.prototype._initRowBounds = function () {
24711
- var rowBound = this._rowBound;
24712
- if(!rowBound) {
24713
- rowBound = this._rowBound = document.createElement("div");
24714
- rowBound.className = "selection-bound";
24715
- }
24716
- this._initBoundLayer();
24717
- };
24718
- /** @private
24719
- */
24720
24854
  VirtualizedLayoutGrid.prototype._requestUpdatingRowBounds = function () {
24721
24855
  if(!this._rowBoundTimer) {
24722
24856
  this._rowBoundTimer = setTimeout(this._updateRowBounds, 10);
@@ -24728,54 +24862,88 @@ VirtualizedLayoutGrid.prototype._updateRowBounds = function () {
24728
24862
  this._rowBoundTimer = 0;
24729
24863
  this._updateCellBounds();
24730
24864
 
24731
- var rowBound = this._rowBound;
24732
- if(!rowBound) {
24865
+ if(!this._rowSelDirty) {
24733
24866
  return;
24734
24867
  }
24735
- var topIdx = this.getFirstSelectedRow();
24736
- var btmIdx = -1; // Inclusive
24737
- var topPx = 0;
24738
- var btmPx = 0;
24739
- var rowCount = this._layoutY.getLaneCount();
24740
- if(topIdx >= rowCount) {
24741
- topIdx = rowCount - 1;
24868
+ var rbs = this._rowBounds;
24869
+ var rbc = this._rowBoundCache;
24870
+ if(!rbs) {
24871
+ rbs = this._rowBounds = [];
24742
24872
  }
24743
- if(topIdx >= 0) {
24744
- btmIdx = this.getLastSelectedRow();
24745
- if(btmIdx >= rowCount) {
24746
- btmIdx = rowCount - 1;
24747
- }
24748
- topPx = this._layoutY.getLaneStart(topIdx);
24749
- btmPx = this._layoutY.getLaneEnd(btmIdx);
24873
+ if(!rbc) {
24874
+ rbc = this._rowBoundCache = [];
24750
24875
  }
24751
24876
 
24752
- if(topPx >= btmPx) {
24753
- var pn = rowBound.parentNode;
24877
+ var selList = this._selectionList;
24878
+ var rowCount = this._layoutY.getLaneCount();
24879
+ selList.deselectFrom(rowCount); // TODO: move this to setRowCount
24880
+
24881
+ var selRanges = selList.getConnectedRanges();
24882
+ var rangeCount = selRanges.length;
24883
+ var i;
24884
+ var pn = null; // parentNode
24885
+ var rowBound = null;
24886
+
24887
+ // Remove unused bounds from document
24888
+ var activeCount = rbs.length;
24889
+ for(i = rangeCount; i < activeCount; ++i) {
24890
+ rowBound = rbs[i];
24891
+ pn = rowBound.parentNode;
24754
24892
  if(pn) {
24755
24893
  pn.removeChild(rowBound);
24756
24894
  }
24757
- } else {
24895
+ }
24896
+ rbs.length = activeCount = rangeCount;
24897
+
24898
+ if(!rangeCount) {
24899
+ var selCount = selList.getSelectionCount();
24900
+ if(!selCount) {
24901
+ this._rowSelDirty = false;
24902
+ }
24903
+ return;
24904
+ }
24905
+
24906
+ // Prepare shared parameters
24907
+ var scrollLeft = 0;
24908
+ var pinnedLftCount = 0;
24909
+ var pinnedRgtCount = 0;
24910
+ var endOfScroll = false;
24911
+ if(this._hscrollbar) {
24912
+ scrollLeft = this._hscrollbar.getScrollLeft();
24913
+ pinnedLftCount = this._hscrollbar.getPinnedLeftColumnCount();
24914
+ pinnedRgtCount = this._hscrollbar.getPinnedRightColumnCount();
24915
+ endOfScroll = this._hscrollbar.isEndOfHorizontalScroll();
24916
+ }
24917
+ var noLeftBound = !pinnedLftCount && scrollLeft > 0;
24918
+ var noRightBound = !pinnedRgtCount && !endOfScroll;
24919
+ var boundWidth = this._grid._getViewSize();
24920
+
24921
+ // Create row bound elements based on number of selection ranges
24922
+ for(i = 0; i < rangeCount; ++i) {
24923
+ var pair = selRanges[i];
24924
+ var topIdx = pair[0];
24925
+ var btmIdx = pair[1]; // Inclusive
24926
+ var topPx = this._layoutY.getLaneStart(topIdx);
24927
+ var btmPx = this._layoutY.getLaneEnd(btmIdx);
24928
+
24929
+ rowBound = rbc[i];
24930
+ if(!rowBound) {
24931
+ rowBound = rbc[i] = document.createElement("div");
24932
+ rowBound.className = "selection-bound";
24933
+ }
24934
+
24758
24935
  rowBound.style.top = topPx + "px";
24759
24936
  rowBound.style.height = (btmPx - topPx) + "px";
24760
-
24761
- var boundWidth = this._grid._getViewSize();
24762
24937
  rowBound.style.width = boundWidth + "px";
24763
24938
 
24764
- var scrollLeft = 0;
24765
- var pinnedLftCount = 0;
24766
- var pinnedRgtCount = 0;
24767
- var endOfScroll = false;
24768
- if(this._hscrollbar) {
24769
- scrollLeft = this._hscrollbar.getScrollLeft();
24770
- pinnedLftCount = this._hscrollbar.getPinnedLeftColumnCount();
24771
- pinnedRgtCount = this._hscrollbar.getPinnedRightColumnCount();
24772
- endOfScroll = this._hscrollbar.isEndOfHorizontalScroll();
24773
- }
24774
- rowBound.classList.toggle("no-left-bound", !pinnedLftCount && scrollLeft > 0);
24775
- rowBound.classList.toggle("no-right-bound", !pinnedRgtCount && !endOfScroll);
24939
+ rowBound.classList.toggle("no-left-bound", noLeftBound);
24940
+ rowBound.classList.toggle("no-right-bound", noRightBound);
24776
24941
 
24777
24942
  if(this._boundLayer) {
24778
- this._boundLayer.appendChild(rowBound);
24943
+ if(!rbs[i]) {
24944
+ rbs[i] = rowBound;
24945
+ this._boundLayer.appendChild(rowBound);
24946
+ }
24779
24947
  }
24780
24948
  }
24781
24949
  };
@@ -25420,7 +25588,7 @@ Core_Core.prototype._groupDefs = null;
25420
25588
  * @return {string}
25421
25589
  */
25422
25590
  Core_Core.getVersion = function () {
25423
- return "5.1.39";
25591
+ return "5.1.41";
25424
25592
  };
25425
25593
  /** {@link ElementWrapper#dispose}
25426
25594
  * @override
@@ -28946,47 +29114,72 @@ Core_Core.prototype._updateColumnBounds = function () {
28946
29114
  return;
28947
29115
  }
28948
29116
 
29117
+ var sectCount = this._settings.length;
29118
+ if(!sectCount) {
29119
+ return;
29120
+ }
29121
+
29122
+ // Collecting column selection and selection ranges
29123
+ var selRanges = [];
29124
+ var pair = null;
28949
29125
  var colCount = this.getColumnCount();
28950
- var colIndices = [];
29126
+ var selIndices = [];
28951
29127
  var i;
28952
29128
  for(i = 0; i < colCount; i++) {
28953
29129
  if(this.isSelectedColumn(i)) {
28954
- colIndices.push(i);
29130
+ selIndices.push(i);
29131
+ if(!pair) {
29132
+ pair = [i, -1];
29133
+ }
29134
+ } else if(pair) {
29135
+ pair[1] = i - 1;
29136
+ selRanges.push(pair);
29137
+ pair = null;
28955
29138
  }
28956
29139
  }
29140
+ if(pair) {
29141
+ pair[1] = colCount - 1;
29142
+ selRanges.push(pair);
29143
+ pair = null;
29144
+ }
29145
+
28957
29146
  var arg = {
28958
- selectedColumns: colIndices
29147
+ "selectedColumns": selIndices,
29148
+ "selectionRanges": selRanges
28959
29149
  };
28960
29150
  this._dispatch("beforeColumnBoundUpdate", arg);
28961
29151
 
28962
- var len = this.getColumnCount();
28963
- var lftIdx = -1;
28964
- var rgtIdx = -1;
28965
- for(i = 0; i < len; ++i) {
28966
- if(this.isSelectedColumn(i)) {
28967
- rgtIdx = i;
28968
- if(lftIdx < 0) {
28969
- lftIdx = i;
28970
- }
28971
- }
28972
- }
28973
- var sectCount = this._settings.length;
28974
- if(sectCount) {
28975
- var sectionSetting = this._settings[0];
28976
- var section = sectionSetting.getSection();
29152
+ // Calculate position from ranges
29153
+ var rangeCount = selRanges.length;
29154
+ var posAry = [];
29155
+ var noBorderAry = [];
29156
+ var topSectionSettings = this._settings[0];
29157
+ var section = topSectionSettings.getSection();
29158
+ for(i = 0; i < rangeCount; ++i) {
29159
+ pair = selRanges[i];
28977
29160
  var positions = [0, 0];
28978
29161
  var noBorders = [false, false];
28979
- section.calculateColumnBounds(lftIdx, rgtIdx, positions, noBorders);
28980
- var topPx = 0;
28981
- if(sectionSetting.getType() === "title" && arg.topBoundRowIndex != null) {
28982
- topPx = this._layoutY.getLaneStart(arg.topBoundRowIndex);
28983
- }
28984
- section.updateColumnBounds(positions, noBorders, topPx);
28985
- for(i = 1; i < sectCount; i++) {
28986
- section = this._settings[i].getSection();
28987
- section.updateColumnBounds(positions, noBorders);
29162
+ section.calculateColumnBounds(pair[0], pair[1], positions, noBorders);
29163
+ if(positions[0] < positions[1]) {
29164
+ posAry.push(positions);
29165
+ noBorderAry.push(noBorders);
28988
29166
  }
28989
29167
  }
29168
+
29169
+ // Render column bounds
29170
+ var topPx = 0;
29171
+ var topBoundIdx = -1;
29172
+ if(arg["topBoundRowIndex"] != null) {
29173
+ topBoundIdx = +arg["topBoundRowIndex"];
29174
+ }
29175
+ if(topBoundIdx >= 0 && topSectionSettings.getType() === "title") {
29176
+ topPx = this._layoutY.getLaneStart(topBoundIdx);
29177
+ }
29178
+ section.updateColumnBounds(posAry, noBorderAry, topPx);
29179
+ for(i = 1; i < sectCount; i++) {
29180
+ section = this._settings[i].getSection();
29181
+ section.updateColumnBounds(posAry, noBorderAry);
29182
+ }
28990
29183
  };
28991
29184
 
28992
29185
  /** @public