handsontable 0.0.0-next-317e00f-20240111 → 0.0.0-next-d247bd5-20240112

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.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

package/editorManager.js CHANGED
@@ -29,7 +29,6 @@ class EditorManager {
29
29
  *
30
30
  * @param {MouseEvent} event The mouse event object.
31
31
  * @param {object} coords The cell coordinates.
32
- * @param {HTMLTableCellElement|HTMLTableHeaderCellElement} elem The element which triggers the action.
33
32
  */
34
33
  _classPrivateMethodInitSpec(this, _onCellDblClick);
35
34
  /**
@@ -220,6 +219,19 @@ class EditorManager {
220
219
  this.clearActiveEditor();
221
220
  return;
222
221
  }
222
+ const selection = this.hot.getSelectedRangeLast();
223
+ let allowOpening = this.hot.runHooks('beforeBeginEditing', selection.highlight.row, selection.highlight.col, newInitialValue, event, enableFullEditMode);
224
+
225
+ // If the above hook does not return boolean apply default behavior which disallows opening
226
+ // an editor after double mouse click for non-contiguous selection (while pressing Ctrl/Cmd) and
227
+ // for multiple selected cells (while pressing SHIFT).
228
+ if (event instanceof MouseEvent && typeof allowOpening !== 'boolean') {
229
+ allowOpening = this.hot.selection.getLayerLevel() === 0 && selection.isSingle();
230
+ }
231
+ if (allowOpening === false) {
232
+ this.clearActiveEditor();
233
+ return;
234
+ }
223
235
  if (!this.activeEditor) {
224
236
  this.hot.scrollToFocusedCell();
225
237
  this.prepareEditor();
@@ -373,9 +385,8 @@ function _onAfterDocumentKeyDown2(event) {
373
385
  }
374
386
  }
375
387
  }
376
- function _onCellDblClick2(event, coords, elem) {
377
- // may be TD or TH
378
- if (elem.nodeName === 'TD') {
388
+ function _onCellDblClick2(event, coords) {
389
+ if (coords.isCell()) {
379
390
  this.openEditor(null, event, true);
380
391
  }
381
392
  }
package/editorManager.mjs CHANGED
@@ -25,7 +25,6 @@ class EditorManager {
25
25
  *
26
26
  * @param {MouseEvent} event The mouse event object.
27
27
  * @param {object} coords The cell coordinates.
28
- * @param {HTMLTableCellElement|HTMLTableHeaderCellElement} elem The element which triggers the action.
29
28
  */
30
29
  _classPrivateMethodInitSpec(this, _onCellDblClick);
31
30
  /**
@@ -216,6 +215,19 @@ class EditorManager {
216
215
  this.clearActiveEditor();
217
216
  return;
218
217
  }
218
+ const selection = this.hot.getSelectedRangeLast();
219
+ let allowOpening = this.hot.runHooks('beforeBeginEditing', selection.highlight.row, selection.highlight.col, newInitialValue, event, enableFullEditMode);
220
+
221
+ // If the above hook does not return boolean apply default behavior which disallows opening
222
+ // an editor after double mouse click for non-contiguous selection (while pressing Ctrl/Cmd) and
223
+ // for multiple selected cells (while pressing SHIFT).
224
+ if (event instanceof MouseEvent && typeof allowOpening !== 'boolean') {
225
+ allowOpening = this.hot.selection.getLayerLevel() === 0 && selection.isSingle();
226
+ }
227
+ if (allowOpening === false) {
228
+ this.clearActiveEditor();
229
+ return;
230
+ }
219
231
  if (!this.activeEditor) {
220
232
  this.hot.scrollToFocusedCell();
221
233
  this.prepareEditor();
@@ -369,9 +381,8 @@ function _onAfterDocumentKeyDown2(event) {
369
381
  }
370
382
  }
371
383
  }
372
- function _onCellDblClick2(event, coords, elem) {
373
- // may be TD or TH
374
- if (elem.nodeName === 'TD') {
384
+ function _onCellDblClick2(event, coords) {
385
+ if (coords.isCell()) {
375
386
  this.openEditor(null, event, true);
376
387
  }
377
388
  }
package/helpers/mixed.js CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
134
134
  function _injectProductInfo(key, element) {
135
135
  const hasValidType = !isEmpty(key);
136
136
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-317e00f-20240111";
137
+ const hotVersion = "0.0.0-next-d247bd5-20240112";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-317e00f-20240111";
127
+ const hotVersion = "0.0.0-next-d247bd5-20240112";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-317e00f-20240111",
13
+ "version": "0.0.0-next-d247bd5-20240112",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
package/pluginHooks.d.ts CHANGED
@@ -157,6 +157,7 @@ export interface Events {
157
157
  afterViewRender?: (isForced: boolean) => void;
158
158
  beforeAddChild?: (parent: RowObject, element?: RowObject, index?: number) => void;
159
159
  beforeAutofill?: (selectionData: CellValue[][], sourceRange: CellRange, targetRange: CellRange, direction: 'up' | 'down' | 'left' | 'right') => CellValue[][] | boolean | void;
160
+ beforeBeginEditing?: (row: number, column: number, initialValue: any, event: MouseEvent | KeyboardEvent, fullEditMode: boolean) => boolean | void;
160
161
  beforeCellAlignment?: (stateBefore: { [row: number]: string[] }, range: CellRange[], type: 'horizontal' | 'vertical',
161
162
  alignmentClass: 'htLeft' | 'htCenter' | 'htRight' | 'htJustify' | 'htTop' | 'htMiddle' | 'htBottom') => void;
162
163
  beforeChange?: (changes: Array<CellChange | null>, source: ChangeSource) => void | boolean;
package/pluginHooks.js CHANGED
@@ -2398,6 +2398,24 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
2398
2398
  * @param {number} finalElementPosition The final row index of the detached element.
2399
2399
  */
2400
2400
  'afterDetachChild',
2401
+ /**
2402
+ * Fired before the editor is opened and rendered.
2403
+ *
2404
+ * @since 14.1.0
2405
+ * @event Hooks#beforeBeginEditing
2406
+ * @param {number} row Visual row index of the edited cell.
2407
+ * @param {number} column Visual column index of the edited cell.
2408
+ * @param {*} initialValue The initial editor value.
2409
+ * @param {MouseEvent | KeyboardEvent} event The event which was responsible for opening the editor.
2410
+ * @param {boolean} fullEditMode `true` if the editor is opened in full edit mode, `false` otherwise.
2411
+ * Editor opened in full edit mode does not close after pressing Arrow keys.
2412
+ * @returns {boolean | undefined} If the callback returns `false,` the editor won't be opened after
2413
+ * the mouse double click or after pressing the Enter key. Returning `undefined` (or other value
2414
+ * than boolean) will result in default behavior, which disallows opening an editor for non-contiguous
2415
+ * selection (while pressing Ctrl/Cmd) and for multiple selected cells (while pressing SHIFT).
2416
+ * Returning `true` removes those restrictions.
2417
+ */
2418
+ 'beforeBeginEditing',
2401
2419
  /**
2402
2420
  * Fired after the editor is opened and rendered.
2403
2421
  *
package/pluginHooks.mjs CHANGED
@@ -2394,6 +2394,24 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
2394
2394
  * @param {number} finalElementPosition The final row index of the detached element.
2395
2395
  */
2396
2396
  'afterDetachChild',
2397
+ /**
2398
+ * Fired before the editor is opened and rendered.
2399
+ *
2400
+ * @since 14.1.0
2401
+ * @event Hooks#beforeBeginEditing
2402
+ * @param {number} row Visual row index of the edited cell.
2403
+ * @param {number} column Visual column index of the edited cell.
2404
+ * @param {*} initialValue The initial editor value.
2405
+ * @param {MouseEvent | KeyboardEvent} event The event which was responsible for opening the editor.
2406
+ * @param {boolean} fullEditMode `true` if the editor is opened in full edit mode, `false` otherwise.
2407
+ * Editor opened in full edit mode does not close after pressing Arrow keys.
2408
+ * @returns {boolean | undefined} If the callback returns `false,` the editor won't be opened after
2409
+ * the mouse double click or after pressing the Enter key. Returning `undefined` (or other value
2410
+ * than boolean) will result in default behavior, which disallows opening an editor for non-contiguous
2411
+ * selection (while pressing Ctrl/Cmd) and for multiple selected cells (while pressing SHIFT).
2412
+ * Returning `true` removes those restrictions.
2413
+ */
2414
+ 'beforeBeginEditing',
2397
2415
  /**
2398
2416
  * Fired after the editor is opened and rendered.
2399
2417
  *
@@ -1290,6 +1290,7 @@ function _onEngineSheetAdded2(addedSheetDisplayName) {
1290
1290
  this.hot.runHooks('afterSheetAdded', addedSheetDisplayName);
1291
1291
  }
1292
1292
  function _onEngineSheetRenamed2(oldDisplayName, newDisplayName) {
1293
+ this.sheetName = newDisplayName;
1293
1294
  this.hot.runHooks('afterSheetRenamed', oldDisplayName, newDisplayName);
1294
1295
  }
1295
1296
  function _onEngineSheetRemoved2(removedSheetDisplayName, changes) {
@@ -1285,6 +1285,7 @@ function _onEngineSheetAdded2(addedSheetDisplayName) {
1285
1285
  this.hot.runHooks('afterSheetAdded', addedSheetDisplayName);
1286
1286
  }
1287
1287
  function _onEngineSheetRenamed2(oldDisplayName, newDisplayName) {
1288
+ this.sheetName = newDisplayName;
1288
1289
  this.hot.runHooks('afterSheetRenamed', oldDisplayName, newDisplayName);
1289
1290
  }
1290
1291
  function _onEngineSheetRemoved2(removedSheetDisplayName, changes) {
@@ -282,7 +282,7 @@ class AxisSyncer {
282
282
  return;
283
283
  }
284
284
  const newSequence = _classPrivateFieldGet(this, _indexMapper).getIndexesSequence();
285
- if (source === 'update') {
285
+ if (source === 'update' && newSequence.length > 0) {
286
286
  const relativeTransformation = _classPrivateFieldGet(this, _indexesSequence).map(index => newSequence.indexOf(index));
287
287
  const sheetDimensions = _classPrivateFieldGet(this, _indexSyncer).getEngine().getSheetDimensions(_classPrivateFieldGet(this, _indexSyncer).getSheetId());
288
288
  let sizeForAxis;
@@ -279,7 +279,7 @@ class AxisSyncer {
279
279
  return;
280
280
  }
281
281
  const newSequence = _classPrivateFieldGet(this, _indexMapper).getIndexesSequence();
282
- if (source === 'update') {
282
+ if (source === 'update' && newSequence.length > 0) {
283
283
  const relativeTransformation = _classPrivateFieldGet(this, _indexesSequence).map(index => newSequence.indexOf(index));
284
284
  const sheetDimensions = _classPrivateFieldGet(this, _indexSyncer).getEngine().getSheetDimensions(_classPrivateFieldGet(this, _indexSyncer).getSheetId());
285
285
  let sizeForAxis;
@@ -77,7 +77,7 @@ class MergedCellsCollection {
77
77
  }
78
78
 
79
79
  /**
80
- * Get a merged cell containing the provided range.
80
+ * Get the first-found merged cell containing the provided range.
81
81
  *
82
82
  * @param {CellRange|object} range The range to search merged cells for.
83
83
  * @returns {MergedCellCoords|boolean}
@@ -73,7 +73,7 @@ class MergedCellsCollection {
73
73
  }
74
74
 
75
75
  /**
76
- * Get a merged cell containing the provided range.
76
+ * Get the first-found merged cell containing the provided range.
77
77
  *
78
78
  * @param {CellRange|object} range The range to search merged cells for.
79
79
  * @returns {MergedCellCoords|boolean}
@@ -98,9 +98,20 @@ var _onBeforeDrawAreaBorders = /*#__PURE__*/new WeakSet();
98
98
  var _onAfterModifyTransformStart = /*#__PURE__*/new WeakSet();
99
99
  var _onAfterDrawSelection = /*#__PURE__*/new WeakSet();
100
100
  var _onBeforeRemoveCellClassNames = /*#__PURE__*/new WeakSet();
101
+ var _onBeforeBeginEditing = /*#__PURE__*/new WeakSet();
101
102
  class MergeCells extends _base.BasePlugin {
102
103
  constructor() {
103
104
  super(...arguments);
105
+ /**
106
+ * Allows to prevent opening the editor while more than one merged cell is selected.
107
+ *
108
+ * @param {number} row Visual row index of the edited cell.
109
+ * @param {number} column Visual column index of the edited cell.
110
+ * @param {string | null} initialValue The initial editor value.
111
+ * @param {MouseEvent | KeyboardEvent} event The event which was responsible for opening the editor.
112
+ * @returns {boolean | undefined}
113
+ */
114
+ _classPrivateMethodInitSpec(this, _onBeforeBeginEditing);
104
115
  /**
105
116
  * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
106
117
  *
@@ -459,6 +470,12 @@ class MergeCells extends _base.BasePlugin {
459
470
  }
460
471
  return _classPrivateMethodGet(_this, _onBeforeRemoveCellClassNames, _onBeforeRemoveCellClassNames2).call(_this, ...args);
461
472
  });
473
+ this.addHook('beforeBeginEditing', function () {
474
+ for (var _len24 = arguments.length, args = new Array(_len24), _key24 = 0; _key24 < _len24; _key24++) {
475
+ args[_key24] = arguments[_key24];
476
+ }
477
+ return _classPrivateMethodGet(_this, _onBeforeBeginEditing, _onBeforeBeginEditing2).call(_this, ...args);
478
+ });
462
479
  this.addHook('beforeUndoStackChange', (action, source) => {
463
480
  if (source === 'MergeCells') {
464
481
  return false;
@@ -1290,4 +1307,17 @@ function _onAfterDrawSelection2(currentRow, currentColumn, cornersOfSelection, l
1290
1307
  }
1291
1308
  function _onBeforeRemoveCellClassNames2() {
1292
1309
  return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
1310
+ }
1311
+ function _onBeforeBeginEditing2(row, column, initialValue, event) {
1312
+ if (!(event instanceof MouseEvent)) {
1313
+ return;
1314
+ }
1315
+ const selection = this.hot.getSelectedRangeLast();
1316
+ const mergeCell = this.mergedCellsCollection.getByRange(selection);
1317
+ if (!mergeCell) {
1318
+ return;
1319
+ }
1320
+ const from = this.hot._createCellCoords(mergeCell.row, mergeCell.col);
1321
+ const to = this.hot._createCellCoords(mergeCell.row + mergeCell.rowspan - 1, mergeCell.col + mergeCell.colspan - 1);
1322
+ return this.hot.selection.getLayerLevel() === 0 && selection.isEqual(this.hot._createCellRange(from, from, to));
1293
1323
  }
@@ -94,9 +94,20 @@ var _onBeforeDrawAreaBorders = /*#__PURE__*/new WeakSet();
94
94
  var _onAfterModifyTransformStart = /*#__PURE__*/new WeakSet();
95
95
  var _onAfterDrawSelection = /*#__PURE__*/new WeakSet();
96
96
  var _onBeforeRemoveCellClassNames = /*#__PURE__*/new WeakSet();
97
+ var _onBeforeBeginEditing = /*#__PURE__*/new WeakSet();
97
98
  export class MergeCells extends BasePlugin {
98
99
  constructor() {
99
100
  super(...arguments);
101
+ /**
102
+ * Allows to prevent opening the editor while more than one merged cell is selected.
103
+ *
104
+ * @param {number} row Visual row index of the edited cell.
105
+ * @param {number} column Visual column index of the edited cell.
106
+ * @param {string | null} initialValue The initial editor value.
107
+ * @param {MouseEvent | KeyboardEvent} event The event which was responsible for opening the editor.
108
+ * @returns {boolean | undefined}
109
+ */
110
+ _classPrivateMethodInitSpec(this, _onBeforeBeginEditing);
100
111
  /**
101
112
  * `beforeRemoveCellClassNames` hook callback. Used to remove additional class name from all cells in the table.
102
113
  *
@@ -455,6 +466,12 @@ export class MergeCells extends BasePlugin {
455
466
  }
456
467
  return _classPrivateMethodGet(_this, _onBeforeRemoveCellClassNames, _onBeforeRemoveCellClassNames2).call(_this, ...args);
457
468
  });
469
+ this.addHook('beforeBeginEditing', function () {
470
+ for (var _len24 = arguments.length, args = new Array(_len24), _key24 = 0; _key24 < _len24; _key24++) {
471
+ args[_key24] = arguments[_key24];
472
+ }
473
+ return _classPrivateMethodGet(_this, _onBeforeBeginEditing, _onBeforeBeginEditing2).call(_this, ...args);
474
+ });
458
475
  this.addHook('beforeUndoStackChange', (action, source) => {
459
476
  if (source === 'MergeCells') {
460
477
  return false;
@@ -1285,4 +1302,17 @@ function _onAfterDrawSelection2(currentRow, currentColumn, cornersOfSelection, l
1285
1302
  }
1286
1303
  function _onBeforeRemoveCellClassNames2() {
1287
1304
  return this.selectionCalculations.getSelectedMergedCellClassNameToRemove();
1305
+ }
1306
+ function _onBeforeBeginEditing2(row, column, initialValue, event) {
1307
+ if (!(event instanceof MouseEvent)) {
1308
+ return;
1309
+ }
1310
+ const selection = this.hot.getSelectedRangeLast();
1311
+ const mergeCell = this.mergedCellsCollection.getByRange(selection);
1312
+ if (!mergeCell) {
1313
+ return;
1314
+ }
1315
+ const from = this.hot._createCellCoords(mergeCell.row, mergeCell.col);
1316
+ const to = this.hot._createCellCoords(mergeCell.row + mergeCell.rowspan - 1, mergeCell.col + mergeCell.colspan - 1);
1317
+ return this.hot.selection.getLayerLevel() === 0 && selection.isEqual(this.hot._createCellRange(from, from, to));
1288
1318
  }