handsontable 0.0.0-next-95bb75e-20240131 → 0.0.0-next-ffffb2f-20240131

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

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-95bb75e-20240131";
137
+ const hotVersion = "0.0.0-next-ffffb2f-20240131";
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-95bb75e-20240131";
127
+ const hotVersion = "0.0.0-next-ffffb2f-20240131";
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-95bb75e-20240131",
13
+ "version": "0.0.0-next-ffffb2f-20240131",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -4,7 +4,6 @@ exports.__esModule = true;
4
4
  require("core-js/modules/es.array.push.js");
5
5
  require("core-js/modules/es.error.cause.js");
6
6
  var _string = require("../../../helpers/string");
7
- var _moves = require("../../../helpers/moves");
8
7
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
9
8
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
10
9
  function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
@@ -177,6 +176,79 @@ class AxisSyncer {
177
176
  _classPrivateFieldSet(this, _finalIndex, this.getHfIndexFromVisualIndex(visualFinalIndex));
178
177
  }
179
178
 
179
+ /**
180
+ * Gets first position where to move element (respecting the fact that some element will be sooner or later
181
+ * taken out of the dataset in order to move them).
182
+ *
183
+ * @param {Array<number>} movedHfIndexes Sequence of moved HF indexes for certain axis.
184
+ * @param {number} finalHfIndex Final HF place where to move rows.
185
+ * @returns {number} HF's index informing where to move the first element.
186
+ * @private
187
+ */
188
+ getMoveLine(movedHfIndexes, finalHfIndex) {
189
+ const numberOfElements = _classPrivateFieldGet(this, _indexMapper).getNumberOfIndexes();
190
+ const notMovedElements = Array.from(Array(numberOfElements).keys()).filter(index => movedHfIndexes.includes(index) === false);
191
+ if (finalHfIndex === 0) {
192
+ var _notMovedElements$fin;
193
+ return (_notMovedElements$fin = notMovedElements[finalHfIndex]) !== null && _notMovedElements$fin !== void 0 ? _notMovedElements$fin : 0; // Moving before the first dataset's element.
194
+ }
195
+ return notMovedElements[finalHfIndex - 1] + 1; // Moving before another element.
196
+ }
197
+
198
+ /**
199
+ * Gets initially calculated HF's move positions.
200
+ *
201
+ * @private
202
+ * @param {Array<number>} movedHfIndexes Sequence of moved HF indexes for certain axis.
203
+ * @param {number} finalHfIndex Final HF place where to move rows.
204
+ * @returns {Array<{from: number, to: number}>} Initially calculated HF's move positions.
205
+ */
206
+ getInitiallyCalculatedMoves(movedHfIndexes, finalHfIndex) {
207
+ let moveLine = this.getMoveLine(movedHfIndexes, finalHfIndex);
208
+ const moves = [];
209
+ movedHfIndexes.forEach(movedHfIndex => {
210
+ const move = {
211
+ from: movedHfIndex,
212
+ to: moveLine
213
+ };
214
+ moves.forEach(previouslyMovedIndex => {
215
+ const isMovingFromEndToStart = previouslyMovedIndex.from > previouslyMovedIndex.to;
216
+ const isMovingElementBefore = previouslyMovedIndex.to <= move.from;
217
+ const isMovingAfterElement = previouslyMovedIndex.from > move.from;
218
+ if (isMovingAfterElement && isMovingElementBefore && isMovingFromEndToStart) {
219
+ move.from += 1;
220
+ }
221
+ });
222
+
223
+ // Moved element from right to left (or bottom to top).
224
+ if (move.from >= moveLine) {
225
+ moveLine += 1;
226
+ }
227
+ moves.push(move);
228
+ });
229
+ return moves;
230
+ }
231
+
232
+ /**
233
+ * Gets finally calculated HF's move positions (after adjusting).
234
+ *
235
+ * @private
236
+ * @param {Array<{from: number, to: number}>} moves Initially calculated HF's move positions.
237
+ * @returns {Array<{from: number, to: number}>} Finally calculated HF's move positions (after adjusting).
238
+ */
239
+ adjustedCalculatedMoves(moves) {
240
+ moves.forEach((move, index) => {
241
+ const nextMoved = moves.slice(index + 1);
242
+ nextMoved.forEach(nextMovedIndex => {
243
+ const isMovingFromStartToEnd = nextMovedIndex.from < nextMovedIndex.to;
244
+ if (nextMovedIndex.from > move.from && isMovingFromStartToEnd) {
245
+ nextMovedIndex.from -= 1;
246
+ }
247
+ });
248
+ });
249
+ return moves;
250
+ }
251
+
180
252
  /**
181
253
  * Calculating where to move HF elements and performing already calculated moves.
182
254
  *
@@ -190,7 +262,7 @@ class AxisSyncer {
190
262
  if (movePossible === false || orderChanged === false) {
191
263
  return;
192
264
  }
193
- const calculatedMoves = (0, _moves.getMoves)(_classPrivateFieldGet(this, _movedIndexes), _classPrivateFieldGet(this, _finalIndex), _classPrivateFieldGet(this, _indexMapper).getNumberOfIndexes());
265
+ const calculatedMoves = this.adjustedCalculatedMoves(this.getInitiallyCalculatedMoves(_classPrivateFieldGet(this, _movedIndexes), _classPrivateFieldGet(this, _finalIndex)));
194
266
  if (_classPrivateFieldGet(this, _indexSyncer).getSheetId() === null) {
195
267
  _classPrivateFieldGet(this, _indexSyncer).getPostponeAction(() => this.syncMoves(calculatedMoves));
196
268
  } else {
@@ -8,7 +8,6 @@ function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _
8
8
  function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
9
9
  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; } }
10
10
  import { toUpperCaseFirst } from "../../../helpers/string.mjs";
11
- import { getMoves } from "../../../helpers/moves.mjs";
12
11
  /**
13
12
  * @private
14
13
  * @class IndexSyncer
@@ -174,6 +173,79 @@ class AxisSyncer {
174
173
  _classPrivateFieldSet(this, _finalIndex, this.getHfIndexFromVisualIndex(visualFinalIndex));
175
174
  }
176
175
 
176
+ /**
177
+ * Gets first position where to move element (respecting the fact that some element will be sooner or later
178
+ * taken out of the dataset in order to move them).
179
+ *
180
+ * @param {Array<number>} movedHfIndexes Sequence of moved HF indexes for certain axis.
181
+ * @param {number} finalHfIndex Final HF place where to move rows.
182
+ * @returns {number} HF's index informing where to move the first element.
183
+ * @private
184
+ */
185
+ getMoveLine(movedHfIndexes, finalHfIndex) {
186
+ const numberOfElements = _classPrivateFieldGet(this, _indexMapper).getNumberOfIndexes();
187
+ const notMovedElements = Array.from(Array(numberOfElements).keys()).filter(index => movedHfIndexes.includes(index) === false);
188
+ if (finalHfIndex === 0) {
189
+ var _notMovedElements$fin;
190
+ return (_notMovedElements$fin = notMovedElements[finalHfIndex]) !== null && _notMovedElements$fin !== void 0 ? _notMovedElements$fin : 0; // Moving before the first dataset's element.
191
+ }
192
+ return notMovedElements[finalHfIndex - 1] + 1; // Moving before another element.
193
+ }
194
+
195
+ /**
196
+ * Gets initially calculated HF's move positions.
197
+ *
198
+ * @private
199
+ * @param {Array<number>} movedHfIndexes Sequence of moved HF indexes for certain axis.
200
+ * @param {number} finalHfIndex Final HF place where to move rows.
201
+ * @returns {Array<{from: number, to: number}>} Initially calculated HF's move positions.
202
+ */
203
+ getInitiallyCalculatedMoves(movedHfIndexes, finalHfIndex) {
204
+ let moveLine = this.getMoveLine(movedHfIndexes, finalHfIndex);
205
+ const moves = [];
206
+ movedHfIndexes.forEach(movedHfIndex => {
207
+ const move = {
208
+ from: movedHfIndex,
209
+ to: moveLine
210
+ };
211
+ moves.forEach(previouslyMovedIndex => {
212
+ const isMovingFromEndToStart = previouslyMovedIndex.from > previouslyMovedIndex.to;
213
+ const isMovingElementBefore = previouslyMovedIndex.to <= move.from;
214
+ const isMovingAfterElement = previouslyMovedIndex.from > move.from;
215
+ if (isMovingAfterElement && isMovingElementBefore && isMovingFromEndToStart) {
216
+ move.from += 1;
217
+ }
218
+ });
219
+
220
+ // Moved element from right to left (or bottom to top).
221
+ if (move.from >= moveLine) {
222
+ moveLine += 1;
223
+ }
224
+ moves.push(move);
225
+ });
226
+ return moves;
227
+ }
228
+
229
+ /**
230
+ * Gets finally calculated HF's move positions (after adjusting).
231
+ *
232
+ * @private
233
+ * @param {Array<{from: number, to: number}>} moves Initially calculated HF's move positions.
234
+ * @returns {Array<{from: number, to: number}>} Finally calculated HF's move positions (after adjusting).
235
+ */
236
+ adjustedCalculatedMoves(moves) {
237
+ moves.forEach((move, index) => {
238
+ const nextMoved = moves.slice(index + 1);
239
+ nextMoved.forEach(nextMovedIndex => {
240
+ const isMovingFromStartToEnd = nextMovedIndex.from < nextMovedIndex.to;
241
+ if (nextMovedIndex.from > move.from && isMovingFromStartToEnd) {
242
+ nextMovedIndex.from -= 1;
243
+ }
244
+ });
245
+ });
246
+ return moves;
247
+ }
248
+
177
249
  /**
178
250
  * Calculating where to move HF elements and performing already calculated moves.
179
251
  *
@@ -187,7 +259,7 @@ class AxisSyncer {
187
259
  if (movePossible === false || orderChanged === false) {
188
260
  return;
189
261
  }
190
- const calculatedMoves = getMoves(_classPrivateFieldGet(this, _movedIndexes), _classPrivateFieldGet(this, _finalIndex), _classPrivateFieldGet(this, _indexMapper).getNumberOfIndexes());
262
+ const calculatedMoves = this.adjustedCalculatedMoves(this.getInitiallyCalculatedMoves(_classPrivateFieldGet(this, _movedIndexes), _classPrivateFieldGet(this, _finalIndex)));
191
263
  if (_classPrivateFieldGet(this, _indexSyncer).getSheetId() === null) {
192
264
  _classPrivateFieldGet(this, _indexSyncer).getPostponeAction(() => this.syncMoves(calculatedMoves));
193
265
  } else {
@@ -8,7 +8,6 @@ var _array = require("../../helpers/array");
8
8
  var _number = require("../../helpers/number");
9
9
  var _object = require("../../helpers/object");
10
10
  var _utils = require("../contextMenu/utils");
11
- var _moves = require("../../helpers/moves");
12
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
12
  const SHORTCUTS_GROUP = 'undoRedo';
14
13
  const PLUGIN_KEY = exports.PLUGIN_KEY = 'undoRedo';
@@ -133,12 +132,6 @@ function UndoRedo(instance) {
133
132
  }
134
133
  plugin.done(() => new UndoRedo.RowMoveAction(rows, finalIndex));
135
134
  });
136
- instance.addHook('beforeColumnMove', (columns, finalIndex) => {
137
- if (columns === false) {
138
- return;
139
- }
140
- plugin.done(() => new UndoRedo.ColumnMoveAction(columns, finalIndex));
141
- });
142
135
  instance.addHook('beforeMergeCells', (cellRange, auto) => {
143
136
  if (auto) {
144
137
  return;
@@ -721,24 +714,24 @@ UndoRedo.UnmergeCellsAction = UnmergeCellsAction;
721
714
  */
722
715
  UndoRedo.RowMoveAction = function (rows, finalIndex) {
723
716
  this.rows = rows.slice();
724
- this.finalRowIndex = finalIndex;
717
+ this.finalIndex = finalIndex;
725
718
  this.actionType = 'row_move';
726
719
  };
727
720
  (0, _object.inherit)(UndoRedo.RowMoveAction, UndoRedo.Action);
728
721
  UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
729
722
  const manualRowMove = instance.getPlugin('manualRowMove');
723
+ const copyOfRows = [].concat(this.rows);
724
+ const rowsMovedUp = copyOfRows.filter(a => a > this.finalIndex);
725
+ const rowsMovedDown = copyOfRows.filter(a => a <= this.finalIndex);
726
+ const allMovedRows = rowsMovedUp.sort((a, b) => b - a).concat(rowsMovedDown.sort((a, b) => a - b));
730
727
  instance.addHookOnce('afterViewRender', undoneCallback);
731
- const rowMoves = (0, _moves.getMoves)(this.rows, this.finalRowIndex, instance.rowIndexMapper.getNumberOfIndexes());
732
- rowMoves.reverse().forEach(_ref4 => {
733
- let {
734
- from,
735
- to
736
- } = _ref4;
737
- if (from < to) {
738
- to -= 1;
739
- }
740
- manualRowMove.moveRow(to, from);
741
- });
728
+
729
+ // Moving rows from those with higher indexes to those with lower indexes when action was performed from bottom to top
730
+ // Moving rows from those with lower indexes to those with higher indexes when action was performed from top to bottom
731
+ for (let i = 0; i < allMovedRows.length; i += 1) {
732
+ const newPhysicalRow = instance.toVisualRow(allMovedRows[i]);
733
+ manualRowMove.moveRow(newPhysicalRow, allMovedRows[i]);
734
+ }
742
735
  instance.render();
743
736
  instance.deselectCell();
744
737
  instance.selectRows(this.rows[0], this.rows[0] + this.rows.length - 1);
@@ -746,50 +739,10 @@ UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
746
739
  UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) {
747
740
  const manualRowMove = instance.getPlugin('manualRowMove');
748
741
  instance.addHookOnce('afterViewRender', redoneCallback);
749
- manualRowMove.moveRows(this.rows.slice(), this.finalRowIndex);
750
- instance.render();
751
- instance.deselectCell();
752
- instance.selectRows(this.finalRowIndex, this.finalRowIndex + this.rows.length - 1);
753
- };
754
-
755
- /**
756
- * ManualColumnMove action.
757
- *
758
- * @private
759
- * @param {number[]} columns An array with moved columns.
760
- * @param {number} finalIndex The destination index.
761
- */
762
- UndoRedo.ColumnMoveAction = function (columns, finalIndex) {
763
- this.columns = columns.slice();
764
- this.finalColumnIndex = finalIndex;
765
- this.actionType = 'col_move';
766
- };
767
- (0, _object.inherit)(UndoRedo.ColumnMoveAction, UndoRedo.Action);
768
- UndoRedo.ColumnMoveAction.prototype.undo = function (instance, undoneCallback) {
769
- const manualColumnMove = instance.getPlugin('manualColumnMove');
770
- instance.addHookOnce('afterViewRender', undoneCallback);
771
- const columnMoves = (0, _moves.getMoves)(this.columns, this.finalColumnIndex, instance.columnIndexMapper.getNumberOfIndexes());
772
- columnMoves.reverse().forEach(_ref5 => {
773
- let {
774
- from,
775
- to
776
- } = _ref5;
777
- if (from < to) {
778
- to -= 1;
779
- }
780
- manualColumnMove.moveColumn(to, from);
781
- });
782
- instance.render();
783
- instance.deselectCell();
784
- instance.selectColumns(this.columns[0], this.columns[0] + this.columns.length - 1);
785
- };
786
- UndoRedo.ColumnMoveAction.prototype.redo = function (instance, redoneCallback) {
787
- const manualColumnMove = instance.getPlugin('manualColumnMove');
788
- instance.addHookOnce('afterViewRender', redoneCallback);
789
- manualColumnMove.moveColumns(this.columns.slice(), this.finalColumnIndex);
742
+ manualRowMove.moveRows(this.rows.slice(), this.finalIndex);
790
743
  instance.render();
791
744
  instance.deselectCell();
792
- instance.selectColumns(this.finalColumnIndex, this.finalColumnIndex + this.columns.length - 1);
745
+ instance.selectRows(this.finalIndex, this.finalIndex + this.rows.length - 1);
793
746
  };
794
747
 
795
748
  /**
@@ -5,7 +5,6 @@ import { arrayMap, arrayEach } from "../../helpers/array.mjs";
5
5
  import { rangeEach } from "../../helpers/number.mjs";
6
6
  import { inherit, deepClone } from "../../helpers/object.mjs";
7
7
  import { align } from "../contextMenu/utils.mjs";
8
- import { getMoves } from "../../helpers/moves.mjs";
9
8
  const SHORTCUTS_GROUP = 'undoRedo';
10
9
  export const PLUGIN_KEY = 'undoRedo';
11
10
 
@@ -129,12 +128,6 @@ function UndoRedo(instance) {
129
128
  }
130
129
  plugin.done(() => new UndoRedo.RowMoveAction(rows, finalIndex));
131
130
  });
132
- instance.addHook('beforeColumnMove', (columns, finalIndex) => {
133
- if (columns === false) {
134
- return;
135
- }
136
- plugin.done(() => new UndoRedo.ColumnMoveAction(columns, finalIndex));
137
- });
138
131
  instance.addHook('beforeMergeCells', (cellRange, auto) => {
139
132
  if (auto) {
140
133
  return;
@@ -717,24 +710,24 @@ UndoRedo.UnmergeCellsAction = UnmergeCellsAction;
717
710
  */
718
711
  UndoRedo.RowMoveAction = function (rows, finalIndex) {
719
712
  this.rows = rows.slice();
720
- this.finalRowIndex = finalIndex;
713
+ this.finalIndex = finalIndex;
721
714
  this.actionType = 'row_move';
722
715
  };
723
716
  inherit(UndoRedo.RowMoveAction, UndoRedo.Action);
724
717
  UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
725
718
  const manualRowMove = instance.getPlugin('manualRowMove');
719
+ const copyOfRows = [].concat(this.rows);
720
+ const rowsMovedUp = copyOfRows.filter(a => a > this.finalIndex);
721
+ const rowsMovedDown = copyOfRows.filter(a => a <= this.finalIndex);
722
+ const allMovedRows = rowsMovedUp.sort((a, b) => b - a).concat(rowsMovedDown.sort((a, b) => a - b));
726
723
  instance.addHookOnce('afterViewRender', undoneCallback);
727
- const rowMoves = getMoves(this.rows, this.finalRowIndex, instance.rowIndexMapper.getNumberOfIndexes());
728
- rowMoves.reverse().forEach(_ref4 => {
729
- let {
730
- from,
731
- to
732
- } = _ref4;
733
- if (from < to) {
734
- to -= 1;
735
- }
736
- manualRowMove.moveRow(to, from);
737
- });
724
+
725
+ // Moving rows from those with higher indexes to those with lower indexes when action was performed from bottom to top
726
+ // Moving rows from those with lower indexes to those with higher indexes when action was performed from top to bottom
727
+ for (let i = 0; i < allMovedRows.length; i += 1) {
728
+ const newPhysicalRow = instance.toVisualRow(allMovedRows[i]);
729
+ manualRowMove.moveRow(newPhysicalRow, allMovedRows[i]);
730
+ }
738
731
  instance.render();
739
732
  instance.deselectCell();
740
733
  instance.selectRows(this.rows[0], this.rows[0] + this.rows.length - 1);
@@ -742,50 +735,10 @@ UndoRedo.RowMoveAction.prototype.undo = function (instance, undoneCallback) {
742
735
  UndoRedo.RowMoveAction.prototype.redo = function (instance, redoneCallback) {
743
736
  const manualRowMove = instance.getPlugin('manualRowMove');
744
737
  instance.addHookOnce('afterViewRender', redoneCallback);
745
- manualRowMove.moveRows(this.rows.slice(), this.finalRowIndex);
746
- instance.render();
747
- instance.deselectCell();
748
- instance.selectRows(this.finalRowIndex, this.finalRowIndex + this.rows.length - 1);
749
- };
750
-
751
- /**
752
- * ManualColumnMove action.
753
- *
754
- * @private
755
- * @param {number[]} columns An array with moved columns.
756
- * @param {number} finalIndex The destination index.
757
- */
758
- UndoRedo.ColumnMoveAction = function (columns, finalIndex) {
759
- this.columns = columns.slice();
760
- this.finalColumnIndex = finalIndex;
761
- this.actionType = 'col_move';
762
- };
763
- inherit(UndoRedo.ColumnMoveAction, UndoRedo.Action);
764
- UndoRedo.ColumnMoveAction.prototype.undo = function (instance, undoneCallback) {
765
- const manualColumnMove = instance.getPlugin('manualColumnMove');
766
- instance.addHookOnce('afterViewRender', undoneCallback);
767
- const columnMoves = getMoves(this.columns, this.finalColumnIndex, instance.columnIndexMapper.getNumberOfIndexes());
768
- columnMoves.reverse().forEach(_ref5 => {
769
- let {
770
- from,
771
- to
772
- } = _ref5;
773
- if (from < to) {
774
- to -= 1;
775
- }
776
- manualColumnMove.moveColumn(to, from);
777
- });
778
- instance.render();
779
- instance.deselectCell();
780
- instance.selectColumns(this.columns[0], this.columns[0] + this.columns.length - 1);
781
- };
782
- UndoRedo.ColumnMoveAction.prototype.redo = function (instance, redoneCallback) {
783
- const manualColumnMove = instance.getPlugin('manualColumnMove');
784
- instance.addHookOnce('afterViewRender', redoneCallback);
785
- manualColumnMove.moveColumns(this.columns.slice(), this.finalColumnIndex);
738
+ manualRowMove.moveRows(this.rows.slice(), this.finalIndex);
786
739
  instance.render();
787
740
  instance.deselectCell();
788
- instance.selectColumns(this.finalColumnIndex, this.finalColumnIndex + this.columns.length - 1);
741
+ instance.selectRows(this.finalIndex, this.finalIndex + this.rows.length - 1);
789
742
  };
790
743
 
791
744
  /**
package/tableView.js CHANGED
@@ -307,15 +307,13 @@ class TableView {
307
307
  const {
308
308
  rootElement,
309
309
  rootDocument,
310
- selection
310
+ selection,
311
+ rootWindow
311
312
  } = this.hot;
312
313
  const documentElement = rootDocument.documentElement;
313
314
  this.eventManager.addEventListener(rootElement, 'mousedown', event => {
314
315
  _classPrivateFieldSet(this, _selectionMouseDown, true);
315
316
  if (!this.isTextSelectionAllowed(event.target)) {
316
- const {
317
- rootWindow
318
- } = this.hot;
319
317
  (0, _element.clearTextSelection)(rootWindow);
320
318
  event.preventDefault();
321
319
  rootWindow.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
@@ -328,7 +326,7 @@ class TableView {
328
326
  if (_classPrivateFieldGet(this, _selectionMouseDown) && !this.isTextSelectionAllowed(event.target)) {
329
327
  // Clear selection only when fragmentSelection is enabled, otherwise clearing selection breaks the IME editor.
330
328
  if (this.settings.fragmentSelection) {
331
- (0, _element.clearTextSelection)(this.hot.rootWindow);
329
+ (0, _element.clearTextSelection)(rootWindow);
332
330
  }
333
331
  event.preventDefault();
334
332
  }
@@ -408,6 +406,13 @@ class TableView {
408
406
  this.hot.destroyEditor(false, false);
409
407
  }
410
408
  });
409
+ let parentWindow = (0, _element.getParentWindow)(rootWindow);
410
+ while (parentWindow !== null) {
411
+ this.eventManager.addEventListener(parentWindow.document.documentElement, 'click', () => {
412
+ this.hot.unlisten();
413
+ });
414
+ parentWindow = (0, _element.getParentWindow)(parentWindow);
415
+ }
411
416
  this.eventManager.addEventListener(_classPrivateFieldGet(this, _table), 'selectstart', event => {
412
417
  if (this.settings.fragmentSelection || (0, _element.isInput)(event.target)) {
413
418
  return;
package/tableView.mjs CHANGED
@@ -12,7 +12,7 @@ function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) {
12
12
  function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
13
13
  function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
14
14
  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; } }
15
- import { addClass, clearTextSelection, empty, fastInnerHTML, fastInnerText, getScrollbarWidth, hasClass, isChildOf, isInput, isOutsideInput, isVisible, setAttribute } from "./helpers/dom/element.mjs";
15
+ import { addClass, clearTextSelection, empty, fastInnerHTML, fastInnerText, getScrollbarWidth, hasClass, isChildOf, isInput, isOutsideInput, isVisible, setAttribute, getParentWindow } from "./helpers/dom/element.mjs";
16
16
  import EventManager from "./eventManager.mjs";
17
17
  import { isImmediatePropagationStopped, isRightClick, isLeftClick } from "./helpers/dom/event.mjs";
18
18
  import Walkontable from "./3rdparty/walkontable/src/index.mjs";
@@ -303,15 +303,13 @@ class TableView {
303
303
  const {
304
304
  rootElement,
305
305
  rootDocument,
306
- selection
306
+ selection,
307
+ rootWindow
307
308
  } = this.hot;
308
309
  const documentElement = rootDocument.documentElement;
309
310
  this.eventManager.addEventListener(rootElement, 'mousedown', event => {
310
311
  _classPrivateFieldSet(this, _selectionMouseDown, true);
311
312
  if (!this.isTextSelectionAllowed(event.target)) {
312
- const {
313
- rootWindow
314
- } = this.hot;
315
313
  clearTextSelection(rootWindow);
316
314
  event.preventDefault();
317
315
  rootWindow.focus(); // make sure that window that contains HOT is active. Important when HOT is in iframe.
@@ -324,7 +322,7 @@ class TableView {
324
322
  if (_classPrivateFieldGet(this, _selectionMouseDown) && !this.isTextSelectionAllowed(event.target)) {
325
323
  // Clear selection only when fragmentSelection is enabled, otherwise clearing selection breaks the IME editor.
326
324
  if (this.settings.fragmentSelection) {
327
- clearTextSelection(this.hot.rootWindow);
325
+ clearTextSelection(rootWindow);
328
326
  }
329
327
  event.preventDefault();
330
328
  }
@@ -404,6 +402,13 @@ class TableView {
404
402
  this.hot.destroyEditor(false, false);
405
403
  }
406
404
  });
405
+ let parentWindow = getParentWindow(rootWindow);
406
+ while (parentWindow !== null) {
407
+ this.eventManager.addEventListener(parentWindow.document.documentElement, 'click', () => {
408
+ this.hot.unlisten();
409
+ });
410
+ parentWindow = getParentWindow(parentWindow);
411
+ }
407
412
  this.eventManager.addEventListener(_classPrivateFieldGet(this, _table), 'selectstart', event => {
408
413
  if (this.settings.fragmentSelection || isInput(event.target)) {
409
414
  return;
@@ -5,6 +5,7 @@ exports._dataToHTML = _dataToHTML;
5
5
  exports.htmlToGridSettings = htmlToGridSettings;
6
6
  exports.instanceToHTML = instanceToHTML;
7
7
  require("core-js/modules/es.array.push.js");
8
+ require("core-js/modules/es.string.replace-all.js");
8
9
  var _mixed = require("./../helpers/mixed");
9
10
  const ESCAPED_HTML_CHARS = {
10
11
  '&nbsp;': '\x20',
@@ -140,7 +141,14 @@ function htmlToGridSettings(element) {
140
141
  if (typeof checkElement === 'string') {
141
142
  const escapedAdjacentHTML = checkElement.replace(/<td\b[^>]*?>([\s\S]*?)<\/\s*td>/g, cellFragment => {
142
143
  const openingTag = cellFragment.match(/<td\b[^>]*?>/g)[0];
143
- const cellValue = cellFragment.substring(openingTag.length, cellFragment.lastIndexOf('<')).replace(/(<(?!br)([^>]+)>)/gi, '');
144
+ const paragraphRegexp = /<p.*?>/g;
145
+ const cellValue = cellFragment.substring(openingTag.length, cellFragment.lastIndexOf('<')).trim() // Removing whitespaces from the start and the end of HTML fragment
146
+ .replaceAll(/\n\s+/g, ' ') // HTML tags may be split using multiple new lines and whitespaces
147
+ .replaceAll(paragraphRegexp, '\n') // Only paragraphs should split text using new line characters
148
+ .replace('\n', '') // First paragraph shouldn't start with new line characters
149
+ .replaceAll(/<\/(.*)>\s+$/mg, '</$1>') // HTML tags may end with whitespace.
150
+ .replace(/(<(?!br)([^>]+)>)/gi, '') // Removing HTML tags
151
+ .replaceAll(/^&nbsp;$/mg, ''); // Removing single &nbsp; characters separating new lines
144
152
  const closingTag = '</td>';
145
153
  return `${openingTag}${cellValue}${closingTag}`;
146
154
  });
@@ -1,4 +1,5 @@
1
1
  import "core-js/modules/es.array.push.js";
2
+ import "core-js/modules/es.string.replace-all.js";
2
3
  import { isEmpty } from "./../helpers/mixed.mjs";
3
4
  const ESCAPED_HTML_CHARS = {
4
5
  '&nbsp;': '\x20',
@@ -134,7 +135,14 @@ export function htmlToGridSettings(element) {
134
135
  if (typeof checkElement === 'string') {
135
136
  const escapedAdjacentHTML = checkElement.replace(/<td\b[^>]*?>([\s\S]*?)<\/\s*td>/g, cellFragment => {
136
137
  const openingTag = cellFragment.match(/<td\b[^>]*?>/g)[0];
137
- const cellValue = cellFragment.substring(openingTag.length, cellFragment.lastIndexOf('<')).replace(/(<(?!br)([^>]+)>)/gi, '');
138
+ const paragraphRegexp = /<p.*?>/g;
139
+ const cellValue = cellFragment.substring(openingTag.length, cellFragment.lastIndexOf('<')).trim() // Removing whitespaces from the start and the end of HTML fragment
140
+ .replaceAll(/\n\s+/g, ' ') // HTML tags may be split using multiple new lines and whitespaces
141
+ .replaceAll(paragraphRegexp, '\n') // Only paragraphs should split text using new line characters
142
+ .replace('\n', '') // First paragraph shouldn't start with new line characters
143
+ .replaceAll(/<\/(.*)>\s+$/mg, '</$1>') // HTML tags may end with whitespace.
144
+ .replace(/(<(?!br)([^>]+)>)/gi, '') // Removing HTML tags
145
+ .replaceAll(/^&nbsp;$/mg, ''); // Removing single &nbsp; characters separating new lines
138
146
  const closingTag = '</td>';
139
147
  return `${openingTag}${cellValue}${closingTag}`;
140
148
  });