handsontable 14.0.0-next-c22ab6f-20231030 → 14.0.0-next-f88c253-20231106

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 (36) hide show
  1. package/base.js +2 -2
  2. package/base.mjs +2 -2
  3. package/dist/handsontable.css +8 -2
  4. package/dist/handsontable.full.css +8 -2
  5. package/dist/handsontable.full.js +2084 -3359
  6. package/dist/handsontable.full.min.css +3 -3
  7. package/dist/handsontable.full.min.js +59 -66
  8. package/dist/handsontable.js +2086 -3361
  9. package/dist/handsontable.min.css +3 -3
  10. package/dist/handsontable.min.js +16 -23
  11. package/helpers/mixed.js +2 -2
  12. package/helpers/mixed.mjs +2 -2
  13. package/package.json +1 -1
  14. package/pluginHooks.d.ts +6 -28
  15. package/pluginHooks.js +63 -117
  16. package/pluginHooks.mjs +63 -117
  17. package/plugins/copyPaste/clipboardData.js +18 -0
  18. package/plugins/copyPaste/clipboardData.mjs +14 -0
  19. package/plugins/copyPaste/copyPaste.js +92 -38
  20. package/plugins/copyPaste/copyPaste.mjs +94 -40
  21. package/plugins/copyPaste/pasteEvent.js +14 -0
  22. package/plugins/copyPaste/pasteEvent.mjs +9 -0
  23. package/plugins/mergeCells/mergeCells.js +14 -0
  24. package/plugins/mergeCells/mergeCells.mjs +14 -0
  25. package/plugins/nestedHeaders/nestedHeaders.js +22 -21
  26. package/plugins/nestedHeaders/nestedHeaders.mjs +22 -21
  27. package/utils/parseTable.js +83 -527
  28. package/utils/parseTable.mjs +82 -523
  29. package/plugins/copyPaste/clipboardData/clipboardData.js +0 -516
  30. package/plugins/copyPaste/clipboardData/clipboardData.mjs +0 -512
  31. package/plugins/copyPaste/clipboardData/copyClipboardData.js +0 -69
  32. package/plugins/copyPaste/clipboardData/copyClipboardData.mjs +0 -65
  33. package/plugins/copyPaste/clipboardData/index.js +0 -9
  34. package/plugins/copyPaste/clipboardData/index.mjs +0 -4
  35. package/plugins/copyPaste/clipboardData/pasteClipboardData.js +0 -81
  36. package/plugins/copyPaste/clipboardData/pasteClipboardData.mjs +0 -77
@@ -14,7 +14,8 @@ function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!priva
14
14
  function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
15
15
  import { BasePlugin } from "../base/index.mjs";
16
16
  import Hooks from "../../pluginHooks.mjs";
17
- import { stringify } from "../../3rdparty/SheetClip/index.mjs";
17
+ import { stringify, parse } from "../../3rdparty/SheetClip/index.mjs";
18
+ import { arrayEach } from "../../helpers/array.mjs";
18
19
  import { sanitize } from "../../helpers/string.mjs";
19
20
  import { removeContentEditableFromElementAndDeselect, runWithSelectedContendEditableElement, makeElementContentEditableAndSelectItsContent } from "../../helpers/dom/element.mjs";
20
21
  import { isSafari } from "../../helpers/browser.mjs";
@@ -23,10 +24,10 @@ import copyColumnHeadersOnlyItem from "./contextMenuItem/copyColumnHeadersOnly.m
23
24
  import copyWithColumnGroupHeadersItem from "./contextMenuItem/copyWithColumnGroupHeaders.mjs";
24
25
  import copyWithColumnHeadersItem from "./contextMenuItem/copyWithColumnHeaders.mjs";
25
26
  import cutItem from "./contextMenuItem/cut.mjs";
27
+ import PasteEvent from "./pasteEvent.mjs";
26
28
  import { CopyableRangesFactory, normalizeRanges } from "./copyableRanges.mjs";
27
- import { getDataByCoords, getHTMLFromConfig } from "../../utils/parseTable.mjs";
29
+ import { _dataToHTML, htmlToGridSettings } from "../../utils/parseTable.mjs";
28
30
  import EventManager from "../../eventManager.mjs";
29
- import { CopyClipboardData, PasteClipboardData, META_HEAD } from "./clipboardData/index.mjs";
30
31
  Hooks.getSingleton().register('afterCopyLimit');
31
32
  Hooks.getSingleton().register('modifyCopyableRange');
32
33
  Hooks.getSingleton().register('beforeCut');
@@ -38,6 +39,7 @@ Hooks.getSingleton().register('afterCopy');
38
39
  export const PLUGIN_KEY = 'copyPaste';
39
40
  export const PLUGIN_PRIORITY = 80;
40
41
  const SETTING_KEYS = ['fragmentSelection'];
42
+ const META_HEAD = ['<meta name="generator" content="Handsontable"/>', '<style type="text/css">td{white-space:normal}br{mso-data-placement:same-cell}</style>'].join('');
41
43
 
42
44
  /* eslint-disable jsdoc/require-description-complete-sentence */
43
45
  /**
@@ -82,6 +84,7 @@ var _isTriggeredByCopy = /*#__PURE__*/new WeakMap();
82
84
  var _isTriggeredByCut = /*#__PURE__*/new WeakMap();
83
85
  var _copyableRangesFactory = /*#__PURE__*/new WeakMap();
84
86
  var _ensureClipboardEventsGetTriggered = /*#__PURE__*/new WeakSet();
87
+ var _countCopiedHeaders = /*#__PURE__*/new WeakSet();
85
88
  var _addContentEditableToHighlightedCell = /*#__PURE__*/new WeakSet();
86
89
  var _removeContentEditableFromHighlightedCell = /*#__PURE__*/new WeakSet();
87
90
  export class CopyPaste extends BasePlugin {
@@ -95,6 +98,15 @@ export class CopyPaste extends BasePlugin {
95
98
  * Add the `contenteditable` attribute to the highlighted cell and select its content.
96
99
  */
97
100
  _classPrivateMethodInitSpec(this, _addContentEditableToHighlightedCell);
101
+ /**
102
+ * Counts how many column headers will be copied based on the passed range.
103
+ *
104
+ * @private
105
+ * @param {Array<{startRow: number, startCol: number, endRow: number, endCol: number}>} ranges Array of objects with properties `startRow`, `startCol`, `endRow` and `endCol`.
106
+ * @returns {{ columnHeadersCount: number }} Returns an object with keys that holds
107
+ * information with the number of copied headers.
108
+ */
109
+ _classPrivateMethodInitSpec(this, _countCopiedHeaders);
98
110
  /**
99
111
  * Ensure that the `copy`/`cut` events get triggered properly in Safari.
100
112
  *
@@ -379,14 +391,26 @@ export class CopyPaste extends BasePlugin {
379
391
  * @returns {Array[]} An array of arrays that will be copied to the clipboard.
380
392
  */
381
393
  getRangedData(ranges) {
394
+ const data = [];
382
395
  const {
383
396
  rows,
384
397
  columns
385
398
  } = normalizeRanges(ranges);
386
- return getDataByCoords(this.hot, {
387
- rows,
388
- columns
399
+
400
+ // concatenate all rows and columns data defined in ranges into one copyable string
401
+ arrayEach(rows, row => {
402
+ const rowSet = [];
403
+ arrayEach(columns, column => {
404
+ if (row < 0) {
405
+ // `row` as the second argument acts here as the `headerLevel` argument
406
+ rowSet.push(this.hot.getColHeader(column, row));
407
+ } else {
408
+ rowSet.push(this.hot.getCopyableData(row, column));
409
+ }
410
+ });
411
+ data.push(rowSet);
389
412
  });
413
+ return data;
390
414
  }
391
415
 
392
416
  /**
@@ -403,17 +427,7 @@ export class CopyPaste extends BasePlugin {
403
427
  if (!pastableText && !pastableHtml) {
404
428
  return;
405
429
  }
406
- const pasteData = {
407
- clipboardData: {
408
- data: {},
409
- setData(type, value) {
410
- this.data[type] = value;
411
- },
412
- getData(type) {
413
- return this.data[type];
414
- }
415
- }
416
- };
430
+ const pasteData = new PasteEvent();
417
431
  if (pastableText) {
418
432
  pasteData.clipboardData.setData('text/plain', pastableText);
419
433
  }
@@ -552,7 +566,7 @@ export class CopyPaste extends BasePlugin {
552
566
  /**
553
567
  * `copy` event callback on textarea element.
554
568
  *
555
- * @param {ClipboardEvent} event ClipboardEvent.
569
+ * @param {Event} event ClipboardEvent.
556
570
  * @private
557
571
  */
558
572
  onCopy(event) {
@@ -561,12 +575,19 @@ export class CopyPaste extends BasePlugin {
561
575
  }
562
576
  this.setCopyableText();
563
577
  _classPrivateFieldSet(this, _isTriggeredByCopy, false);
564
- const copyClipboardData = new CopyClipboardData(this.hot, this.copyableRanges);
565
- const allowCopying = !!this.hot.runHooks('beforeCopy', copyClipboardData);
578
+ const data = this.getRangedData(this.copyableRanges);
579
+ const copiedHeadersCount = _classPrivateMethodGet(this, _countCopiedHeaders, _countCopiedHeaders2).call(this, this.copyableRanges);
580
+ const allowCopying = !!this.hot.runHooks('beforeCopy', data, this.copyableRanges, copiedHeadersCount);
566
581
  if (allowCopying) {
567
- event.clipboardData.setData('text/plain', stringify(copyClipboardData.getData()));
568
- event.clipboardData.setData('text/html', [copyClipboardData.getType() === 'handsontable' ? META_HEAD : '', getHTMLFromConfig(copyClipboardData.getMetaInfo())].join(''));
569
- this.hot.runHooks('afterCopy', copyClipboardData);
582
+ const textPlain = stringify(data);
583
+ if (event && event.clipboardData) {
584
+ const textHTML = _dataToHTML(data, this.hot.rootDocument);
585
+ event.clipboardData.setData('text/plain', textPlain);
586
+ event.clipboardData.setData('text/html', [META_HEAD, textHTML].join(''));
587
+ } else if (typeof ClipboardEvent === 'undefined') {
588
+ this.hot.rootWindow.clipboardData.setData('Text', textPlain);
589
+ }
590
+ this.hot.runHooks('afterCopy', data, this.copyableRanges, copiedHeadersCount);
570
591
  }
571
592
  _classPrivateFieldSet(this, _copyMode, 'cells-only');
572
593
  event.preventDefault();
@@ -575,7 +596,7 @@ export class CopyPaste extends BasePlugin {
575
596
  /**
576
597
  * `cut` event callback on textarea element.
577
598
  *
578
- * @param {ClipboardEvent} event ClipboardEvent.
599
+ * @param {Event} event ClipboardEvent.
579
600
  * @private
580
601
  */
581
602
  onCut(event) {
@@ -584,13 +605,19 @@ export class CopyPaste extends BasePlugin {
584
605
  }
585
606
  this.setCopyableText();
586
607
  _classPrivateFieldSet(this, _isTriggeredByCut, false);
587
- const copyClipboardData = new CopyClipboardData(this.hot, this.copyableRanges);
588
- const allowCuttingOut = !!this.hot.runHooks('beforeCut', copyClipboardData);
608
+ const rangedData = this.getRangedData(this.copyableRanges);
609
+ const allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
589
610
  if (allowCuttingOut) {
590
- event.clipboardData.setData('text/plain', stringify(copyClipboardData.getData()));
591
- event.clipboardData.setData('text/html', [copyClipboardData.getType() === 'handsontable' ? META_HEAD : '', getHTMLFromConfig(copyClipboardData.getMetaInfo())].join(''));
611
+ const textPlain = stringify(rangedData);
612
+ if (event && event.clipboardData) {
613
+ const textHTML = _dataToHTML(rangedData, this.hot.rootDocument);
614
+ event.clipboardData.setData('text/plain', textPlain);
615
+ event.clipboardData.setData('text/html', [META_HEAD, textHTML].join(''));
616
+ } else if (typeof ClipboardEvent === 'undefined') {
617
+ this.hot.rootWindow.clipboardData.setData('Text', textPlain);
618
+ }
592
619
  this.hot.emptySelectedCells('CopyPaste.cut');
593
- this.hot.runHooks('afterCut', copyClipboardData);
620
+ this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
594
621
  }
595
622
  event.preventDefault();
596
623
  }
@@ -608,22 +635,34 @@ export class CopyPaste extends BasePlugin {
608
635
  if (event && event.preventDefault) {
609
636
  event.preventDefault();
610
637
  }
611
- const html = sanitize(event.clipboardData.getData('text/html'), {
612
- ADD_TAGS: ['meta'],
613
- ADD_ATTR: ['content'],
614
- FORCE_BODY: true
615
- });
616
- const pasteClipboardData = new PasteClipboardData(event.clipboardData.getData('text/plain'), html);
617
- if (this.hot.runHooks('beforePaste', pasteClipboardData) === false) {
638
+ let pastedData;
639
+ if (event && typeof event.clipboardData !== 'undefined') {
640
+ const textHTML = sanitize(event.clipboardData.getData('text/html'), {
641
+ ADD_TAGS: ['meta'],
642
+ ADD_ATTR: ['content'],
643
+ FORCE_BODY: true
644
+ });
645
+ if (textHTML && /(<table)|(<TABLE)/g.test(textHTML)) {
646
+ const parsedConfig = htmlToGridSettings(textHTML, this.hot.rootDocument);
647
+ pastedData = parsedConfig.data;
648
+ } else {
649
+ pastedData = event.clipboardData.getData('text/plain');
650
+ }
651
+ } else if (typeof ClipboardEvent === 'undefined' && typeof this.hot.rootWindow.clipboardData !== 'undefined') {
652
+ pastedData = this.hot.rootWindow.clipboardData.getData('Text');
653
+ }
654
+ if (typeof pastedData === 'string') {
655
+ pastedData = parse(pastedData);
656
+ }
657
+ if (pastedData === void 0 || pastedData && pastedData.length === 0) {
618
658
  return;
619
659
  }
620
- const pastedTable = pasteClipboardData.getData();
621
- if (pastedTable.length === 0) {
660
+ if (this.hot.runHooks('beforePaste', pastedData, this.copyableRanges) === false) {
622
661
  return;
623
662
  }
624
- const [startRow, startColumn, endRow, endColumn] = this.populateValues(pastedTable);
663
+ const [startRow, startColumn, endRow, endColumn] = this.populateValues(pastedData);
625
664
  this.hot.selectCell(startRow, startColumn, Math.min(this.hot.countRows() - 1, endRow), Math.min(this.hot.countCols() - 1, endColumn));
626
- this.hot.runHooks('afterPaste', pasteClipboardData);
665
+ this.hot.runHooks('afterPaste', pastedData, this.copyableRanges);
627
666
  }
628
667
 
629
668
  /**
@@ -719,6 +758,21 @@ function _ensureClipboardEventsGetTriggered2(eventName) {
719
758
  this.hot.rootDocument.execCommand(eventName);
720
759
  }
721
760
  }
761
+ function _countCopiedHeaders2(ranges) {
762
+ const {
763
+ rows
764
+ } = normalizeRanges(ranges);
765
+ let columnHeadersCount = 0;
766
+ for (let row = 0; row < rows.length; row++) {
767
+ if (rows[row] >= 0) {
768
+ break;
769
+ }
770
+ columnHeadersCount += 1;
771
+ }
772
+ return {
773
+ columnHeadersCount
774
+ };
775
+ }
722
776
  function _addContentEditableToHighlightedCell2() {
723
777
  if (this.hot.isListening()) {
724
778
  const lastSelectedRange = this.hot.getSelectedRangeLast();
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ var _clipboardData = _interopRequireDefault(require("./clipboardData"));
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+ /**
7
+ * @private
8
+ */
9
+ class PasteEvent {
10
+ constructor() {
11
+ this.clipboardData = new _clipboardData.default();
12
+ }
13
+ }
14
+ exports.default = PasteEvent;
@@ -0,0 +1,9 @@
1
+ import ClipboardData from "./clipboardData.mjs";
2
+ /**
3
+ * @private
4
+ */
5
+ export default class PasteEvent {
6
+ constructor() {
7
+ this.clipboardData = new ClipboardData();
8
+ }
9
+ }
@@ -186,6 +186,9 @@ class MergeCells extends _base.BasePlugin {
186
186
  this.addHook('afterDrawSelection', function () {
187
187
  return _this.onAfterDrawSelection(...arguments);
188
188
  });
189
+ this.addHook('beforeRemoveCellClassNames', function () {
190
+ return _this.onBeforeRemoveCellClassNames(...arguments);
191
+ });
189
192
  this.addHook('beforeUndoStackChange', (action, source) => {
190
193
  if (source === 'MergeCells') {
191
194
  return false;
@@ -1197,5 +1200,16 @@ class MergeCells extends _base.BasePlugin {
1197
1200
  }
1198
1201
  return this.selectionCalculations.getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel);
1199
1202
  }
1203
+
1204
+ /**
1205
+ * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
1206
+ *
1207
+ * @private
1208
+ * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from
1209
+ * all the cells in the table.
1210
+ */
1211
+ onBeforeRemoveCellClassNames() {
1212
+ return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
1213
+ }
1200
1214
  }
1201
1215
  exports.MergeCells = MergeCells;
@@ -182,6 +182,9 @@ export class MergeCells extends BasePlugin {
182
182
  this.addHook('afterDrawSelection', function () {
183
183
  return _this.onAfterDrawSelection(...arguments);
184
184
  });
185
+ this.addHook('beforeRemoveCellClassNames', function () {
186
+ return _this.onBeforeRemoveCellClassNames(...arguments);
187
+ });
185
188
  this.addHook('beforeUndoStackChange', (action, source) => {
186
189
  if (source === 'MergeCells') {
187
190
  return false;
@@ -1193,4 +1196,15 @@ export class MergeCells extends BasePlugin {
1193
1196
  }
1194
1197
  return this.selectionCalculations.getSelectedMergedCellClassName(currentRow, currentColumn, cornersOfSelection, layerLevel);
1195
1198
  }
1199
+
1200
+ /**
1201
+ * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
1202
+ *
1203
+ * @private
1204
+ * @returns {string[]} An `Array` of `String`s. Each of these strings will act like class names to be removed from
1205
+ * all the cells in the table.
1206
+ */
1207
+ onBeforeRemoveCellClassNames() {
1208
+ return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
1209
+ }
1196
1210
  }
@@ -529,44 +529,45 @@ class NestedHeaders extends _base.BasePlugin {
529
529
  * of the column.
530
530
  *
531
531
  * @private
532
- * @param {object} clipboardData Information about already performed copy action.
533
- * @param {Function} clipboardData.removeRow Remove row from the copied/pasted dataset.
534
- * @param {Function} clipboardData.removeColumn Remove column from the copied/pasted dataset.
535
- * @param {Function} clipboardData.insertAtRow Insert values at row index.
536
- * @param {Function} clipboardData.insertAtColumn Insert values at column index.
537
- * @param {Function} clipboardData.setCellAt Change headers or cells in the copied/pasted dataset.
538
- * @param {Function} clipboardData.getCellAt Get headers or cells from the copied/pasted dataset.
539
- * @param {Function} clipboardData.getData Gets copied data stored as array of arrays.
540
- * @param {Function} clipboardData.getMetaInfo Gets grid settings for copied data.
541
- * @param {Function} clipboardData.getRanges Returns ranges related to copied part of Handsontable.
532
+ * @param {Array[]} data An array of arrays which contains data to copied.
533
+ * @param {object[]} copyableRanges An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
534
+ * which will copied.
535
+ * @param {{ columnHeadersCount: number }} copiedHeadersCount An object with keys that holds information with
536
+ * the number of copied headers.
542
537
  */
543
- onBeforeCopy(clipboardData) {
544
- const copyableRanges = clipboardData.getRanges();
545
- for (let rangeIndex = 0; rangeIndex < copyableRanges.length; rangeIndex += 1) {
538
+ onBeforeCopy(data, copyableRanges, _ref2) {
539
+ let {
540
+ columnHeadersCount
541
+ } = _ref2;
542
+ if (columnHeadersCount === 0) {
543
+ return;
544
+ }
545
+ for (let rangeIndex = 0; rangeIndex < copyableRanges.length; rangeIndex++) {
546
546
  const {
547
547
  startRow,
548
548
  startCol,
549
549
  endRow,
550
550
  endCol
551
551
  } = copyableRanges[rangeIndex];
552
+ const rowsCount = endRow - startRow + 1;
552
553
  const columnsCount = startCol - endCol + 1;
553
554
 
554
555
  // do not process dataset ranges and column headers where only one column is copied
555
556
  if (startRow >= 0 || columnsCount === 1) {
556
557
  break;
557
558
  }
558
- for (let column = startCol; column <= endCol; column += 1) {
559
- for (let row = startRow; row <= endRow; row += 1) {
560
- var _classPrivateFieldGet4, _classPrivateFieldGet5;
559
+ for (let column = startCol; column <= endCol; column++) {
560
+ for (let row = startRow; row <= endRow; row++) {
561
+ var _classPrivateFieldGet4;
562
+ const zeroBasedColumnHeaderLevel = rowsCount + row;
561
563
  const zeroBasedColumnIndex = column - startCol;
562
564
  if (zeroBasedColumnIndex === 0) {
563
565
  continue; // eslint-disable-line no-continue
564
566
  }
565
567
 
566
568
  const isRoot = (_classPrivateFieldGet4 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(row, column)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.isRoot;
567
- const collapsible = (_classPrivateFieldGet5 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(row, column)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.collapsible;
568
- if (collapsible === true && isRoot === false) {
569
- clipboardData.setCellAt(row, zeroBasedColumnIndex, '');
569
+ if (isRoot === false) {
570
+ data[zeroBasedColumnHeaderLevel][zeroBasedColumnIndex] = '';
570
571
  }
571
572
  }
572
573
  }
@@ -869,10 +870,10 @@ class NestedHeaders extends _base.BasePlugin {
869
870
  * @returns {string} Returns the column header value to update.
870
871
  */
871
872
  onModifyColumnHeaderValue(value, visualColumnIndex, headerLevel) {
872
- var _classPrivateFieldGet6;
873
+ var _classPrivateFieldGet5;
873
874
  const {
874
875
  label
875
- } = (_classPrivateFieldGet6 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(headerLevel, visualColumnIndex)) !== null && _classPrivateFieldGet6 !== void 0 ? _classPrivateFieldGet6 : {
876
+ } = (_classPrivateFieldGet5 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(headerLevel, visualColumnIndex)) !== null && _classPrivateFieldGet5 !== void 0 ? _classPrivateFieldGet5 : {
876
877
  label: ''
877
878
  };
878
879
  return label;
@@ -525,44 +525,45 @@ export class NestedHeaders extends BasePlugin {
525
525
  * of the column.
526
526
  *
527
527
  * @private
528
- * @param {object} clipboardData Information about already performed copy action.
529
- * @param {Function} clipboardData.removeRow Remove row from the copied/pasted dataset.
530
- * @param {Function} clipboardData.removeColumn Remove column from the copied/pasted dataset.
531
- * @param {Function} clipboardData.insertAtRow Insert values at row index.
532
- * @param {Function} clipboardData.insertAtColumn Insert values at column index.
533
- * @param {Function} clipboardData.setCellAt Change headers or cells in the copied/pasted dataset.
534
- * @param {Function} clipboardData.getCellAt Get headers or cells from the copied/pasted dataset.
535
- * @param {Function} clipboardData.getData Gets copied data stored as array of arrays.
536
- * @param {Function} clipboardData.getMetaInfo Gets grid settings for copied data.
537
- * @param {Function} clipboardData.getRanges Returns ranges related to copied part of Handsontable.
528
+ * @param {Array[]} data An array of arrays which contains data to copied.
529
+ * @param {object[]} copyableRanges An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
530
+ * which will copied.
531
+ * @param {{ columnHeadersCount: number }} copiedHeadersCount An object with keys that holds information with
532
+ * the number of copied headers.
538
533
  */
539
- onBeforeCopy(clipboardData) {
540
- const copyableRanges = clipboardData.getRanges();
541
- for (let rangeIndex = 0; rangeIndex < copyableRanges.length; rangeIndex += 1) {
534
+ onBeforeCopy(data, copyableRanges, _ref2) {
535
+ let {
536
+ columnHeadersCount
537
+ } = _ref2;
538
+ if (columnHeadersCount === 0) {
539
+ return;
540
+ }
541
+ for (let rangeIndex = 0; rangeIndex < copyableRanges.length; rangeIndex++) {
542
542
  const {
543
543
  startRow,
544
544
  startCol,
545
545
  endRow,
546
546
  endCol
547
547
  } = copyableRanges[rangeIndex];
548
+ const rowsCount = endRow - startRow + 1;
548
549
  const columnsCount = startCol - endCol + 1;
549
550
 
550
551
  // do not process dataset ranges and column headers where only one column is copied
551
552
  if (startRow >= 0 || columnsCount === 1) {
552
553
  break;
553
554
  }
554
- for (let column = startCol; column <= endCol; column += 1) {
555
- for (let row = startRow; row <= endRow; row += 1) {
556
- var _classPrivateFieldGet4, _classPrivateFieldGet5;
555
+ for (let column = startCol; column <= endCol; column++) {
556
+ for (let row = startRow; row <= endRow; row++) {
557
+ var _classPrivateFieldGet4;
558
+ const zeroBasedColumnHeaderLevel = rowsCount + row;
557
559
  const zeroBasedColumnIndex = column - startCol;
558
560
  if (zeroBasedColumnIndex === 0) {
559
561
  continue; // eslint-disable-line no-continue
560
562
  }
561
563
 
562
564
  const isRoot = (_classPrivateFieldGet4 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(row, column)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.isRoot;
563
- const collapsible = (_classPrivateFieldGet5 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(row, column)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.collapsible;
564
- if (collapsible === true && isRoot === false) {
565
- clipboardData.setCellAt(row, zeroBasedColumnIndex, '');
565
+ if (isRoot === false) {
566
+ data[zeroBasedColumnHeaderLevel][zeroBasedColumnIndex] = '';
566
567
  }
567
568
  }
568
569
  }
@@ -865,10 +866,10 @@ export class NestedHeaders extends BasePlugin {
865
866
  * @returns {string} Returns the column header value to update.
866
867
  */
867
868
  onModifyColumnHeaderValue(value, visualColumnIndex, headerLevel) {
868
- var _classPrivateFieldGet6;
869
+ var _classPrivateFieldGet5;
869
870
  const {
870
871
  label
871
- } = (_classPrivateFieldGet6 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(headerLevel, visualColumnIndex)) !== null && _classPrivateFieldGet6 !== void 0 ? _classPrivateFieldGet6 : {
872
+ } = (_classPrivateFieldGet5 = _classPrivateFieldGet(this, _stateManager).getHeaderTreeNodeData(headerLevel, visualColumnIndex)) !== null && _classPrivateFieldGet5 !== void 0 ? _classPrivateFieldGet5 : {
872
873
  label: ''
873
874
  };
874
875
  return label;