handsontable 0.0.0-next-aebdd36-20240821 → 0.0.0-next-eaf150e-20240823
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/dist/handsontable.css +2 -2
- package/dist/handsontable.full.css +2 -2
- package/dist/handsontable.full.js +54 -20
- package/dist/handsontable.full.min.css +2 -2
- package/dist/handsontable.full.min.js +7 -7
- package/dist/handsontable.js +54 -20
- package/dist/handsontable.min.css +2 -2
- package/dist/handsontable.min.js +7 -7
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/pluginHooks.d.ts +1 -1
- package/pluginHooks.js +1 -0
- package/pluginHooks.mjs +1 -0
- package/plugins/filters/conditionCollection.js +26 -0
- package/plugins/filters/conditionCollection.mjs +26 -0
- package/plugins/filters/filters.js +2 -1
- package/plugins/filters/filters.mjs +2 -1
- package/plugins/mergeCells/cellsCollection.js +11 -9
- package/plugins/mergeCells/cellsCollection.mjs +12 -10
- package/plugins/undoRedo/undoRedo.js +9 -5
- package/plugins/undoRedo/undoRedo.mjs +9 -5
package/helpers/mixed.js
CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
|
|
134
134
|
function _injectProductInfo(key, element) {
|
135
135
|
const hasValidType = !isEmpty(key);
|
136
136
|
const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
|
137
|
-
const hotVersion = "0.0.0-next-
|
137
|
+
const hotVersion = "0.0.0-next-eaf150e-20240823";
|
138
138
|
let keyValidityDate;
|
139
139
|
let consoleMessageState = 'invalid';
|
140
140
|
let domMessageState = 'invalid';
|
package/helpers/mixed.mjs
CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
|
|
124
124
|
export function _injectProductInfo(key, element) {
|
125
125
|
const hasValidType = !isEmpty(key);
|
126
126
|
const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
|
127
|
-
const hotVersion = "0.0.0-next-
|
127
|
+
const hotVersion = "0.0.0-next-eaf150e-20240823";
|
128
128
|
let keyValidityDate;
|
129
129
|
let consoleMessageState = 'invalid';
|
130
130
|
let domMessageState = 'invalid';
|
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"url": "https://github.com/handsontable/handsontable/issues"
|
11
11
|
},
|
12
12
|
"author": "Handsoncode <hello@handsontable.com>",
|
13
|
-
"version": "0.0.0-next-
|
13
|
+
"version": "0.0.0-next-eaf150e-20240823",
|
14
14
|
"main": "index",
|
15
15
|
"module": "index.mjs",
|
16
16
|
"jsnext:main": "index.mjs",
|
package/pluginHooks.d.ts
CHANGED
@@ -180,7 +180,7 @@ export interface Events {
|
|
180
180
|
beforeDrawBorders?: (corners: number[], borderClassName: 'current' | 'area' | 'highlight' | undefined) => void;
|
181
181
|
beforeDropdownMenuSetItems?: (menuItems: ContextMenuMenuItemConfig[]) => void;
|
182
182
|
beforeDropdownMenuShow?: (instance: DropdownMenu) => void;
|
183
|
-
beforeFilter?: (conditionsStack: FiltersColumnConditions[]) => void | boolean;
|
183
|
+
beforeFilter?: (conditionsStack: FiltersColumnConditions[], previousConditionsStack: FiltersColumnConditions[]) => void | boolean;
|
184
184
|
beforeGetCellMeta?: (row: number, column: number, cellProperties: CellProperties) => void;
|
185
185
|
beforeHideColumns?: (currentHideConfig: number[], destinationHideConfig: number[], actionPossible: boolean) => void | boolean;
|
186
186
|
beforeHideRows?: (currentHideConfig: number[], destinationHideConfig: number[], actionPossible: boolean) => void | boolean;
|
package/pluginHooks.js
CHANGED
@@ -2004,6 +2004,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
|
|
2004
2004
|
*
|
2005
2005
|
* @event Hooks#beforeFilter
|
2006
2006
|
* @param {object[]} conditionsStack An array of objects with your [column filters](@/api/filters.md#addcondition).
|
2007
|
+
* @param {object[]|null} previousConditionsStack An array of objects with your previous [column filters](@/api/filters.md#addcondition). It can also be `null` if there was no previous filters applied or the conditions did not change between performing the `filter` action.
|
2007
2008
|
* @returns {boolean} To perform server-side filtering (i.e., to not apply filtering to Handsontable's UI), return `false`.
|
2008
2009
|
*/
|
2009
2010
|
'beforeFilter',
|
package/pluginHooks.mjs
CHANGED
@@ -2000,6 +2000,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
|
|
2000
2000
|
*
|
2001
2001
|
* @event Hooks#beforeFilter
|
2002
2002
|
* @param {object[]} conditionsStack An array of objects with your [column filters](@/api/filters.md#addcondition).
|
2003
|
+
* @param {object[]|null} previousConditionsStack An array of objects with your previous [column filters](@/api/filters.md#addcondition). It can also be `null` if there was no previous filters applied or the conditions did not change between performing the `filter` action.
|
2003
2004
|
* @returns {boolean} To perform server-side filtering (i.e., to not apply filtering to Handsontable's UI), return `false`.
|
2004
2005
|
*/
|
2005
2006
|
'beforeFilter',
|
@@ -45,6 +45,13 @@ class ConditionCollection {
|
|
45
45
|
* @type {LinkedPhysicalIndexToValueMap}
|
46
46
|
*/
|
47
47
|
_defineProperty(this, "filteringStates", new _translations.LinkedPhysicalIndexToValueMap());
|
48
|
+
/**
|
49
|
+
* Stores the previous state of the condition stack before the latest filter operation.
|
50
|
+
* This is used in the `beforeFilter` plugin to allow performing the undo operation.
|
51
|
+
*
|
52
|
+
* @type {null|Array}
|
53
|
+
*/
|
54
|
+
_defineProperty(this, "previousConditionStack", null);
|
48
55
|
this.hot = hot;
|
49
56
|
this.isMapRegistrable = isMapRegistrable;
|
50
57
|
if (this.isMapRegistrable === true) {
|
@@ -113,6 +120,13 @@ class ConditionCollection {
|
|
113
120
|
const localeForColumn = this.hot.getCellMeta(0, column).locale;
|
114
121
|
const args = (0, _array.arrayMap)(conditionDefinition.args, v => typeof v === 'string' ? v.toLocaleLowerCase(localeForColumn) : v);
|
115
122
|
const name = conditionDefinition.name || conditionDefinition.command.key;
|
123
|
+
|
124
|
+
// If there's no previous condition stack defined (which means the condition stack was not cleared after the
|
125
|
+
// previous filter operation or that there was no filter operation performed yet), store the current conditions as
|
126
|
+
// the previous condition stack.
|
127
|
+
if (this.previousConditionStack === null) {
|
128
|
+
this.setPreviousConditionStack(this.exportAllConditions());
|
129
|
+
}
|
116
130
|
this.runLocalHooks('beforeAdd', column);
|
117
131
|
const columnType = this.getOperation(column);
|
118
132
|
if (columnType) {
|
@@ -241,6 +255,8 @@ class ConditionCollection {
|
|
241
255
|
* @fires ConditionCollection#afterRemove
|
242
256
|
*/
|
243
257
|
removeConditions(column) {
|
258
|
+
// Store the current conditions as the previous condition stack before it's cleared.
|
259
|
+
this.setPreviousConditionStack(this.exportAllConditions());
|
244
260
|
this.runLocalHooks('beforeRemove', column);
|
245
261
|
this.filteringStates.clearValue(column);
|
246
262
|
this.runLocalHooks('afterRemove', column);
|
@@ -274,6 +290,16 @@ class ConditionCollection {
|
|
274
290
|
return conditions.length > 0;
|
275
291
|
}
|
276
292
|
|
293
|
+
/**
|
294
|
+
* Updates the `previousConditionStack` property with the provided stack.
|
295
|
+
* It is used to store the current conditions before they are modified, allowing for undo operations.
|
296
|
+
*
|
297
|
+
* @param {Array|null} previousConditionStack The stack of previous conditions.
|
298
|
+
*/
|
299
|
+
setPreviousConditionStack(previousConditionStack) {
|
300
|
+
this.previousConditionStack = previousConditionStack;
|
301
|
+
}
|
302
|
+
|
277
303
|
/**
|
278
304
|
* Destroy object.
|
279
305
|
*/
|
@@ -41,6 +41,13 @@ class ConditionCollection {
|
|
41
41
|
* @type {LinkedPhysicalIndexToValueMap}
|
42
42
|
*/
|
43
43
|
_defineProperty(this, "filteringStates", new IndexToValueMap());
|
44
|
+
/**
|
45
|
+
* Stores the previous state of the condition stack before the latest filter operation.
|
46
|
+
* This is used in the `beforeFilter` plugin to allow performing the undo operation.
|
47
|
+
*
|
48
|
+
* @type {null|Array}
|
49
|
+
*/
|
50
|
+
_defineProperty(this, "previousConditionStack", null);
|
44
51
|
this.hot = hot;
|
45
52
|
this.isMapRegistrable = isMapRegistrable;
|
46
53
|
if (this.isMapRegistrable === true) {
|
@@ -109,6 +116,13 @@ class ConditionCollection {
|
|
109
116
|
const localeForColumn = this.hot.getCellMeta(0, column).locale;
|
110
117
|
const args = arrayMap(conditionDefinition.args, v => typeof v === 'string' ? v.toLocaleLowerCase(localeForColumn) : v);
|
111
118
|
const name = conditionDefinition.name || conditionDefinition.command.key;
|
119
|
+
|
120
|
+
// If there's no previous condition stack defined (which means the condition stack was not cleared after the
|
121
|
+
// previous filter operation or that there was no filter operation performed yet), store the current conditions as
|
122
|
+
// the previous condition stack.
|
123
|
+
if (this.previousConditionStack === null) {
|
124
|
+
this.setPreviousConditionStack(this.exportAllConditions());
|
125
|
+
}
|
112
126
|
this.runLocalHooks('beforeAdd', column);
|
113
127
|
const columnType = this.getOperation(column);
|
114
128
|
if (columnType) {
|
@@ -237,6 +251,8 @@ class ConditionCollection {
|
|
237
251
|
* @fires ConditionCollection#afterRemove
|
238
252
|
*/
|
239
253
|
removeConditions(column) {
|
254
|
+
// Store the current conditions as the previous condition stack before it's cleared.
|
255
|
+
this.setPreviousConditionStack(this.exportAllConditions());
|
240
256
|
this.runLocalHooks('beforeRemove', column);
|
241
257
|
this.filteringStates.clearValue(column);
|
242
258
|
this.runLocalHooks('afterRemove', column);
|
@@ -270,6 +286,16 @@ class ConditionCollection {
|
|
270
286
|
return conditions.length > 0;
|
271
287
|
}
|
272
288
|
|
289
|
+
/**
|
290
|
+
* Updates the `previousConditionStack` property with the provided stack.
|
291
|
+
* It is used to store the current conditions before they are modified, allowing for undo operations.
|
292
|
+
*
|
293
|
+
* @param {Array|null} previousConditionStack The stack of previous conditions.
|
294
|
+
*/
|
295
|
+
setPreviousConditionStack(previousConditionStack) {
|
296
|
+
this.previousConditionStack = previousConditionStack;
|
297
|
+
}
|
298
|
+
|
273
299
|
/**
|
274
300
|
* Destroy object.
|
275
301
|
*/
|
@@ -483,7 +483,7 @@ class Filters extends _base.BasePlugin {
|
|
483
483
|
const needToFilter = !this.conditionCollection.isEmpty();
|
484
484
|
let visibleVisualRows = [];
|
485
485
|
const conditions = this.conditionCollection.exportAllConditions();
|
486
|
-
const allowFiltering = this.hot.runHooks('beforeFilter', conditions);
|
486
|
+
const allowFiltering = this.hot.runHooks('beforeFilter', conditions, this.conditionCollection.previousConditionStack);
|
487
487
|
if (allowFiltering !== false) {
|
488
488
|
if (needToFilter) {
|
489
489
|
const trimmedRows = [];
|
@@ -508,6 +508,7 @@ class Filters extends _base.BasePlugin {
|
|
508
508
|
}
|
509
509
|
}
|
510
510
|
this.hot.runHooks('afterFilter', conditions);
|
511
|
+
this.conditionCollection.setPreviousConditionStack(null);
|
511
512
|
this.hot.view.adjustElementsSize();
|
512
513
|
this.hot.render();
|
513
514
|
if (this.hot.selection.isSelected()) {
|
@@ -477,7 +477,7 @@ export class Filters extends BasePlugin {
|
|
477
477
|
const needToFilter = !this.conditionCollection.isEmpty();
|
478
478
|
let visibleVisualRows = [];
|
479
479
|
const conditions = this.conditionCollection.exportAllConditions();
|
480
|
-
const allowFiltering = this.hot.runHooks('beforeFilter', conditions);
|
480
|
+
const allowFiltering = this.hot.runHooks('beforeFilter', conditions, this.conditionCollection.previousConditionStack);
|
481
481
|
if (allowFiltering !== false) {
|
482
482
|
if (needToFilter) {
|
483
483
|
const trimmedRows = [];
|
@@ -502,6 +502,7 @@ export class Filters extends BasePlugin {
|
|
502
502
|
}
|
503
503
|
}
|
504
504
|
this.hot.runHooks('afterFilter', conditions);
|
505
|
+
this.conditionCollection.setPreviousConditionStack(null);
|
505
506
|
this.hot.view.adjustElementsSize();
|
506
507
|
this.hot.render();
|
507
508
|
if (this.hot.selection.isSelected()) {
|
@@ -424,18 +424,20 @@ class MergedCellsCollection {
|
|
424
424
|
break;
|
425
425
|
default:
|
426
426
|
}
|
427
|
-
|
428
|
-
|
427
|
+
const removedMergedCells = [];
|
428
|
+
this.mergedCells.forEach(currentMerge => {
|
429
429
|
currentMerge.shift(shiftVector, index);
|
430
|
-
|
431
|
-
|
432
|
-
(0, _number.rangeEachReverse)(this.mergedCells.length - 1, 0, i => {
|
433
|
-
const currentMerge = this.mergedCells[i];
|
434
|
-
if (currentMerge && currentMerge.removed) {
|
435
|
-
this.mergedCells.splice(this.mergedCells.indexOf(currentMerge), 1);
|
436
|
-
_assertClassBrand(_MergedCellsCollection_brand, this, _removeMergedCellFromMatrix).call(this, currentMerge);
|
430
|
+
if (currentMerge.removed) {
|
431
|
+
removedMergedCells.push(currentMerge);
|
437
432
|
}
|
438
433
|
});
|
434
|
+
removedMergedCells.forEach(removedMerge => {
|
435
|
+
this.mergedCells.splice(this.mergedCells.indexOf(removedMerge), 1);
|
436
|
+
});
|
437
|
+
this.mergedCellsMatrix.clear();
|
438
|
+
this.mergedCells.forEach(currentMerge => {
|
439
|
+
_assertClassBrand(_MergedCellsCollection_brand, this, _addMergedCellToMatrix).call(this, currentMerge);
|
440
|
+
});
|
439
441
|
}
|
440
442
|
|
441
443
|
/**
|
@@ -15,7 +15,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
15
15
|
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); }
|
16
16
|
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
17
|
import MergedCellCoords from "./cellCoords.mjs";
|
18
|
-
import { rangeEach
|
18
|
+
import { rangeEach } from "../../helpers/number.mjs";
|
19
19
|
import { warn } from "../../helpers/console.mjs";
|
20
20
|
import { arrayEach } from "../../helpers/array.mjs";
|
21
21
|
import { toSingleLine } from "../../helpers/templateLiteralTag.mjs";
|
@@ -420,18 +420,20 @@ class MergedCellsCollection {
|
|
420
420
|
break;
|
421
421
|
default:
|
422
422
|
}
|
423
|
-
|
424
|
-
|
423
|
+
const removedMergedCells = [];
|
424
|
+
this.mergedCells.forEach(currentMerge => {
|
425
425
|
currentMerge.shift(shiftVector, index);
|
426
|
-
|
427
|
-
|
428
|
-
rangeEachReverse(this.mergedCells.length - 1, 0, i => {
|
429
|
-
const currentMerge = this.mergedCells[i];
|
430
|
-
if (currentMerge && currentMerge.removed) {
|
431
|
-
this.mergedCells.splice(this.mergedCells.indexOf(currentMerge), 1);
|
432
|
-
_assertClassBrand(_MergedCellsCollection_brand, this, _removeMergedCellFromMatrix).call(this, currentMerge);
|
426
|
+
if (currentMerge.removed) {
|
427
|
+
removedMergedCells.push(currentMerge);
|
433
428
|
}
|
434
429
|
});
|
430
|
+
removedMergedCells.forEach(removedMerge => {
|
431
|
+
this.mergedCells.splice(this.mergedCells.indexOf(removedMerge), 1);
|
432
|
+
});
|
433
|
+
this.mergedCellsMatrix.clear();
|
434
|
+
this.mergedCells.forEach(currentMerge => {
|
435
|
+
_assertClassBrand(_MergedCellsCollection_brand, this, _addMergedCellToMatrix).call(this, currentMerge);
|
436
|
+
});
|
435
437
|
}
|
436
438
|
|
437
439
|
/**
|
@@ -124,8 +124,8 @@ function UndoRedo(instance) {
|
|
124
124
|
instance.addHook('beforeCellAlignment', (stateBefore, range, type, alignment) => {
|
125
125
|
plugin.done(() => new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment));
|
126
126
|
});
|
127
|
-
instance.addHook('beforeFilter', conditionsStack => {
|
128
|
-
plugin.done(() => new UndoRedo.FiltersAction(conditionsStack));
|
127
|
+
instance.addHook('beforeFilter', (conditionsStack, previousConditionsStack) => {
|
128
|
+
plugin.done(() => new UndoRedo.FiltersAction(conditionsStack, previousConditionsStack));
|
129
129
|
});
|
130
130
|
instance.addHook('beforeRowMove', (rows, finalIndex) => {
|
131
131
|
if (rows === false) {
|
@@ -645,9 +645,11 @@ UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback
|
|
645
645
|
* Filters action.
|
646
646
|
*
|
647
647
|
* @private
|
648
|
-
* @param {Array} conditionsStack An array of the filter
|
648
|
+
* @param {Array} conditionsStack An array of the filter conditions.
|
649
|
+
* @param {Array} previousConditionsStack An array of the previous filter conditions.
|
649
650
|
*/
|
650
|
-
UndoRedo.FiltersAction = function (conditionsStack) {
|
651
|
+
UndoRedo.FiltersAction = function (conditionsStack, previousConditionsStack) {
|
652
|
+
this.previousConditionsStack = previousConditionsStack;
|
651
653
|
this.conditionsStack = conditionsStack;
|
652
654
|
this.actionType = 'filter';
|
653
655
|
};
|
@@ -655,7 +657,9 @@ UndoRedo.FiltersAction = function (conditionsStack) {
|
|
655
657
|
UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
|
656
658
|
const filters = instance.getPlugin('filters');
|
657
659
|
instance.addHookOnce('afterViewRender', undoneCallback);
|
658
|
-
|
660
|
+
if (this.previousConditionsStack) {
|
661
|
+
filters.conditionCollection.importAllConditions(this.previousConditionsStack);
|
662
|
+
}
|
659
663
|
filters.filter();
|
660
664
|
};
|
661
665
|
UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
|
@@ -120,8 +120,8 @@ function UndoRedo(instance) {
|
|
120
120
|
instance.addHook('beforeCellAlignment', (stateBefore, range, type, alignment) => {
|
121
121
|
plugin.done(() => new UndoRedo.CellAlignmentAction(stateBefore, range, type, alignment));
|
122
122
|
});
|
123
|
-
instance.addHook('beforeFilter', conditionsStack => {
|
124
|
-
plugin.done(() => new UndoRedo.FiltersAction(conditionsStack));
|
123
|
+
instance.addHook('beforeFilter', (conditionsStack, previousConditionsStack) => {
|
124
|
+
plugin.done(() => new UndoRedo.FiltersAction(conditionsStack, previousConditionsStack));
|
125
125
|
});
|
126
126
|
instance.addHook('beforeRowMove', (rows, finalIndex) => {
|
127
127
|
if (rows === false) {
|
@@ -641,9 +641,11 @@ UndoRedo.CellAlignmentAction.prototype.redo = function (instance, undoneCallback
|
|
641
641
|
* Filters action.
|
642
642
|
*
|
643
643
|
* @private
|
644
|
-
* @param {Array} conditionsStack An array of the filter
|
644
|
+
* @param {Array} conditionsStack An array of the filter conditions.
|
645
|
+
* @param {Array} previousConditionsStack An array of the previous filter conditions.
|
645
646
|
*/
|
646
|
-
UndoRedo.FiltersAction = function (conditionsStack) {
|
647
|
+
UndoRedo.FiltersAction = function (conditionsStack, previousConditionsStack) {
|
648
|
+
this.previousConditionsStack = previousConditionsStack;
|
647
649
|
this.conditionsStack = conditionsStack;
|
648
650
|
this.actionType = 'filter';
|
649
651
|
};
|
@@ -651,7 +653,9 @@ inherit(UndoRedo.FiltersAction, UndoRedo.Action);
|
|
651
653
|
UndoRedo.FiltersAction.prototype.undo = function (instance, undoneCallback) {
|
652
654
|
const filters = instance.getPlugin('filters');
|
653
655
|
instance.addHookOnce('afterViewRender', undoneCallback);
|
654
|
-
|
656
|
+
if (this.previousConditionsStack) {
|
657
|
+
filters.conditionCollection.importAllConditions(this.previousConditionsStack);
|
658
|
+
}
|
655
659
|
filters.filter();
|
656
660
|
};
|
657
661
|
UndoRedo.FiltersAction.prototype.redo = function (instance, redoneCallback) {
|