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.
- package/.travis.yml +2 -0
- package/README.md +127 -96
- package/commonjs/core.js +11 -6
- package/commonjs/helpers/dom/element.js +4 -3
- package/commonjs/helpers/mixed.js +8 -4
- package/commonjs/index.js +5 -4
- package/commonjs/pluginHooks.js +18 -2
- package/commonjs/plugins/copyPaste/clipboardData.js +31 -0
- package/commonjs/plugins/copyPaste/contextMenuItem/copy.js +1 -2
- package/commonjs/plugins/copyPaste/contextMenuItem/cut.js +1 -2
- package/commonjs/plugins/copyPaste/copyPaste.js +127 -134
- package/commonjs/plugins/copyPaste/pasteEvent.js +19 -0
- package/commonjs/plugins/copyPaste/test/copyPaste.e2e.js +90 -189
- package/commonjs/plugins/copyPaste/test/textarea.unit.js +2 -2
- package/commonjs/plugins/copyPaste/textarea.js +2 -1
- package/commonjs/plugins/manualColumnMove/manualColumnMove.js +8 -11
- package/commonjs/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
- package/commonjs/plugins/manualRowMove/manualRowMove.js +9 -12
- package/commonjs/plugins/manualRowMove/test/manualRowMove.e2e.js +256 -60
- package/commonjs/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +40 -182
- package/commonjs/plugins/manualRowMove/ui/_base.js +2 -2
- package/commonjs/tableView.js +1 -0
- package/dist/handsontable.css +6 -5
- package/dist/handsontable.css.map +1 -1
- package/dist/handsontable.full.css +6 -5
- package/dist/handsontable.full.js +37721 -42290
- package/dist/handsontable.full.min.css +4 -4
- package/dist/handsontable.full.min.js +5 -5
- package/dist/handsontable.js +28732 -28433
- package/dist/handsontable.js.map +1 -1
- package/dist/handsontable.min.css +4 -4
- package/dist/handsontable.min.js +3 -3
- package/es/core.js +11 -6
- package/es/helpers/dom/element.js +4 -3
- package/es/helpers/mixed.js +4 -4
- package/es/index.js +3 -4
- package/es/pluginHooks.js +18 -2
- package/es/plugins/copyPaste/clipboardData.js +27 -0
- package/es/plugins/copyPaste/contextMenuItem/copy.js +1 -2
- package/es/plugins/copyPaste/contextMenuItem/cut.js +1 -2
- package/es/plugins/copyPaste/copyPaste.js +124 -132
- package/es/plugins/copyPaste/pasteEvent.js +11 -0
- package/es/plugins/copyPaste/test/copyPaste.e2e.js +90 -189
- package/es/plugins/copyPaste/test/textarea.unit.js +2 -2
- package/es/plugins/copyPaste/textarea.js +2 -1
- package/es/plugins/manualColumnMove/manualColumnMove.js +8 -11
- package/es/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
- package/es/plugins/manualRowMove/manualRowMove.js +9 -12
- package/es/plugins/manualRowMove/test/manualRowMove.e2e.js +256 -60
- package/es/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +40 -182
- package/es/plugins/manualRowMove/ui/_base.js +2 -2
- package/es/tableView.js +1 -0
- package/handsontable.jquery.json +1 -1
- package/hot.config.js +1 -1
- package/package.json +5 -5
- package/src/3rdparty/walkontable/dist/walkontable.js +27234 -11175
- package/src/3rdparty/walkontable/dist/walkontable.js.map +1 -1
- package/src/3rdparty/walkontable/test/dist/helpers.entry.js +32 -36
- package/src/3rdparty/walkontable/test/dist/helpers.entry.js.map +1 -1
- package/src/3rdparty/walkontable/test/dist/specs.entry.js +36 -39
- package/src/3rdparty/walkontable/test/dist/specs.entry.js.map +1 -1
- package/src/core.js +11 -6
- package/src/css/handsontable.css +1 -2
- package/src/helpers/dom/element.js +4 -3
- package/src/helpers/mixed.js +3 -3
- package/src/index.js +1 -2
- package/src/pluginHooks.js +18 -2
- package/src/plugins/copyPaste/clipboardData.js +11 -0
- package/src/plugins/copyPaste/contextMenuItem/copy.js +1 -2
- package/src/plugins/copyPaste/contextMenuItem/cut.js +1 -2
- package/src/plugins/copyPaste/copyPaste.css +3 -1
- package/src/plugins/copyPaste/copyPaste.js +120 -127
- package/src/plugins/copyPaste/pasteEvent.js +7 -0
- package/src/plugins/copyPaste/test/copyPaste.e2e.js +75 -193
- package/src/plugins/copyPaste/test/textarea.unit.js +2 -2
- package/src/plugins/copyPaste/textarea.js +2 -1
- package/src/plugins/manualColumnMove/manualColumnMove.js +6 -9
- package/src/plugins/manualColumnMove/test/manualColumnMoveUI.e2e.js +35 -0
- package/src/plugins/manualRowMove/manualRowMove.js +7 -10
- package/src/plugins/manualRowMove/test/manualRowMove.e2e.js +282 -86
- package/src/plugins/manualRowMove/test/manualRowMoveUI.e2e.js +51 -190
- package/src/plugins/manualRowMove/ui/_base.js +2 -2
- package/test/dist/e2e.entry.js +31381 -31131
- package/test/dist/e2e.entry.js.map +1 -1
- package/test/dist/helpers.entry.js +16 -19
- package/test/dist/helpers.entry.js.map +1 -1
- package/test/e2e/Core_listen.spec.js +32 -0
- package/test/e2e/Core_selection.spec.js +1 -1
- package/test/e2e/Core_validate.spec.js +29 -0
- package/test/e2e/renderers/checkboxRenderer.spec.js +20 -7
- package/test/e2e/settings/fragmentSelection.spec.js +12 -9
- package/test/scripts/trigger-pro-tests.sh +41 -0
- package/yarn.lock +260 -208
- package/.npmignore +0 -19
- package/demo/bower_components/numbro/package.json +0 -63
package/src/core.js
CHANGED
@@ -1049,7 +1049,7 @@ export default function Core(rootElement, userSettings, rootInstanceSymbol = fal
|
|
1049
1049
|
if (result === false && cellProperties.allowInvalid === false) {
|
1050
1050
|
changes.splice(i, 1); // cancel the change
|
1051
1051
|
cellProperties.valid = true; // we cancelled the change, so cell value is still valid
|
1052
|
-
const cell = instance.getCell(cellProperties.
|
1052
|
+
const cell = instance.getCell(cellProperties.visualRow, cellProperties.visualCol);
|
1053
1053
|
removeClass(cell, instance.getSettings().invalidCellClassName);
|
1054
1054
|
--i;
|
1055
1055
|
}
|
@@ -1305,7 +1305,10 @@ export default function Core(rootElement, userSettings, rootInstanceSymbol = fal
|
|
1305
1305
|
document.body.focus();
|
1306
1306
|
}
|
1307
1307
|
|
1308
|
-
|
1308
|
+
if (instance && !instance.isListening()) {
|
1309
|
+
activeGuid = instance.guid;
|
1310
|
+
instance.runHooks('afterListen');
|
1311
|
+
}
|
1309
1312
|
};
|
1310
1313
|
|
1311
1314
|
/**
|
@@ -1318,6 +1321,7 @@ export default function Core(rootElement, userSettings, rootInstanceSymbol = fal
|
|
1318
1321
|
this.unlisten = function() {
|
1319
1322
|
if (this.isListening()) {
|
1320
1323
|
activeGuid = null;
|
1324
|
+
instance.runHooks('afterUnlisten');
|
1321
1325
|
}
|
1322
1326
|
};
|
1323
1327
|
|
@@ -3058,7 +3062,6 @@ export default function Core(rootElement, userSettings, rootInstanceSymbol = fal
|
|
3058
3062
|
selection.setRangeEnd(new CellCoords(endRow, endCol), scrollToCell);
|
3059
3063
|
}
|
3060
3064
|
instance.selection.finish();
|
3061
|
-
|
3062
3065
|
return true;
|
3063
3066
|
};
|
3064
3067
|
|
@@ -3155,10 +3158,12 @@ export default function Core(rootElement, userSettings, rootInstanceSymbol = fal
|
|
3155
3158
|
}
|
3156
3159
|
dataSource = null;
|
3157
3160
|
|
3158
|
-
|
3161
|
+
if (process.env.HOT_PACKAGE_TYPE !== '\x63\x65' && isRootInstance(instance)) {
|
3162
|
+
const licenseInfo = document.querySelector('#hot-display-license-info');
|
3159
3163
|
|
3160
|
-
|
3161
|
-
|
3164
|
+
if (licenseInfo) {
|
3165
|
+
licenseInfo.parentNode.removeChild(licenseInfo);
|
3166
|
+
}
|
3162
3167
|
}
|
3163
3168
|
empty(instance.rootElement);
|
3164
3169
|
eventManager.destroy();
|
package/src/css/handsontable.css
CHANGED
@@ -287,7 +287,7 @@ if (classListSupport) {
|
|
287
287
|
|
288
288
|
_hasClass = function _hasClass(element, className) {
|
289
289
|
// http://snipplr.com/view/3561/addclass-removeclass-hasclass/
|
290
|
-
return element.className !== void 0 &&
|
290
|
+
return element.className !== void 0 && createClassNameRegExp(className).test(element.className);
|
291
291
|
};
|
292
292
|
|
293
293
|
_addClass = function _addClass(element, className) {
|
@@ -613,11 +613,12 @@ export function getScrollableElement(element) {
|
|
613
613
|
}
|
614
614
|
}
|
615
615
|
|
616
|
-
|
616
|
+
// The '+ 1' after the scrollHeight/scrollWidth is to prevent problems with zoomed out Chrome.
|
617
|
+
if (el.clientHeight <= el.scrollHeight + 1 && (props.indexOf(overflowY) !== -1 || props.indexOf(overflow) !== -1 ||
|
617
618
|
props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowY) !== -1)) {
|
618
619
|
return el;
|
619
620
|
}
|
620
|
-
if (el.clientWidth <= el.scrollWidth && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 ||
|
621
|
+
if (el.clientWidth <= el.scrollWidth + 1 && (props.indexOf(overflowX) !== -1 || props.indexOf(overflow) !== -1 ||
|
621
622
|
props.indexOf(computedOverflow) !== -1 || props.indexOf(computedOverflowX) !== -1)) {
|
622
623
|
return el;
|
623
624
|
}
|
package/src/helpers/mixed.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import moment from 'moment';
|
2
2
|
import {toSingleLine} from './templateLiteralTag';
|
3
3
|
|
4
4
|
/**
|
@@ -76,7 +76,7 @@ const _hd = (v) => parseInt(v, 16);
|
|
76
76
|
const _pi = (v) => parseInt(v, 10);
|
77
77
|
const _ss = (v, s, l) => v['\x73\x75\x62\x73\x74\x72'](s, l);
|
78
78
|
const _cp = (v) => v['\x63\x6F\x64\x65\x50\x6F\x69\x6E\x74\x41\x74'](0) - 65;
|
79
|
-
const _norm = (v) => v
|
79
|
+
const _norm = (v) => `${v}`.replace(/\-/g, '');
|
80
80
|
const _extractTime = (v) => _hd(_ss(_norm(v), _hd('12'), _cp('\x46'))) / (_hd(_ss(_norm(v), _cp('\x42'), ~~![][_m])) || 9);
|
81
81
|
const _ignored = () => typeof location !== 'undefined' && /^([a-z0-9\-]+\.)?\x68\x61\x6E\x64\x73\x6F\x6E\x74\x61\x62\x6C\x65\x2E\x63\x6F\x6D$/i.test(location.host);
|
82
82
|
let _notified = false;
|
@@ -128,7 +128,7 @@ export function _injectProductInfo(key, element) {
|
|
128
128
|
if (showDomMessage && element.parentNode) {
|
129
129
|
const message = document.createElement('div');
|
130
130
|
|
131
|
-
|
131
|
+
message.id = 'hot-display-license-info';
|
132
132
|
message.appendChild(document.createTextNode('Evaluation version of Handsontable Pro.'));
|
133
133
|
message.appendChild(document.createElement('br'));
|
134
134
|
message.appendChild(document.createTextNode('Not licensed for production use.'));
|
package/src/index.js
CHANGED
package/src/pluginHooks.js
CHANGED
@@ -1107,7 +1107,7 @@ const REGISTERED_HOOKS = [
|
|
1107
1107
|
/**
|
1108
1108
|
* Fired after values are pasted into table.
|
1109
1109
|
*
|
1110
|
-
* @event Hooks#
|
1110
|
+
* @event Hooks#afterPaste
|
1111
1111
|
* @since 0.31.1
|
1112
1112
|
* @param {Array} data An array of arrays which contains the pasted data.
|
1113
1113
|
* @param {Array} coords An array of objects with ranges of the visual indexes (`startRow`, `startCol`, `endRow`, `endCol`)
|
@@ -1484,7 +1484,23 @@ const REGISTERED_HOOKS = [
|
|
1484
1484
|
* @param {Number} row Row index of the edited cell.
|
1485
1485
|
* @param {Number} column Column index of the edited cell.
|
1486
1486
|
*/
|
1487
|
-
'afterBeginEditing'
|
1487
|
+
'afterBeginEditing',
|
1488
|
+
|
1489
|
+
/**
|
1490
|
+
* Fired after the listening is turned on.
|
1491
|
+
*
|
1492
|
+
* @event Hooks#afterListen
|
1493
|
+
* @since 0.34.5
|
1494
|
+
*/
|
1495
|
+
'afterListen',
|
1496
|
+
|
1497
|
+
/**
|
1498
|
+
* Fired after the listening is turned off.
|
1499
|
+
*
|
1500
|
+
* @event Hooks#afterUnlisten
|
1501
|
+
* @since 0.34.5
|
1502
|
+
*/
|
1503
|
+
'afterUnlisten',
|
1488
1504
|
];
|
1489
1505
|
|
1490
1506
|
class Hooks {
|
@@ -2,16 +2,15 @@ import BasePlugin from './../_base.js';
|
|
2
2
|
import Hooks from './../../pluginHooks';
|
3
3
|
import SheetClip from './../../../lib/SheetClip/SheetClip';
|
4
4
|
import {CellCoords, CellRange} from './../../3rdparty/walkontable/src';
|
5
|
-
import {KEY_CODES, isCtrlKey} from './../../helpers/unicode';
|
6
5
|
import {getSelectionText} from './../../helpers/dom/element';
|
7
6
|
import {arrayEach} from './../../helpers/array';
|
8
7
|
import {rangeEach} from './../../helpers/number';
|
9
|
-
import {stopImmediatePropagation, stopPropagation, isImmediatePropagationStopped} from './../../helpers/dom/event';
|
10
8
|
import {registerPlugin} from './../../plugins';
|
11
9
|
import Textarea from './textarea';
|
12
10
|
import copyItem from './contextMenuItem/copy';
|
13
11
|
import cutItem from './contextMenuItem/cut';
|
14
12
|
import EventManager from './../../eventManager';
|
13
|
+
import PasteEvent from './pasteEvent';
|
15
14
|
|
16
15
|
import './copyPaste.css';
|
17
16
|
|
@@ -94,7 +93,10 @@ class CopyPaste extends BasePlugin {
|
|
94
93
|
this.textarea = void 0;
|
95
94
|
|
96
95
|
privatePool.set(this, {
|
97
|
-
|
96
|
+
isTriggeredByCopy: false,
|
97
|
+
isTriggeredByCut: false,
|
98
|
+
isBeginEditing: false,
|
99
|
+
isFragmentSelectionEnabled: false,
|
98
100
|
});
|
99
101
|
}
|
100
102
|
|
@@ -114,10 +116,11 @@ class CopyPaste extends BasePlugin {
|
|
114
116
|
if (this.enabled) {
|
115
117
|
return;
|
116
118
|
}
|
117
|
-
|
118
119
|
const settings = this.hot.getSettings();
|
120
|
+
const priv = privatePool.get(this);
|
119
121
|
|
120
122
|
this.textarea = Textarea.getSingleton();
|
123
|
+
priv.isFragmentSelectionEnabled = settings.fragmentSelection;
|
121
124
|
|
122
125
|
if (typeof settings.copyPaste === 'object') {
|
123
126
|
this.pasteMode = settings.copyPaste.pasteMode || this.pasteMode;
|
@@ -126,12 +129,13 @@ class CopyPaste extends BasePlugin {
|
|
126
129
|
}
|
127
130
|
|
128
131
|
this.addHook('afterContextMenuDefaultOptions', (options) => this.onAfterContextMenuDefaultOptions(options));
|
129
|
-
this.addHook('
|
132
|
+
this.addHook('afterSelectionEnd', () => this.onAfterSelectionEnd());
|
130
133
|
|
131
134
|
this.registerEvents();
|
132
135
|
|
133
136
|
super.enablePlugin();
|
134
137
|
}
|
138
|
+
|
135
139
|
/**
|
136
140
|
* Updates the plugin to use the latest options you have specified.
|
137
141
|
*/
|
@@ -186,10 +190,6 @@ class CopyPaste extends BasePlugin {
|
|
186
190
|
|
187
191
|
this.copyableRanges = this.hot.runHooks('modifyCopyableRange', this.copyableRanges);
|
188
192
|
|
189
|
-
let copyableData = this.getRangedCopyableData(this.copyableRanges);
|
190
|
-
|
191
|
-
this.textarea.setValue(copyableData);
|
192
|
-
|
193
193
|
if (endRow !== finalEndRow || endCol !== finalEndCol) {
|
194
194
|
this.hot.runHooks('afterCopyLimit', endRow - startRow + 1, endCol - startCol + 1, this.rowsLimit, this.columnsLimit);
|
195
195
|
}
|
@@ -275,53 +275,26 @@ class CopyPaste extends BasePlugin {
|
|
275
275
|
|
276
276
|
/**
|
277
277
|
* Copy action.
|
278
|
-
*
|
279
|
-
* @param {Boolean} isTriggeredByClick Flag to determine that copy action was executed by the mouse click.
|
280
278
|
*/
|
281
|
-
copy(
|
282
|
-
|
283
|
-
|
284
|
-
let allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
|
285
|
-
|
286
|
-
if (allowCopying) {
|
287
|
-
this.textarea.setValue(SheetClip.stringify(rangedData));
|
288
|
-
this.textarea.select();
|
289
|
-
|
290
|
-
if (isTriggeredByClick) {
|
291
|
-
document.execCommand('copy');
|
292
|
-
}
|
279
|
+
copy() {
|
280
|
+
const priv = privatePool.get(this);
|
293
281
|
|
294
|
-
|
282
|
+
priv.isTriggeredByCopy = true;
|
295
283
|
|
296
|
-
|
297
|
-
|
298
|
-
}
|
284
|
+
this.textarea.select();
|
285
|
+
document.execCommand('copy');
|
299
286
|
}
|
300
287
|
|
301
288
|
/**
|
302
289
|
* Cut action.
|
303
|
-
*
|
304
|
-
* @param {Boolean} isTriggeredByClick Flag to determine that cut action was executed by the mouse click.
|
305
290
|
*/
|
306
|
-
cut(
|
307
|
-
|
308
|
-
|
309
|
-
let allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
|
310
|
-
|
311
|
-
if (allowCuttingOut) {
|
312
|
-
this.textarea.setValue(SheetClip.stringify(rangedData));
|
313
|
-
this.hot.selection.empty();
|
314
|
-
this.textarea.select();
|
315
|
-
|
316
|
-
if (isTriggeredByClick) {
|
317
|
-
document.execCommand('cut');
|
318
|
-
}
|
291
|
+
cut() {
|
292
|
+
const priv = privatePool.get(this);
|
319
293
|
|
320
|
-
|
294
|
+
priv.isTriggeredByCut = true;
|
321
295
|
|
322
|
-
|
323
|
-
|
324
|
-
}
|
296
|
+
this.textarea.select();
|
297
|
+
document.execCommand('cut');
|
325
298
|
}
|
326
299
|
|
327
300
|
/**
|
@@ -330,10 +303,10 @@ class CopyPaste extends BasePlugin {
|
|
330
303
|
* @param {String} [value=''] New value, which should be `pasted`.
|
331
304
|
*/
|
332
305
|
paste(value = '') {
|
333
|
-
|
306
|
+
let pasteData = new PasteEvent();
|
307
|
+
pasteData.clipboardData.setData('text/plain', value);
|
334
308
|
|
335
|
-
this.onPaste();
|
336
|
-
this.onInput();
|
309
|
+
this.onPaste(pasteData);
|
337
310
|
}
|
338
311
|
|
339
312
|
/**
|
@@ -343,58 +316,112 @@ class CopyPaste extends BasePlugin {
|
|
343
316
|
*/
|
344
317
|
registerEvents() {
|
345
318
|
this.eventManager.addEventListener(this.textarea.element, 'paste', (event) => this.onPaste(event));
|
346
|
-
this.eventManager.addEventListener(this.textarea.element, '
|
319
|
+
this.eventManager.addEventListener(this.textarea.element, 'cut', (event) => this.onCut(event));
|
320
|
+
this.eventManager.addEventListener(this.textarea.element, 'copy', (event) => this.onCopy(event));
|
347
321
|
}
|
348
322
|
|
349
323
|
/**
|
350
|
-
*
|
324
|
+
* `copy` event callback on textarea element.
|
351
325
|
*
|
326
|
+
* @param {Event} event ClipboardEvent.
|
352
327
|
* @private
|
353
328
|
*/
|
354
|
-
|
355
|
-
|
329
|
+
onCopy(event) {
|
330
|
+
const priv = privatePool.get(this);
|
331
|
+
|
332
|
+
if (!this.hot.isListening() && !priv.isTriggeredByCopy) {
|
333
|
+
return;
|
334
|
+
}
|
335
|
+
|
336
|
+
this.setCopyableText();
|
337
|
+
priv.isTriggeredByCopy = false;
|
338
|
+
|
339
|
+
let rangedData = this.getRangedData(this.copyableRanges);
|
340
|
+
let allowCopying = !!this.hot.runHooks('beforeCopy', rangedData, this.copyableRanges);
|
341
|
+
let value = '';
|
342
|
+
|
343
|
+
if (allowCopying) {
|
344
|
+
value = SheetClip.stringify(rangedData);
|
345
|
+
|
346
|
+
if (event && event.clipboardData) {
|
347
|
+
event.clipboardData.setData('text/plain', value);
|
348
|
+
|
349
|
+
} else if (typeof ClipboardEvent === 'undefined') {
|
350
|
+
window.clipboardData.setData('Text', value);
|
351
|
+
}
|
352
|
+
|
353
|
+
this.hot.runHooks('afterCopy', rangedData, this.copyableRanges);
|
354
|
+
}
|
356
355
|
|
357
|
-
|
356
|
+
event.preventDefault();
|
358
357
|
}
|
359
358
|
|
360
359
|
/**
|
361
|
-
* `
|
360
|
+
* `cut` event callback on textarea element.
|
362
361
|
*
|
362
|
+
* @param {Event} event ClipboardEvent.
|
363
363
|
* @private
|
364
364
|
*/
|
365
|
-
|
365
|
+
onCut(event) {
|
366
366
|
const priv = privatePool.get(this);
|
367
367
|
|
368
|
-
priv.
|
368
|
+
if (!this.hot.isListening() && !priv.isTriggeredByCut) {
|
369
|
+
return;
|
370
|
+
}
|
371
|
+
|
372
|
+
this.setCopyableText();
|
373
|
+
priv.isTriggeredByCut = false;
|
374
|
+
|
375
|
+
let rangedData = this.getRangedData(this.copyableRanges);
|
376
|
+
let allowCuttingOut = !!this.hot.runHooks('beforeCut', rangedData, this.copyableRanges);
|
377
|
+
let value;
|
378
|
+
|
379
|
+
if (allowCuttingOut) {
|
380
|
+
value = SheetClip.stringify(rangedData);
|
381
|
+
|
382
|
+
if (event && event.clipboardData) {
|
383
|
+
event.clipboardData.setData('text/plain', value);
|
384
|
+
|
385
|
+
} else if (typeof ClipboardEvent === 'undefined') {
|
386
|
+
window.clipboardData.setData('Text', value);
|
387
|
+
}
|
388
|
+
|
389
|
+
this.hot.selection.empty();
|
390
|
+
this.hot.runHooks('afterCut', rangedData, this.copyableRanges);
|
391
|
+
}
|
392
|
+
|
393
|
+
event.preventDefault();
|
369
394
|
}
|
370
395
|
|
371
396
|
/**
|
372
|
-
* `
|
397
|
+
* `paste` event callback on textarea element.
|
373
398
|
*
|
399
|
+
* @param {Event} event ClipboardEvent or pseudo ClipboardEvent, if paste was called manually.
|
374
400
|
* @private
|
375
401
|
*/
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
if (!this.hot.isListening() || !priv.isTriggeredByPaste) {
|
402
|
+
onPaste(event) {
|
403
|
+
if (!this.hot.isListening()) {
|
380
404
|
return;
|
381
405
|
}
|
406
|
+
if (event && event.preventDefault) {
|
407
|
+
event.preventDefault();
|
408
|
+
}
|
409
|
+
|
410
|
+
let inputArray;
|
382
411
|
|
383
|
-
|
412
|
+
if (event && typeof event.clipboardData !== 'undefined') {
|
413
|
+
this.textarea.setValue(event.clipboardData.getData('text/plain'));
|
384
414
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
topLeftCorner,
|
392
|
-
bottomRightCorner,
|
393
|
-
areaStart,
|
394
|
-
areaEnd;
|
415
|
+
} else if (typeof ClipboardEvent === 'undefined' && typeof window.clipboardData !== 'undefined') {
|
416
|
+
this.textarea.setValue(window.clipboardData.getData('Text'));
|
417
|
+
}
|
418
|
+
|
419
|
+
inputArray = SheetClip.parse(this.textarea.getValue());
|
420
|
+
this.textarea.setValue(' ');
|
395
421
|
|
396
|
-
|
397
|
-
|
422
|
+
if (inputArray.length === 0) {
|
423
|
+
return;
|
424
|
+
}
|
398
425
|
|
399
426
|
let allowPasting = !!this.hot.runHooks('beforePaste', inputArray, this.copyableRanges);
|
400
427
|
|
@@ -402,21 +429,21 @@ class CopyPaste extends BasePlugin {
|
|
402
429
|
return;
|
403
430
|
}
|
404
431
|
|
405
|
-
selected = this.hot.getSelected();
|
406
|
-
coordsFrom = new CellCoords(selected[0], selected[1]);
|
407
|
-
coordsTo = new CellCoords(selected[2], selected[3]);
|
408
|
-
cellRange = new CellRange(coordsFrom, coordsFrom, coordsTo);
|
409
|
-
topLeftCorner = cellRange.getTopLeftCorner();
|
410
|
-
bottomRightCorner = cellRange.getBottomRightCorner();
|
411
|
-
areaStart = topLeftCorner;
|
412
|
-
areaEnd = new CellCoords(
|
432
|
+
let selected = this.hot.getSelected();
|
433
|
+
let coordsFrom = new CellCoords(selected[0], selected[1]);
|
434
|
+
let coordsTo = new CellCoords(selected[2], selected[3]);
|
435
|
+
let cellRange = new CellRange(coordsFrom, coordsFrom, coordsTo);
|
436
|
+
let topLeftCorner = cellRange.getTopLeftCorner();
|
437
|
+
let bottomRightCorner = cellRange.getBottomRightCorner();
|
438
|
+
let areaStart = topLeftCorner;
|
439
|
+
let areaEnd = new CellCoords(
|
413
440
|
Math.max(bottomRightCorner.row, inputArray.length - 1 + topLeftCorner.row),
|
414
441
|
Math.max(bottomRightCorner.col, inputArray[0].length - 1 + topLeftCorner.col));
|
415
442
|
|
416
443
|
let isSelRowAreaCoverInputValue = coordsTo.row - coordsFrom.row >= inputArray.length - 1;
|
417
444
|
let isSelColAreaCoverInputValue = coordsTo.col - coordsFrom.col >= inputArray[0].length - 1;
|
418
445
|
|
419
|
-
this.hot.addHookOnce('afterChange', (changes
|
446
|
+
this.hot.addHookOnce('afterChange', (changes) => {
|
420
447
|
let changesLength = changes ? changes.length : 0;
|
421
448
|
|
422
449
|
if (changesLength) {
|
@@ -461,57 +488,23 @@ class CopyPaste extends BasePlugin {
|
|
461
488
|
}
|
462
489
|
|
463
490
|
/**
|
464
|
-
*
|
491
|
+
* We have to keep focus on textarea element, to make possible use of the browser tools (copy, cut, paste).
|
465
492
|
*
|
466
493
|
* @private
|
467
|
-
* @param {Event} event
|
468
494
|
*/
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
if (
|
474
|
-
return;
|
475
|
-
}
|
476
|
-
if (isImmediatePropagationStopped(event)) {
|
495
|
+
onAfterSelectionEnd() {
|
496
|
+
const priv = privatePool.get(this);
|
497
|
+
const editor = this.hot.getActiveEditor();
|
498
|
+
|
499
|
+
if (editor && typeof editor.isOpened !== 'undefined' && editor.isOpened()) {
|
477
500
|
return;
|
478
501
|
}
|
479
|
-
if (!this.textarea.isActive() && getSelectionText()) {
|
502
|
+
if (priv.isFragmentSelectionEnabled && !this.textarea.isActive() && getSelectionText()) {
|
480
503
|
return;
|
481
504
|
}
|
482
505
|
|
483
|
-
|
484
|
-
|
485
|
-
if (this.hot.getSettings().fragmentSelection && getSelectionText()) {
|
486
|
-
return;
|
487
|
-
}
|
488
|
-
|
489
|
-
// when CTRL is pressed, prepare selectable text in textarea
|
490
|
-
this.setCopyableText();
|
491
|
-
stopImmediatePropagation(event);
|
492
|
-
|
493
|
-
return;
|
494
|
-
}
|
495
|
-
|
496
|
-
// catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
|
497
|
-
let ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
|
498
|
-
|
499
|
-
if (ctrlDown) {
|
500
|
-
if (event.keyCode == KEY_CODES.A) {
|
501
|
-
setTimeout(() => {
|
502
|
-
this.setCopyableText();
|
503
|
-
}, 0);
|
504
|
-
}
|
505
|
-
if (event.keyCode == KEY_CODES.X) {
|
506
|
-
this.cut();
|
507
|
-
}
|
508
|
-
if (event.keyCode == KEY_CODES.C) {
|
509
|
-
this.copy();
|
510
|
-
}
|
511
|
-
if (event.keyCode == KEY_CODES.V) {
|
512
|
-
this.triggerPaste();
|
513
|
-
}
|
514
|
-
}
|
506
|
+
this.setCopyableText();
|
507
|
+
this.textarea.select();
|
515
508
|
}
|
516
509
|
|
517
510
|
/**
|