handsontable 0.34.1 → 0.34.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

Files changed (95) hide show
  1. package/.travis.yml +2 -0
  2. package/README.md +127 -96
  3. package/commonjs/core.js +11 -6
  4. package/commonjs/helpers/dom/element.js +4 -3
  5. package/commonjs/helpers/mixed.js +8 -4
  6. package/commonjs/index.js +5 -4
  7. package/commonjs/pluginHooks.js +18 -2
  8. package/commonjs/plugins/copyPaste/clipboardData.js +31 -0
  9. package/commonjs/plugins/copyPaste/contextMenuItem/copy.js +1 -2
  10. package/commonjs/plugins/copyPaste/contextMenuItem/cut.js +1 -2
  11. package/commonjs/plugins/copyPaste/copyPaste.js +127 -134
  12. package/commonjs/plugins/copyPaste/pasteEvent.js +19 -0
  13. package/commonjs/plugins/copyPaste/test/copyPaste.e2e.js +90 -189
  14. package/commonjs/plugins/copyPaste/test/textarea.unit.js +2 -2
  15. package/commonjs/plugins/copyPaste/textarea.js +2 -1
  16. package/commonjs/plugins/manualColumnMove/manualColumnMove.js +8 -11
  17. package/commonjs/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
  18. package/commonjs/plugins/manualRowMove/manualRowMove.js +9 -12
  19. package/commonjs/plugins/manualRowMove/test/manualRowMove.e2e.js +256 -60
  20. package/commonjs/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +40 -182
  21. package/commonjs/plugins/manualRowMove/ui/_base.js +2 -2
  22. package/commonjs/tableView.js +1 -0
  23. package/dist/handsontable.css +6 -5
  24. package/dist/handsontable.css.map +1 -1
  25. package/dist/handsontable.full.css +6 -5
  26. package/dist/handsontable.full.js +37721 -42290
  27. package/dist/handsontable.full.min.css +4 -4
  28. package/dist/handsontable.full.min.js +5 -5
  29. package/dist/handsontable.js +28732 -28433
  30. package/dist/handsontable.js.map +1 -1
  31. package/dist/handsontable.min.css +4 -4
  32. package/dist/handsontable.min.js +3 -3
  33. package/es/core.js +11 -6
  34. package/es/helpers/dom/element.js +4 -3
  35. package/es/helpers/mixed.js +4 -4
  36. package/es/index.js +3 -4
  37. package/es/pluginHooks.js +18 -2
  38. package/es/plugins/copyPaste/clipboardData.js +27 -0
  39. package/es/plugins/copyPaste/contextMenuItem/copy.js +1 -2
  40. package/es/plugins/copyPaste/contextMenuItem/cut.js +1 -2
  41. package/es/plugins/copyPaste/copyPaste.js +124 -132
  42. package/es/plugins/copyPaste/pasteEvent.js +11 -0
  43. package/es/plugins/copyPaste/test/copyPaste.e2e.js +90 -189
  44. package/es/plugins/copyPaste/test/textarea.unit.js +2 -2
  45. package/es/plugins/copyPaste/textarea.js +2 -1
  46. package/es/plugins/manualColumnMove/manualColumnMove.js +8 -11
  47. package/es/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
  48. package/es/plugins/manualRowMove/manualRowMove.js +9 -12
  49. package/es/plugins/manualRowMove/test/manualRowMove.e2e.js +256 -60
  50. package/es/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +40 -182
  51. package/es/plugins/manualRowMove/ui/_base.js +2 -2
  52. package/es/tableView.js +1 -0
  53. package/handsontable.jquery.json +1 -1
  54. package/hot.config.js +1 -1
  55. package/package.json +5 -5
  56. package/src/3rdparty/walkontable/dist/walkontable.js +27234 -11175
  57. package/src/3rdparty/walkontable/dist/walkontable.js.map +1 -1
  58. package/src/3rdparty/walkontable/test/dist/helpers.entry.js +32 -36
  59. package/src/3rdparty/walkontable/test/dist/helpers.entry.js.map +1 -1
  60. package/src/3rdparty/walkontable/test/dist/specs.entry.js +36 -39
  61. package/src/3rdparty/walkontable/test/dist/specs.entry.js.map +1 -1
  62. package/src/core.js +11 -6
  63. package/src/css/handsontable.css +1 -2
  64. package/src/helpers/dom/element.js +4 -3
  65. package/src/helpers/mixed.js +3 -3
  66. package/src/index.js +1 -2
  67. package/src/pluginHooks.js +18 -2
  68. package/src/plugins/copyPaste/clipboardData.js +11 -0
  69. package/src/plugins/copyPaste/contextMenuItem/copy.js +1 -2
  70. package/src/plugins/copyPaste/contextMenuItem/cut.js +1 -2
  71. package/src/plugins/copyPaste/copyPaste.css +3 -1
  72. package/src/plugins/copyPaste/copyPaste.js +120 -127
  73. package/src/plugins/copyPaste/pasteEvent.js +7 -0
  74. package/src/plugins/copyPaste/test/copyPaste.e2e.js +75 -193
  75. package/src/plugins/copyPaste/test/textarea.unit.js +2 -2
  76. package/src/plugins/copyPaste/textarea.js +2 -1
  77. package/src/plugins/manualColumnMove/manualColumnMove.js +6 -9
  78. package/src/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
  79. package/src/plugins/manualRowMove/manualRowMove.js +7 -10
  80. package/src/plugins/manualRowMove/test/manualRowMove.e2e.js +282 -86
  81. package/src/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +51 -190
  82. package/src/plugins/manualRowMove/ui/_base.js +2 -2
  83. package/test/dist/e2e.entry.js +31381 -31131
  84. package/test/dist/e2e.entry.js.map +1 -1
  85. package/test/dist/helpers.entry.js +16 -19
  86. package/test/dist/helpers.entry.js.map +1 -1
  87. package/test/e2e/Core_listen.spec.js +32 -0
  88. package/test/e2e/Core_selection.spec.js +1 -1
  89. package/test/e2e/Core_validate.spec.js +29 -0
  90. package/test/e2e/renderers/checkboxRenderer.spec.js +20 -7
  91. package/test/e2e/settings/fragmentSelection.spec.js +12 -9
  92. package/test/scripts/trigger-pro-tests.sh +41 -0
  93. package/yarn.lock +260 -208
  94. package/.npmignore +0 -19
  95. package/demo/bower_components/numbro/package.json +0 -63
package/es/core.js CHANGED
@@ -1067,7 +1067,7 @@ export default function Core(rootElement, userSettings) {
1067
1067
  if (result === false && cellProperties.allowInvalid === false) {
1068
1068
  changes.splice(i, 1); // cancel the change
1069
1069
  cellProperties.valid = true; // we cancelled the change, so cell value is still valid
1070
- var cell = instance.getCell(cellProperties.row, cellProperties.col);
1070
+ var cell = instance.getCell(cellProperties.visualRow, cellProperties.visualCol);
1071
1071
  removeClass(cell, instance.getSettings().invalidCellClassName);
1072
1072
  --i;
1073
1073
  }
@@ -1310,7 +1310,10 @@ export default function Core(rootElement, userSettings) {
1310
1310
  document.body.focus();
1311
1311
  }
1312
1312
 
1313
- activeGuid = instance.guid;
1313
+ if (instance && !instance.isListening()) {
1314
+ activeGuid = instance.guid;
1315
+ instance.runHooks('afterListen');
1316
+ }
1314
1317
  };
1315
1318
 
1316
1319
  /**
@@ -1323,6 +1326,7 @@ export default function Core(rootElement, userSettings) {
1323
1326
  this.unlisten = function () {
1324
1327
  if (this.isListening()) {
1325
1328
  activeGuid = null;
1329
+ instance.runHooks('afterUnlisten');
1326
1330
  }
1327
1331
  };
1328
1332
 
@@ -3069,7 +3073,6 @@ export default function Core(rootElement, userSettings) {
3069
3073
  selection.setRangeEnd(new CellCoords(endRow, endCol), scrollToCell);
3070
3074
  }
3071
3075
  instance.selection.finish();
3072
-
3073
3076
  return true;
3074
3077
  };
3075
3078
 
@@ -3172,10 +3175,12 @@ export default function Core(rootElement, userSettings) {
3172
3175
  }
3173
3176
  dataSource = null;
3174
3177
 
3175
- var nextSibling = instance.rootElement.nextSibling;
3178
+ if ('ce' !== '\x63\x65' && isRootInstance(instance)) {
3179
+ var licenseInfo = document.querySelector('#hot-display-license-info');
3176
3180
 
3177
- if (isRootInstance(instance) && nextSibling) {
3178
- instance.rootElement.parentNode.removeChild(nextSibling);
3181
+ if (licenseInfo) {
3182
+ licenseInfo.parentNode.removeChild(licenseInfo);
3183
+ }
3179
3184
  }
3180
3185
  empty(instance.rootElement);
3181
3186
  eventManager.destroy();
@@ -281,7 +281,7 @@ if (classListSupport) {
281
281
 
282
282
  _hasClass = function _hasClass(element, className) {
283
283
  // http://snipplr.com/view/3561/addclass-removeclass-hasclass/
284
- return element.className !== void 0 && element.className.test(createClassNameRegExp(className));
284
+ return element.className !== void 0 && createClassNameRegExp(className).test(element.className);
285
285
  };
286
286
 
287
287
  _addClass = function _addClass(element, className) {
@@ -603,10 +603,11 @@ export function getScrollableElement(element) {
603
603
  }
604
604
  }
605
605
 
606
- if (el.clientHeight <= el.scrollHeight && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) {
606
+ // The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome.
607
+ if (el.clientHeight <= el.scrollHeight + 1 && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) {
607
608
  return el;
608
609
  }
609
- if (el.clientWidth <= el.scrollWidth && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) {
610
+ if (el.clientWidth <= el.scrollWidth + 1 && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 || props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) {
610
611
  return el;
611
612
  }
612
613
  el = el.parentNode;
@@ -4,7 +4,7 @@ var _templateObject = _taggedTemplateLiteral(['\n Your license key of H
4
4
 
5
5
  function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
6
6
 
7
- import { addClass } from './dom/element';
7
+ import moment from 'moment';
8
8
  import { toSingleLine } from './templateLiteralTag';
9
9
 
10
10
  /**
@@ -91,7 +91,7 @@ var _cp = function _cp(v) {
91
91
  return v['\x63\x6F\x64\x65\x50\x6F\x69\x6E\x74\x41\x74'](0) - 65;
92
92
  };
93
93
  var _norm = function _norm(v) {
94
- return v.replace(/\-/g, '');
94
+ return ('' + v).replace(/\-/g, '');
95
95
  };
96
96
  var _extractTime = function _extractTime(v) {
97
97
  return _hd(_ss(_norm(v), _hd('12'), _cp('\x46'))) / (_hd(_ss(_norm(v), _cp('\x42'), ~~![][_m])) || 9);
@@ -112,7 +112,7 @@ export function _injectProductInfo(key, element) {
112
112
 
113
113
  if (trial || schemaValidity) {
114
114
  if (schemaValidity) {
115
- var releaseTime = Math.floor(moment('06/09/2017', 'DD/MM/YYYY').toDate().getTime() / 8.64e7);
115
+ var releaseTime = Math.floor(moment('12/10/2017', 'DD/MM/YYYY').toDate().getTime() / 8.64e7);
116
116
  var keyGenTime = _extractTime(key);
117
117
 
118
118
  if (keyGenTime > 45000 || keyGenTime !== parseInt(keyGenTime, 10)) {
@@ -143,7 +143,7 @@ export function _injectProductInfo(key, element) {
143
143
  if (showDomMessage && element.parentNode) {
144
144
  var message = document.createElement('div');
145
145
 
146
- addClass(message, 'display-license-info');
146
+ message.id = 'hot-display-license-info';
147
147
  message.appendChild(document.createTextNode('Evaluation version of Handsontable Pro.'));
148
148
  message.appendChild(document.createElement('br'));
149
149
  message.appendChild(document.createTextNode('Not licensed for production use.'));
package/es/index.js CHANGED
@@ -88,9 +88,9 @@ Handsontable.DefaultSettings = DefaultSettings;
88
88
  Handsontable.EventManager = EventManager;
89
89
  Handsontable._getListenersCounter = getListenersCounter; // For MemoryLeak tests
90
90
 
91
- Handsontable.buildDate = '06/09/2017 13:08:45';
91
+ Handsontable.buildDate = '12/10/2017 10:11:24';
92
92
  Handsontable.packageName = 'handsontable';
93
- Handsontable.version = '0.34.1';
93
+ Handsontable.version = '0.34.5';
94
94
 
95
95
  var baseVersion = '';
96
96
 
@@ -190,5 +190,4 @@ arrayHelpers.arrayEach(Object.getOwnPropertyNames(plugins), function (pluginName
190
190
 
191
191
  Handsontable.plugins.registerPlugin = registerPlugin;
192
192
 
193
- // Export Handsontable
194
- module.exports = Handsontable;
193
+ export default Handsontable;
package/es/pluginHooks.js CHANGED
@@ -1111,7 +1111,7 @@ var REGISTERED_HOOKS = [
1111
1111
  /**
1112
1112
  * Fired after values are pasted into table.
1113
1113
  *
1114
- * @event Hooks#afterePaste
1114
+ * @event Hooks#afterPaste
1115
1115
  * @since 0.31.1
1116
1116
  * @param {Array} data An array of arrays which contains the pasted data.
1117
1117
  * @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
@@ -1488,7 +1488,23 @@ var REGISTERED_HOOKS = [
1488
1488
  * @param {Number} row Row index of the edited cell.
1489
1489
  * @param {Number} column Column index of the edited cell.
1490
1490
  */
1491
- 'afterBeginEditing'];
1491
+ 'afterBeginEditing',
1492
+
1493
+ /**
1494
+ * Fired after the listening is turned on.
1495
+ *
1496
+ * @event Hooks#afterListen
1497
+ * @since 0.34.5
1498
+ */
1499
+ 'afterListen',
1500
+
1501
+ /**
1502
+ * Fired after the listening is turned off.
1503
+ *
1504
+ * @event Hooks#afterUnlisten
1505
+ * @since 0.34.5
1506
+ */
1507
+ 'afterUnlisten'];
1492
1508
 
1493
1509
  var Hooks = function () {
1494
1510
  _createClass(Hooks, null, [{
@@ -0,0 +1,27 @@
1
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
2
+
3
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4
+
5
+ var ClipboardData = function () {
6
+ function ClipboardData() {
7
+ _classCallCheck(this, ClipboardData);
8
+
9
+ this.data = {};
10
+ }
11
+
12
+ _createClass(ClipboardData, [{
13
+ key: "setData",
14
+ value: function setData(type, value) {
15
+ this.data[type] = value;
16
+ }
17
+ }, {
18
+ key: "getData",
19
+ value: function getData(type) {
20
+ return this.data[type] || void 0;
21
+ }
22
+ }]);
23
+
24
+ return ClipboardData;
25
+ }();
26
+
27
+ export default ClipboardData;
@@ -3,8 +3,7 @@ export default function copyItem(copyPastePlugin) {
3
3
  key: 'copy',
4
4
  name: 'Copy',
5
5
  callback: function callback() {
6
- copyPastePlugin.setCopyableText();
7
- copyPastePlugin.copy(true);
6
+ copyPastePlugin.copy();
8
7
  },
9
8
  disabled: function disabled() {
10
9
  return !copyPastePlugin.hot.getSelected();
@@ -3,8 +3,7 @@ export default function cutItem(copyPastePlugin) {
3
3
  key: 'cut',
4
4
  name: 'Cut',
5
5
  callback: function callback() {
6
- copyPastePlugin.setCopyableText();
7
- copyPastePlugin.cut(true);
6
+ copyPastePlugin.cut();
8
7
  },
9
8
  disabled: function disabled() {
10
9
  return !copyPastePlugin.hot.getSelected();
@@ -14,16 +14,15 @@ import BasePlugin from './../_base.js';
14
14
  import Hooks from './../../pluginHooks';
15
15
  import SheetClip from './../../../lib/SheetClip/SheetClip';
16
16
  import { CellCoords, CellRange } from './../../3rdparty/walkontable/src';
17
- import { KEY_CODES, isCtrlKey } from './../../helpers/unicode';
18
17
  import { getSelectionText } from './../../helpers/dom/element';
19
18
  import { arrayEach } from './../../helpers/array';
20
19
  import { rangeEach } from './../../helpers/number';
21
- import { stopImmediatePropagation, stopPropagation, isImmediatePropagationStopped } from './../../helpers/dom/event';
22
20
  import { registerPlugin } from './../../plugins';
23
21
  import Textarea from './textarea';
24
22
  import copyItem from './contextMenuItem/copy';
25
23
  import cutItem from './contextMenuItem/cut';
26
24
  import EventManager from './../../eventManager';
25
+ import PasteEvent from './pasteEvent';
27
26
 
28
27
  Hooks.getSingleton().register('afterCopyLimit');
29
28
  Hooks.getSingleton().register('modifyCopyableRange');
@@ -110,7 +109,10 @@ var CopyPaste = function (_BasePlugin) {
110
109
  _this.textarea = void 0;
111
110
 
112
111
  privatePool.set(_this, {
113
- isTriggeredByPaste: false
112
+ isTriggeredByCopy: false,
113
+ isTriggeredByCut: false,
114
+ isBeginEditing: false,
115
+ isFragmentSelectionEnabled: false
114
116
  });
115
117
  return _this;
116
118
  }
@@ -140,10 +142,11 @@ var CopyPaste = function (_BasePlugin) {
140
142
  if (this.enabled) {
141
143
  return;
142
144
  }
143
-
144
145
  var settings = this.hot.getSettings();
146
+ var priv = privatePool.get(this);
145
147
 
146
148
  this.textarea = Textarea.getSingleton();
149
+ priv.isFragmentSelectionEnabled = settings.fragmentSelection;
147
150
 
148
151
  if (_typeof(settings.copyPaste) === 'object') {
149
152
  this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode;
@@ -154,14 +157,15 @@ var CopyPaste = function (_BasePlugin) {
154
157
  this.addHook('afterContextMenuDefaultOptions', function (options) {
155
158
  return _this2.onAfterContextMenuDefaultOptions(options);
156
159
  });
157
- this.addHook('beforeKeyDown', function (event) {
158
- return _this2.onBeforeKeyDown(event);
160
+ this.addHook('afterSelectionEnd', function () {
161
+ return _this2.onAfterSelectionEnd();
159
162
  });
160
163
 
161
164
  this.registerEvents();
162
165
 
163
166
  _get(CopyPaste.prototype.__proto__ || Object.getPrototypeOf(CopyPaste.prototype), 'enablePlugin', this).call(this);
164
167
  }
168
+
165
169
  /**
166
170
  * Updates the plugin to use the latest options you have specified.
167
171
  */
@@ -225,10 +229,6 @@ var CopyPaste = function (_BasePlugin) {
225
229
 
226
230
  this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges);
227
231
 
228
- var copyableData = this.getRangedCopyableData(this.copyableRanges);
229
-
230
- this.textarea.setValue(copyableData);
231
-
232
232
  if (endRow !== finalEndRow || endCol !== finalEndCol) {
233
233
  this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit);
234
234
  }
@@ -324,57 +324,32 @@ var CopyPaste = function (_BasePlugin) {
324
324
 
325
325
  /**
326
326
  * Copy action.
327
- *
328
- * @param {Boolean} isTriggeredByClick Flag to determine that copy action was executed by the mouse click.
329
327
  */
330
328
 
331
329
  }, {
332
330
  key: 'copy',
333
- value: function copy(isTriggeredByClick) {
334
- var rangedData = this.getRangedData(this.copyableRanges);
335
-
336
- var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
331
+ value: function copy() {
332
+ var priv = privatePool.get(this);
337
333
 
338
- if (allowCopying) {
339
- this.textarea.setValue(SheetClip.stringify(rangedData));
340
- this.textarea.select();
334
+ priv.isTriggeredByCopy = true;
341
335
 
342
- if (isTriggeredByClick) {
343
- document.execCommand('copy');
344
- }
345
-
346
- this.hot.runHooks('afterCopy', rangedData, this.copyableRanges);
347
- } else {
348
- this.textarea.setValue('');
349
- }
336
+ this.textarea.select();
337
+ document.execCommand('copy');
350
338
  }
351
339
 
352
340
  /**
353
341
  * Cut action.
354
- *
355
- * @param {Boolean} isTriggeredByClick Flag to determine that cut action was executed by the mouse click.
356
342
  */
357
343
 
358
344
  }, {
359
345
  key: 'cut',
360
- value: function cut(isTriggeredByClick) {
361
- var rangedData = this.getRangedData(this.copyableRanges);
362
-
363
- var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
364
-
365
- if (allowCuttingOut) {
366
- this.textarea.setValue(SheetClip.stringify(rangedData));
367
- this.hot.selection.empty();
368
- this.textarea.select();
346
+ value: function cut() {
347
+ var priv = privatePool.get(this);
369
348
 
370
- if (isTriggeredByClick) {
371
- document.execCommand('cut');
372
- }
349
+ priv.isTriggeredByCut = true;
373
350
 
374
- this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
375
- } else {
376
- this.textarea.setValue('');
377
- }
351
+ this.textarea.select();
352
+ document.execCommand('cut');
378
353
  }
379
354
 
380
355
  /**
@@ -388,10 +363,10 @@ var CopyPaste = function (_BasePlugin) {
388
363
  value: function paste() {
389
364
  var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
390
365
 
391
- this.textarea.setValue(value);
366
+ var pasteData = new PasteEvent();
367
+ pasteData.clipboardData.setData('text/plain', value);
392
368
 
393
- this.onPaste();
394
- this.onInput();
369
+ this.onPaste(pasteData);
395
370
  }
396
371
 
397
372
  /**
@@ -408,71 +383,124 @@ var CopyPaste = function (_BasePlugin) {
408
383
  this.eventManager.addEventListener(this.textarea.element, 'paste', function (event) {
409
384
  return _this5.onPaste(event);
410
385
  });
411
- this.eventManager.addEventListener(this.textarea.element, 'input', function (event) {
412
- return _this5.onInput(event);
386
+ this.eventManager.addEventListener(this.textarea.element, 'cut', function (event) {
387
+ return _this5.onCut(event);
388
+ });
389
+ this.eventManager.addEventListener(this.textarea.element, 'copy', function (event) {
390
+ return _this5.onCopy(event);
413
391
  });
414
392
  }
415
393
 
416
394
  /**
417
- * Trigger to make possible observe `onInput` in textarea.
395
+ * `copy` event callback on textarea element.
418
396
  *
397
+ * @param {Event} event ClipboardEvent.
419
398
  * @private
420
399
  */
421
400
 
422
401
  }, {
423
- key: 'triggerPaste',
424
- value: function triggerPaste() {
425
- this.textarea.select();
402
+ key: 'onCopy',
403
+ value: function onCopy(event) {
404
+ var priv = privatePool.get(this);
405
+
406
+ if (!this.hot.isListening() && !priv.isTriggeredByCopy) {
407
+ return;
408
+ }
409
+
410
+ this.setCopyableText();
411
+ priv.isTriggeredByCopy = false;
412
+
413
+ var rangedData = this.getRangedData(this.copyableRanges);
414
+ var allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
415
+ var value = '';
416
+
417
+ if (allowCopying) {
418
+ value = SheetClip.stringify(rangedData);
419
+
420
+ if (event && event.clipboardData) {
421
+ event.clipboardData.setData('text/plain', value);
422
+ } else if (typeof ClipboardEvent === 'undefined') {
423
+ window.clipboardData.setData('Text', value);
424
+ }
425
+
426
+ this.hot.runHooks('afterCopy', rangedData, this.copyableRanges);
427
+ }
426
428
 
427
- this.onPaste();
429
+ event.preventDefault();
428
430
  }
429
431
 
430
432
  /**
431
- * `paste` event callback on textarea element.
433
+ * `cut` event callback on textarea element.
432
434
  *
435
+ * @param {Event} event ClipboardEvent.
433
436
  * @private
434
437
  */
435
438
 
436
439
  }, {
437
- key: 'onPaste',
438
- value: function onPaste() {
440
+ key: 'onCut',
441
+ value: function onCut(event) {
439
442
  var priv = privatePool.get(this);
440
443
 
441
- priv.isTriggeredByPaste = true;
444
+ if (!this.hot.isListening() && !priv.isTriggeredByCut) {
445
+ return;
446
+ }
447
+
448
+ this.setCopyableText();
449
+ priv.isTriggeredByCut = false;
450
+
451
+ var rangedData = this.getRangedData(this.copyableRanges);
452
+ var allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
453
+ var value = void 0;
454
+
455
+ if (allowCuttingOut) {
456
+ value = SheetClip.stringify(rangedData);
457
+
458
+ if (event && event.clipboardData) {
459
+ event.clipboardData.setData('text/plain', value);
460
+ } else if (typeof ClipboardEvent === 'undefined') {
461
+ window.clipboardData.setData('Text', value);
462
+ }
463
+
464
+ this.hot.selection.empty();
465
+ this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
466
+ }
467
+
468
+ event.preventDefault();
442
469
  }
443
470
 
444
471
  /**
445
- * `input` event callback is called after `paste` event callback.
472
+ * `paste` event callback on textarea element.
446
473
  *
474
+ * @param {Event} event ClipboardEvent or pseudo ClipboardEvent, if paste was called manually.
447
475
  * @private
448
476
  */
449
477
 
450
478
  }, {
451
- key: 'onInput',
452
- value: function onInput() {
479
+ key: 'onPaste',
480
+ value: function onPaste(event) {
453
481
  var _this6 = this;
454
482
 
455
- var priv = privatePool.get(this);
456
-
457
- if (!this.hot.isListening() || !priv.isTriggeredByPaste) {
483
+ if (!this.hot.isListening()) {
458
484
  return;
459
485
  }
486
+ if (event && event.preventDefault) {
487
+ event.preventDefault();
488
+ }
460
489
 
461
- priv.isTriggeredByPaste = false;
490
+ var inputArray = void 0;
462
491
 
463
- var input = void 0,
464
- inputArray = void 0,
465
- selected = void 0,
466
- coordsFrom = void 0,
467
- coordsTo = void 0,
468
- cellRange = void 0,
469
- topLeftCorner = void 0,
470
- bottomRightCorner = void 0,
471
- areaStart = void 0,
472
- areaEnd = void 0;
492
+ if (event && typeof event.clipboardData !== 'undefined') {
493
+ this.textarea.setValue(event.clipboardData.getData('text/plain'));
494
+ } else if (typeof ClipboardEvent === 'undefined' && typeof window.clipboardData !== 'undefined') {
495
+ this.textarea.setValue(window.clipboardData.getData('Text'));
496
+ }
497
+
498
+ inputArray = SheetClip.parse(this.textarea.getValue());
499
+ this.textarea.setValue(' ');
473
500
 
474
- input = this.textarea.getValue();
475
- inputArray = SheetClip.parse(input);
501
+ if (inputArray.length === 0) {
502
+ return;
503
+ }
476
504
 
477
505
  var allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges);
478
506
 
@@ -480,19 +508,19 @@ var CopyPaste = function (_BasePlugin) {
480
508
  return;
481
509
  }
482
510
 
483
- selected = this.hot.getSelected();
484
- coordsFrom = new CellCoords(selected[0], selected[1]);
485
- coordsTo = new CellCoords(selected[2], selected[3]);
486
- cellRange = new CellRange(coordsFrom, coordsFrom, coordsTo);
487
- topLeftCorner = cellRange.getTopLeftCorner();
488
- bottomRightCorner = cellRange.getBottomRightCorner();
489
- areaStart = topLeftCorner;
490
- areaEnd = new CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col));
511
+ var selected = this.hot.getSelected();
512
+ var coordsFrom = new CellCoords(selected[0], selected[1]);
513
+ var coordsTo = new CellCoords(selected[2], selected[3]);
514
+ var cellRange = new CellRange(coordsFrom, coordsFrom, coordsTo);
515
+ var topLeftCorner = cellRange.getTopLeftCorner();
516
+ var bottomRightCorner = cellRange.getBottomRightCorner();
517
+ var areaStart = topLeftCorner;
518
+ var areaEnd = new CellCoords(Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row), Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col));
491
519
 
492
520
  var isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1;
493
521
  var isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1;
494
522
 
495
- this.hot.addHookOnce('afterChange', function (changes, source) {
523
+ this.hot.addHookOnce('afterChange', function (changes) {
496
524
  var changesLength = changes ? changes.length : 0;
497
525
 
498
526
  if (changesLength) {
@@ -536,62 +564,26 @@ var CopyPaste = function (_BasePlugin) {
536
564
  }
537
565
 
538
566
  /**
539
- * beforeKeyDown callback.
567
+ * We have to keep focus on textarea element, to make possible use of the browser tools (copy, cut, paste).
540
568
  *
541
569
  * @private
542
- * @param {Event} event
543
570
  */
544
571
 
545
572
  }, {
546
- key: 'onBeforeKeyDown',
547
- value: function onBeforeKeyDown(event) {
548
- var _this7 = this;
573
+ key: 'onAfterSelectionEnd',
574
+ value: function onAfterSelectionEnd() {
575
+ var priv = privatePool.get(this);
576
+ var editor = this.hot.getActiveEditor();
549
577
 
550
- if (!this.hot.getSelected()) {
551
- return;
552
- }
553
- if (this.hot.getActiveEditor() && this.hot.getActiveEditor().isOpened()) {
554
- return;
555
- }
556
- if (isImmediatePropagationStopped(event)) {
557
- return;
558
- }
559
- if (!this.textarea.isActive() && getSelectionText()) {
578
+ if (editor && typeof editor.isOpened !== 'undefined' && editor.isOpened()) {
560
579
  return;
561
580
  }
562
-
563
- if (isCtrlKey(event.keyCode)) {
564
- // When fragmentSelection is enabled and some text is selected then don't blur selection calling 'setCopyableText'
565
- if (this.hot.getSettings().fragmentSelection && getSelectionText()) {
566
- return;
567
- }
568
-
569
- // when CTRL is pressed, prepare selectable text in textarea
570
- this.setCopyableText();
571
- stopImmediatePropagation(event);
572
-
581
+ if (priv.isFragmentSelectionEnabled && !this.textarea.isActive() && getSelectionText()) {
573
582
  return;
574
583
  }
575
584
 
576
- // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
577
- var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
578
-
579
- if (ctrlDown) {
580
- if (event.keyCode == KEY_CODES.A) {
581
- setTimeout(function () {
582
- _this7.setCopyableText();
583
- }, 0);
584
- }
585
- if (event.keyCode == KEY_CODES.X) {
586
- this.cut();
587
- }
588
- if (event.keyCode == KEY_CODES.C) {
589
- this.copy();
590
- }
591
- if (event.keyCode == KEY_CODES.V) {
592
- this.triggerPaste();
593
- }
594
- }
585
+ this.setCopyableText();
586
+ this.textarea.select();
595
587
  }
596
588
 
597
589
  /**
@@ -0,0 +1,11 @@
1
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
+
3
+ import ClipboardData from './clipboardData';
4
+
5
+ var PasteEvent = function PasteEvent() {
6
+ _classCallCheck(this, PasteEvent);
7
+
8
+ this.clipboardData = new ClipboardData();
9
+ };
10
+
11
+ export default PasteEvent;