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/base.js +2 -2
- package/base.mjs +2 -2
- package/dist/handsontable.css +2 -2
- package/dist/handsontable.full.css +2 -2
- package/dist/handsontable.full.js +1894 -1752
- package/dist/handsontable.full.min.css +2 -2
- package/dist/handsontable.full.min.js +8 -8
- package/dist/handsontable.js +1896 -1754
- package/dist/handsontable.min.css +2 -2
- package/dist/handsontable.min.js +25 -25
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/plugins/formulas/indexSyncer/axisSyncer.js +74 -2
- package/plugins/formulas/indexSyncer/axisSyncer.mjs +74 -2
- package/plugins/undoRedo/undoRedo.js +14 -61
- package/plugins/undoRedo/undoRedo.mjs +14 -61
- package/tableView.js +10 -5
- package/tableView.mjs +11 -6
- package/utils/parseTable.js +9 -1
- package/utils/parseTable.mjs +9 -1
- package/helpers/moves.js +0 -86
- package/helpers/moves.mjs +0 -82
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-
|
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-
|
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-
|
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 = (
|
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 =
|
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.
|
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
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
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.
|
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.
|
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.
|
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
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
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.
|
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.
|
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)(
|
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(
|
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;
|
package/utils/parseTable.js
CHANGED
@@ -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
|
' ': '\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
|
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(/^ $/mg, ''); // Removing single characters separating new lines
|
144
152
|
const closingTag = '</td>';
|
145
153
|
return `${openingTag}${cellValue}${closingTag}`;
|
146
154
|
});
|
package/utils/parseTable.mjs
CHANGED
@@ -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
|
' ': '\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
|
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(/^ $/mg, ''); // Removing single characters separating new lines
|
138
146
|
const closingTag = '</td>';
|
139
147
|
return `${openingTag}${cellValue}${closingTag}`;
|
140
148
|
});
|