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