handsontable 15.2.0 → 15.3.0-next-6f5f494-20250424
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/3rdparty/walkontable/src/cell/range.js +14 -0
- package/3rdparty/walkontable/src/cell/range.mjs +14 -0
- package/3rdparty/walkontable/src/core/_base.js +2 -2
- package/3rdparty/walkontable/src/core/_base.mjs +3 -3
- package/3rdparty/walkontable/src/overlay/_base.js +0 -2
- package/3rdparty/walkontable/src/overlay/_base.mjs +0 -2
- package/3rdparty/walkontable/src/overlay/bottom.js +9 -6
- package/3rdparty/walkontable/src/overlay/bottom.mjs +9 -6
- package/3rdparty/walkontable/src/overlay/inlineStart.js +8 -5
- package/3rdparty/walkontable/src/overlay/inlineStart.mjs +8 -5
- package/3rdparty/walkontable/src/overlay/top.js +11 -6
- package/3rdparty/walkontable/src/overlay/top.mjs +11 -6
- package/3rdparty/walkontable/src/overlays.js +15 -11
- package/3rdparty/walkontable/src/overlays.mjs +15 -11
- package/3rdparty/walkontable/src/renderer/rowHeaders.js +4 -1
- package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +4 -1
- package/3rdparty/walkontable/src/selection/border/border.js +5 -0
- package/3rdparty/walkontable/src/selection/border/border.mjs +5 -0
- package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +8 -10
- package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +8 -10
- package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +3 -4
- package/3rdparty/walkontable/src/table.js +5 -2
- package/3rdparty/walkontable/src/table.mjs +5 -2
- package/3rdparty/walkontable/src/utils/orderView/viewDiffer/viewOrder.js +0 -2
- package/3rdparty/walkontable/src/utils/orderView/viewDiffer/viewOrder.mjs +0 -2
- package/CHANGELOG.md +45 -1
- package/README.md +1 -1
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/core/focusCatcher/focusDetector.js +1 -1
- package/core/focusCatcher/focusDetector.mjs +2 -2
- package/core/hooks/constants.js +8 -0
- package/core/hooks/constants.mjs +8 -0
- package/core/hooks/index.d.ts +1 -0
- package/core/viewportScroll/scrollStrategies/columnHeaderScroll.js +7 -5
- package/core/viewportScroll/scrollStrategies/columnHeaderScroll.mjs +7 -5
- package/core/viewportScroll/scrollStrategies/focusScroll.js +8 -1
- package/core/viewportScroll/scrollStrategies/focusScroll.mjs +8 -1
- package/core/viewportScroll/scrollStrategies/multipleScroll.js +13 -1
- package/core/viewportScroll/scrollStrategies/multipleScroll.mjs +13 -1
- package/core/viewportScroll/scrollStrategies/noncontiguousScroll.js +13 -1
- package/core/viewportScroll/scrollStrategies/noncontiguousScroll.mjs +13 -1
- package/core/viewportScroll/scrollStrategies/rowHeaderScroll.js +7 -5
- package/core/viewportScroll/scrollStrategies/rowHeaderScroll.mjs +7 -5
- package/core/viewportScroll/scrollStrategies/singleScroll.js +8 -4
- package/core/viewportScroll/scrollStrategies/singleScroll.mjs +8 -4
- package/core/viewportScroll/utils.js +111 -0
- package/core/viewportScroll/utils.mjs +106 -0
- package/core.d.ts +2 -3
- package/core.js +125 -71
- package/core.mjs +126 -72
- package/dataMap/dataMap.js +0 -7
- package/dataMap/dataMap.mjs +0 -7
- package/dataMap/metaManager/index.js +8 -9
- package/dataMap/metaManager/index.mjs +8 -9
- package/dataMap/metaManager/mods/dynamicCellMeta.js +4 -1
- package/dataMap/metaManager/mods/dynamicCellMeta.mjs +4 -1
- package/dist/handsontable.css +4 -15
- package/dist/handsontable.full.css +4 -17
- package/dist/handsontable.full.js +4573 -4013
- package/dist/handsontable.full.min.css +3 -3
- package/dist/handsontable.full.min.js +148 -148
- package/dist/handsontable.js +4287 -3730
- package/dist/handsontable.min.css +3 -3
- package/dist/handsontable.min.js +19 -19
- package/editorManager.js +1 -7
- package/editorManager.mjs +1 -7
- package/editors/autocompleteEditor/autocompleteEditor.js +31 -7
- package/editors/autocompleteEditor/autocompleteEditor.mjs +31 -7
- package/focusManager.js +4 -2
- package/focusManager.mjs +4 -2
- package/helpers/browser.js +1 -1
- package/helpers/browser.mjs +1 -1
- package/helpers/dom/element.d.ts +1 -0
- package/helpers/dom/element.js +20 -0
- package/helpers/dom/element.mjs +19 -0
- package/helpers/mixed.js +2 -2
- package/helpers/mixed.mjs +2 -2
- package/helpers/object.js +3 -0
- package/helpers/object.mjs +3 -0
- package/package.json +1 -1
- package/plugins/autoColumnSize/autoColumnSize.js +38 -17
- package/plugins/autoColumnSize/autoColumnSize.mjs +38 -17
- package/plugins/autoRowSize/autoRowSize.js +12 -6
- package/plugins/autoRowSize/autoRowSize.mjs +12 -6
- package/plugins/columnSorting/columnSorting.js +0 -4
- package/plugins/columnSorting/columnSorting.mjs +0 -4
- package/plugins/comments/comments.js +1 -0
- package/plugins/comments/comments.mjs +1 -0
- package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
- package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
- package/plugins/contextMenu/menu/menu.js +1 -0
- package/plugins/contextMenu/menu/menu.mjs +1 -0
- package/plugins/contextMenu/menu/positioner.js +10 -2
- package/plugins/contextMenu/menu/positioner.mjs +10 -2
- package/plugins/contextMenu/predefinedItems/redo.js +3 -3
- package/plugins/contextMenu/predefinedItems/redo.mjs +3 -3
- package/plugins/contextMenu/predefinedItems/undo.js +3 -3
- package/plugins/contextMenu/predefinedItems/undo.mjs +3 -3
- package/plugins/copyPaste/copyPaste.js +12 -9
- package/plugins/copyPaste/copyPaste.mjs +12 -9
- package/plugins/copyPaste/pasteEvent.js +3 -0
- package/plugins/copyPaste/pasteEvent.mjs +3 -0
- package/plugins/exportFile/exportFile.d.ts +1 -0
- package/plugins/exportFile/exportFile.js +2 -1
- package/plugins/exportFile/exportFile.mjs +2 -1
- package/plugins/exportFile/types/csv.js +76 -11
- package/plugins/exportFile/types/csv.mjs +76 -11
- package/plugins/filters/filters.js +24 -23
- package/plugins/filters/filters.mjs +24 -23
- package/plugins/filters/ui/multipleSelect.js +7 -1
- package/plugins/filters/ui/multipleSelect.mjs +7 -1
- package/plugins/formulas/formulas.d.ts +1 -1
- package/plugins/formulas/formulas.js +57 -60
- package/plugins/formulas/formulas.mjs +59 -62
- package/plugins/formulas/indexSyncer/axisSyncer.js +5 -1
- package/plugins/formulas/indexSyncer/axisSyncer.mjs +5 -1
- package/plugins/hiddenColumns/hiddenColumns.js +1 -1
- package/plugins/hiddenColumns/hiddenColumns.mjs +1 -1
- package/plugins/hiddenRows/hiddenRows.js +1 -1
- package/plugins/hiddenRows/hiddenRows.mjs +1 -1
- package/plugins/manualColumnResize/manualColumnResize.js +4 -6
- package/plugins/manualColumnResize/manualColumnResize.mjs +4 -6
- package/plugins/manualRowResize/manualRowResize.js +4 -6
- package/plugins/manualRowResize/manualRowResize.mjs +4 -6
- package/plugins/mergeCells/mergeCells.js +10 -30
- package/plugins/mergeCells/mergeCells.mjs +10 -30
- package/plugins/mergeCells/renderer.js +15 -0
- package/plugins/mergeCells/renderer.mjs +15 -0
- package/plugins/mergeCells/utils.js +31 -0
- package/plugins/mergeCells/utils.mjs +27 -0
- package/plugins/nestedRows/data/dataManager.js +2 -2
- package/plugins/nestedRows/data/dataManager.mjs +2 -2
- package/plugins/undoRedo/actions/index.js +0 -2
- package/plugins/undoRedo/actions/index.mjs +0 -2
- package/plugins/undoRedo/actions/removeColumn.js +19 -14
- package/plugins/undoRedo/actions/removeColumn.mjs +19 -14
- package/plugins/undoRedo/actions/removeRow.js +12 -4
- package/plugins/undoRedo/actions/removeRow.mjs +12 -4
- package/selection/selection.js +3 -1
- package/selection/selection.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/down.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/down.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.js +8 -2
- package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.mjs +8 -2
- package/shortcutContexts/commands/extendCellsSelection/left.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/left.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/right.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/right.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/toColumns.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toRows.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/up.js +7 -2
- package/shortcutContexts/commands/extendCellsSelection/up.mjs +7 -2
- package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.js +8 -2
- package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.mjs +8 -2
- package/shortcutContexts/commands/index.js +0 -2
- package/shortcutContexts/commands/index.mjs +0 -2
- package/shortcutContexts/commands/moveCellSelection/down.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/down.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/downByViewportHeight.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/downByViewportHeight.mjs +6 -1
- package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +8 -3
- package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +8 -3
- package/shortcutContexts/commands/moveCellSelection/inlineStart.js +8 -3
- package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +8 -3
- package/shortcutContexts/commands/moveCellSelection/left.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/left.mjs +6 -1
- package/shortcutContexts/commands/moveCellSelection/right.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/right.mjs +6 -1
- package/shortcutContexts/commands/moveCellSelection/toMostBottom.js +4 -1
- package/shortcutContexts/commands/moveCellSelection/toMostBottom.mjs +4 -1
- package/shortcutContexts/commands/moveCellSelection/toMostBottomInlineEnd.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostBottomInlineEnd.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostInlineEnd.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostInlineEnd.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostInlineStart.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostInlineStart.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostLeft.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostLeft.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostRight.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostRight.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostTop.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/toMostTop.mjs +6 -1
- package/shortcutContexts/commands/moveCellSelection/toMostTopInlineStart.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/toMostTopInlineStart.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/up.js +2 -0
- package/shortcutContexts/commands/moveCellSelection/up.mjs +2 -0
- package/shortcutContexts/commands/moveCellSelection/upByViewportHeight.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/upByViewportHeight.mjs +6 -1
- package/shortcutContexts/commands/selectAllCells.js +7 -2
- package/shortcutContexts/commands/selectAllCells.mjs +7 -2
- package/shortcutContexts/commands/selectAllCellsAndHeaders.js +7 -2
- package/shortcutContexts/commands/selectAllCellsAndHeaders.mjs +7 -2
- package/shortcutContexts/index.js +2 -2
- package/shortcutContexts/index.mjs +0 -2
- package/styles/handsontable.css +15 -17
- 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/tableView.js +5 -8
- package/tableView.mjs +5 -8
- package/translations/indexMapper.js +0 -1
- package/translations/indexMapper.mjs +0 -1
- package/utils/ghostTable.js +3 -0
- package/utils/ghostTable.mjs +3 -0
@@ -1,16 +1,37 @@
|
|
1
|
+
import "core-js/modules/es.error.cause.js";
|
1
2
|
import "core-js/modules/esnext.iterator.constructor.js";
|
2
3
|
import "core-js/modules/esnext.iterator.map.js";
|
4
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
5
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
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"); }
|
3
7
|
import { arrayEach, arrayMap } from "../../../helpers/array.mjs";
|
4
8
|
import { stringify } from "../../../helpers/mixed.mjs";
|
5
9
|
import BaseType from "./_base.mjs";
|
6
10
|
const CHAR_CARRIAGE_RETURN = String.fromCharCode(13);
|
7
11
|
const CHAR_DOUBLE_QUOTES = String.fromCharCode(34);
|
8
12
|
const CHAR_LINE_FEED = String.fromCharCode(10);
|
13
|
+
const CHAR_EQUAL = String.fromCharCode(61);
|
14
|
+
const CHAR_PLUS = String.fromCharCode(43);
|
15
|
+
const CHAR_MINUS = String.fromCharCode(45);
|
16
|
+
const CHAR_AT = String.fromCharCode(64);
|
17
|
+
const CHAR_TAB = String.fromCharCode(9);
|
9
18
|
|
10
19
|
/**
|
11
20
|
* @private
|
12
21
|
*/
|
22
|
+
var _Csv_brand = /*#__PURE__*/new WeakSet();
|
13
23
|
class Csv extends BaseType {
|
24
|
+
constructor() {
|
25
|
+
super(...arguments);
|
26
|
+
/**
|
27
|
+
* Sanitize value that may be interpreted as a formula in spreadsheet software.
|
28
|
+
* Following the OWASP recommendations: https://owasp.org/www-community/attacks/CSV_Injection.
|
29
|
+
*
|
30
|
+
* @param {string} value Cell value.
|
31
|
+
* @returns {string}
|
32
|
+
*/
|
33
|
+
_classPrivateMethodInitSpec(this, _Csv_brand);
|
34
|
+
}
|
14
35
|
/**
|
15
36
|
* Default options for exporting CSV format.
|
16
37
|
*
|
@@ -22,7 +43,8 @@ class Csv extends BaseType {
|
|
22
43
|
fileExtension: 'csv',
|
23
44
|
bom: true,
|
24
45
|
columnDelimiter: ',',
|
25
|
-
rowDelimiter: '\r\n'
|
46
|
+
rowDelimiter: '\r\n',
|
47
|
+
sanitizeValues: false
|
26
48
|
};
|
27
49
|
}
|
28
50
|
|
@@ -40,7 +62,10 @@ class Csv extends BaseType {
|
|
40
62
|
const hasRowHeaders = rowHeaders.length > 0;
|
41
63
|
let result = options.bom ? String.fromCharCode(0xFEFF) : '';
|
42
64
|
if (hasColumnHeaders) {
|
43
|
-
columnHeaders = arrayMap(columnHeaders, value => this._escapeCell(value,
|
65
|
+
columnHeaders = arrayMap(columnHeaders, value => this._escapeCell(value, {
|
66
|
+
force: true,
|
67
|
+
sanitizeValue: options.sanitizeValues
|
68
|
+
}));
|
44
69
|
if (hasRowHeaders) {
|
45
70
|
result += options.columnDelimiter;
|
46
71
|
}
|
@@ -52,9 +77,15 @@ class Csv extends BaseType {
|
|
52
77
|
result += options.rowDelimiter;
|
53
78
|
}
|
54
79
|
if (hasRowHeaders) {
|
55
|
-
result += this._escapeCell(rowHeaders[index]
|
80
|
+
result += this._escapeCell(rowHeaders[index], {
|
81
|
+
sanitizeValue: options.sanitizeValues
|
82
|
+
});
|
83
|
+
result += options.columnDelimiter;
|
56
84
|
}
|
57
|
-
|
85
|
+
const escapedValue = value.map(cellValue => this._escapeCell(cellValue, {
|
86
|
+
sanitizeValue: options.sanitizeValues
|
87
|
+
})).join(options.columnDelimiter);
|
88
|
+
result += escapedValue;
|
58
89
|
});
|
59
90
|
return result;
|
60
91
|
}
|
@@ -63,17 +94,51 @@ class Csv extends BaseType {
|
|
63
94
|
* Escape cell value.
|
64
95
|
*
|
65
96
|
* @param {*} value Cell value.
|
66
|
-
* @param {
|
97
|
+
* @param {object} options Options.
|
98
|
+
* @param {boolean} [options.force=false] Indicates if cell value will be escaped forcefully.
|
99
|
+
* @param {boolean|RegExp|Function} [options.sanitizeValue=false] Controls the sanitization of cell value.
|
67
100
|
* @returns {string}
|
68
101
|
*/
|
69
102
|
_escapeCell(value) {
|
70
|
-
let
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
103
|
+
let {
|
104
|
+
force = false,
|
105
|
+
sanitizeValue = false
|
106
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
107
|
+
let returnValue = stringify(value);
|
108
|
+
if (returnValue === '') {
|
109
|
+
return returnValue;
|
110
|
+
}
|
111
|
+
if (sanitizeValue) {
|
112
|
+
force = true;
|
113
|
+
}
|
114
|
+
if (sanitizeValue instanceof RegExp) {
|
115
|
+
returnValue = _assertClassBrand(_Csv_brand, this, _sanitizeValueWithRegExp).call(this, returnValue, sanitizeValue);
|
116
|
+
} else if (typeof sanitizeValue === 'function') {
|
117
|
+
returnValue = sanitizeValue(returnValue);
|
118
|
+
} else if (sanitizeValue) {
|
119
|
+
returnValue = _assertClassBrand(_Csv_brand, this, _sanitizeValueWithOWASP).call(this, returnValue);
|
120
|
+
}
|
121
|
+
if (force || returnValue.indexOf(CHAR_CARRIAGE_RETURN) >= 0 || returnValue.indexOf(CHAR_DOUBLE_QUOTES) >= 0 || returnValue.indexOf(CHAR_LINE_FEED) >= 0 || returnValue.indexOf(this.options.columnDelimiter) >= 0) {
|
122
|
+
returnValue = returnValue.replace(new RegExp('"', 'g'), '""');
|
123
|
+
returnValue = `"${returnValue}"`;
|
75
124
|
}
|
76
|
-
return
|
125
|
+
return returnValue;
|
77
126
|
}
|
78
127
|
}
|
128
|
+
function _sanitizeValueWithOWASP(value) {
|
129
|
+
if (value.startsWith(CHAR_EQUAL) || value.startsWith(CHAR_PLUS) || value.startsWith(CHAR_MINUS) || value.startsWith(CHAR_AT) || value.startsWith(CHAR_TAB) || value.startsWith(CHAR_CARRIAGE_RETURN)) {
|
130
|
+
return `'${value}`;
|
131
|
+
}
|
132
|
+
return value;
|
133
|
+
}
|
134
|
+
/**
|
135
|
+
* Sanitize value using regular expression.
|
136
|
+
*
|
137
|
+
* @param {string} value Cell value.
|
138
|
+
* @param {RegExp} regexp Regular expression to test against.
|
139
|
+
* @returns {string}
|
140
|
+
*/
|
141
|
+
function _sanitizeValueWithRegExp(value, regexp) {
|
142
|
+
return regexp.test(value) ? `'${value}` : value;
|
143
|
+
}
|
79
144
|
export default Csv;
|
@@ -562,38 +562,39 @@ class Filters extends _base.BasePlugin {
|
|
562
562
|
let visibleVisualRows = [];
|
563
563
|
const conditions = this.exportConditions();
|
564
564
|
const allowFiltering = this.hot.runHooks('beforeFilter', conditions, _classPrivateFieldGet(_previousConditionStack, this));
|
565
|
-
if (allowFiltering !== false) {
|
566
|
-
|
567
|
-
|
568
|
-
this.hot.batchExecution(() => {
|
569
|
-
this.filtersRowsMap.clear();
|
570
|
-
visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), rowData => rowData.meta.visualRow);
|
571
|
-
const visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
|
572
|
-
(0, _number.rangeEach)(this.hot.countSourceRows() - 1, row => {
|
573
|
-
if (!visibleVisualRowsAssertion(row)) {
|
574
|
-
trimmedRows.push(row);
|
575
|
-
}
|
576
|
-
});
|
577
|
-
(0, _array.arrayEach)(trimmedRows, physicalRow => {
|
578
|
-
this.filtersRowsMap.setValueAtIndex(physicalRow, true);
|
579
|
-
});
|
580
|
-
}, true);
|
581
|
-
if (!navigableHeaders && !visibleVisualRows.length) {
|
582
|
-
this.hot.deselectCell();
|
583
|
-
}
|
584
|
-
} else {
|
565
|
+
if (allowFiltering !== false && needToFilter) {
|
566
|
+
const trimmedRows = [];
|
567
|
+
this.hot.batchExecution(() => {
|
585
568
|
this.filtersRowsMap.clear();
|
569
|
+
visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), rowData => rowData.meta.visualRow);
|
570
|
+
const visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
|
571
|
+
(0, _number.rangeEach)(this.hot.countSourceRows() - 1, row => {
|
572
|
+
if (!visibleVisualRowsAssertion(row)) {
|
573
|
+
trimmedRows.push(row);
|
574
|
+
}
|
575
|
+
});
|
576
|
+
(0, _array.arrayEach)(trimmedRows, physicalRow => {
|
577
|
+
this.filtersRowsMap.setValueAtIndex(physicalRow, true);
|
578
|
+
});
|
579
|
+
}, true);
|
580
|
+
if (!navigableHeaders && !visibleVisualRows.length) {
|
581
|
+
this.hot.deselectCell();
|
586
582
|
}
|
587
583
|
_classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
|
588
|
-
|
589
|
-
this.
|
590
|
-
this.
|
584
|
+
} else if (allowFiltering !== false && !needToFilter) {
|
585
|
+
_classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
|
586
|
+
this.filtersRowsMap.clear();
|
591
587
|
} else {
|
592
588
|
this.importConditions(_classPrivateFieldGet(_previousConditionStack, this));
|
593
589
|
}
|
594
590
|
if (this.hot.selection.isSelected()) {
|
595
591
|
this.hot.selectCell(navigableHeaders ? -1 : 0, this.hot.getSelectedRangeLast().highlight.col);
|
596
592
|
}
|
593
|
+
if (allowFiltering !== false) {
|
594
|
+
this.hot.runHooks('afterFilter', conditions);
|
595
|
+
this.hot.view.adjustElementsSize();
|
596
|
+
this.hot.render();
|
597
|
+
}
|
597
598
|
}
|
598
599
|
|
599
600
|
/**
|
@@ -556,38 +556,39 @@ export class Filters extends BasePlugin {
|
|
556
556
|
let visibleVisualRows = [];
|
557
557
|
const conditions = this.exportConditions();
|
558
558
|
const allowFiltering = this.hot.runHooks('beforeFilter', conditions, _classPrivateFieldGet(_previousConditionStack, this));
|
559
|
-
if (allowFiltering !== false) {
|
560
|
-
|
561
|
-
|
562
|
-
this.hot.batchExecution(() => {
|
563
|
-
this.filtersRowsMap.clear();
|
564
|
-
visibleVisualRows = arrayMap(dataFilter.filter(), rowData => rowData.meta.visualRow);
|
565
|
-
const visibleVisualRowsAssertion = createArrayAssertion(visibleVisualRows);
|
566
|
-
rangeEach(this.hot.countSourceRows() - 1, row => {
|
567
|
-
if (!visibleVisualRowsAssertion(row)) {
|
568
|
-
trimmedRows.push(row);
|
569
|
-
}
|
570
|
-
});
|
571
|
-
arrayEach(trimmedRows, physicalRow => {
|
572
|
-
this.filtersRowsMap.setValueAtIndex(physicalRow, true);
|
573
|
-
});
|
574
|
-
}, true);
|
575
|
-
if (!navigableHeaders && !visibleVisualRows.length) {
|
576
|
-
this.hot.deselectCell();
|
577
|
-
}
|
578
|
-
} else {
|
559
|
+
if (allowFiltering !== false && needToFilter) {
|
560
|
+
const trimmedRows = [];
|
561
|
+
this.hot.batchExecution(() => {
|
579
562
|
this.filtersRowsMap.clear();
|
563
|
+
visibleVisualRows = arrayMap(dataFilter.filter(), rowData => rowData.meta.visualRow);
|
564
|
+
const visibleVisualRowsAssertion = createArrayAssertion(visibleVisualRows);
|
565
|
+
rangeEach(this.hot.countSourceRows() - 1, row => {
|
566
|
+
if (!visibleVisualRowsAssertion(row)) {
|
567
|
+
trimmedRows.push(row);
|
568
|
+
}
|
569
|
+
});
|
570
|
+
arrayEach(trimmedRows, physicalRow => {
|
571
|
+
this.filtersRowsMap.setValueAtIndex(physicalRow, true);
|
572
|
+
});
|
573
|
+
}, true);
|
574
|
+
if (!navigableHeaders && !visibleVisualRows.length) {
|
575
|
+
this.hot.deselectCell();
|
580
576
|
}
|
581
577
|
_classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
|
582
|
-
|
583
|
-
this.
|
584
|
-
this.
|
578
|
+
} else if (allowFiltering !== false && !needToFilter) {
|
579
|
+
_classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
|
580
|
+
this.filtersRowsMap.clear();
|
585
581
|
} else {
|
586
582
|
this.importConditions(_classPrivateFieldGet(_previousConditionStack, this));
|
587
583
|
}
|
588
584
|
if (this.hot.selection.isSelected()) {
|
589
585
|
this.hot.selectCell(navigableHeaders ? -1 : 0, this.hot.getSelectedRangeLast().highlight.col);
|
590
586
|
}
|
587
|
+
if (allowFiltering !== false) {
|
588
|
+
this.hot.runHooks('afterFilter', conditions);
|
589
|
+
this.hot.view.adjustElementsSize();
|
590
|
+
this.hot.render();
|
591
|
+
}
|
591
592
|
}
|
592
593
|
|
593
594
|
/**
|
@@ -253,7 +253,13 @@ class MultipleSelectUI extends _base.BaseUI {
|
|
253
253
|
beforeOnCellMouseUp: () => {
|
254
254
|
_classPrivateFieldGet(_itemsBox, this).listen();
|
255
255
|
},
|
256
|
-
|
256
|
+
modifyColWidth: width => {
|
257
|
+
const minWidth = _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument);
|
258
|
+
if (width !== undefined && width < minWidth) {
|
259
|
+
return minWidth;
|
260
|
+
}
|
261
|
+
return width;
|
262
|
+
},
|
257
263
|
maxCols: 1,
|
258
264
|
autoWrapCol: true,
|
259
265
|
height: 110,
|
@@ -248,7 +248,13 @@ export class MultipleSelectUI extends BaseUI {
|
|
248
248
|
beforeOnCellMouseUp: () => {
|
249
249
|
_classPrivateFieldGet(_itemsBox, this).listen();
|
250
250
|
},
|
251
|
-
|
251
|
+
modifyColWidth: width => {
|
252
|
+
const minWidth = _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - getScrollbarWidth(rootDocument);
|
253
|
+
if (width !== undefined && width < minWidth) {
|
254
|
+
return minWidth;
|
255
|
+
}
|
256
|
+
return width;
|
257
|
+
},
|
252
258
|
maxCols: 1,
|
253
259
|
autoWrapCol: true,
|
254
260
|
height: 110,
|
@@ -32,7 +32,7 @@ export class Formulas extends BasePlugin {
|
|
32
32
|
|
33
33
|
engine: HyperFormula | null;
|
34
34
|
sheetName: string | null;
|
35
|
-
|
35
|
+
sheetId: number | null;
|
36
36
|
|
37
37
|
isEnabled(): boolean;
|
38
38
|
addSheet(sheetName?: string | null, sheetData?: CellValue[][]): string | boolean;
|
@@ -13,7 +13,6 @@ require("core-js/modules/es.set.symmetric-difference.v2.js");
|
|
13
13
|
require("core-js/modules/es.set.union.v2.js");
|
14
14
|
require("core-js/modules/esnext.iterator.constructor.js");
|
15
15
|
require("core-js/modules/esnext.iterator.every.js");
|
16
|
-
require("core-js/modules/esnext.iterator.find.js");
|
17
16
|
require("core-js/modules/esnext.iterator.for-each.js");
|
18
17
|
require("core-js/modules/esnext.iterator.map.js");
|
19
18
|
var _base = require("../base");
|
@@ -74,13 +73,9 @@ class Formulas extends _base.BasePlugin {
|
|
74
73
|
super(...arguments);
|
75
74
|
_this = this;
|
76
75
|
/**
|
77
|
-
*
|
78
|
-
* validator function.
|
76
|
+
* Update sheetName and sheetId properties.
|
79
77
|
*
|
80
|
-
* @param {
|
81
|
-
* @param {number} visualRow The visual row index.
|
82
|
-
* @param {number|string} prop The visual column index or property name of the column.
|
83
|
-
* @returns {*} Returns value to validate.
|
78
|
+
* @param {string} [sheetName] The new sheet name.
|
84
79
|
*/
|
85
80
|
_classPrivateMethodInitSpec(this, _Formulas_brand);
|
86
81
|
/**
|
@@ -147,6 +142,12 @@ class Formulas extends _base.BasePlugin {
|
|
147
142
|
* @type {HyperFormula|null}
|
148
143
|
*/
|
149
144
|
_defineProperty(this, "engine", null);
|
145
|
+
/**
|
146
|
+
* HyperFormula's sheet id.
|
147
|
+
*
|
148
|
+
* @type {number|null}
|
149
|
+
*/
|
150
|
+
_defineProperty(this, "sheetId", null);
|
150
151
|
/**
|
151
152
|
* HyperFormula's sheet name.
|
152
153
|
*
|
@@ -181,15 +182,6 @@ class Formulas extends _base.BasePlugin {
|
|
181
182
|
static get SETTING_KEYS() {
|
182
183
|
return [PLUGIN_KEY, ...SETTING_KEYS];
|
183
184
|
}
|
184
|
-
/**
|
185
|
-
* HyperFormula's sheet id.
|
186
|
-
*
|
187
|
-
* @type {number|null}
|
188
|
-
*/
|
189
|
-
get sheetId() {
|
190
|
-
return this.sheetName === null ? null : this.engine.getSheetId(this.sheetName);
|
191
|
-
}
|
192
|
-
|
193
185
|
/**
|
194
186
|
* Checks if the plugin is enabled in the handsontable settings. This method is executed in {@link Hooks#beforeInit}
|
195
187
|
* hook and if it returns `true` then the {@link Formulas#enablePlugin} method is called.
|
@@ -220,7 +212,7 @@ class Formulas extends _base.BasePlugin {
|
|
220
212
|
if (this.sheetName !== null && !this.engine.doesSheetExist(this.sheetName)) {
|
221
213
|
const newSheetName = this.addSheet(this.sheetName, this.hot.getSourceDataArray());
|
222
214
|
if (newSheetName !== false) {
|
223
|
-
this.
|
215
|
+
_assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, newSheetName);
|
224
216
|
}
|
225
217
|
}
|
226
218
|
this.addHook('beforeLoadData', function () {
|
@@ -451,7 +443,8 @@ class Formulas extends _base.BasePlugin {
|
|
451
443
|
if (sheetName && this.engine.doesSheetExist(sheetName)) {
|
452
444
|
this.switchSheet(this.sheetName);
|
453
445
|
} else {
|
454
|
-
|
446
|
+
const newSheetName = this.addSheet(sheetName !== null && sheetName !== void 0 ? sheetName : undefined, this.hot.getSourceDataArray());
|
447
|
+
_assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, newSheetName);
|
455
448
|
}
|
456
449
|
}
|
457
450
|
super.updatePlugin(newSettings);
|
@@ -471,7 +464,6 @@ class Formulas extends _base.BasePlugin {
|
|
471
464
|
this.engine = null;
|
472
465
|
super.destroy();
|
473
466
|
}
|
474
|
-
|
475
467
|
/**
|
476
468
|
* Add a sheet to the shared HyperFormula instance.
|
477
469
|
*
|
@@ -514,7 +506,7 @@ class Formulas extends _base.BasePlugin {
|
|
514
506
|
(0, _console.error)(`The sheet named \`${sheetName}\` does not exist, switch aborted.`);
|
515
507
|
return;
|
516
508
|
}
|
517
|
-
this.
|
509
|
+
_assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, sheetName);
|
518
510
|
const serialized = this.engine.getSheetSerialized(this.sheetId);
|
519
511
|
if (serialized.length > 0) {
|
520
512
|
this.hot.loadData(serialized, `${(0, _string.toUpperCaseFirst)(PLUGIN_KEY)}.switchSheet`);
|
@@ -674,8 +666,22 @@ class Formulas extends _base.BasePlugin {
|
|
674
666
|
}
|
675
667
|
return this.engine.setCellContents(address, newValue);
|
676
668
|
}
|
669
|
+
|
670
|
+
/**
|
671
|
+
* The hook allows to translate the formula value to calculated value before it goes to the
|
672
|
+
* validator function.
|
673
|
+
*
|
674
|
+
* @param {*} value The cell value to validate.
|
675
|
+
* @param {number} visualRow The visual row index.
|
676
|
+
* @param {number|string} prop The visual column index or property name of the column.
|
677
|
+
* @returns {*} Returns value to validate.
|
678
|
+
*/
|
677
679
|
}
|
678
680
|
exports.Formulas = Formulas;
|
681
|
+
function _updateSheetNameAndSheetId(sheetName) {
|
682
|
+
this.sheetName = sheetName;
|
683
|
+
this.sheetId = this.engine.getSheetId(this.sheetName);
|
684
|
+
}
|
679
685
|
function _onBeforeValidate(value, visualRow, prop) {
|
680
686
|
const visualColumn = this.hot.propToCol(prop);
|
681
687
|
if (this.isFormulaCellType(visualRow, visualColumn)) {
|
@@ -803,29 +809,33 @@ function _onBeforeLoadData(sourceData, initialLoad) {
|
|
803
809
|
* Callback to `afterCellMetaReset` hook which is triggered after setting cell meta.
|
804
810
|
*/
|
805
811
|
function _onAfterCellMetaReset() {
|
812
|
+
if (_classPrivateFieldGet(_hotWasInitializedWithEmptyData, this)) {
|
813
|
+
this.switchSheet(this.sheetName);
|
814
|
+
return;
|
815
|
+
}
|
806
816
|
const sourceDataArray = this.hot.getSourceDataArray();
|
807
|
-
let valueChanged = false;
|
808
817
|
sourceDataArray.forEach((rowData, rowIndex) => {
|
809
818
|
rowData.forEach((cellValue, columnIndex) => {
|
810
|
-
const cellMeta = this.hot.getCellMeta(rowIndex, columnIndex
|
819
|
+
const cellMeta = this.hot.getCellMeta(rowIndex, columnIndex, {
|
820
|
+
skipMetaExtension: true
|
821
|
+
});
|
811
822
|
const dateFormat = cellMeta.dateFormat;
|
812
823
|
if ((0, _utils.isDate)(cellValue, cellMeta.type)) {
|
813
|
-
valueChanged = true;
|
814
824
|
if ((0, _utils.isDateValid)(cellValue, dateFormat)) {
|
815
825
|
// Rewriting date in HOT format to HF format.
|
816
826
|
sourceDataArray[rowIndex][columnIndex] = (0, _utils.getDateInHfFormat)(cellValue, dateFormat);
|
817
|
-
} else if (
|
827
|
+
} else if (!cellValue.startsWith('=')) {
|
818
828
|
// Escaping value from date parsing using "'" sign (HF feature).
|
819
829
|
sourceDataArray[rowIndex][columnIndex] = `'${cellValue}`;
|
820
830
|
}
|
821
831
|
}
|
822
832
|
});
|
823
833
|
});
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
834
|
+
_classPrivateFieldSet(_internalOperationPending, this, true);
|
835
|
+
const dependentCells = this.engine.setSheetContent(this.sheetId, sourceDataArray);
|
836
|
+
this.indexSyncer.setupSyncEndpoint(this.engine, this.sheetId);
|
837
|
+
this.renderDependentSheets(dependentCells);
|
838
|
+
_classPrivateFieldSet(_internalOperationPending, this, false);
|
829
839
|
}
|
830
840
|
/**
|
831
841
|
* `afterLoadData` hook callback.
|
@@ -839,7 +849,12 @@ function _onAfterLoadData(sourceData, initialLoad) {
|
|
839
849
|
if (source.includes((0, _string.toUpperCaseFirst)(PLUGIN_KEY))) {
|
840
850
|
return;
|
841
851
|
}
|
842
|
-
|
852
|
+
const sheetName = (0, _register.setupSheet)(this.engine, this.hot.getSettings()[PLUGIN_KEY].sheetName);
|
853
|
+
_assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, sheetName);
|
854
|
+
if (source === 'updateSettings') {
|
855
|
+
// For performance reasons, the initialization will be done in afterCellMetaReset hook
|
856
|
+
return;
|
857
|
+
}
|
843
858
|
if (!_classPrivateFieldGet(_hotWasInitializedWithEmptyData, this)) {
|
844
859
|
const sourceDataArray = this.hot.getSourceDataArray();
|
845
860
|
if (this.engine.isItPossibleToReplaceSheetContent(this.sheetId, sourceDataArray)) {
|
@@ -870,17 +885,10 @@ function _onModifyData(physicalRow, visualColumn, valueHolder, ioMode) {
|
|
870
885
|
if (visualRow === null || visualColumn === null) {
|
871
886
|
return;
|
872
887
|
}
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
const cellType = this.getCellType(visualRow, visualColumn);
|
878
|
-
if (cellType !== 'ARRAY') {
|
879
|
-
if ((0, _utils.isEscapedFormulaExpression)(valueHolder.value)) {
|
880
|
-
valueHolder.value = (0, _utils.unescapeFormulaExpression)(valueHolder.value);
|
881
|
-
}
|
882
|
-
return;
|
883
|
-
}
|
888
|
+
const cellType = this.getCellType(visualRow, visualColumn);
|
889
|
+
if (cellType === 'VALUE' || cellType === 'EMPTY') {
|
890
|
+
valueHolder.value = (0, _utils.unescapeFormulaExpression)(valueHolder.value);
|
891
|
+
return;
|
884
892
|
}
|
885
893
|
const address = {
|
886
894
|
row: this.rowAxisSyncer.getHfIndexFromVisualIndex(visualRow),
|
@@ -889,21 +897,15 @@ function _onModifyData(physicalRow, visualColumn, valueHolder, ioMode) {
|
|
889
897
|
};
|
890
898
|
let cellValue = this.engine.getCellValue(address); // Date as an integer (Excel like date).
|
891
899
|
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
// is executed once again and it cause creation of an infinite loop.
|
896
|
-
let cellMeta = this.hot.getCellsMeta().find(singleCellMeta => singleCellMeta.visualRow === visualRow && singleCellMeta.visualCol === visualColumn);
|
897
|
-
if (cellMeta === undefined) {
|
898
|
-
cellMeta = {};
|
899
|
-
}
|
900
|
+
const cellMeta = this.hot.getCellMeta(visualRow, visualColumn, {
|
901
|
+
skipMetaExtension: true
|
902
|
+
});
|
900
903
|
if (cellMeta.type === 'date' && (0, _number.isNumeric)(cellValue)) {
|
901
904
|
cellValue = (0, _utils.getDateFromExcelDate)(cellValue, cellMeta.dateFormat);
|
902
905
|
}
|
903
906
|
|
904
907
|
// If `cellValue` is an object it is expected to be an error
|
905
|
-
|
906
|
-
valueHolder.value = value;
|
908
|
+
valueHolder.value = typeof cellValue === 'object' && cellValue !== null ? cellValue.value : cellValue;
|
907
909
|
}
|
908
910
|
/**
|
909
911
|
* `modifySourceData` hook callback.
|
@@ -923,14 +925,9 @@ function _onModifySourceData(row, columnOrProp, valueHolder, ioMode) {
|
|
923
925
|
if (visualRow === null || visualColumn === null) {
|
924
926
|
return;
|
925
927
|
}
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
if (!isFormulaCellType) {
|
930
|
-
const cellType = this.getCellType(visualRow, visualColumn);
|
931
|
-
if (cellType !== 'ARRAY') {
|
932
|
-
return;
|
933
|
-
}
|
928
|
+
const cellType = this.getCellType(visualRow, visualColumn);
|
929
|
+
if (cellType === 'VALUE' || cellType === 'EMPTY') {
|
930
|
+
return;
|
934
931
|
}
|
935
932
|
const dimensions = this.engine.getSheetDimensions(this.engine.getSheetId(this.sheetName));
|
936
933
|
|
@@ -1239,7 +1236,7 @@ function _onEngineSheetAdded(addedSheetDisplayName) {
|
|
1239
1236
|
* @param {string} newDisplayName The new name of the sheet.
|
1240
1237
|
*/
|
1241
1238
|
function _onEngineSheetRenamed(oldDisplayName, newDisplayName) {
|
1242
|
-
this.
|
1239
|
+
_assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, newDisplayName);
|
1243
1240
|
this.hot.runHooks('afterSheetRenamed', oldDisplayName, newDisplayName);
|
1244
1241
|
}
|
1245
1242
|
/**
|