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.
Files changed (224) hide show
  1. package/3rdparty/walkontable/src/cell/range.js +14 -0
  2. package/3rdparty/walkontable/src/cell/range.mjs +14 -0
  3. package/3rdparty/walkontable/src/core/_base.js +2 -2
  4. package/3rdparty/walkontable/src/core/_base.mjs +3 -3
  5. package/3rdparty/walkontable/src/overlay/_base.js +0 -2
  6. package/3rdparty/walkontable/src/overlay/_base.mjs +0 -2
  7. package/3rdparty/walkontable/src/overlay/bottom.js +9 -6
  8. package/3rdparty/walkontable/src/overlay/bottom.mjs +9 -6
  9. package/3rdparty/walkontable/src/overlay/inlineStart.js +8 -5
  10. package/3rdparty/walkontable/src/overlay/inlineStart.mjs +8 -5
  11. package/3rdparty/walkontable/src/overlay/top.js +11 -6
  12. package/3rdparty/walkontable/src/overlay/top.mjs +11 -6
  13. package/3rdparty/walkontable/src/overlays.js +15 -11
  14. package/3rdparty/walkontable/src/overlays.mjs +15 -11
  15. package/3rdparty/walkontable/src/renderer/rowHeaders.js +4 -1
  16. package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +4 -1
  17. package/3rdparty/walkontable/src/selection/border/border.js +5 -0
  18. package/3rdparty/walkontable/src/selection/border/border.mjs +5 -0
  19. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +3 -4
  20. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +3 -4
  21. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +8 -10
  22. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +8 -10
  23. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +3 -4
  24. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +3 -4
  25. package/3rdparty/walkontable/src/table.js +5 -2
  26. package/3rdparty/walkontable/src/table.mjs +5 -2
  27. package/3rdparty/walkontable/src/utils/orderView/viewDiffer/viewOrder.js +0 -2
  28. package/3rdparty/walkontable/src/utils/orderView/viewDiffer/viewOrder.mjs +0 -2
  29. package/CHANGELOG.md +45 -1
  30. package/README.md +1 -1
  31. package/base.js +2 -2
  32. package/base.mjs +2 -2
  33. package/core/focusCatcher/focusDetector.js +1 -1
  34. package/core/focusCatcher/focusDetector.mjs +2 -2
  35. package/core/hooks/constants.js +8 -0
  36. package/core/hooks/constants.mjs +8 -0
  37. package/core/hooks/index.d.ts +1 -0
  38. package/core/viewportScroll/scrollStrategies/columnHeaderScroll.js +7 -5
  39. package/core/viewportScroll/scrollStrategies/columnHeaderScroll.mjs +7 -5
  40. package/core/viewportScroll/scrollStrategies/focusScroll.js +8 -1
  41. package/core/viewportScroll/scrollStrategies/focusScroll.mjs +8 -1
  42. package/core/viewportScroll/scrollStrategies/multipleScroll.js +13 -1
  43. package/core/viewportScroll/scrollStrategies/multipleScroll.mjs +13 -1
  44. package/core/viewportScroll/scrollStrategies/noncontiguousScroll.js +13 -1
  45. package/core/viewportScroll/scrollStrategies/noncontiguousScroll.mjs +13 -1
  46. package/core/viewportScroll/scrollStrategies/rowHeaderScroll.js +7 -5
  47. package/core/viewportScroll/scrollStrategies/rowHeaderScroll.mjs +7 -5
  48. package/core/viewportScroll/scrollStrategies/singleScroll.js +8 -4
  49. package/core/viewportScroll/scrollStrategies/singleScroll.mjs +8 -4
  50. package/core/viewportScroll/utils.js +111 -0
  51. package/core/viewportScroll/utils.mjs +106 -0
  52. package/core.d.ts +2 -3
  53. package/core.js +125 -71
  54. package/core.mjs +126 -72
  55. package/dataMap/dataMap.js +0 -7
  56. package/dataMap/dataMap.mjs +0 -7
  57. package/dataMap/metaManager/index.js +8 -9
  58. package/dataMap/metaManager/index.mjs +8 -9
  59. package/dataMap/metaManager/mods/dynamicCellMeta.js +4 -1
  60. package/dataMap/metaManager/mods/dynamicCellMeta.mjs +4 -1
  61. package/dist/handsontable.css +4 -15
  62. package/dist/handsontable.full.css +4 -17
  63. package/dist/handsontable.full.js +4573 -4013
  64. package/dist/handsontable.full.min.css +3 -3
  65. package/dist/handsontable.full.min.js +148 -148
  66. package/dist/handsontable.js +4287 -3730
  67. package/dist/handsontable.min.css +3 -3
  68. package/dist/handsontable.min.js +19 -19
  69. package/editorManager.js +1 -7
  70. package/editorManager.mjs +1 -7
  71. package/editors/autocompleteEditor/autocompleteEditor.js +31 -7
  72. package/editors/autocompleteEditor/autocompleteEditor.mjs +31 -7
  73. package/focusManager.js +4 -2
  74. package/focusManager.mjs +4 -2
  75. package/helpers/browser.js +1 -1
  76. package/helpers/browser.mjs +1 -1
  77. package/helpers/dom/element.d.ts +1 -0
  78. package/helpers/dom/element.js +20 -0
  79. package/helpers/dom/element.mjs +19 -0
  80. package/helpers/mixed.js +2 -2
  81. package/helpers/mixed.mjs +2 -2
  82. package/helpers/object.js +3 -0
  83. package/helpers/object.mjs +3 -0
  84. package/package.json +1 -1
  85. package/plugins/autoColumnSize/autoColumnSize.js +38 -17
  86. package/plugins/autoColumnSize/autoColumnSize.mjs +38 -17
  87. package/plugins/autoRowSize/autoRowSize.js +12 -6
  88. package/plugins/autoRowSize/autoRowSize.mjs +12 -6
  89. package/plugins/columnSorting/columnSorting.js +0 -4
  90. package/plugins/columnSorting/columnSorting.mjs +0 -4
  91. package/plugins/comments/comments.js +1 -0
  92. package/plugins/comments/comments.mjs +1 -0
  93. package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
  94. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
  95. package/plugins/contextMenu/menu/menu.js +1 -0
  96. package/plugins/contextMenu/menu/menu.mjs +1 -0
  97. package/plugins/contextMenu/menu/positioner.js +10 -2
  98. package/plugins/contextMenu/menu/positioner.mjs +10 -2
  99. package/plugins/contextMenu/predefinedItems/redo.js +3 -3
  100. package/plugins/contextMenu/predefinedItems/redo.mjs +3 -3
  101. package/plugins/contextMenu/predefinedItems/undo.js +3 -3
  102. package/plugins/contextMenu/predefinedItems/undo.mjs +3 -3
  103. package/plugins/copyPaste/copyPaste.js +12 -9
  104. package/plugins/copyPaste/copyPaste.mjs +12 -9
  105. package/plugins/copyPaste/pasteEvent.js +3 -0
  106. package/plugins/copyPaste/pasteEvent.mjs +3 -0
  107. package/plugins/exportFile/exportFile.d.ts +1 -0
  108. package/plugins/exportFile/exportFile.js +2 -1
  109. package/plugins/exportFile/exportFile.mjs +2 -1
  110. package/plugins/exportFile/types/csv.js +76 -11
  111. package/plugins/exportFile/types/csv.mjs +76 -11
  112. package/plugins/filters/filters.js +24 -23
  113. package/plugins/filters/filters.mjs +24 -23
  114. package/plugins/filters/ui/multipleSelect.js +7 -1
  115. package/plugins/filters/ui/multipleSelect.mjs +7 -1
  116. package/plugins/formulas/formulas.d.ts +1 -1
  117. package/plugins/formulas/formulas.js +57 -60
  118. package/plugins/formulas/formulas.mjs +59 -62
  119. package/plugins/formulas/indexSyncer/axisSyncer.js +5 -1
  120. package/plugins/formulas/indexSyncer/axisSyncer.mjs +5 -1
  121. package/plugins/hiddenColumns/hiddenColumns.js +1 -1
  122. package/plugins/hiddenColumns/hiddenColumns.mjs +1 -1
  123. package/plugins/hiddenRows/hiddenRows.js +1 -1
  124. package/plugins/hiddenRows/hiddenRows.mjs +1 -1
  125. package/plugins/manualColumnResize/manualColumnResize.js +4 -6
  126. package/plugins/manualColumnResize/manualColumnResize.mjs +4 -6
  127. package/plugins/manualRowResize/manualRowResize.js +4 -6
  128. package/plugins/manualRowResize/manualRowResize.mjs +4 -6
  129. package/plugins/mergeCells/mergeCells.js +10 -30
  130. package/plugins/mergeCells/mergeCells.mjs +10 -30
  131. package/plugins/mergeCells/renderer.js +15 -0
  132. package/plugins/mergeCells/renderer.mjs +15 -0
  133. package/plugins/mergeCells/utils.js +31 -0
  134. package/plugins/mergeCells/utils.mjs +27 -0
  135. package/plugins/nestedRows/data/dataManager.js +2 -2
  136. package/plugins/nestedRows/data/dataManager.mjs +2 -2
  137. package/plugins/undoRedo/actions/index.js +0 -2
  138. package/plugins/undoRedo/actions/index.mjs +0 -2
  139. package/plugins/undoRedo/actions/removeColumn.js +19 -14
  140. package/plugins/undoRedo/actions/removeColumn.mjs +19 -14
  141. package/plugins/undoRedo/actions/removeRow.js +12 -4
  142. package/plugins/undoRedo/actions/removeRow.mjs +12 -4
  143. package/selection/selection.js +3 -1
  144. package/selection/selection.mjs +3 -1
  145. package/shortcutContexts/commands/extendCellsSelection/down.js +7 -2
  146. package/shortcutContexts/commands/extendCellsSelection/down.mjs +7 -2
  147. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.js +8 -2
  148. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.mjs +8 -2
  149. package/shortcutContexts/commands/extendCellsSelection/left.js +7 -2
  150. package/shortcutContexts/commands/extendCellsSelection/left.mjs +7 -2
  151. package/shortcutContexts/commands/extendCellsSelection/right.js +7 -2
  152. package/shortcutContexts/commands/extendCellsSelection/right.mjs +7 -2
  153. package/shortcutContexts/commands/extendCellsSelection/toColumns.js +7 -2
  154. package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +7 -2
  155. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +3 -1
  156. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +3 -1
  157. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +3 -1
  158. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +3 -1
  159. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +3 -1
  160. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +3 -1
  161. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +3 -1
  162. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +3 -1
  163. package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +3 -1
  164. package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +3 -1
  165. package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +3 -1
  166. package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +3 -1
  167. package/shortcutContexts/commands/extendCellsSelection/toRows.js +7 -2
  168. package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +7 -2
  169. package/shortcutContexts/commands/extendCellsSelection/up.js +7 -2
  170. package/shortcutContexts/commands/extendCellsSelection/up.mjs +7 -2
  171. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.js +8 -2
  172. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.mjs +8 -2
  173. package/shortcutContexts/commands/index.js +0 -2
  174. package/shortcutContexts/commands/index.mjs +0 -2
  175. package/shortcutContexts/commands/moveCellSelection/down.js +2 -0
  176. package/shortcutContexts/commands/moveCellSelection/down.mjs +2 -0
  177. package/shortcutContexts/commands/moveCellSelection/downByViewportHeight.js +6 -1
  178. package/shortcutContexts/commands/moveCellSelection/downByViewportHeight.mjs +6 -1
  179. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +8 -3
  180. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +8 -3
  181. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +8 -3
  182. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +8 -3
  183. package/shortcutContexts/commands/moveCellSelection/left.js +6 -1
  184. package/shortcutContexts/commands/moveCellSelection/left.mjs +6 -1
  185. package/shortcutContexts/commands/moveCellSelection/right.js +6 -1
  186. package/shortcutContexts/commands/moveCellSelection/right.mjs +6 -1
  187. package/shortcutContexts/commands/moveCellSelection/toMostBottom.js +4 -1
  188. package/shortcutContexts/commands/moveCellSelection/toMostBottom.mjs +4 -1
  189. package/shortcutContexts/commands/moveCellSelection/toMostBottomInlineEnd.js +2 -0
  190. package/shortcutContexts/commands/moveCellSelection/toMostBottomInlineEnd.mjs +2 -0
  191. package/shortcutContexts/commands/moveCellSelection/toMostInlineEnd.js +2 -0
  192. package/shortcutContexts/commands/moveCellSelection/toMostInlineEnd.mjs +2 -0
  193. package/shortcutContexts/commands/moveCellSelection/toMostInlineStart.js +2 -0
  194. package/shortcutContexts/commands/moveCellSelection/toMostInlineStart.mjs +2 -0
  195. package/shortcutContexts/commands/moveCellSelection/toMostLeft.js +2 -0
  196. package/shortcutContexts/commands/moveCellSelection/toMostLeft.mjs +2 -0
  197. package/shortcutContexts/commands/moveCellSelection/toMostRight.js +2 -0
  198. package/shortcutContexts/commands/moveCellSelection/toMostRight.mjs +2 -0
  199. package/shortcutContexts/commands/moveCellSelection/toMostTop.js +6 -1
  200. package/shortcutContexts/commands/moveCellSelection/toMostTop.mjs +6 -1
  201. package/shortcutContexts/commands/moveCellSelection/toMostTopInlineStart.js +2 -0
  202. package/shortcutContexts/commands/moveCellSelection/toMostTopInlineStart.mjs +2 -0
  203. package/shortcutContexts/commands/moveCellSelection/up.js +2 -0
  204. package/shortcutContexts/commands/moveCellSelection/up.mjs +2 -0
  205. package/shortcutContexts/commands/moveCellSelection/upByViewportHeight.js +6 -1
  206. package/shortcutContexts/commands/moveCellSelection/upByViewportHeight.mjs +6 -1
  207. package/shortcutContexts/commands/selectAllCells.js +7 -2
  208. package/shortcutContexts/commands/selectAllCells.mjs +7 -2
  209. package/shortcutContexts/commands/selectAllCellsAndHeaders.js +7 -2
  210. package/shortcutContexts/commands/selectAllCellsAndHeaders.mjs +7 -2
  211. package/shortcutContexts/index.js +2 -2
  212. package/shortcutContexts/index.mjs +0 -2
  213. package/styles/handsontable.css +15 -17
  214. package/styles/handsontable.min.css +3 -3
  215. package/styles/ht-theme-horizon.css +2 -2
  216. package/styles/ht-theme-horizon.min.css +2 -2
  217. package/styles/ht-theme-main.css +2 -2
  218. package/styles/ht-theme-main.min.css +2 -2
  219. package/tableView.js +5 -8
  220. package/tableView.mjs +5 -8
  221. package/translations/indexMapper.js +0 -1
  222. package/translations/indexMapper.mjs +0 -1
  223. package/utils/ghostTable.js +3 -0
  224. 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, true));
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]) + options.columnDelimiter;
80
+ result += this._escapeCell(rowHeaders[index], {
81
+ sanitizeValue: options.sanitizeValues
82
+ });
83
+ result += options.columnDelimiter;
56
84
  }
57
- result += value.map(cellValue => this._escapeCell(cellValue)).join(options.columnDelimiter);
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 {boolean} [force=false] Indicates if cell value will be escaped forcefully.
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 force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
71
- let escapedValue = stringify(value);
72
- if (escapedValue !== '' && (force || escapedValue.indexOf(CHAR_CARRIAGE_RETURN) >= 0 || escapedValue.indexOf(CHAR_DOUBLE_QUOTES) >= 0 || escapedValue.indexOf(CHAR_LINE_FEED) >= 0 || escapedValue.indexOf(this.options.columnDelimiter) >= 0)) {
73
- escapedValue = escapedValue.replace(new RegExp('"', 'g'), '""');
74
- escapedValue = `"${escapedValue}"`;
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 escapedValue;
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
- if (needToFilter) {
567
- const trimmedRows = [];
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
- this.hot.runHooks('afterFilter', conditions);
589
- this.hot.view.adjustElementsSize();
590
- this.hot.render();
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
- if (needToFilter) {
561
- const trimmedRows = [];
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
- this.hot.runHooks('afterFilter', conditions);
583
- this.hot.view.adjustElementsSize();
584
- this.hot.render();
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
- colWidths: () => _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument),
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
- colWidths: () => _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - getScrollbarWidth(rootDocument),
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
- get sheetId(): number | null;
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
- * The hook allows to translate the formula value to calculated value before it goes to the
78
- * validator function.
76
+ * Update sheetName and sheetId properties.
79
77
  *
80
- * @param {*} value The cell value to validate.
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.sheetName = newSheetName;
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
- this.sheetName = this.addSheet(sheetName !== null && sheetName !== void 0 ? sheetName : undefined, this.hot.getSourceDataArray());
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.sheetName = sheetName;
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 (this.isFormulaCellType(rowIndex, columnIndex) === false) {
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
- if (valueChanged === true) {
825
- _classPrivateFieldSet(_internalOperationPending, this, true);
826
- this.engine.setSheetContent(this.sheetId, sourceDataArray);
827
- _classPrivateFieldSet(_internalOperationPending, this, false);
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
- this.sheetName = (0, _register.setupSheet)(this.engine, this.hot.getSettings()[PLUGIN_KEY].sheetName);
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
- // `column` is here as visual index because of inconsistencies related to hook execution in `src/dataMap`.
875
- const isFormulaCellType = this.isFormulaCellType(visualRow, visualColumn);
876
- if (!isFormulaCellType) {
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
- // TODO: Workaround. We use HOT's `getCellsMeta` method instead of HOT's `getCellMeta` method. Getting cell meta
893
- // using the second method lead to execution of the `cells` method. Using the `getDataAtCell` (which may be useful)
894
- // in a callback to the `cells` method leads to triggering the `modifyData` hook. Thus, the `onModifyData` callback
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
- const value = typeof cellValue === 'object' && cellValue !== null ? cellValue.value : cellValue;
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
- // `column` is here as visual index because of inconsistencies related to hook execution in `src/dataMap`.
928
- const isFormulaCellType = this.isFormulaCellType(visualRow, visualColumn);
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.sheetName = newDisplayName;
1239
+ _assertClassBrand(_Formulas_brand, this, _updateSheetNameAndSheetId).call(this, newDisplayName);
1243
1240
  this.hot.runHooks('afterSheetRenamed', oldDisplayName, newDisplayName);
1244
1241
  }
1245
1242
  /**