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

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 (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