@refinitiv-ui/efx-grid 6.0.30 → 6.0.32

Sign up to get free protection for your applications and to get access to all the features.
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