handsontable 0.0.0-next-442b0cf-20241209 → 0.0.0-next-aa821c7-20241209
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/base.js +2 -2
- package/base.mjs +2 -2
- package/core.js +1 -7
- package/core.mjs +1 -7
- package/dataMap/metaManager/metaSchema.js +2 -3
- package/dataMap/metaManager/metaSchema.mjs +2 -3
- package/dist/handsontable.css +12 -2
- package/dist/handsontable.full.css +12 -2
- package/dist/handsontable.full.js +1438 -864
- package/dist/handsontable.full.min.css +3 -3
- package/dist/handsontable.full.min.js +9 -7
- package/dist/handsontable.js +1437 -863
- package/dist/handsontable.min.css +3 -3
- package/dist/handsontable.min.js +35 -33
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/plugins/base/base.js +0 -7
- package/plugins/base/base.mjs +0 -7
- package/plugins/undoRedo/actions/_base.js +19 -0
- package/plugins/undoRedo/actions/_base.mjs +15 -0
- package/plugins/undoRedo/actions/cellAlignment.js +85 -0
- package/plugins/undoRedo/actions/cellAlignment.mjs +81 -0
- package/plugins/undoRedo/actions/columnMove.js +84 -0
- package/plugins/undoRedo/actions/columnMove.mjs +80 -0
- package/plugins/undoRedo/actions/columnSort.js +73 -0
- package/plugins/undoRedo/actions/columnSort.mjs +69 -0
- package/plugins/undoRedo/actions/createColumn.js +60 -0
- package/plugins/undoRedo/actions/createColumn.mjs +56 -0
- package/plugins/undoRedo/actions/createRow.js +65 -0
- package/plugins/undoRedo/actions/createRow.mjs +61 -0
- package/plugins/undoRedo/actions/dataChange.js +114 -0
- package/plugins/undoRedo/actions/dataChange.mjs +110 -0
- package/plugins/undoRedo/actions/filters.js +68 -0
- package/plugins/undoRedo/actions/filters.mjs +64 -0
- package/plugins/undoRedo/actions/index.js +27 -0
- package/plugins/undoRedo/actions/index.mjs +23 -0
- package/plugins/undoRedo/actions/mergeCells.js +63 -0
- package/plugins/undoRedo/actions/mergeCells.mjs +59 -0
- package/plugins/undoRedo/actions/removeColumn.js +176 -0
- package/plugins/undoRedo/actions/removeColumn.mjs +172 -0
- package/plugins/undoRedo/actions/removeRow.js +119 -0
- package/plugins/undoRedo/actions/removeRow.mjs +115 -0
- package/plugins/undoRedo/actions/rowMove.js +84 -0
- package/plugins/undoRedo/actions/rowMove.mjs +80 -0
- package/plugins/undoRedo/actions/unmergeCells.js +56 -0
- package/plugins/undoRedo/actions/unmergeCells.mjs +52 -0
- package/plugins/undoRedo/index.js +3 -4
- package/plugins/undoRedo/index.mjs +1 -2
- package/plugins/undoRedo/undoRedo.js +277 -879
- package/plugins/undoRedo/undoRedo.mjs +277 -880
- package/plugins/undoRedo/utils.js +37 -0
- package/plugins/undoRedo/utils.mjs +33 -0
- package/styles/handsontable.css +9 -2
- package/styles/handsontable.min.css +3 -3
- package/styles/ht-theme-horizon.css +2 -2
- package/styles/ht-theme-horizon.min.css +2 -2
- package/styles/ht-theme-main.css +2 -2
- package/styles/ht-theme-main.min.css +2 -2
- package/utils/ghostTable.js +1 -5
- package/utils/ghostTable.mjs +1 -5
@@ -1,21 +1,35 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
+
require("core-js/modules/es.error.cause.js");
|
3
4
|
exports.__esModule = true;
|
4
5
|
require("core-js/modules/es.array.push.js");
|
5
|
-
require("core-js/modules/es.
|
6
|
-
require("core-js/modules/
|
7
|
-
require("core-js/modules/
|
8
|
-
require("core-js/modules/
|
9
|
-
require("core-js/modules/
|
10
|
-
require("core-js/modules/
|
6
|
+
require("core-js/modules/es.set.difference.v2.js");
|
7
|
+
require("core-js/modules/es.set.intersection.v2.js");
|
8
|
+
require("core-js/modules/es.set.is-disjoint-from.v2.js");
|
9
|
+
require("core-js/modules/es.set.is-subset-of.v2.js");
|
10
|
+
require("core-js/modules/es.set.is-superset-of.v2.js");
|
11
|
+
require("core-js/modules/es.set.symmetric-difference.v2.js");
|
12
|
+
require("core-js/modules/es.set.union.v2.js");
|
13
|
+
var _base = require("../base");
|
11
14
|
var _hooks = require("../../core/hooks");
|
12
|
-
var _array = require("../../helpers/array");
|
13
|
-
var _number = require("../../helpers/number");
|
14
15
|
var _object = require("../../helpers/object");
|
15
|
-
var
|
16
|
-
var
|
16
|
+
var _templateLiteralTag = require("../../helpers/templateLiteralTag");
|
17
|
+
var _console = require("../../helpers/console");
|
18
|
+
var _actions = require("./actions");
|
19
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
20
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
21
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
23
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
24
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
17
25
|
const SHORTCUTS_GROUP = 'undoRedo';
|
18
26
|
const PLUGIN_KEY = exports.PLUGIN_KEY = 'undoRedo';
|
27
|
+
const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 1000;
|
28
|
+
_hooks.Hooks.getSingleton().register('beforeUndo');
|
29
|
+
_hooks.Hooks.getSingleton().register('afterUndo');
|
30
|
+
_hooks.Hooks.getSingleton().register('beforeRedo');
|
31
|
+
_hooks.Hooks.getSingleton().register('afterRedo');
|
32
|
+
const deprecationWarns = new Set();
|
19
33
|
|
20
34
|
/**
|
21
35
|
* @description
|
@@ -28,910 +42,305 @@ const PLUGIN_KEY = exports.PLUGIN_KEY = 'undoRedo';
|
|
28
42
|
* ```
|
29
43
|
* @class UndoRedo
|
30
44
|
* @plugin UndoRedo
|
31
|
-
* @param {Core} instance The Handsontable instance.
|
32
45
|
*/
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
var _UndoRedo_brand = /*#__PURE__*/new WeakSet();
|
47
|
+
class UndoRedo extends _base.BasePlugin {
|
48
|
+
static get PLUGIN_KEY() {
|
49
|
+
return PLUGIN_KEY;
|
50
|
+
}
|
51
|
+
static get PLUGIN_PRIORITY() {
|
52
|
+
return PLUGIN_PRIORITY;
|
53
|
+
}
|
54
|
+
static get SETTING_KEYS() {
|
55
|
+
return true;
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* The list of registered action do undo.
|
60
|
+
*
|
61
|
+
* @private
|
62
|
+
* @type {Array}
|
63
|
+
*/
|
64
|
+
|
65
|
+
constructor(hotInstance) {
|
66
|
+
super(hotInstance);
|
67
|
+
/**
|
68
|
+
* Listens to the data change and if the source is `loadData` then clears the undo and redo history.
|
69
|
+
*
|
70
|
+
* @param {Array} changes The data changes.
|
71
|
+
* @param {string} source The source of the change.
|
72
|
+
*/
|
73
|
+
_classPrivateMethodInitSpec(this, _UndoRedo_brand);
|
74
|
+
_defineProperty(this, "doneActions", []);
|
75
|
+
/**
|
76
|
+
* The list of registered action do redo.
|
77
|
+
*
|
78
|
+
* @private
|
79
|
+
* @type {Array}
|
80
|
+
*/
|
81
|
+
_defineProperty(this, "undoneActions", []);
|
82
|
+
/**
|
83
|
+
* The flag that determines if new actions should be ignored.
|
84
|
+
*
|
85
|
+
* @private
|
86
|
+
* @type {boolean}
|
87
|
+
*/
|
88
|
+
_defineProperty(this, "ignoreNewActions", false);
|
89
|
+
(0, _actions.registerActions)(hotInstance, this);
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
|
94
|
+
* hook and if it returns `true` then the {@link UndoRedo#enablePlugin} method is called.
|
95
|
+
*
|
96
|
+
* @returns {boolean}
|
97
|
+
*/
|
98
|
+
isEnabled() {
|
99
|
+
return !!this.hot.getSettings().undo;
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Enables the plugin functionality for this Handsontable instance.
|
104
|
+
*/
|
105
|
+
enablePlugin() {
|
106
|
+
var _this = this;
|
107
|
+
if (this.enabled) {
|
43
108
|
return;
|
44
109
|
}
|
45
|
-
|
46
|
-
|
47
|
-
|
110
|
+
this.addHook('afterChange', function () {
|
111
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
112
|
+
args[_key] = arguments[_key];
|
113
|
+
}
|
114
|
+
return _assertClassBrand(_UndoRedo_brand, _this, _onAfterChange).call(_this, ...args);
|
48
115
|
});
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
116
|
+
this.registerShortcuts();
|
117
|
+
_assertClassBrand(_UndoRedo_brand, this, _exposeAPIToCore).call(this);
|
118
|
+
super.enablePlugin();
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Disables the plugin functionality for this Handsontable instance.
|
123
|
+
*/
|
124
|
+
disablePlugin() {
|
125
|
+
super.disablePlugin();
|
126
|
+
this.clear();
|
127
|
+
this.unregisterShortcuts();
|
128
|
+
_assertClassBrand(_UndoRedo_brand, this, _removeAPIFromCore).call(this);
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Registers shortcuts responsible for performing undo/redo.
|
133
|
+
*
|
134
|
+
* @private
|
135
|
+
*/
|
136
|
+
registerShortcuts() {
|
137
|
+
const shortcutManager = this.hot.getShortcutManager();
|
138
|
+
const gridContext = shortcutManager.getContext('grid');
|
139
|
+
const runOnlyIf = event => {
|
140
|
+
return !event.altKey; // right ALT in some systems triggers ALT+CTR
|
62
141
|
};
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
plugin.done(() => new UndoRedo.CreateRowAction(index, amount), source);
|
67
|
-
});
|
68
|
-
const getCellMetas = (fromRow, toRow, fromColumn, toColumn) => {
|
69
|
-
const genericKeys = ['visualRow', 'visualCol', 'row', 'col', 'prop'];
|
70
|
-
const genericKeysLength = genericKeys.length;
|
71
|
-
const cellMetas = [];
|
72
|
-
(0, _number.rangeEach)(fromColumn, toColumn, columnIndex => {
|
73
|
-
(0, _number.rangeEach)(fromRow, toRow, rowIndex => {
|
74
|
-
const cellMeta = instance.getCellMeta(rowIndex, columnIndex);
|
75
|
-
if (Object.keys(cellMeta).length !== genericKeysLength) {
|
76
|
-
const uniqueMeta = Object.fromEntries(Object.entries(cellMeta).filter(_ref => {
|
77
|
-
let [key] = _ref;
|
78
|
-
return genericKeys.includes(key) === false;
|
79
|
-
}));
|
80
|
-
cellMetas.push([cellMeta.visualRow, cellMeta.visualCol, uniqueMeta]);
|
81
|
-
}
|
82
|
-
});
|
83
|
-
});
|
84
|
-
return cellMetas;
|
85
|
-
};
|
86
|
-
instance.addHook('beforeRemoveRow', (index, amount, logicRows, source) => {
|
87
|
-
const wrappedAction = () => {
|
88
|
-
const physicalRowIndex = instance.toPhysicalRow(index);
|
89
|
-
const lastRowIndex = physicalRowIndex + amount - 1;
|
90
|
-
const removedData = (0, _object.deepClone)(plugin.instance.getSourceData(physicalRowIndex, 0, physicalRowIndex + amount - 1, plugin.instance.countSourceCols() - 1));
|
91
|
-
return new UndoRedo.RemoveRowAction(physicalRowIndex, removedData, instance.getSettings().fixedRowsBottom, instance.getSettings().fixedRowsTop, instance.rowIndexMapper.getIndexesSequence(), getCellMetas(physicalRowIndex, lastRowIndex, 0, instance.countCols() - 1));
|
142
|
+
const config = {
|
143
|
+
runOnlyIf,
|
144
|
+
group: SHORTCUTS_GROUP
|
92
145
|
};
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
});
|
98
|
-
instance.addHook('beforeRemoveCol', (index, amount, logicColumns, source) => {
|
99
|
-
const wrappedAction = () => {
|
100
|
-
const originalData = plugin.instance.getSourceDataArray();
|
101
|
-
const columnIndex = (plugin.instance.countCols() + index) % plugin.instance.countCols();
|
102
|
-
const lastColumnIndex = columnIndex + amount - 1;
|
103
|
-
const removedData = [];
|
104
|
-
const headers = [];
|
105
|
-
const indexes = [];
|
106
|
-
(0, _number.rangeEach)(originalData.length - 1, i => {
|
107
|
-
const column = [];
|
108
|
-
const origRow = originalData[i];
|
109
|
-
(0, _number.rangeEach)(columnIndex, lastColumnIndex, j => {
|
110
|
-
column.push(origRow[instance.toPhysicalColumn(j)]);
|
111
|
-
});
|
112
|
-
removedData.push(column);
|
113
|
-
});
|
114
|
-
(0, _number.rangeEach)(amount - 1, i => {
|
115
|
-
indexes.push(instance.toPhysicalColumn(columnIndex + i));
|
116
|
-
});
|
117
|
-
if (Array.isArray(instance.getSettings().colHeaders)) {
|
118
|
-
(0, _number.rangeEach)(amount - 1, i => {
|
119
|
-
headers.push(instance.getSettings().colHeaders[instance.toPhysicalColumn(columnIndex + i)] || null);
|
120
|
-
});
|
146
|
+
gridContext.addShortcuts([{
|
147
|
+
keys: [['Control/Meta', 'z']],
|
148
|
+
callback: () => {
|
149
|
+
this.undo();
|
121
150
|
}
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
}
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
151
|
+
}, {
|
152
|
+
keys: [['Control/Meta', 'y'], ['Control/Meta', 'Shift', 'z']],
|
153
|
+
callback: () => {
|
154
|
+
this.redo();
|
155
|
+
}
|
156
|
+
}], config);
|
157
|
+
}
|
158
|
+
|
159
|
+
/**
|
160
|
+
* Unregister shortcuts responsible for performing undo/redo.
|
161
|
+
*
|
162
|
+
* @private
|
163
|
+
*/
|
164
|
+
unregisterShortcuts() {
|
165
|
+
const shortcutManager = this.hot.getShortcutManager();
|
166
|
+
const gridContext = shortcutManager.getContext('grid');
|
167
|
+
gridContext.removeShortcutsByGroup(SHORTCUTS_GROUP);
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Stash information about performed actions.
|
172
|
+
*
|
173
|
+
* @fires Hooks#beforeUndoStackChange
|
174
|
+
* @fires Hooks#afterUndoStackChange
|
175
|
+
* @fires Hooks#beforeRedoStackChange
|
176
|
+
* @fires Hooks#afterRedoStackChange
|
177
|
+
* @param {Function} wrappedAction The action descriptor wrapped in a closure.
|
178
|
+
* @param {string} [source] Source of the action. It is defined just for more general actions (not related to plugins).
|
179
|
+
*/
|
180
|
+
done(wrappedAction, source) {
|
181
|
+
if (this.ignoreNewActions) {
|
148
182
|
return;
|
149
183
|
}
|
150
|
-
|
151
|
-
|
152
|
-
instance.addHook('afterUnmergeCells', (cellRange, auto) => {
|
153
|
-
if (auto) {
|
184
|
+
const isBlockedByDefault = source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto';
|
185
|
+
if (isBlockedByDefault) {
|
154
186
|
return;
|
155
187
|
}
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
if (!sortPossible) {
|
188
|
+
const doneActionsCopy = this.doneActions.slice();
|
189
|
+
const continueAction = this.hot.runHooks('beforeUndoStackChange', doneActionsCopy, source);
|
190
|
+
if (continueAction === false) {
|
160
191
|
return;
|
161
192
|
}
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
}
|
170
|
-
|
171
|
-
/**
|
172
|
-
* Stash information about performed actions.
|
173
|
-
*
|
174
|
-
* @function done
|
175
|
-
* @memberof UndoRedo#
|
176
|
-
* @fires Hooks#beforeUndoStackChange
|
177
|
-
* @fires Hooks#afterUndoStackChange
|
178
|
-
* @fires Hooks#beforeRedoStackChange
|
179
|
-
* @fires Hooks#afterRedoStackChange
|
180
|
-
* @param {Function} wrappedAction The action descriptor wrapped in a closure.
|
181
|
-
* @param {string} [source] Source of the action. It is defined just for more general actions (not related to plugins).
|
182
|
-
*/
|
183
|
-
UndoRedo.prototype.done = function (wrappedAction, source) {
|
184
|
-
if (this.ignoreNewActions) {
|
185
|
-
return;
|
186
|
-
}
|
187
|
-
const isBlockedByDefault = source === 'UndoRedo.undo' || source === 'UndoRedo.redo' || source === 'auto';
|
188
|
-
if (isBlockedByDefault) {
|
189
|
-
return;
|
190
|
-
}
|
191
|
-
const doneActionsCopy = this.doneActions.slice();
|
192
|
-
const continueAction = this.instance.runHooks('beforeUndoStackChange', doneActionsCopy, source);
|
193
|
-
if (continueAction === false) {
|
194
|
-
return;
|
193
|
+
const newAction = wrappedAction();
|
194
|
+
const undoneActionsCopy = this.undoneActions.slice();
|
195
|
+
this.doneActions.push(newAction);
|
196
|
+
this.hot.runHooks('afterUndoStackChange', doneActionsCopy, this.doneActions.slice());
|
197
|
+
this.hot.runHooks('beforeRedoStackChange', undoneActionsCopy);
|
198
|
+
this.undoneActions.length = 0;
|
199
|
+
this.hot.runHooks('afterRedoStackChange', undoneActionsCopy, this.undoneActions.slice());
|
195
200
|
}
|
196
|
-
const newAction = wrappedAction();
|
197
|
-
const undoneActionsCopy = this.undoneActions.slice();
|
198
|
-
this.doneActions.push(newAction);
|
199
|
-
this.instance.runHooks('afterUndoStackChange', doneActionsCopy, this.doneActions.slice());
|
200
|
-
this.instance.runHooks('beforeRedoStackChange', undoneActionsCopy);
|
201
|
-
this.undoneActions.length = 0;
|
202
|
-
this.instance.runHooks('afterRedoStackChange', undoneActionsCopy, this.undoneActions.slice());
|
203
|
-
};
|
204
201
|
|
205
|
-
/**
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
202
|
+
/**
|
203
|
+
* Undo the last action performed to the table.
|
204
|
+
*
|
205
|
+
* @fires Hooks#beforeUndoStackChange
|
206
|
+
* @fires Hooks#afterUndoStackChange
|
207
|
+
* @fires Hooks#beforeRedoStackChange
|
208
|
+
* @fires Hooks#afterRedoStackChange
|
209
|
+
* @fires Hooks#beforeUndo
|
210
|
+
* @fires Hooks#afterUndo
|
211
|
+
*/
|
212
|
+
undo() {
|
213
|
+
if (!this.isUndoAvailable()) {
|
214
|
+
return;
|
215
|
+
}
|
219
216
|
const doneActionsCopy = this.doneActions.slice();
|
220
|
-
this.
|
217
|
+
this.hot.runHooks('beforeUndoStackChange', doneActionsCopy);
|
221
218
|
const action = this.doneActions.pop();
|
222
|
-
this.
|
219
|
+
this.hot.runHooks('afterUndoStackChange', doneActionsCopy, this.doneActions.slice());
|
223
220
|
const actionClone = (0, _object.deepClone)(action);
|
224
|
-
const continueAction = this.
|
221
|
+
const continueAction = this.hot.runHooks('beforeUndo', actionClone);
|
225
222
|
if (continueAction === false) {
|
226
223
|
return;
|
227
224
|
}
|
228
225
|
this.ignoreNewActions = true;
|
229
|
-
const that = this;
|
230
226
|
const undoneActionsCopy = this.undoneActions.slice();
|
231
|
-
this.
|
232
|
-
action.undo(this.
|
233
|
-
|
234
|
-
|
227
|
+
this.hot.runHooks('beforeRedoStackChange', undoneActionsCopy);
|
228
|
+
action.undo(this.hot, () => {
|
229
|
+
this.ignoreNewActions = false;
|
230
|
+
this.undoneActions.push(action);
|
235
231
|
});
|
236
|
-
this.
|
237
|
-
this.
|
232
|
+
this.hot.runHooks('afterRedoStackChange', undoneActionsCopy, this.undoneActions.slice());
|
233
|
+
this.hot.runHooks('afterUndo', actionClone);
|
238
234
|
}
|
239
|
-
};
|
240
235
|
|
241
|
-
/**
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
236
|
+
/**
|
237
|
+
* Redo the previous action performed to the table (used to reverse an undo).
|
238
|
+
*
|
239
|
+
* @fires Hooks#beforeUndoStackChange
|
240
|
+
* @fires Hooks#afterUndoStackChange
|
241
|
+
* @fires Hooks#beforeRedoStackChange
|
242
|
+
* @fires Hooks#afterRedoStackChange
|
243
|
+
* @fires Hooks#beforeRedo
|
244
|
+
* @fires Hooks#afterRedo
|
245
|
+
*/
|
246
|
+
redo() {
|
247
|
+
if (!this.isRedoAvailable()) {
|
248
|
+
return;
|
249
|
+
}
|
255
250
|
const undoneActionsCopy = this.undoneActions.slice();
|
256
|
-
this.
|
251
|
+
this.hot.runHooks('beforeRedoStackChange', undoneActionsCopy);
|
257
252
|
const action = this.undoneActions.pop();
|
258
|
-
this.
|
253
|
+
this.hot.runHooks('afterRedoStackChange', undoneActionsCopy, this.undoneActions.slice());
|
259
254
|
const actionClone = (0, _object.deepClone)(action);
|
260
|
-
const continueAction = this.
|
255
|
+
const continueAction = this.hot.runHooks('beforeRedo', actionClone);
|
261
256
|
if (continueAction === false) {
|
262
257
|
return;
|
263
258
|
}
|
264
259
|
this.ignoreNewActions = true;
|
265
|
-
const that = this;
|
266
260
|
const doneActionsCopy = this.doneActions.slice();
|
267
|
-
this.
|
268
|
-
action.redo(this.
|
269
|
-
|
270
|
-
|
261
|
+
this.hot.runHooks('beforeUndoStackChange', doneActionsCopy);
|
262
|
+
action.redo(this.hot, () => {
|
263
|
+
this.ignoreNewActions = false;
|
264
|
+
this.doneActions.push(action);
|
271
265
|
});
|
272
|
-
this.
|
273
|
-
this.
|
266
|
+
this.hot.runHooks('afterUndoStackChange', doneActionsCopy, this.doneActions.slice());
|
267
|
+
this.hot.runHooks('afterRedo', actionClone);
|
274
268
|
}
|
275
|
-
};
|
276
|
-
|
277
|
-
/**
|
278
|
-
* Checks if undo action is available.
|
279
|
-
*
|
280
|
-
* @function isUndoAvailable
|
281
|
-
* @memberof UndoRedo#
|
282
|
-
* @returns {boolean} Return `true` if undo can be performed, `false` otherwise.
|
283
|
-
*/
|
284
|
-
UndoRedo.prototype.isUndoAvailable = function () {
|
285
|
-
return this.doneActions.length > 0;
|
286
|
-
};
|
287
|
-
|
288
|
-
/**
|
289
|
-
* Checks if redo action is available.
|
290
|
-
*
|
291
|
-
* @function isRedoAvailable
|
292
|
-
* @memberof UndoRedo#
|
293
|
-
* @returns {boolean} Return `true` if redo can be performed, `false` otherwise.
|
294
|
-
*/
|
295
|
-
UndoRedo.prototype.isRedoAvailable = function () {
|
296
|
-
return this.undoneActions.length > 0;
|
297
|
-
};
|
298
269
|
|
299
|
-
/**
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
this.doneActions.length = 0;
|
307
|
-
this.undoneActions.length = 0;
|
308
|
-
};
|
309
|
-
|
310
|
-
/**
|
311
|
-
* Checks if the plugin is enabled.
|
312
|
-
*
|
313
|
-
* @function isEnabled
|
314
|
-
* @memberof UndoRedo#
|
315
|
-
* @returns {boolean}
|
316
|
-
*/
|
317
|
-
UndoRedo.prototype.isEnabled = function () {
|
318
|
-
return this.enabled;
|
319
|
-
};
|
320
|
-
|
321
|
-
/**
|
322
|
-
* Enables the plugin.
|
323
|
-
*
|
324
|
-
* @function enable
|
325
|
-
* @memberof UndoRedo#
|
326
|
-
*/
|
327
|
-
UndoRedo.prototype.enable = function () {
|
328
|
-
if (this.isEnabled()) {
|
329
|
-
return;
|
330
|
-
}
|
331
|
-
const hot = this.instance;
|
332
|
-
this.enabled = true;
|
333
|
-
exposeUndoRedoMethods(hot);
|
334
|
-
this.registerShortcuts();
|
335
|
-
hot.addHook('afterChange', onAfterChange);
|
336
|
-
};
|
337
|
-
|
338
|
-
/**
|
339
|
-
* Disables the plugin.
|
340
|
-
*
|
341
|
-
* @function disable
|
342
|
-
* @memberof UndoRedo#
|
343
|
-
*/
|
344
|
-
UndoRedo.prototype.disable = function () {
|
345
|
-
if (!this.isEnabled()) {
|
346
|
-
return;
|
347
|
-
}
|
348
|
-
const hot = this.instance;
|
349
|
-
this.enabled = false;
|
350
|
-
removeExposedUndoRedoMethods(hot);
|
351
|
-
this.unregisterShortcuts();
|
352
|
-
hot.removeHook('afterChange', onAfterChange);
|
353
|
-
};
|
354
|
-
|
355
|
-
/**
|
356
|
-
* Destroys the instance.
|
357
|
-
*
|
358
|
-
* @function destroy
|
359
|
-
* @memberof UndoRedo#
|
360
|
-
*/
|
361
|
-
UndoRedo.prototype.destroy = function () {
|
362
|
-
this.clear();
|
363
|
-
this.instance = null;
|
364
|
-
this.doneActions = null;
|
365
|
-
this.undoneActions = null;
|
366
|
-
};
|
367
|
-
UndoRedo.Action = function () {};
|
368
|
-
UndoRedo.Action.prototype.undo = function () {};
|
369
|
-
UndoRedo.Action.prototype.redo = function () {};
|
370
|
-
|
371
|
-
/**
|
372
|
-
* Change action.
|
373
|
-
*
|
374
|
-
* @private
|
375
|
-
* @param {Array} changes 2D array containing information about each of the edited cells.
|
376
|
-
* @param {number[]} selected The cell selection.
|
377
|
-
*/
|
378
|
-
UndoRedo.ChangeAction = function (changes, selected) {
|
379
|
-
this.changes = changes;
|
380
|
-
this.selected = selected;
|
381
|
-
this.actionType = 'change';
|
382
|
-
};
|
383
|
-
(0, _object.inherit)(UndoRedo.ChangeAction, UndoRedo.Action);
|
384
|
-
UndoRedo.ChangeAction.prototype.undo = function (instance, undoneCallback) {
|
385
|
-
const data = (0, _object.deepClone)(this.changes);
|
386
|
-
const emptyRowsAtTheEnd = instance.countEmptyRows(true);
|
387
|
-
const emptyColsAtTheEnd = instance.countEmptyCols(true);
|
388
|
-
for (let i = 0, len = data.length; i < len; i++) {
|
389
|
-
data[i].splice(3, 1);
|
390
|
-
}
|
391
|
-
instance.addHookOnce('afterChange', undoneCallback);
|
392
|
-
instance.setDataAtCell(data, null, null, 'UndoRedo.undo');
|
393
|
-
for (let i = 0, len = data.length; i < len; i++) {
|
394
|
-
const [row, column] = data[i];
|
395
|
-
if (instance.getSettings().minSpareRows && row + 1 + instance.getSettings().minSpareRows === instance.countRows() && emptyRowsAtTheEnd === instance.getSettings().minSpareRows) {
|
396
|
-
instance.alter('remove_row', parseInt(row + 1, 10), instance.getSettings().minSpareRows);
|
397
|
-
instance.undoRedo.doneActions.pop();
|
398
|
-
}
|
399
|
-
if (instance.getSettings().minSpareCols && column + 1 + instance.getSettings().minSpareCols === instance.countCols() && emptyColsAtTheEnd === instance.getSettings().minSpareCols) {
|
400
|
-
instance.alter('remove_col', parseInt(column + 1, 10), instance.getSettings().minSpareCols);
|
401
|
-
instance.undoRedo.doneActions.pop();
|
402
|
-
}
|
403
|
-
}
|
404
|
-
const selectedLast = instance.getSelectedLast();
|
405
|
-
if (selectedLast !== undefined) {
|
406
|
-
const [changedRow, changedColumn] = data[0];
|
407
|
-
const [selectedRow, selectedColumn] = selectedLast;
|
408
|
-
const firstFullyVisibleRow = instance.getFirstFullyVisibleRow();
|
409
|
-
const firstFullyVisibleColumn = instance.getFirstFullyVisibleColumn();
|
410
|
-
const isInVerticalViewPort = changedRow >= firstFullyVisibleRow;
|
411
|
-
const isInHorizontalViewPort = changedColumn >= firstFullyVisibleColumn;
|
412
|
-
const isInViewport = isInVerticalViewPort && isInHorizontalViewPort;
|
413
|
-
const isChangedSelection = selectedRow !== changedRow || selectedColumn !== changedColumn;
|
414
|
-
|
415
|
-
// Performing scroll only when selection has been changed right after editing a cell.
|
416
|
-
if (isInViewport === false && isChangedSelection === true) {
|
417
|
-
const scrollConfig = {
|
418
|
-
row: changedRow,
|
419
|
-
col: changedColumn
|
420
|
-
};
|
421
|
-
if (isInVerticalViewPort === false) {
|
422
|
-
scrollConfig.verticalSnap = 'top';
|
423
|
-
}
|
424
|
-
if (isInHorizontalViewPort === false) {
|
425
|
-
scrollConfig.horizontalSnap = 'start';
|
426
|
-
}
|
427
|
-
instance.scrollViewportTo(scrollConfig);
|
428
|
-
}
|
429
|
-
}
|
430
|
-
instance.selectCells(this.selected, false, false);
|
431
|
-
};
|
432
|
-
UndoRedo.ChangeAction.prototype.redo = function (instance, onFinishCallback) {
|
433
|
-
const data = (0, _object.deepClone)(this.changes);
|
434
|
-
for (let i = 0, len = data.length; i < len; i++) {
|
435
|
-
data[i].splice(2, 1);
|
436
|
-
}
|
437
|
-
instance.addHookOnce('afterChange', onFinishCallback);
|
438
|
-
instance.setDataAtCell(data, null, null, 'UndoRedo.redo');
|
439
|
-
if (this.selected) {
|
440
|
-
instance.selectCells(this.selected, false, false);
|
441
|
-
}
|
442
|
-
};
|
443
|
-
|
444
|
-
/**
|
445
|
-
* Create row action.
|
446
|
-
*
|
447
|
-
* @private
|
448
|
-
* @param {number} index The visual row index.
|
449
|
-
* @param {number} amount The number of created rows.
|
450
|
-
*/
|
451
|
-
UndoRedo.CreateRowAction = function (index, amount) {
|
452
|
-
this.index = index;
|
453
|
-
this.amount = amount;
|
454
|
-
this.actionType = 'insert_row';
|
455
|
-
};
|
456
|
-
(0, _object.inherit)(UndoRedo.CreateRowAction, UndoRedo.Action);
|
457
|
-
UndoRedo.CreateRowAction.prototype.undo = function (instance, undoneCallback) {
|
458
|
-
const rowCount = instance.countRows();
|
459
|
-
const minSpareRows = instance.getSettings().minSpareRows;
|
460
|
-
if (this.index >= rowCount && this.index - minSpareRows < rowCount) {
|
461
|
-
this.index -= minSpareRows; // work around the situation where the needed row was removed due to an 'undo' of a made change
|
462
|
-
}
|
463
|
-
instance.addHookOnce('afterRemoveRow', undoneCallback);
|
464
|
-
instance.alter('remove_row', this.index, this.amount, 'UndoRedo.undo');
|
465
|
-
};
|
466
|
-
UndoRedo.CreateRowAction.prototype.redo = function (instance, redoneCallback) {
|
467
|
-
instance.addHookOnce('afterCreateRow', redoneCallback);
|
468
|
-
instance.alter('insert_row_above', this.index, this.amount, 'UndoRedo.redo');
|
469
|
-
};
|
470
|
-
|
471
|
-
/**
|
472
|
-
* Remove row action.
|
473
|
-
*
|
474
|
-
* @private
|
475
|
-
* @param {number} index The visual row index.
|
476
|
-
* @param {Array} data The removed data.
|
477
|
-
* @param {number} fixedRowsBottom Number of fixed rows on the bottom. Remove row action change it sometimes.
|
478
|
-
* @param {number} fixedRowsTop Number of fixed rows on the top. Remove row action change it sometimes.
|
479
|
-
* @param {Array} rowIndexesSequence Row index sequence taken from the row index mapper.
|
480
|
-
* @param {Array} removedCellMetas List of removed cell metas.
|
481
|
-
*/
|
482
|
-
UndoRedo.RemoveRowAction = function (index, data, fixedRowsBottom, fixedRowsTop, rowIndexesSequence, removedCellMetas) {
|
483
|
-
this.index = index;
|
484
|
-
this.data = data;
|
485
|
-
this.actionType = 'remove_row';
|
486
|
-
this.fixedRowsBottom = fixedRowsBottom;
|
487
|
-
this.fixedRowsTop = fixedRowsTop;
|
488
|
-
this.rowIndexesSequence = rowIndexesSequence;
|
489
|
-
this.removedCellMetas = removedCellMetas;
|
490
|
-
};
|
491
|
-
(0, _object.inherit)(UndoRedo.RemoveRowAction, UndoRedo.Action);
|
492
|
-
UndoRedo.RemoveRowAction.prototype.undo = function (instance, undoneCallback) {
|
493
|
-
const settings = instance.getSettings();
|
494
|
-
const changes = [];
|
495
|
-
|
496
|
-
// Changing by the reference as `updateSettings` doesn't work the best.
|
497
|
-
settings.fixedRowsBottom = this.fixedRowsBottom;
|
498
|
-
settings.fixedRowsTop = this.fixedRowsTop;
|
499
|
-
|
500
|
-
// Prepare the change list to fill the source data.
|
501
|
-
this.data.forEach((dataRow, rowIndexDelta) => {
|
502
|
-
Object.keys(dataRow).forEach(columnProp => {
|
503
|
-
const columnIndex = parseInt(columnProp, 10);
|
504
|
-
changes.push([this.index + rowIndexDelta, isNaN(columnIndex) ? columnProp : columnIndex, dataRow[columnProp]]);
|
505
|
-
});
|
506
|
-
});
|
507
|
-
instance.alter('insert_row_above', this.index, this.data.length, 'UndoRedo.undo');
|
508
|
-
this.removedCellMetas.forEach(_ref2 => {
|
509
|
-
let [rowIndex, columnIndex, cellMeta] = _ref2;
|
510
|
-
instance.setCellMetaObject(rowIndex, columnIndex, cellMeta);
|
511
|
-
});
|
512
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
513
|
-
instance.setSourceDataAtCell(changes, null, null, 'UndoRedo.undo');
|
514
|
-
instance.rowIndexMapper.setIndexesSequence(this.rowIndexesSequence);
|
515
|
-
};
|
516
|
-
UndoRedo.RemoveRowAction.prototype.redo = function (instance, redoneCallback) {
|
517
|
-
instance.addHookOnce('afterRemoveRow', redoneCallback);
|
518
|
-
instance.alter('remove_row', this.index, this.data.length, 'UndoRedo.redo');
|
519
|
-
};
|
520
|
-
|
521
|
-
/**
|
522
|
-
* Create column action.
|
523
|
-
*
|
524
|
-
* @private
|
525
|
-
* @param {number} index The visual column index.
|
526
|
-
* @param {number} amount The number of created columns.
|
527
|
-
*/
|
528
|
-
UndoRedo.CreateColumnAction = function (index, amount) {
|
529
|
-
this.index = index;
|
530
|
-
this.amount = amount;
|
531
|
-
this.actionType = 'insert_col';
|
532
|
-
};
|
533
|
-
(0, _object.inherit)(UndoRedo.CreateColumnAction, UndoRedo.Action);
|
534
|
-
UndoRedo.CreateColumnAction.prototype.undo = function (instance, undoneCallback) {
|
535
|
-
instance.addHookOnce('afterRemoveCol', undoneCallback);
|
536
|
-
instance.alter('remove_col', this.index, this.amount, 'UndoRedo.undo');
|
537
|
-
};
|
538
|
-
UndoRedo.CreateColumnAction.prototype.redo = function (instance, redoneCallback) {
|
539
|
-
instance.addHookOnce('afterCreateCol', redoneCallback);
|
540
|
-
instance.alter('insert_col_start', this.index, this.amount, 'UndoRedo.redo');
|
541
|
-
};
|
542
|
-
|
543
|
-
/**
|
544
|
-
* Remove column action.
|
545
|
-
*
|
546
|
-
* @private
|
547
|
-
* @param {number} index The visual column index.
|
548
|
-
* @param {number[]} indexes The visual column indexes.
|
549
|
-
* @param {Array} data The removed data.
|
550
|
-
* @param {Array} headers The header values.
|
551
|
-
* @param {number[]} columnPositions The column position.
|
552
|
-
* @param {number[]} rowPositions The row position.
|
553
|
-
* @param {number} fixedColumnsStart Number of fixed columns on the left. Remove column action change it sometimes.
|
554
|
-
* @param {Array} removedCellMetas List of removed cell metas.
|
555
|
-
*/
|
556
|
-
UndoRedo.RemoveColumnAction = function (index, indexes, data, headers, columnPositions, rowPositions, fixedColumnsStart, removedCellMetas) {
|
557
|
-
// eslint-disable-line max-len
|
558
|
-
this.index = index;
|
559
|
-
this.indexes = indexes;
|
560
|
-
this.data = data;
|
561
|
-
this.amount = this.data[0].length;
|
562
|
-
this.headers = headers;
|
563
|
-
this.columnPositions = columnPositions.slice(0);
|
564
|
-
this.rowPositions = rowPositions.slice(0);
|
565
|
-
this.actionType = 'remove_col';
|
566
|
-
this.fixedColumnsStart = fixedColumnsStart;
|
567
|
-
this.removedCellMetas = removedCellMetas;
|
568
|
-
};
|
569
|
-
(0, _object.inherit)(UndoRedo.RemoveColumnAction, UndoRedo.Action);
|
570
|
-
UndoRedo.RemoveColumnAction.prototype.undo = function (instance, undoneCallback) {
|
571
|
-
const settings = instance.getSettings();
|
572
|
-
|
573
|
-
// Changing by the reference as `updateSettings` doesn't work the best.
|
574
|
-
settings.fixedColumnsStart = this.fixedColumnsStart;
|
575
|
-
const ascendingIndexes = this.indexes.slice(0).sort();
|
576
|
-
const sortByIndexes = (elem, j, arr) => arr[this.indexes.indexOf(ascendingIndexes[j])];
|
577
|
-
const removedDataLength = this.data.length;
|
578
|
-
const sortedData = [];
|
579
|
-
for (let rowIndex = 0; rowIndex < removedDataLength; rowIndex++) {
|
580
|
-
sortedData.push((0, _array.arrayMap)(this.data[rowIndex], sortByIndexes));
|
581
|
-
}
|
582
|
-
const sortedHeaders = (0, _array.arrayMap)(this.headers, sortByIndexes);
|
583
|
-
const changes = [];
|
584
|
-
instance.alter('insert_col_start', this.indexes[0], this.indexes.length, 'UndoRedo.undo');
|
585
|
-
(0, _array.arrayEach)(instance.getSourceDataArray(), (rowData, rowIndex) => {
|
586
|
-
(0, _array.arrayEach)(ascendingIndexes, (changedIndex, contiquesIndex) => {
|
587
|
-
rowData[changedIndex] = sortedData[rowIndex][contiquesIndex];
|
588
|
-
changes.push([rowIndex, changedIndex, rowData[changedIndex]]);
|
589
|
-
});
|
590
|
-
});
|
591
|
-
instance.setSourceDataAtCell(changes, undefined, undefined, 'UndoRedo.undo');
|
592
|
-
if (typeof this.headers !== 'undefined') {
|
593
|
-
(0, _array.arrayEach)(sortedHeaders, (headerData, columnIndex) => {
|
594
|
-
instance.getSettings().colHeaders[ascendingIndexes[columnIndex]] = headerData;
|
595
|
-
});
|
270
|
+
/**
|
271
|
+
* Checks if undo action is available.
|
272
|
+
*
|
273
|
+
* @returns {boolean} Return `true` if undo can be performed, `false` otherwise.
|
274
|
+
*/
|
275
|
+
isUndoAvailable() {
|
276
|
+
return this.doneActions.length > 0;
|
596
277
|
}
|
597
|
-
this.removedCellMetas.forEach(_ref3 => {
|
598
|
-
let [rowIndex, columnIndex, cellMeta] = _ref3;
|
599
|
-
instance.setCellMetaObject(rowIndex, columnIndex, cellMeta);
|
600
|
-
});
|
601
|
-
instance.batchExecution(() => {
|
602
|
-
// Restore row sequence in a case when all columns are removed. the original
|
603
|
-
// row sequence is lost in that case.
|
604
|
-
instance.rowIndexMapper.setIndexesSequence(this.rowPositions);
|
605
|
-
instance.columnIndexMapper.setIndexesSequence(this.columnPositions);
|
606
|
-
}, true);
|
607
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
608
|
-
instance.render();
|
609
|
-
};
|
610
|
-
UndoRedo.RemoveColumnAction.prototype.redo = function (instance, redoneCallback) {
|
611
|
-
instance.addHookOnce('afterRemoveCol', redoneCallback);
|
612
|
-
instance.alter('remove_col', this.index, this.amount, 'UndoRedo.redo');
|
613
|
-
};
|
614
|
-
|
615
|
-
/**
|
616
|
-
* Cell alignment action.
|
617
|
-
*
|
618
|
-
* @private
|
619
|
-
* @param {Array} stateBefore The previous state.
|
620
|
-
* @param {object} range The cell range.
|
621
|
-
* @param {string} type The type of the alignment ("top", "left", "bottom" or "right").
|
622
|
-
* @param {string} alignment The alignment CSS class.
|
623
|
-
*/
|
624
|
-
UndoRedo.CellAlignmentAction = function (stateBefore, range, type, alignment) {
|
625
|
-
this.stateBefore = stateBefore;
|
626
|
-
this.range = range;
|
627
|
-
this.type = type;
|
628
|
-
this.alignment = alignment;
|
629
|
-
};
|
630
|
-
UndoRedo.CellAlignmentAction.prototype.undo = function (instance, undoneCallback) {
|
631
|
-
(0, _array.arrayEach)(this.range, range => {
|
632
|
-
range.forAll((row, col) => {
|
633
|
-
// Alignment classes should only collected within cell ranges. We skip header coordinates.
|
634
|
-
if (row >= 0 && col >= 0) {
|
635
|
-
instance.setCellMeta(row, col, 'className', this.stateBefore[row][col] || ' htLeft');
|
636
|
-
}
|
637
|
-
});
|
638
|
-
});
|
639
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
640
|
-
instance.render();
|
641
|
-
};
|
642
|
-
UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback) {
|
643
|
-
(0, _utils.align)(this.range, this.type, this.alignment, (row, col) => instance.getCellMeta(row, col), (row, col, key, value) => instance.setCellMeta(row, col, key, value));
|
644
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
645
|
-
instance.render();
|
646
|
-
};
|
647
278
|
|
648
|
-
/**
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
UndoRedo.FiltersAction = function (conditionsStack, previousConditionsStack) {
|
656
|
-
this.previousConditionsStack = previousConditionsStack;
|
657
|
-
this.conditionsStack = conditionsStack;
|
658
|
-
this.actionType = 'filter';
|
659
|
-
};
|
660
|
-
(0, _object.inherit)(UndoRedo.FiltersAction, UndoRedo.Action);
|
661
|
-
UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
|
662
|
-
const filters = instance.getPlugin('filters');
|
663
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
664
|
-
if (this.previousConditionsStack) {
|
665
|
-
filters.conditionCollection.importAllConditions(this.previousConditionsStack);
|
279
|
+
/**
|
280
|
+
* Checks if redo action is available.
|
281
|
+
*
|
282
|
+
* @returns {boolean} Return `true` if redo can be performed, `false` otherwise.
|
283
|
+
*/
|
284
|
+
isRedoAvailable() {
|
285
|
+
return this.undoneActions.length > 0;
|
666
286
|
}
|
667
|
-
filters.filter();
|
668
|
-
};
|
669
|
-
UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
|
670
|
-
const filters = instance.getPlugin('filters');
|
671
|
-
instance.addHookOnce('afterViewRender', redoneCallback);
|
672
|
-
filters.conditionCollection.importAllConditions(this.conditionsStack);
|
673
|
-
filters.filter();
|
674
|
-
};
|
675
287
|
|
676
|
-
/**
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
constructor(instance, cellRange) {
|
683
|
-
super();
|
684
|
-
this.cellRange = cellRange;
|
685
|
-
const topStartCorner = this.cellRange.getTopStartCorner();
|
686
|
-
const bottomEndCorner = this.cellRange.getBottomEndCorner();
|
687
|
-
this.rangeData = instance.getData(topStartCorner.row, topStartCorner.col, bottomEndCorner.row, bottomEndCorner.col);
|
688
|
-
}
|
689
|
-
undo(instance, undoneCallback) {
|
690
|
-
const mergeCellsPlugin = instance.getPlugin('mergeCells');
|
691
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
692
|
-
mergeCellsPlugin.unmergeRange(this.cellRange, true);
|
693
|
-
const topStartCorner = this.cellRange.getTopStartCorner();
|
694
|
-
instance.populateFromArray(topStartCorner.row, topStartCorner.col, this.rangeData, undefined, undefined, 'MergeCells');
|
288
|
+
/**
|
289
|
+
* Clears undo and redo history.
|
290
|
+
*/
|
291
|
+
clear() {
|
292
|
+
this.doneActions.length = 0;
|
293
|
+
this.undoneActions.length = 0;
|
695
294
|
}
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
295
|
+
/**
|
296
|
+
* Destroys the plugin instance.
|
297
|
+
*/
|
298
|
+
destroy() {
|
299
|
+
this.clear();
|
300
|
+
this.doneActions = null;
|
301
|
+
this.undoneActions = null;
|
302
|
+
super.destroy();
|
700
303
|
}
|
701
304
|
}
|
702
|
-
UndoRedo
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
*
|
707
|
-
* @util
|
708
|
-
*/
|
709
|
-
class UnmergeCellsAction extends UndoRedo.Action {
|
710
|
-
constructor(instance, cellRange) {
|
711
|
-
super();
|
712
|
-
this.cellRange = cellRange;
|
713
|
-
}
|
714
|
-
undo(instance, undoneCallback) {
|
715
|
-
const mergeCellsPlugin = instance.getPlugin('mergeCells');
|
716
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
717
|
-
mergeCellsPlugin.mergeRange(this.cellRange, true);
|
718
|
-
}
|
719
|
-
redo(instance, redoneCallback) {
|
720
|
-
const mergeCellsPlugin = instance.getPlugin('mergeCells');
|
721
|
-
instance.addHookOnce('afterViewRender', redoneCallback);
|
722
|
-
mergeCellsPlugin.unmergeRange(this.cellRange, true);
|
723
|
-
instance.render();
|
305
|
+
exports.UndoRedo = UndoRedo;
|
306
|
+
function _onAfterChange(changes, source) {
|
307
|
+
if (source === 'loadData') {
|
308
|
+
this.clear();
|
724
309
|
}
|
725
310
|
}
|
726
|
-
UndoRedo.UnmergeCellsAction = UnmergeCellsAction;
|
727
|
-
|
728
311
|
/**
|
729
|
-
*
|
730
|
-
*
|
731
|
-
* @TODO removeRow undo should works on logical index
|
732
|
-
* @private
|
733
|
-
* @param {number[]} rows An array with moved rows.
|
734
|
-
* @param {number} finalIndex The destination index.
|
312
|
+
* Expose the plugin API to the Core. It is for backward compatibility and it should be removed in the future.
|
735
313
|
*/
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
(
|
742
|
-
|
743
|
-
const manualRowMove = instance.getPlugin('manualRowMove');
|
744
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
745
|
-
const rowMoves = (0, _moves.getMoves)(this.rows, this.finalRowIndex, instance.rowIndexMapper.getNumberOfIndexes());
|
746
|
-
rowMoves.reverse().forEach(_ref4 => {
|
747
|
-
let {
|
748
|
-
from,
|
749
|
-
to
|
750
|
-
} = _ref4;
|
751
|
-
if (from < to) {
|
752
|
-
to -= 1;
|
314
|
+
function _exposeAPIToCore() {
|
315
|
+
const deprecatedWarn = methodName => {
|
316
|
+
if (!deprecationWarns.has(methodName)) {
|
317
|
+
(0, _console.warn)((0, _templateLiteralTag.toSingleLine)`The "${methodName}" method is deprecated and it will be removed\x20
|
318
|
+
from the Core API in the future. Please use the method from the UndoRedo plugin\x20
|
319
|
+
(e.g. \`hotInstance.getPlugin("undoRedo").${methodName}()\`).`);
|
320
|
+
deprecationWarns.add(methodName);
|
753
321
|
}
|
754
|
-
manualRowMove.moveRow(to, from);
|
755
|
-
});
|
756
|
-
instance.render();
|
757
|
-
instance.deselectCell();
|
758
|
-
instance.selectRows(this.rows[0], this.rows[0] + this.rows.length - 1);
|
759
|
-
};
|
760
|
-
UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) {
|
761
|
-
const manualRowMove = instance.getPlugin('manualRowMove');
|
762
|
-
instance.addHookOnce('afterViewRender', redoneCallback);
|
763
|
-
manualRowMove.moveRows(this.rows.slice(), this.finalRowIndex);
|
764
|
-
instance.render();
|
765
|
-
instance.deselectCell();
|
766
|
-
instance.selectRows(this.finalRowIndex, this.finalRowIndex + this.rows.length - 1);
|
767
|
-
};
|
768
|
-
|
769
|
-
/**
|
770
|
-
* ManualColumnMove action.
|
771
|
-
*
|
772
|
-
* @private
|
773
|
-
* @param {number[]} columns An array with moved columns.
|
774
|
-
* @param {number} finalIndex The destination index.
|
775
|
-
*/
|
776
|
-
UndoRedo.ColumnMoveAction = function (columns, finalIndex) {
|
777
|
-
this.columns = columns.slice();
|
778
|
-
this.finalColumnIndex = finalIndex;
|
779
|
-
this.actionType = 'col_move';
|
780
|
-
};
|
781
|
-
(0, _object.inherit)(UndoRedo.ColumnMoveAction, UndoRedo.Action);
|
782
|
-
UndoRedo.ColumnMoveAction.prototype.undo = function (instance, undoneCallback) {
|
783
|
-
const manualColumnMove = instance.getPlugin('manualColumnMove');
|
784
|
-
instance.addHookOnce('afterViewRender', undoneCallback);
|
785
|
-
const columnMoves = (0, _moves.getMoves)(this.columns, this.finalColumnIndex, instance.columnIndexMapper.getNumberOfIndexes());
|
786
|
-
columnMoves.reverse().forEach(_ref5 => {
|
787
|
-
let {
|
788
|
-
from,
|
789
|
-
to
|
790
|
-
} = _ref5;
|
791
|
-
if (from < to) {
|
792
|
-
to -= 1;
|
793
|
-
}
|
794
|
-
manualColumnMove.moveColumn(to, from);
|
795
|
-
});
|
796
|
-
instance.render();
|
797
|
-
instance.deselectCell();
|
798
|
-
instance.selectColumns(this.columns[0], this.columns[0] + this.columns.length - 1);
|
799
|
-
};
|
800
|
-
UndoRedo.ColumnMoveAction.prototype.redo = function (instance, redoneCallback) {
|
801
|
-
const manualColumnMove = instance.getPlugin('manualColumnMove');
|
802
|
-
instance.addHookOnce('afterViewRender', redoneCallback);
|
803
|
-
manualColumnMove.moveColumns(this.columns.slice(), this.finalColumnIndex);
|
804
|
-
instance.render();
|
805
|
-
instance.deselectCell();
|
806
|
-
instance.selectColumns(this.finalColumnIndex, this.finalColumnIndex + this.columns.length - 1);
|
807
|
-
};
|
808
|
-
|
809
|
-
/**
|
810
|
-
* ColumnSort action.
|
811
|
-
*
|
812
|
-
* @private
|
813
|
-
* @param {Array} currentSortState The current sort state.
|
814
|
-
* @param {Array} newSortState The new sort state.
|
815
|
-
*/
|
816
|
-
UndoRedo.ColumnSortAction = function (currentSortState, newSortState) {
|
817
|
-
this.previousSortState = currentSortState;
|
818
|
-
this.nextSortState = newSortState;
|
819
|
-
};
|
820
|
-
(0, _object.inherit)(UndoRedo.ColumnSortAction, UndoRedo.Action);
|
821
|
-
UndoRedo.ColumnSortAction.prototype.undo = function (instance, undoneCallback) {
|
822
|
-
const sortPlugin = instance.getPlugin('columnSorting');
|
823
|
-
const multiSortPlugin = instance.getPlugin('multiColumnSorting');
|
824
|
-
const enabledSortPlugin = multiSortPlugin.isEnabled() ? multiSortPlugin : sortPlugin;
|
825
|
-
if (this.previousSortState.length) {
|
826
|
-
enabledSortPlugin.sort(this.previousSortState);
|
827
|
-
} else {
|
828
|
-
enabledSortPlugin.clearSort();
|
829
|
-
}
|
830
|
-
undoneCallback();
|
831
|
-
};
|
832
|
-
UndoRedo.ColumnSortAction.prototype.redo = function (instance, redoneCallback) {
|
833
|
-
const sortPlugin = instance.getPlugin('columnSorting');
|
834
|
-
const multiSortPlugin = instance.getPlugin('multiColumnSorting');
|
835
|
-
const enabledSortPlugin = multiSortPlugin.isEnabled() ? multiSortPlugin : sortPlugin;
|
836
|
-
enabledSortPlugin.sort(this.nextSortState);
|
837
|
-
redoneCallback();
|
838
|
-
};
|
839
|
-
|
840
|
-
/**
|
841
|
-
* Enabling and disabling plugin and attaching its to an instance.
|
842
|
-
*
|
843
|
-
* @private
|
844
|
-
*/
|
845
|
-
UndoRedo.prototype.init = function () {
|
846
|
-
const settings = this.instance.getSettings().undo;
|
847
|
-
const pluginEnabled = typeof settings === 'undefined' || settings;
|
848
|
-
if (!this.instance.undoRedo) {
|
849
|
-
this.instance.undoRedo = this;
|
850
|
-
}
|
851
|
-
if (pluginEnabled) {
|
852
|
-
this.instance.undoRedo.enable();
|
853
|
-
} else {
|
854
|
-
this.instance.undoRedo.disable();
|
855
|
-
}
|
856
|
-
};
|
857
|
-
|
858
|
-
/**
|
859
|
-
* Registers shortcuts responsible for performing undo/redo.
|
860
|
-
*
|
861
|
-
* @private
|
862
|
-
*/
|
863
|
-
UndoRedo.prototype.registerShortcuts = function () {
|
864
|
-
const shortcutManager = this.instance.getShortcutManager();
|
865
|
-
const gridContext = shortcutManager.getContext('grid');
|
866
|
-
const runOnlyIf = event => {
|
867
|
-
return !event.altKey; // right ALT in some systems triggers ALT+CTR
|
868
|
-
};
|
869
|
-
const config = {
|
870
|
-
runOnlyIf,
|
871
|
-
group: SHORTCUTS_GROUP
|
872
322
|
};
|
873
|
-
gridContext.addShortcuts([{
|
874
|
-
keys: [['Control/Meta', 'z']],
|
875
|
-
callback: () => {
|
876
|
-
this.undo();
|
877
|
-
}
|
878
|
-
}, {
|
879
|
-
keys: [['Control/Meta', 'y'], ['Control/Meta', 'Shift', 'z']],
|
880
|
-
callback: () => {
|
881
|
-
this.redo();
|
882
|
-
}
|
883
|
-
}], config);
|
884
|
-
};
|
885
|
-
|
886
|
-
/**
|
887
|
-
* Unregister shortcuts responsible for performing undo/redo.
|
888
|
-
*
|
889
|
-
* @private
|
890
|
-
*/
|
891
|
-
UndoRedo.prototype.unregisterShortcuts = function () {
|
892
|
-
const shortcutManager = this.instance.getShortcutManager();
|
893
|
-
const gridContext = shortcutManager.getContext('grid');
|
894
|
-
gridContext.removeShortcutsByGroup(SHORTCUTS_GROUP);
|
895
|
-
};
|
896
323
|
|
897
|
-
/**
|
898
|
-
* @param {Array} changes 2D array containing information about each of the edited cells.
|
899
|
-
* @param {string} source String that identifies source of hook call.
|
900
|
-
* @returns {boolean}
|
901
|
-
*/
|
902
|
-
function onAfterChange(changes, source) {
|
903
|
-
const instance = this;
|
904
|
-
if (source === 'loadData') {
|
905
|
-
return instance.undoRedo.clear();
|
906
|
-
}
|
907
|
-
}
|
908
|
-
|
909
|
-
/**
|
910
|
-
* @param {Core} instance The Handsontable instance.
|
911
|
-
*/
|
912
|
-
function exposeUndoRedoMethods(instance) {
|
913
324
|
/**
|
914
325
|
* {@link UndoRedo#undo}.
|
915
326
|
*
|
916
327
|
* @alias undo
|
917
328
|
* @memberof! Core#
|
918
|
-
* @returns {boolean}
|
919
329
|
*/
|
920
|
-
|
921
|
-
|
330
|
+
this.hot.undo = () => {
|
331
|
+
deprecatedWarn('undo');
|
332
|
+
this.undo();
|
922
333
|
};
|
923
|
-
|
924
334
|
/**
|
925
335
|
* {@link UndoRedo#redo}.
|
926
336
|
*
|
927
337
|
* @alias redo
|
928
338
|
* @memberof! Core#
|
929
|
-
* @returns {boolean}
|
930
339
|
*/
|
931
|
-
|
932
|
-
|
340
|
+
this.hot.redo = () => {
|
341
|
+
deprecatedWarn('redo');
|
342
|
+
this.redo();
|
933
343
|
};
|
934
|
-
|
935
344
|
/**
|
936
345
|
* {@link UndoRedo#isUndoAvailable}.
|
937
346
|
*
|
@@ -939,10 +348,10 @@ function exposeUndoRedoMethods(instance) {
|
|
939
348
|
* @memberof! Core#
|
940
349
|
* @returns {boolean}
|
941
350
|
*/
|
942
|
-
|
943
|
-
|
351
|
+
this.hot.isUndoAvailable = () => {
|
352
|
+
deprecatedWarn('isUndoAvailable');
|
353
|
+
return this.isUndoAvailable();
|
944
354
|
};
|
945
|
-
|
946
355
|
/**
|
947
356
|
* {@link UndoRedo#isRedoAvailable}.
|
948
357
|
*
|
@@ -950,41 +359,30 @@ function exposeUndoRedoMethods(instance) {
|
|
950
359
|
* @memberof! Core#
|
951
360
|
* @returns {boolean}
|
952
361
|
*/
|
953
|
-
|
954
|
-
|
362
|
+
this.hot.isRedoAvailable = () => {
|
363
|
+
deprecatedWarn('isRedoAvailable');
|
364
|
+
return this.isRedoAvailable();
|
955
365
|
};
|
956
|
-
|
957
366
|
/**
|
958
367
|
* {@link UndoRedo#clear}.
|
959
368
|
*
|
960
369
|
* @alias clearUndo
|
961
370
|
* @memberof! Core#
|
962
|
-
* @returns {boolean}
|
963
371
|
*/
|
964
|
-
|
965
|
-
|
372
|
+
this.hot.clearUndo = () => {
|
373
|
+
deprecatedWarn('clear');
|
374
|
+
this.clear();
|
966
375
|
};
|
376
|
+
this.hot.undoRedo = this;
|
967
377
|
}
|
968
|
-
|
969
378
|
/**
|
970
|
-
*
|
379
|
+
* Removes the plugin API from the Core. It is for backward compatibility and it should be removed in the future.
|
971
380
|
*/
|
972
|
-
function
|
973
|
-
delete
|
974
|
-
delete
|
975
|
-
delete
|
976
|
-
delete
|
977
|
-
delete
|
978
|
-
|
979
|
-
|
980
|
-
hook.add('afterUpdateSettings', function () {
|
981
|
-
var _this$getPlugin;
|
982
|
-
(_this$getPlugin = this.getPlugin('undoRedo')) === null || _this$getPlugin === void 0 || _this$getPlugin.init();
|
983
|
-
});
|
984
|
-
hook.register('beforeUndo');
|
985
|
-
hook.register('afterUndo');
|
986
|
-
hook.register('beforeRedo');
|
987
|
-
hook.register('afterRedo');
|
988
|
-
UndoRedo.PLUGIN_KEY = PLUGIN_KEY;
|
989
|
-
UndoRedo.SETTING_KEYS = true;
|
990
|
-
var _default = exports.default = UndoRedo;
|
381
|
+
function _removeAPIFromCore() {
|
382
|
+
delete this.hot.undo;
|
383
|
+
delete this.hot.redo;
|
384
|
+
delete this.hot.isUndoAvailable;
|
385
|
+
delete this.hot.isRedoAvailable;
|
386
|
+
delete this.hot.clearUndo;
|
387
|
+
delete this.hot.undoRedo;
|
388
|
+
}
|