handsontable 12.3.3-next-e19badf-20230328 → 12.4.0-next-ddbea0c-20230512

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. package/3rdparty/walkontable/src/cell/coords.js +13 -16
  2. package/3rdparty/walkontable/src/cell/coords.mjs +13 -16
  3. package/3rdparty/walkontable/src/cell/range.js +25 -29
  4. package/3rdparty/walkontable/src/cell/range.mjs +24 -28
  5. package/3rdparty/walkontable/src/event.js +4 -0
  6. package/3rdparty/walkontable/src/event.mjs +4 -0
  7. package/3rdparty/walkontable/src/overlay/_base.js +6 -7
  8. package/3rdparty/walkontable/src/overlay/_base.mjs +6 -7
  9. package/3rdparty/walkontable/src/overlay/bottom.js +6 -7
  10. package/3rdparty/walkontable/src/overlay/bottom.mjs +6 -7
  11. package/3rdparty/walkontable/src/overlay/top.js +6 -7
  12. package/3rdparty/walkontable/src/overlay/top.mjs +6 -7
  13. package/3rdparty/walkontable/src/overlay/topInlineStartCorner.js +10 -12
  14. package/3rdparty/walkontable/src/overlay/topInlineStartCorner.mjs +10 -12
  15. package/3rdparty/walkontable/src/overlays.js +55 -64
  16. package/3rdparty/walkontable/src/overlays.mjs +55 -64
  17. package/3rdparty/walkontable/src/scroll.js +20 -23
  18. package/3rdparty/walkontable/src/scroll.mjs +20 -23
  19. package/3rdparty/walkontable/src/settings.js +13 -15
  20. package/3rdparty/walkontable/src/settings.mjs +13 -15
  21. package/3rdparty/walkontable/src/table.js +22 -26
  22. package/3rdparty/walkontable/src/table.mjs +22 -26
  23. package/CHANGELOG.md +14 -0
  24. package/base.js +2 -4
  25. package/base.mjs +2 -2
  26. package/core.js +23 -6
  27. package/core.mjs +23 -6
  28. package/dataMap/dataSource.js +5 -5
  29. package/dataMap/dataSource.mjs +5 -5
  30. package/dataMap/metaManager/metaSchema.js +9 -7
  31. package/dataMap/metaManager/metaSchema.mjs +9 -7
  32. package/dist/handsontable.css +2 -2
  33. package/dist/handsontable.full.css +2 -2
  34. package/dist/handsontable.full.js +5047 -4193
  35. package/dist/handsontable.full.min.css +2 -2
  36. package/dist/handsontable.full.min.js +86 -78
  37. package/dist/handsontable.js +4023 -3170
  38. package/dist/handsontable.min.css +2 -2
  39. package/dist/handsontable.min.js +11 -3
  40. package/dist/languages/all.js +133 -0
  41. package/dist/languages/ar-AR.js +7 -0
  42. package/dist/languages/cs-CZ.js +7 -0
  43. package/dist/languages/de-CH.js +7 -0
  44. package/dist/languages/de-DE.js +7 -0
  45. package/dist/languages/en-US.js +7 -0
  46. package/dist/languages/es-MX.js +7 -0
  47. package/dist/languages/fr-FR.js +7 -0
  48. package/dist/languages/it-IT.js +7 -0
  49. package/dist/languages/ja-JP.js +7 -0
  50. package/dist/languages/ko-KR.js +7 -0
  51. package/dist/languages/lv-LV.js +7 -0
  52. package/dist/languages/nb-NO.js +7 -0
  53. package/dist/languages/nl-NL.js +7 -0
  54. package/dist/languages/pl-PL.js +7 -0
  55. package/dist/languages/pt-BR.js +7 -0
  56. package/dist/languages/ru-RU.js +7 -0
  57. package/dist/languages/sr-SP.js +7 -0
  58. package/dist/languages/zh-CN.js +7 -0
  59. package/dist/languages/zh-TW.js +7 -0
  60. package/helpers/mixed.js +2 -2
  61. package/helpers/mixed.mjs +2 -2
  62. package/i18n/languages/ar-AR.js +7 -1
  63. package/i18n/languages/cs-CZ.js +7 -1
  64. package/i18n/languages/de-CH.js +7 -1
  65. package/i18n/languages/de-DE.js +7 -1
  66. package/i18n/languages/en-US.js +7 -1
  67. package/i18n/languages/es-MX.js +7 -1
  68. package/i18n/languages/fr-FR.js +7 -1
  69. package/i18n/languages/it-IT.js +7 -1
  70. package/i18n/languages/ja-JP.js +7 -1
  71. package/i18n/languages/ko-KR.js +7 -1
  72. package/i18n/languages/lv-LV.js +7 -1
  73. package/i18n/languages/nb-NO.js +7 -1
  74. package/i18n/languages/nl-NL.js +7 -1
  75. package/i18n/languages/pl-PL.js +7 -1
  76. package/i18n/languages/pt-BR.js +7 -1
  77. package/i18n/languages/ru-RU.js +7 -1
  78. package/i18n/languages/sr-SP.js +7 -1
  79. package/i18n/languages/zh-CN.js +7 -1
  80. package/i18n/languages/zh-TW.js +7 -1
  81. package/languages/all.js +133 -0
  82. package/languages/ar-AR.js +7 -0
  83. package/languages/cs-CZ.js +7 -0
  84. package/languages/de-CH.js +7 -0
  85. package/languages/de-DE.js +7 -0
  86. package/languages/en-US.js +7 -0
  87. package/languages/es-MX.js +7 -0
  88. package/languages/fr-FR.js +7 -0
  89. package/languages/index.js +133 -0
  90. package/languages/it-IT.js +7 -0
  91. package/languages/ja-JP.js +7 -0
  92. package/languages/ko-KR.js +7 -0
  93. package/languages/lv-LV.js +7 -0
  94. package/languages/nb-NO.js +7 -0
  95. package/languages/nl-NL.js +7 -0
  96. package/languages/pl-PL.js +7 -0
  97. package/languages/pt-BR.js +7 -0
  98. package/languages/ru-RU.js +7 -0
  99. package/languages/sr-SP.js +7 -0
  100. package/languages/zh-CN.js +7 -0
  101. package/languages/zh-TW.js +7 -0
  102. package/package.json +3 -2
  103. package/pluginHooks.js +16 -6
  104. package/pluginHooks.mjs +15 -3
  105. package/plugins/autoRowSize/autoRowSize.js +2 -2
  106. package/plugins/autoRowSize/autoRowSize.mjs +2 -2
  107. package/plugins/copyPaste/copyableRanges.js +25 -31
  108. package/plugins/copyPaste/copyableRanges.mjs +18 -24
  109. package/plugins/customBorders/customBorders.d.ts +2 -0
  110. package/plugins/filters/filters.js +5 -0
  111. package/plugins/filters/filters.mjs +5 -0
  112. package/plugins/formulas/engine/register.js +9 -0
  113. package/plugins/formulas/engine/register.mjs +13 -4
  114. package/plugins/formulas/engine/settings.js +18 -3
  115. package/plugins/formulas/engine/settings.mjs +16 -3
  116. package/plugins/formulas/formulas.js +274 -155
  117. package/plugins/formulas/formulas.mjs +274 -156
  118. package/plugins/formulas/indexSyncer/axisSyncer.js +379 -0
  119. package/plugins/formulas/indexSyncer/axisSyncer.mjs +374 -0
  120. package/plugins/formulas/indexSyncer/index.js +225 -0
  121. package/plugins/formulas/indexSyncer/index.mjs +219 -0
  122. package/plugins/formulas/utils.js +81 -0
  123. package/plugins/formulas/utils.mjs +74 -0
  124. package/plugins/manualRowMove/manualRowMove.js +26 -11
  125. package/plugins/manualRowMove/manualRowMove.mjs +27 -12
  126. package/plugins/nestedHeaders/stateManager/headersTree.js +23 -26
  127. package/plugins/nestedHeaders/stateManager/headersTree.mjs +20 -23
  128. package/plugins/nestedHeaders/stateManager/index.js +3 -3
  129. package/plugins/nestedHeaders/stateManager/matrixGenerator.js +1 -0
  130. package/plugins/nestedHeaders/stateManager/settingsNormalizer.js +1 -1
  131. package/plugins/nestedHeaders/utils/ghostTable.js +30 -35
  132. package/plugins/nestedHeaders/utils/ghostTable.mjs +30 -35
  133. package/plugins/registry.js +3 -1
  134. package/plugins/undoRedo/undoRedo.js +0 -1
  135. package/plugins/undoRedo/undoRedo.mjs +0 -1
  136. package/selection/highlight/visualSelection.js +5 -6
  137. package/selection/highlight/visualSelection.mjs +5 -6
  138. package/tableView.js +62 -72
  139. package/tableView.mjs +62 -72
  140. package/translations/changesObservable/observable.js +41 -46
  141. package/translations/changesObservable/observable.mjs +36 -41
  142. package/translations/changesObservable/observer.js +1 -1
  143. package/translations/indexMapper.js +21 -0
  144. package/translations/indexMapper.mjs +21 -0
  145. package/utils/dataStructures/tree.js +15 -18
  146. package/utils/dataStructures/tree.mjs +15 -18
  147. package/utils/parseTable.js +5 -1
  148. package/utils/parseTable.mjs +5 -1
@@ -0,0 +1,219 @@
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+ import "core-js/modules/es.array.iterator.js";
3
+ import "core-js/modules/es.object.to-string.js";
4
+ import "core-js/modules/es.string.iterator.js";
5
+ import "core-js/modules/es.weak-map.js";
6
+ import "core-js/modules/web.dom-collections.iterator.js";
7
+ import "core-js/modules/es.symbol.to-primitive.js";
8
+ import "core-js/modules/es.date.to-primitive.js";
9
+ import "core-js/modules/es.symbol.js";
10
+ import "core-js/modules/es.symbol.description.js";
11
+ import "core-js/modules/es.number.constructor.js";
12
+ import "core-js/modules/es.symbol.iterator.js";
13
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
14
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
15
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
16
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
17
+ function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
18
+ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
19
+ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
20
+ function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
21
+ function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
22
+ function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
23
+ function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
24
+ function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
25
+ import AxisSyncer from "./axisSyncer.mjs";
26
+ /**
27
+ * @private
28
+ * @class IndexSyncer
29
+ * @description
30
+ *
31
+ * Indexes synchronizer responsible for providing logic for syncing actions done on indexes for HOT to actions performed
32
+ * on HF's.
33
+ *
34
+ */
35
+ var _rowIndexSyncer = /*#__PURE__*/new WeakMap();
36
+ var _columnIndexSyncer = /*#__PURE__*/new WeakMap();
37
+ var _postponeAction = /*#__PURE__*/new WeakMap();
38
+ var _isPerformingUndo = /*#__PURE__*/new WeakMap();
39
+ var _isPerformingRedo = /*#__PURE__*/new WeakMap();
40
+ var _engine = /*#__PURE__*/new WeakMap();
41
+ var _sheetId = /*#__PURE__*/new WeakMap();
42
+ var IndexSyncer = /*#__PURE__*/function () {
43
+ function IndexSyncer(rowIndexMapper, columnIndexMapper, postponeAction) {
44
+ _classCallCheck(this, IndexSyncer);
45
+ /**
46
+ * Indexes synchronizer for the axis of the rows.
47
+ *
48
+ * @private
49
+ * @type {AxisSyncer}
50
+ */
51
+ _classPrivateFieldInitSpec(this, _rowIndexSyncer, {
52
+ writable: true,
53
+ value: void 0
54
+ });
55
+ /**
56
+ * Indexes synchronizer for the axis of the columns.
57
+ *
58
+ * @private
59
+ * @type {AxisSyncer}
60
+ */
61
+ _classPrivateFieldInitSpec(this, _columnIndexSyncer, {
62
+ writable: true,
63
+ value: void 0
64
+ });
65
+ /**
66
+ * Method which will postpone execution of some action (needed when synchronization endpoint isn't setup yet).
67
+ *
68
+ * @private
69
+ * @type {Function}
70
+ */
71
+ _classPrivateFieldInitSpec(this, _postponeAction, {
72
+ writable: true,
73
+ value: void 0
74
+ });
75
+ /**
76
+ * Flag informing whether undo is already performed (we don't perform synchronization in such case).
77
+ *
78
+ * @private
79
+ * @type {boolean}
80
+ */
81
+ _classPrivateFieldInitSpec(this, _isPerformingUndo, {
82
+ writable: true,
83
+ value: false
84
+ });
85
+ /**
86
+ * Flag informing whether redo is already performed (we don't perform synchronization in such case).
87
+ *
88
+ * @private
89
+ * @type {boolean}
90
+ */
91
+ _classPrivateFieldInitSpec(this, _isPerformingRedo, {
92
+ writable: true,
93
+ value: false
94
+ });
95
+ /**
96
+ * The HF's engine instance which will be synced.
97
+ *
98
+ * @private
99
+ * @type {HyperFormula|null}
100
+ */
101
+ _classPrivateFieldInitSpec(this, _engine, {
102
+ writable: true,
103
+ value: null
104
+ });
105
+ /**
106
+ * HyperFormula's sheet name.
107
+ *
108
+ * @private
109
+ * @type {string|null}
110
+ */
111
+ _classPrivateFieldInitSpec(this, _sheetId, {
112
+ writable: true,
113
+ value: null
114
+ });
115
+ _classPrivateFieldSet(this, _rowIndexSyncer, new AxisSyncer('row', rowIndexMapper, this));
116
+ _classPrivateFieldSet(this, _columnIndexSyncer, new AxisSyncer('column', columnIndexMapper, this));
117
+ _classPrivateFieldSet(this, _postponeAction, postponeAction);
118
+ }
119
+
120
+ /**
121
+ * Gets index synchronizer for a particular axis.
122
+ *
123
+ * @param {'row'|'column'} indexType Type of indexes.
124
+ * @returns {AxisSyncer}
125
+ */
126
+ _createClass(IndexSyncer, [{
127
+ key: "getForAxis",
128
+ value: function getForAxis(indexType) {
129
+ if (indexType === 'row') {
130
+ return _classPrivateFieldGet(this, _rowIndexSyncer);
131
+ }
132
+ return _classPrivateFieldGet(this, _columnIndexSyncer);
133
+ }
134
+
135
+ /**
136
+ * Sets flag informing whether an undo action is already performed (we don't execute synchronization in such case).
137
+ *
138
+ * @param {boolean} flagValue Boolean value for the flag.
139
+ */
140
+ }, {
141
+ key: "setPerformUndo",
142
+ value: function setPerformUndo(flagValue) {
143
+ _classPrivateFieldSet(this, _isPerformingUndo, flagValue);
144
+ }
145
+
146
+ /**
147
+ * Sets flag informing whether a redo action is already performed (we don't execute synchronization in such case).
148
+ *
149
+ * @param {boolean} flagValue Boolean value for the flag.
150
+ */
151
+ }, {
152
+ key: "setPerformRedo",
153
+ value: function setPerformRedo(flagValue) {
154
+ _classPrivateFieldSet(this, _isPerformingRedo, flagValue);
155
+ }
156
+
157
+ /**
158
+ * Gets information whether redo or undo action is already performed (we don't execute synchronization in such case).
159
+ *
160
+ * @private
161
+ * @returns {boolean}
162
+ */
163
+ }, {
164
+ key: "isPerformingUndoRedo",
165
+ value: function isPerformingUndoRedo() {
166
+ return _classPrivateFieldGet(this, _isPerformingUndo) || _classPrivateFieldGet(this, _isPerformingRedo);
167
+ }
168
+
169
+ /**
170
+ * Gets HyperFormula's sheet id.
171
+ *
172
+ * @returns {string|null}
173
+ */
174
+ }, {
175
+ key: "getSheetId",
176
+ value: function getSheetId() {
177
+ return _classPrivateFieldGet(this, _sheetId);
178
+ }
179
+
180
+ /**
181
+ * Gets engine instance that will be used for handled instance of Handsontable.
182
+ *
183
+ * @type {HyperFormula|null}
184
+ */
185
+ }, {
186
+ key: "getEngine",
187
+ value: function getEngine() {
188
+ return _classPrivateFieldGet(this, _engine);
189
+ }
190
+
191
+ /**
192
+ * Gets method which will postpone execution of some action (needed when synchronization endpoint isn't setup yet).
193
+ *
194
+ * @returns {Function}
195
+ */
196
+ }, {
197
+ key: "getPostponeAction",
198
+ value: function getPostponeAction() {
199
+ return _classPrivateFieldGet(this, _postponeAction);
200
+ }
201
+
202
+ /**
203
+ * Setups a synchronization endpoint.
204
+ *
205
+ * @param {HyperFormula|null} engine The HF's engine instance which will be synced.
206
+ * @param {string|null} sheetId HyperFormula's sheet name.
207
+ */
208
+ }, {
209
+ key: "setupSyncEndpoint",
210
+ value: function setupSyncEndpoint(engine, sheetId) {
211
+ _classPrivateFieldSet(this, _engine, engine);
212
+ _classPrivateFieldSet(this, _sheetId, sheetId);
213
+ _classPrivateFieldGet(this, _rowIndexSyncer).init();
214
+ _classPrivateFieldGet(this, _columnIndexSyncer).init();
215
+ }
216
+ }]);
217
+ return IndexSyncer;
218
+ }();
219
+ export default IndexSyncer;
@@ -1,8 +1,19 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
+ exports.getDateFromExcelDate = getDateFromExcelDate;
5
+ exports.getDateInHfFormat = getDateInHfFormat;
6
+ exports.getDateInHotFormat = getDateInHotFormat;
7
+ exports.isDate = isDate;
8
+ exports.isDateValid = isDateValid;
4
9
  exports.isEscapedFormulaExpression = isEscapedFormulaExpression;
10
+ exports.isFormula = isFormula;
5
11
  exports.unescapeFormulaExpression = unescapeFormulaExpression;
12
+ require("core-js/modules/es.string.starts-with.js");
13
+ var _moment = _interopRequireDefault(require("moment"));
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ var DEFAULT_DATE_FORMAT_HYPERFORMULA = 'DD/MM/YYYY';
16
+
6
17
  /**
7
18
  * Checks if provided formula expression is escaped.
8
19
  *
@@ -21,4 +32,74 @@ function isEscapedFormulaExpression(expression) {
21
32
  */
22
33
  function unescapeFormulaExpression(expression) {
23
34
  return isEscapedFormulaExpression(expression) ? expression.substr(1) : expression;
35
+ }
36
+
37
+ /**
38
+ * Checks whether string looks like formula or not. Corresponds to {@link https://hyperformula.handsontable.com/api/globals.html#isformula|HyperFormula's implementation}.
39
+ *
40
+ * @param {string} value Checked value.
41
+ * @returns {boolean}
42
+ */
43
+ function isFormula(value) {
44
+ return typeof value === 'string' && value.startsWith('=');
45
+ }
46
+
47
+ /**
48
+ * Checks if provided value is a date according to cell meta.
49
+ *
50
+ * @param {*} value Checked value.
51
+ * @param {string} cellType Type of a cell.
52
+ * @returns {boolean}
53
+ */
54
+ function isDate(value, cellType) {
55
+ return typeof value === 'string' && cellType === 'date';
56
+ }
57
+
58
+ /**
59
+ * Checks if provided date is a valid date according to cell date format.
60
+ *
61
+ * @param {*} date Checked date.
62
+ * @param {object} dateFormat Handled format for a date.
63
+ * @returns {boolean}
64
+ */
65
+ function isDateValid(date, dateFormat) {
66
+ return (0, _moment.default)(date, dateFormat, true).isValid();
67
+ }
68
+
69
+ /**
70
+ * Returns date formatted in HF's default format.
71
+ *
72
+ * @param {string} date Date formatted according to Handsontable cell date format.
73
+ * @param {string} dateFormat The format used for the date passed.
74
+ * @returns {string}
75
+ */
76
+ function getDateInHfFormat(date, dateFormat) {
77
+ return (0, _moment.default)(date, dateFormat, true).format(DEFAULT_DATE_FORMAT_HYPERFORMULA);
78
+ }
79
+
80
+ /**
81
+ * Returns date formatted in HF's default format.
82
+ *
83
+ * @param {string} date Date formatted according to Handsontable cell date format.
84
+ * @param {string} dateFormat The format used for the date passed.
85
+ * @returns {string}
86
+ */
87
+ function getDateInHotFormat(date, dateFormat) {
88
+ return (0, _moment.default)(date, DEFAULT_DATE_FORMAT_HYPERFORMULA, true).format(dateFormat);
89
+ }
90
+
91
+ /**
92
+ * Converts Excel-like dates into strings and formats them based on the handled date format.
93
+ *
94
+ * @param {number} numericDate An integer representing numbers of days from January 1, 1900.
95
+ * @param {string} dateFormat The format used for parsing an output.
96
+ * @returns {string}
97
+ */
98
+ function getDateFromExcelDate(numericDate, dateFormat) {
99
+ // To replicate the behavior from the HyperFormula. UTC starts from 31/12/1899, while HF from 30/12/1899.
100
+ var dateOffset = -1;
101
+
102
+ // Based on solution from: https://stackoverflow.com/a/67130235.
103
+ var dateForFormatting = new Date(Date.UTC(0, 0, numericDate + dateOffset));
104
+ return (0, _moment.default)(dateForFormatting).format(dateFormat);
24
105
  }
@@ -1,3 +1,7 @@
1
+ import "core-js/modules/es.string.starts-with.js";
2
+ import moment from 'moment';
3
+ var DEFAULT_DATE_FORMAT_HYPERFORMULA = 'DD/MM/YYYY';
4
+
1
5
  /**
2
6
  * Checks if provided formula expression is escaped.
3
7
  *
@@ -16,4 +20,74 @@ export function isEscapedFormulaExpression(expression) {
16
20
  */
17
21
  export function unescapeFormulaExpression(expression) {
18
22
  return isEscapedFormulaExpression(expression) ? expression.substr(1) : expression;
23
+ }
24
+
25
+ /**
26
+ * Checks whether string looks like formula or not. Corresponds to {@link https://hyperformula.handsontable.com/api/globals.html#isformula|HyperFormula's implementation}.
27
+ *
28
+ * @param {string} value Checked value.
29
+ * @returns {boolean}
30
+ */
31
+ export function isFormula(value) {
32
+ return typeof value === 'string' && value.startsWith('=');
33
+ }
34
+
35
+ /**
36
+ * Checks if provided value is a date according to cell meta.
37
+ *
38
+ * @param {*} value Checked value.
39
+ * @param {string} cellType Type of a cell.
40
+ * @returns {boolean}
41
+ */
42
+ export function isDate(value, cellType) {
43
+ return typeof value === 'string' && cellType === 'date';
44
+ }
45
+
46
+ /**
47
+ * Checks if provided date is a valid date according to cell date format.
48
+ *
49
+ * @param {*} date Checked date.
50
+ * @param {object} dateFormat Handled format for a date.
51
+ * @returns {boolean}
52
+ */
53
+ export function isDateValid(date, dateFormat) {
54
+ return moment(date, dateFormat, true).isValid();
55
+ }
56
+
57
+ /**
58
+ * Returns date formatted in HF's default format.
59
+ *
60
+ * @param {string} date Date formatted according to Handsontable cell date format.
61
+ * @param {string} dateFormat The format used for the date passed.
62
+ * @returns {string}
63
+ */
64
+ export function getDateInHfFormat(date, dateFormat) {
65
+ return moment(date, dateFormat, true).format(DEFAULT_DATE_FORMAT_HYPERFORMULA);
66
+ }
67
+
68
+ /**
69
+ * Returns date formatted in HF's default format.
70
+ *
71
+ * @param {string} date Date formatted according to Handsontable cell date format.
72
+ * @param {string} dateFormat The format used for the date passed.
73
+ * @returns {string}
74
+ */
75
+ export function getDateInHotFormat(date, dateFormat) {
76
+ return moment(date, DEFAULT_DATE_FORMAT_HYPERFORMULA, true).format(dateFormat);
77
+ }
78
+
79
+ /**
80
+ * Converts Excel-like dates into strings and formats them based on the handled date format.
81
+ *
82
+ * @param {number} numericDate An integer representing numbers of days from January 1, 1900.
83
+ * @param {string} dateFormat The format used for parsing an output.
84
+ * @returns {string}
85
+ */
86
+ export function getDateFromExcelDate(numericDate, dateFormat) {
87
+ // To replicate the behavior from the HyperFormula. UTC starts from 31/12/1899, while HF from 30/12/1899.
88
+ var dateOffset = -1;
89
+
90
+ // Based on solution from: https://stackoverflow.com/a/67130235.
91
+ var dateForFormatting = new Date(Date.UTC(0, 0, numericDate + dateOffset));
92
+ return moment(dateForFormatting).format(dateFormat);
19
93
  }
@@ -484,38 +484,53 @@ var ManualRowMove = /*#__PURE__*/function (_BasePlugin) {
484
484
  }
485
485
  var wtTable = this.hot.view._wt.wtTable;
486
486
  var TD = priv.target.TD;
487
- var rootElementOffset = (0, _element.offset)(this.hot.rootElement);
488
- var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row - 1);
489
- var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop;
487
+ var rootElement = this.hot.rootElement;
488
+ var rootElementOffset = (0, _element.offset)(rootElement);
489
+ var trimmingContainer = (0, _element.getTrimmingContainer)(rootElement);
490
+ var tableScroll = wtTable.holder.scrollTop;
491
+ var trimmingContainerScroll;
492
+
493
+ // Trimming container is the `window` element.
494
+ if (this.hot.rootWindow === trimmingContainer) {
495
+ trimmingContainerScroll = trimmingContainer.scrollY;
496
+ } else {
497
+ trimmingContainerScroll = trimmingContainer.scrollTop;
498
+ }
499
+ var pixelsAbove = rootElementOffset.top - trimmingContainerScroll;
500
+ var pixelsRelToTableStart = priv.target.eventPageY - pixelsAbove + tableScroll;
490
501
  var hiderHeight = wtTable.hider.offsetHeight;
491
502
  var tbodyOffsetTop = wtTable.TBODY.offsetTop;
492
503
  var backlightElemMarginTop = this.backlight.getOffset().top;
493
504
  var backlightElemHeight = this.backlight.getSize().height;
505
+ var tdMiddle = TD.offsetHeight / 2;
506
+ var tdHeight = TD.offsetHeight;
507
+ var tdStartPixel = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row - 1);
508
+ var isBelowTable = pixelsRelToTableStart >= tdStartPixel + tdMiddle;
494
509
  if (this.isFixedRowTop(coords.row)) {
495
- tdOffsetTop += wtTable.holder.scrollTop;
510
+ tdStartPixel += wtTable.holder.scrollTop;
496
511
  }
497
512
  if (coords.row < 0) {
498
513
  // if hover on colHeader
499
514
  priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible;
500
- } else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) {
515
+ } else if (isBelowTable) {
501
516
  // if hover on lower part of TD
502
517
  priv.target.row = coords.row + 1;
503
518
  // unfortunately first row is bigger than rest
504
- tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight;
519
+ tdStartPixel += coords.row === 0 ? tdHeight - 1 : tdHeight;
505
520
  } else {
506
521
  // elsewhere on table
507
522
  priv.target.row = coords.row;
508
523
  }
509
- var backlightTop = mouseOffsetTop;
510
- var guidelineTop = tdOffsetTop;
511
- if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
524
+ var backlightTop = pixelsRelToTableStart;
525
+ var guidelineTop = tdStartPixel;
526
+ if (pixelsRelToTableStart + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
512
527
  // prevent display backlight below table
513
528
  backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop;
514
- } else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) {
529
+ } else if (pixelsRelToTableStart + backlightElemMarginTop < tbodyOffsetTop) {
515
530
  // prevent display above below table
516
531
  backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop);
517
532
  }
518
- if (tdOffsetTop >= hiderHeight - 1) {
533
+ if (tdStartPixel >= hiderHeight - 1) {
519
534
  // prevent display guideline below table
520
535
  guidelineTop = hiderHeight - 1;
521
536
  }
@@ -34,7 +34,7 @@ import "core-js/modules/es.symbol.iterator.js";
34
34
  import { BasePlugin } from "../base/index.mjs";
35
35
  import Hooks from "../../pluginHooks.mjs";
36
36
  import { arrayReduce } from "../../helpers/array.mjs";
37
- import { addClass, removeClass, offset } from "../../helpers/dom/element.mjs";
37
+ import { addClass, removeClass, offset, getTrimmingContainer } from "../../helpers/dom/element.mjs";
38
38
  import { rangeEach } from "../../helpers/number.mjs";
39
39
  import EventManager from "../../eventManager.mjs";
40
40
  import BacklightUI from "./ui/backlight.mjs";
@@ -477,38 +477,53 @@ export var ManualRowMove = /*#__PURE__*/function (_BasePlugin) {
477
477
  }
478
478
  var wtTable = this.hot.view._wt.wtTable;
479
479
  var TD = priv.target.TD;
480
- var rootElementOffset = offset(this.hot.rootElement);
481
- var tdOffsetTop = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row - 1);
482
- var mouseOffsetTop = priv.target.eventPageY - rootElementOffset.top + wtTable.holder.scrollTop;
480
+ var rootElement = this.hot.rootElement;
481
+ var rootElementOffset = offset(rootElement);
482
+ var trimmingContainer = getTrimmingContainer(rootElement);
483
+ var tableScroll = wtTable.holder.scrollTop;
484
+ var trimmingContainerScroll;
485
+
486
+ // Trimming container is the `window` element.
487
+ if (this.hot.rootWindow === trimmingContainer) {
488
+ trimmingContainerScroll = trimmingContainer.scrollY;
489
+ } else {
490
+ trimmingContainerScroll = trimmingContainer.scrollTop;
491
+ }
492
+ var pixelsAbove = rootElementOffset.top - trimmingContainerScroll;
493
+ var pixelsRelToTableStart = priv.target.eventPageY - pixelsAbove + tableScroll;
483
494
  var hiderHeight = wtTable.hider.offsetHeight;
484
495
  var tbodyOffsetTop = wtTable.TBODY.offsetTop;
485
496
  var backlightElemMarginTop = this.backlight.getOffset().top;
486
497
  var backlightElemHeight = this.backlight.getSize().height;
498
+ var tdMiddle = TD.offsetHeight / 2;
499
+ var tdHeight = TD.offsetHeight;
500
+ var tdStartPixel = this.hot.view.THEAD.offsetHeight + this.getRowsHeight(0, coords.row - 1);
501
+ var isBelowTable = pixelsRelToTableStart >= tdStartPixel + tdMiddle;
487
502
  if (this.isFixedRowTop(coords.row)) {
488
- tdOffsetTop += wtTable.holder.scrollTop;
503
+ tdStartPixel += wtTable.holder.scrollTop;
489
504
  }
490
505
  if (coords.row < 0) {
491
506
  // if hover on colHeader
492
507
  priv.target.row = firstVisible > 0 ? firstVisible - 1 : firstVisible;
493
- } else if (TD.offsetHeight / 2 + tdOffsetTop <= mouseOffsetTop) {
508
+ } else if (isBelowTable) {
494
509
  // if hover on lower part of TD
495
510
  priv.target.row = coords.row + 1;
496
511
  // unfortunately first row is bigger than rest
497
- tdOffsetTop += coords.row === 0 ? TD.offsetHeight - 1 : TD.offsetHeight;
512
+ tdStartPixel += coords.row === 0 ? tdHeight - 1 : tdHeight;
498
513
  } else {
499
514
  // elsewhere on table
500
515
  priv.target.row = coords.row;
501
516
  }
502
- var backlightTop = mouseOffsetTop;
503
- var guidelineTop = tdOffsetTop;
504
- if (mouseOffsetTop + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
517
+ var backlightTop = pixelsRelToTableStart;
518
+ var guidelineTop = tdStartPixel;
519
+ if (pixelsRelToTableStart + backlightElemHeight + backlightElemMarginTop >= hiderHeight) {
505
520
  // prevent display backlight below table
506
521
  backlightTop = hiderHeight - backlightElemHeight - backlightElemMarginTop;
507
- } else if (mouseOffsetTop + backlightElemMarginTop < tbodyOffsetTop) {
522
+ } else if (pixelsRelToTableStart + backlightElemMarginTop < tbodyOffsetTop) {
508
523
  // prevent display above below table
509
524
  backlightTop = tbodyOffsetTop + Math.abs(backlightElemMarginTop);
510
525
  }
511
- if (tdOffsetTop >= hiderHeight - 1) {
526
+ if (tdStartPixel >= hiderHeight - 1) {
512
527
  // prevent display guideline below table
513
528
  guidelineTop = hiderHeight - 1;
514
529
  }
@@ -48,9 +48,6 @@ function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) {
48
48
  function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
49
49
  function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
50
50
  function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
51
- var _rootNodes = /*#__PURE__*/new WeakMap();
52
- var _rootsIndex = /*#__PURE__*/new WeakMap();
53
- var _sourceSettings = /*#__PURE__*/new WeakMap();
54
51
  /* eslint-disable jsdoc/require-description-complete-sentence */
55
52
  /**
56
53
  * @private
@@ -87,40 +84,40 @@ var _sourceSettings = /*#__PURE__*/new WeakMap();
87
84
  *
88
85
  */
89
86
  /* eslint-enable jsdoc/require-description-complete-sentence */
87
+ var _rootNodes = /*#__PURE__*/new WeakMap();
88
+ var _rootsIndex = /*#__PURE__*/new WeakMap();
89
+ var _sourceSettings = /*#__PURE__*/new WeakMap();
90
90
  var HeadersTree = /*#__PURE__*/function () {
91
- /**
92
- * The collection of nested headers settings structured into trees. The root trees are stored
93
- * under the visual column index.
94
- *
95
- * @private
96
- * @type {Map<number, TreeNode>}
97
- */
98
-
99
- /**
100
- * A map that translates the visual column indexes that intersect the range
101
- * defined by the header colspan width to the root index.
102
- *
103
- * @private
104
- * @type {Map<number, number>}
105
- */
106
-
107
- /**
108
- * The instance of the SourceSettings class.
109
- *
110
- * @private
111
- * @type {SourceSettings}
112
- */
113
-
114
91
  function HeadersTree(sourceSettings) {
115
92
  _classCallCheck(this, HeadersTree);
93
+ /**
94
+ * The collection of nested headers settings structured into trees. The root trees are stored
95
+ * under the visual column index.
96
+ *
97
+ * @private
98
+ * @type {Map<number, TreeNode>}
99
+ */
116
100
  _classPrivateFieldInitSpec(this, _rootNodes, {
117
101
  writable: true,
118
102
  value: new Map()
119
103
  });
104
+ /**
105
+ * A map that translates the visual column indexes that intersect the range
106
+ * defined by the header colspan width to the root index.
107
+ *
108
+ * @private
109
+ * @type {Map<number, number>}
110
+ */
120
111
  _classPrivateFieldInitSpec(this, _rootsIndex, {
121
112
  writable: true,
122
113
  value: new Map()
123
114
  });
115
+ /**
116
+ * The instance of the SourceSettings class.
117
+ *
118
+ * @private
119
+ * @type {SourceSettings}
120
+ */
124
121
  _classPrivateFieldInitSpec(this, _sourceSettings, {
125
122
  writable: true,
126
123
  value: null
@@ -83,39 +83,36 @@ var _rootNodes = /*#__PURE__*/new WeakMap();
83
83
  var _rootsIndex = /*#__PURE__*/new WeakMap();
84
84
  var _sourceSettings = /*#__PURE__*/new WeakMap();
85
85
  var HeadersTree = /*#__PURE__*/function () {
86
- /**
87
- * The collection of nested headers settings structured into trees. The root trees are stored
88
- * under the visual column index.
89
- *
90
- * @private
91
- * @type {Map<number, TreeNode>}
92
- */
93
-
94
- /**
95
- * A map that translates the visual column indexes that intersect the range
96
- * defined by the header colspan width to the root index.
97
- *
98
- * @private
99
- * @type {Map<number, number>}
100
- */
101
-
102
- /**
103
- * The instance of the SourceSettings class.
104
- *
105
- * @private
106
- * @type {SourceSettings}
107
- */
108
-
109
86
  function HeadersTree(sourceSettings) {
110
87
  _classCallCheck(this, HeadersTree);
88
+ /**
89
+ * The collection of nested headers settings structured into trees. The root trees are stored
90
+ * under the visual column index.
91
+ *
92
+ * @private
93
+ * @type {Map<number, TreeNode>}
94
+ */
111
95
  _classPrivateFieldInitSpec(this, _rootNodes, {
112
96
  writable: true,
113
97
  value: new Map()
114
98
  });
99
+ /**
100
+ * A map that translates the visual column indexes that intersect the range
101
+ * defined by the header colspan width to the root index.
102
+ *
103
+ * @private
104
+ * @type {Map<number, number>}
105
+ */
115
106
  _classPrivateFieldInitSpec(this, _rootsIndex, {
116
107
  writable: true,
117
108
  value: new Map()
118
109
  });
110
+ /**
111
+ * The instance of the SourceSettings class.
112
+ *
113
+ * @private
114
+ * @type {SourceSettings}
115
+ */
119
116
  _classPrivateFieldInitSpec(this, _sourceSettings, {
120
117
  writable: true,
121
118
  value: null