handsontable 0.0.0-next-e697250-20230629 → 0.0.0-next-b02b3d1-20230710
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/core/focusCatcher/focusDetector.js +62 -0
- package/core/focusCatcher/focusDetector.mjs +58 -0
- package/core/focusCatcher/index.js +133 -0
- package/core/focusCatcher/index.mjs +129 -0
- package/core/index.js +12 -0
- package/core/index.mjs +1 -0
- package/core.d.ts +0 -1
- package/core.js +24 -31
- package/core.mjs +24 -31
- package/dataMap/metaManager/metaSchema.js +22 -0
- package/dataMap/metaManager/metaSchema.mjs +22 -0
- package/dist/handsontable.css +13 -2
- package/dist/handsontable.full.css +13 -2
- package/dist/handsontable.full.js +4801 -4783
- package/dist/handsontable.full.min.css +3 -3
- package/dist/handsontable.full.min.js +61 -61
- package/dist/handsontable.js +9892 -9874
- package/dist/handsontable.min.css +3 -3
- package/dist/handsontable.min.js +4 -4
- package/editorManager.js +10 -4
- package/editorManager.mjs +10 -4
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/pluginHooks.d.ts +1 -1
- package/pluginHooks.js +10 -7
- package/pluginHooks.mjs +10 -7
- package/plugins/comments/commentEditor.js +0 -1
- package/plugins/comments/commentEditor.mjs +0 -1
- package/plugins/comments/comments.js +231 -289
- package/plugins/comments/comments.mjs +241 -297
- package/plugins/contextMenu/contextMenu.js +0 -1
- package/plugins/contextMenu/contextMenu.mjs +0 -1
- package/plugins/copyPaste/copyPaste.js +1 -1
- package/plugins/copyPaste/copyPaste.mjs +1 -1
- package/plugins/dropdownMenu/dropdownMenu.js +1 -0
- package/plugins/dropdownMenu/dropdownMenu.mjs +1 -0
- package/plugins/formulas/engine/settings.js +2 -2
- package/plugins/formulas/engine/settings.mjs +2 -2
- package/plugins/formulas/formulas.js +2 -2
- package/plugins/formulas/formulas.mjs +2 -2
- package/plugins/manualRowResize/manualRowResize.js +2 -2
- package/plugins/manualRowResize/manualRowResize.mjs +2 -2
- package/settings.d.ts +1 -0
- package/shortcutContexts/constants.js +1 -6
- package/shortcutContexts/constants.mjs +0 -4
- package/tableView.js +4 -9
- package/tableView.mjs +4 -9
- package/plugins/comments/contextMenuItem/addEditComment.js +0 -51
- package/plugins/comments/contextMenuItem/addEditComment.mjs +0 -35
- package/plugins/comments/contextMenuItem/readOnlyComment.js +0 -63
- package/plugins/comments/contextMenuItem/readOnlyComment.mjs +0 -55
- package/plugins/comments/contextMenuItem/removeComment.js +0 -48
- package/plugins/comments/contextMenuItem/removeComment.mjs +0 -32
package/base.js
CHANGED
@@ -44,8 +44,8 @@ Handsontable.hooks = _pluginHooks.default.getSingleton();
|
|
44
44
|
Handsontable.CellCoords = _src.CellCoords;
|
45
45
|
Handsontable.CellRange = _src.CellRange;
|
46
46
|
Handsontable.packageName = 'handsontable';
|
47
|
-
Handsontable.buildDate = "
|
48
|
-
Handsontable.version = "0.0.0-next-
|
47
|
+
Handsontable.buildDate = "10/07/2023 08:56:32";
|
48
|
+
Handsontable.version = "0.0.0-next-b02b3d1-20230710";
|
49
49
|
Handsontable.languages = {
|
50
50
|
dictionaryKeys: _registry.dictionaryKeys,
|
51
51
|
getLanguageDictionary: _registry.getLanguageDictionary,
|
package/base.mjs
CHANGED
@@ -35,8 +35,8 @@ Handsontable.hooks = Hooks.getSingleton();
|
|
35
35
|
Handsontable.CellCoords = CellCoords;
|
36
36
|
Handsontable.CellRange = CellRange;
|
37
37
|
Handsontable.packageName = 'handsontable';
|
38
|
-
Handsontable.buildDate = "
|
39
|
-
Handsontable.version = "0.0.0-next-
|
38
|
+
Handsontable.buildDate = "10/07/2023 08:56:52";
|
39
|
+
Handsontable.version = "0.0.0-next-b02b3d1-20230710";
|
40
40
|
Handsontable.languages = {
|
41
41
|
dictionaryKeys: dictionaryKeys,
|
42
42
|
getLanguageDictionary: getLanguageDictionary,
|
@@ -0,0 +1,62 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
exports.__esModule = true;
|
4
|
+
exports.installFocusDetector = installFocusDetector;
|
5
|
+
/**
|
6
|
+
* Installs a focus detector module. The module appends two input elements into the DOM side by side.
|
7
|
+
* When the first input is focused, then it means that a user entered to the component using the TAB key
|
8
|
+
* from the element above. When the second input is focused, a user enters to the component from
|
9
|
+
* the element below the table. Each action, once detected, triggers the specific hook.
|
10
|
+
*
|
11
|
+
* @param {Handsontable} hot The Handsontable instance.
|
12
|
+
* @param {{ onFocusFromTop: Function, onFocusFromBottom: Function }} hooks An object with defined callbacks to call.
|
13
|
+
* @returns {{ activate: Function, deactivate: Function }}
|
14
|
+
*/
|
15
|
+
function installFocusDetector(hot) {
|
16
|
+
var hooks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
17
|
+
var rootDocument = hot.rootDocument;
|
18
|
+
var rootElement = hot.rootElement;
|
19
|
+
var inputTrapTop = createInputElement(rootDocument);
|
20
|
+
var inputTrapBottom = createInputElement(rootDocument);
|
21
|
+
inputTrapTop.addEventListener('focus', function () {
|
22
|
+
return hooks === null || hooks === void 0 ? void 0 : hooks.onFocusFromTop();
|
23
|
+
});
|
24
|
+
inputTrapBottom.addEventListener('focus', function () {
|
25
|
+
return hooks === null || hooks === void 0 ? void 0 : hooks.onFocusFromBottom();
|
26
|
+
});
|
27
|
+
rootElement.firstChild.before(inputTrapTop);
|
28
|
+
rootElement.lastChild.after(inputTrapBottom);
|
29
|
+
return {
|
30
|
+
/**
|
31
|
+
* Activates the detector by resetting the tabIndex of the input elements.
|
32
|
+
*/
|
33
|
+
activate: function activate() {
|
34
|
+
hot._registerTimeout(function () {
|
35
|
+
inputTrapTop.tabIndex = 0;
|
36
|
+
inputTrapBottom.tabIndex = 0;
|
37
|
+
}, 10);
|
38
|
+
},
|
39
|
+
/**
|
40
|
+
* Deactivates the detector by setting tabIndex to -1.
|
41
|
+
*/
|
42
|
+
deactivate: function deactivate() {
|
43
|
+
hot._registerTimeout(function () {
|
44
|
+
inputTrapTop.tabIndex = -1;
|
45
|
+
inputTrapBottom.tabIndex = -1;
|
46
|
+
}, 10);
|
47
|
+
}
|
48
|
+
};
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Creates a new HTML input element.
|
53
|
+
*
|
54
|
+
* @param {Document} rootDocument The owner document element.
|
55
|
+
* @returns {HTMLInputElement}
|
56
|
+
*/
|
57
|
+
function createInputElement(rootDocument) {
|
58
|
+
var input = rootDocument.createElement('input');
|
59
|
+
input.type = 'text';
|
60
|
+
input.classList.add('htFocusCatcher');
|
61
|
+
return input;
|
62
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
/**
|
2
|
+
* Installs a focus detector module. The module appends two input elements into the DOM side by side.
|
3
|
+
* When the first input is focused, then it means that a user entered to the component using the TAB key
|
4
|
+
* from the element above. When the second input is focused, a user enters to the component from
|
5
|
+
* the element below the table. Each action, once detected, triggers the specific hook.
|
6
|
+
*
|
7
|
+
* @param {Handsontable} hot The Handsontable instance.
|
8
|
+
* @param {{ onFocusFromTop: Function, onFocusFromBottom: Function }} hooks An object with defined callbacks to call.
|
9
|
+
* @returns {{ activate: Function, deactivate: Function }}
|
10
|
+
*/
|
11
|
+
export function installFocusDetector(hot) {
|
12
|
+
var hooks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
13
|
+
var rootDocument = hot.rootDocument;
|
14
|
+
var rootElement = hot.rootElement;
|
15
|
+
var inputTrapTop = createInputElement(rootDocument);
|
16
|
+
var inputTrapBottom = createInputElement(rootDocument);
|
17
|
+
inputTrapTop.addEventListener('focus', function () {
|
18
|
+
return hooks === null || hooks === void 0 ? void 0 : hooks.onFocusFromTop();
|
19
|
+
});
|
20
|
+
inputTrapBottom.addEventListener('focus', function () {
|
21
|
+
return hooks === null || hooks === void 0 ? void 0 : hooks.onFocusFromBottom();
|
22
|
+
});
|
23
|
+
rootElement.firstChild.before(inputTrapTop);
|
24
|
+
rootElement.lastChild.after(inputTrapBottom);
|
25
|
+
return {
|
26
|
+
/**
|
27
|
+
* Activates the detector by resetting the tabIndex of the input elements.
|
28
|
+
*/
|
29
|
+
activate: function activate() {
|
30
|
+
hot._registerTimeout(function () {
|
31
|
+
inputTrapTop.tabIndex = 0;
|
32
|
+
inputTrapBottom.tabIndex = 0;
|
33
|
+
}, 10);
|
34
|
+
},
|
35
|
+
/**
|
36
|
+
* Deactivates the detector by setting tabIndex to -1.
|
37
|
+
*/
|
38
|
+
deactivate: function deactivate() {
|
39
|
+
hot._registerTimeout(function () {
|
40
|
+
inputTrapTop.tabIndex = -1;
|
41
|
+
inputTrapBottom.tabIndex = -1;
|
42
|
+
}, 10);
|
43
|
+
}
|
44
|
+
};
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Creates a new HTML input element.
|
49
|
+
*
|
50
|
+
* @param {Document} rootDocument The owner document element.
|
51
|
+
* @returns {HTMLInputElement}
|
52
|
+
*/
|
53
|
+
function createInputElement(rootDocument) {
|
54
|
+
var input = rootDocument.createElement('input');
|
55
|
+
input.type = 'text';
|
56
|
+
input.classList.add('htFocusCatcher');
|
57
|
+
return input;
|
58
|
+
}
|
@@ -0,0 +1,133 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
exports.__esModule = true;
|
4
|
+
exports.installFocusCatcher = installFocusCatcher;
|
5
|
+
var _shortcutContexts = require("../../shortcutContexts");
|
6
|
+
var _focusDetector = require("./focusDetector");
|
7
|
+
/**
|
8
|
+
* Installs a focus catcher module. The module observes when the table is focused and depending on
|
9
|
+
* from the which side it was focused on it selects a specified cell or releases the TAB navigation
|
10
|
+
* to the browser.
|
11
|
+
*
|
12
|
+
* @param {Core} hot The Handsontable instance.
|
13
|
+
*/
|
14
|
+
function installFocusCatcher(hot) {
|
15
|
+
var recentlyAddedFocusCoords;
|
16
|
+
var _installFocusDetector = (0, _focusDetector.installFocusDetector)(hot, {
|
17
|
+
onFocusFromTop: function onFocusFromTop() {
|
18
|
+
var _recentlyAddedFocusCo;
|
19
|
+
var mostTopStartCoords = (_recentlyAddedFocusCo = recentlyAddedFocusCoords) !== null && _recentlyAddedFocusCo !== void 0 ? _recentlyAddedFocusCo : getMostTopStartPosition(hot);
|
20
|
+
if (mostTopStartCoords) {
|
21
|
+
hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
|
22
|
+
hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
|
23
|
+
}
|
24
|
+
hot.listen();
|
25
|
+
},
|
26
|
+
onFocusFromBottom: function onFocusFromBottom() {
|
27
|
+
var _recentlyAddedFocusCo2;
|
28
|
+
var mostBottomEndCoords = (_recentlyAddedFocusCo2 = recentlyAddedFocusCoords) !== null && _recentlyAddedFocusCo2 !== void 0 ? _recentlyAddedFocusCo2 : getMostBottomEndPosition(hot);
|
29
|
+
if (mostBottomEndCoords) {
|
30
|
+
hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
|
31
|
+
hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
|
32
|
+
}
|
33
|
+
hot.listen();
|
34
|
+
}
|
35
|
+
}),
|
36
|
+
activate = _installFocusDetector.activate,
|
37
|
+
deactivate = _installFocusDetector.deactivate;
|
38
|
+
hot.addHook('afterListen', function () {
|
39
|
+
return deactivate();
|
40
|
+
});
|
41
|
+
hot.addHook('afterUnlisten', function () {
|
42
|
+
return activate();
|
43
|
+
});
|
44
|
+
hot.addHook('afterSelection', function () {
|
45
|
+
var _hot$getSelectedRange;
|
46
|
+
recentlyAddedFocusCoords = (_hot$getSelectedRange = hot.getSelectedRangeLast()) === null || _hot$getSelectedRange === void 0 ? void 0 : _hot$getSelectedRange.highlight;
|
47
|
+
});
|
48
|
+
hot.getShortcutManager().getContext('grid').addShortcut({
|
49
|
+
keys: [['Tab'], ['Shift', 'Tab']],
|
50
|
+
callback: function callback(event) {
|
51
|
+
var _hot$getSelectedRange2;
|
52
|
+
var _hot$getSettings = hot.getSettings(),
|
53
|
+
disableTabNavigation = _hot$getSettings.disableTabNavigation,
|
54
|
+
autoWrapRow = _hot$getSettings.autoWrapRow;
|
55
|
+
if (disableTabNavigation) {
|
56
|
+
hot.deselectCell();
|
57
|
+
hot.unlisten();
|
58
|
+
return false;
|
59
|
+
}
|
60
|
+
var isSelected = hot.selection.isSelected();
|
61
|
+
var highlight = (_hot$getSelectedRange2 = hot.getSelectedRangeLast()) === null || _hot$getSelectedRange2 === void 0 ? void 0 : _hot$getSelectedRange2.highlight;
|
62
|
+
var mostTopStartCoords = getMostTopStartPosition(hot);
|
63
|
+
var mostBottomEndCoords = getMostBottomEndPosition(hot);
|
64
|
+
|
65
|
+
// For disabled `autoWrapRow` option set the row to the same position as the currently selected row.
|
66
|
+
if (!autoWrapRow) {
|
67
|
+
mostTopStartCoords.row = highlight.row;
|
68
|
+
mostBottomEndCoords.row = highlight.row;
|
69
|
+
}
|
70
|
+
if (event.shiftKey && (!isSelected || highlight.isEqual(mostTopStartCoords)) || !event.shiftKey && (!isSelected || highlight.isEqual(mostBottomEndCoords))) {
|
71
|
+
hot.deselectCell();
|
72
|
+
hot.unlisten();
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
return true;
|
76
|
+
},
|
77
|
+
runOnlyIf: function runOnlyIf() {
|
78
|
+
return !hot.getSettings().minSpareCols;
|
79
|
+
},
|
80
|
+
preventDefault: false,
|
81
|
+
stopPropagation: false,
|
82
|
+
position: 'before',
|
83
|
+
relativeToGroup: _shortcutContexts.GRID_GROUP,
|
84
|
+
group: 'focusCatcher'
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
|
90
|
+
*
|
91
|
+
* @param {Core} hot The Handsontable instance.
|
92
|
+
* @returns {CellCoords|null}
|
93
|
+
*/
|
94
|
+
function getMostTopStartPosition(hot) {
|
95
|
+
var rowIndexMapper = hot.rowIndexMapper,
|
96
|
+
columnIndexMapper = hot.columnIndexMapper;
|
97
|
+
var _hot$getSettings2 = hot.getSettings(),
|
98
|
+
navigableHeaders = _hot$getSettings2.navigableHeaders;
|
99
|
+
var topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
|
100
|
+
var startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
|
101
|
+
topRow = topRow === 0 ? rowIndexMapper.getVisualFromRenderableIndex(topRow) : topRow;
|
102
|
+
startColumn = startColumn === 0 ? columnIndexMapper.getVisualFromRenderableIndex(startColumn) : startColumn;
|
103
|
+
if (topRow === null || startColumn === null) {
|
104
|
+
return null;
|
105
|
+
}
|
106
|
+
return hot._createCellCoords(topRow, startColumn);
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
* Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
|
111
|
+
*
|
112
|
+
* @param {Core} hot The Handsontable instance.
|
113
|
+
* @returns {CellCoords|null}
|
114
|
+
*/
|
115
|
+
function getMostBottomEndPosition(hot) {
|
116
|
+
var _rowIndexMapper$getVi, _columnIndexMapper$ge;
|
117
|
+
var rowIndexMapper = hot.rowIndexMapper,
|
118
|
+
columnIndexMapper = hot.columnIndexMapper;
|
119
|
+
var _hot$getSettings3 = hot.getSettings(),
|
120
|
+
navigableHeaders = _hot$getSettings3.navigableHeaders;
|
121
|
+
var bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
|
122
|
+
var endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
|
123
|
+
if (bottomRow < 0) {
|
124
|
+
bottomRow = navigableHeaders && hot.countColHeaders() > 0 ? -1 : null;
|
125
|
+
}
|
126
|
+
if (endColumn < 0) {
|
127
|
+
endColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -1 : null;
|
128
|
+
}
|
129
|
+
if (bottomRow === null || endColumn === null) {
|
130
|
+
return null;
|
131
|
+
}
|
132
|
+
return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
|
133
|
+
}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
import { GRID_GROUP } from "../../shortcutContexts/index.mjs";
|
2
|
+
import { installFocusDetector } from "./focusDetector.mjs";
|
3
|
+
/**
|
4
|
+
* Installs a focus catcher module. The module observes when the table is focused and depending on
|
5
|
+
* from the which side it was focused on it selects a specified cell or releases the TAB navigation
|
6
|
+
* to the browser.
|
7
|
+
*
|
8
|
+
* @param {Core} hot The Handsontable instance.
|
9
|
+
*/
|
10
|
+
export function installFocusCatcher(hot) {
|
11
|
+
var recentlyAddedFocusCoords;
|
12
|
+
var _installFocusDetector = installFocusDetector(hot, {
|
13
|
+
onFocusFromTop: function onFocusFromTop() {
|
14
|
+
var _recentlyAddedFocusCo;
|
15
|
+
var mostTopStartCoords = (_recentlyAddedFocusCo = recentlyAddedFocusCoords) !== null && _recentlyAddedFocusCo !== void 0 ? _recentlyAddedFocusCo : getMostTopStartPosition(hot);
|
16
|
+
if (mostTopStartCoords) {
|
17
|
+
hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
|
18
|
+
hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
|
19
|
+
}
|
20
|
+
hot.listen();
|
21
|
+
},
|
22
|
+
onFocusFromBottom: function onFocusFromBottom() {
|
23
|
+
var _recentlyAddedFocusCo2;
|
24
|
+
var mostBottomEndCoords = (_recentlyAddedFocusCo2 = recentlyAddedFocusCoords) !== null && _recentlyAddedFocusCo2 !== void 0 ? _recentlyAddedFocusCo2 : getMostBottomEndPosition(hot);
|
25
|
+
if (mostBottomEndCoords) {
|
26
|
+
hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
|
27
|
+
hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
|
28
|
+
}
|
29
|
+
hot.listen();
|
30
|
+
}
|
31
|
+
}),
|
32
|
+
activate = _installFocusDetector.activate,
|
33
|
+
deactivate = _installFocusDetector.deactivate;
|
34
|
+
hot.addHook('afterListen', function () {
|
35
|
+
return deactivate();
|
36
|
+
});
|
37
|
+
hot.addHook('afterUnlisten', function () {
|
38
|
+
return activate();
|
39
|
+
});
|
40
|
+
hot.addHook('afterSelection', function () {
|
41
|
+
var _hot$getSelectedRange;
|
42
|
+
recentlyAddedFocusCoords = (_hot$getSelectedRange = hot.getSelectedRangeLast()) === null || _hot$getSelectedRange === void 0 ? void 0 : _hot$getSelectedRange.highlight;
|
43
|
+
});
|
44
|
+
hot.getShortcutManager().getContext('grid').addShortcut({
|
45
|
+
keys: [['Tab'], ['Shift', 'Tab']],
|
46
|
+
callback: function callback(event) {
|
47
|
+
var _hot$getSelectedRange2;
|
48
|
+
var _hot$getSettings = hot.getSettings(),
|
49
|
+
disableTabNavigation = _hot$getSettings.disableTabNavigation,
|
50
|
+
autoWrapRow = _hot$getSettings.autoWrapRow;
|
51
|
+
if (disableTabNavigation) {
|
52
|
+
hot.deselectCell();
|
53
|
+
hot.unlisten();
|
54
|
+
return false;
|
55
|
+
}
|
56
|
+
var isSelected = hot.selection.isSelected();
|
57
|
+
var highlight = (_hot$getSelectedRange2 = hot.getSelectedRangeLast()) === null || _hot$getSelectedRange2 === void 0 ? void 0 : _hot$getSelectedRange2.highlight;
|
58
|
+
var mostTopStartCoords = getMostTopStartPosition(hot);
|
59
|
+
var mostBottomEndCoords = getMostBottomEndPosition(hot);
|
60
|
+
|
61
|
+
// For disabled `autoWrapRow` option set the row to the same position as the currently selected row.
|
62
|
+
if (!autoWrapRow) {
|
63
|
+
mostTopStartCoords.row = highlight.row;
|
64
|
+
mostBottomEndCoords.row = highlight.row;
|
65
|
+
}
|
66
|
+
if (event.shiftKey && (!isSelected || highlight.isEqual(mostTopStartCoords)) || !event.shiftKey && (!isSelected || highlight.isEqual(mostBottomEndCoords))) {
|
67
|
+
hot.deselectCell();
|
68
|
+
hot.unlisten();
|
69
|
+
return false;
|
70
|
+
}
|
71
|
+
return true;
|
72
|
+
},
|
73
|
+
runOnlyIf: function runOnlyIf() {
|
74
|
+
return !hot.getSettings().minSpareCols;
|
75
|
+
},
|
76
|
+
preventDefault: false,
|
77
|
+
stopPropagation: false,
|
78
|
+
position: 'before',
|
79
|
+
relativeToGroup: GRID_GROUP,
|
80
|
+
group: 'focusCatcher'
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
|
86
|
+
*
|
87
|
+
* @param {Core} hot The Handsontable instance.
|
88
|
+
* @returns {CellCoords|null}
|
89
|
+
*/
|
90
|
+
function getMostTopStartPosition(hot) {
|
91
|
+
var rowIndexMapper = hot.rowIndexMapper,
|
92
|
+
columnIndexMapper = hot.columnIndexMapper;
|
93
|
+
var _hot$getSettings2 = hot.getSettings(),
|
94
|
+
navigableHeaders = _hot$getSettings2.navigableHeaders;
|
95
|
+
var topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
|
96
|
+
var startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
|
97
|
+
topRow = topRow === 0 ? rowIndexMapper.getVisualFromRenderableIndex(topRow) : topRow;
|
98
|
+
startColumn = startColumn === 0 ? columnIndexMapper.getVisualFromRenderableIndex(startColumn) : startColumn;
|
99
|
+
if (topRow === null || startColumn === null) {
|
100
|
+
return null;
|
101
|
+
}
|
102
|
+
return hot._createCellCoords(topRow, startColumn);
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
|
107
|
+
*
|
108
|
+
* @param {Core} hot The Handsontable instance.
|
109
|
+
* @returns {CellCoords|null}
|
110
|
+
*/
|
111
|
+
function getMostBottomEndPosition(hot) {
|
112
|
+
var _rowIndexMapper$getVi, _columnIndexMapper$ge;
|
113
|
+
var rowIndexMapper = hot.rowIndexMapper,
|
114
|
+
columnIndexMapper = hot.columnIndexMapper;
|
115
|
+
var _hot$getSettings3 = hot.getSettings(),
|
116
|
+
navigableHeaders = _hot$getSettings3.navigableHeaders;
|
117
|
+
var bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
|
118
|
+
var endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
|
119
|
+
if (bottomRow < 0) {
|
120
|
+
bottomRow = navigableHeaders && hot.countColHeaders() > 0 ? -1 : null;
|
121
|
+
}
|
122
|
+
if (endColumn < 0) {
|
123
|
+
endColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -1 : null;
|
124
|
+
}
|
125
|
+
if (bottomRow === null || endColumn === null) {
|
126
|
+
return null;
|
127
|
+
}
|
128
|
+
return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
|
129
|
+
}
|
package/core/index.js
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
require("core-js/modules/es.object.to-string.js");
|
4
|
+
require("core-js/modules/web.dom-collections.for-each.js");
|
5
|
+
require("core-js/modules/es.object.keys.js");
|
6
|
+
exports.__esModule = true;
|
7
|
+
var _focusCatcher = require("./focusCatcher");
|
8
|
+
Object.keys(_focusCatcher).forEach(function (key) {
|
9
|
+
if (key === "default" || key === "__esModule") return;
|
10
|
+
if (key in exports && exports[key] === _focusCatcher[key]) return;
|
11
|
+
exports[key] = _focusCatcher[key];
|
12
|
+
});
|
package/core/index.mjs
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from "./focusCatcher/index.mjs";
|
package/core.d.ts
CHANGED
@@ -131,7 +131,6 @@ export default class Core {
|
|
131
131
|
rowIndexMapper: IndexMapper;
|
132
132
|
runHooks(key: keyof Events, p1?: any, p2?: any, p3?: any, p4?: any, p5?: any, p6?: any): any;
|
133
133
|
scrollViewportTo(row?: number, column?: number, snapToBottom?: boolean, snapToRight?: boolean, considerHiddenIndexes?: boolean): boolean;
|
134
|
-
scrollToFocusedCell(callback?: () => void): void;
|
135
134
|
selectAll(includeRowHeaders?: boolean, includeColumnHeaders?: boolean, focusPosition?: { row?: number, col?: number }): void;
|
136
135
|
selectCell(row: number, col: number, endRow?: number, endCol?: number, scrollToCell?: boolean, changeListener?: boolean): boolean;
|
137
136
|
selectCellByProp(row: number, prop: string, endRow?: number, endProp?: string, scrollToCell?: boolean): boolean;
|
package/core.js
CHANGED
@@ -8,10 +8,11 @@ require("core-js/modules/es.function.name.js");
|
|
8
8
|
exports.__esModule = true;
|
9
9
|
exports.default = Core;
|
10
10
|
require("core-js/modules/es.array.iterator.js");
|
11
|
+
require("core-js/modules/es.map.js");
|
11
12
|
require("core-js/modules/es.object.to-string.js");
|
12
|
-
require("core-js/modules/es.set.js");
|
13
13
|
require("core-js/modules/es.string.iterator.js");
|
14
14
|
require("core-js/modules/web.dom-collections.iterator.js");
|
15
|
+
require("core-js/modules/es.set.js");
|
15
16
|
require("core-js/modules/es.array.includes.js");
|
16
17
|
require("core-js/modules/es.array.concat.js");
|
17
18
|
require("core-js/modules/es.array.sort.js");
|
@@ -24,10 +25,10 @@ require("core-js/modules/es.array.map.js");
|
|
24
25
|
require("core-js/modules/es.regexp.exec.js");
|
25
26
|
require("core-js/modules/es.string.replace.js");
|
26
27
|
require("core-js/modules/es.array.filter.js");
|
28
|
+
require("core-js/modules/web.dom-collections.for-each.js");
|
27
29
|
require("core-js/modules/es.array.from.js");
|
28
30
|
require("core-js/modules/es.array.index-of.js");
|
29
31
|
require("core-js/modules/es.array.reverse.js");
|
30
|
-
require("core-js/modules/web.dom-collections.for-each.js");
|
31
32
|
require("core-js/modules/web.timers.js");
|
32
33
|
require("core-js/modules/web.immediate.js");
|
33
34
|
var _element = require("./helpers/dom/element");
|
@@ -56,6 +57,7 @@ var _registry5 = require("./i18n/registry");
|
|
56
57
|
var _utils = require("./i18n/utils");
|
57
58
|
var _selection = require("./selection");
|
58
59
|
var _dataMap = require("./dataMap");
|
60
|
+
var _index3 = require("./core/index");
|
59
61
|
var _uniqueMap = require("./utils/dataStructures/uniqueMap");
|
60
62
|
var _shortcuts = require("./shortcuts");
|
61
63
|
var _shortcutContexts = require("./shortcutContexts");
|
@@ -73,6 +75,15 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToAr
|
|
73
75
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
74
76
|
var activeGuid = null;
|
75
77
|
|
78
|
+
/**
|
79
|
+
* Keeps the collection of the all Handsontable instances created on the same page. The
|
80
|
+
* list is then used to trigger the "afterUnlisten" hook when the "listen()" method was
|
81
|
+
* called on another instance.
|
82
|
+
*
|
83
|
+
* @type {Map<string, Core>}
|
84
|
+
*/
|
85
|
+
var foreignHotInstances = new Map();
|
86
|
+
|
76
87
|
/**
|
77
88
|
* A set of deprecated feature names.
|
78
89
|
*
|
@@ -250,6 +261,8 @@ function Core(rootElement, userSettings) {
|
|
250
261
|
}
|
251
262
|
this.guid = "ht_".concat((0, _string.randomString)()); // this is the namespace for global events
|
252
263
|
|
264
|
+
foreignHotInstances.set(this.guid, this);
|
265
|
+
|
253
266
|
/**
|
254
267
|
* Instance of index mapper which is responsible for managing the column indexes.
|
255
268
|
*
|
@@ -1106,6 +1119,9 @@ function Core(rootElement, userSettings) {
|
|
1106
1119
|
this.updateSettings(tableMeta, true);
|
1107
1120
|
this.view = new _tableView.default(this);
|
1108
1121
|
editorManager = _editorManager.default.getInstance(instance, tableMeta, selection);
|
1122
|
+
if ((0, _rootInstance.isRootInstance)(this)) {
|
1123
|
+
(0, _index3.installFocusCatcher)(instance);
|
1124
|
+
}
|
1109
1125
|
instance.runHooks('init');
|
1110
1126
|
this.forceFullRender = true; // used when data was changed
|
1111
1127
|
this.view.render();
|
@@ -1522,6 +1538,11 @@ function Core(rootElement, userSettings) {
|
|
1522
1538
|
*/
|
1523
1539
|
this.listen = function () {
|
1524
1540
|
if (instance && !instance.isListening()) {
|
1541
|
+
foreignHotInstances.forEach(function (foreignHot) {
|
1542
|
+
if (instance !== foreignHot) {
|
1543
|
+
foreignHot.unlisten();
|
1544
|
+
}
|
1545
|
+
});
|
1525
1546
|
activeGuid = instance.guid;
|
1526
1547
|
instance.runHooks('afterListen');
|
1527
1548
|
}
|
@@ -4124,35 +4145,6 @@ function Core(rootElement, userSettings) {
|
|
4124
4145
|
return false;
|
4125
4146
|
};
|
4126
4147
|
|
4127
|
-
/**
|
4128
|
-
* Scrolls the viewport to coordinates specified by the currently focused cell.
|
4129
|
-
*
|
4130
|
-
* @since 14.0.0
|
4131
|
-
* @memberof Core#
|
4132
|
-
* @function scrollToFocusedCell
|
4133
|
-
* @param {Function} callback The callback function to call after the viewport is scrolled.
|
4134
|
-
*/
|
4135
|
-
this.scrollToFocusedCell = function () {
|
4136
|
-
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
|
4137
|
-
if (!this.selection.isSelected()) {
|
4138
|
-
return;
|
4139
|
-
}
|
4140
|
-
this.addHookOnce('afterScroll', callback);
|
4141
|
-
var _this$getSelectedRang = this.getSelectedRangeLast(),
|
4142
|
-
highlight = _this$getSelectedRang.highlight;
|
4143
|
-
var renderableRowIndex = this.rowIndexMapper.getRenderableFromVisualIndex(highlight.row);
|
4144
|
-
var renderableColumnIndex = this.columnIndexMapper.getRenderableFromVisualIndex(highlight.col);
|
4145
|
-
var isScrolled = this.view.scrollViewport(this._createCellCoords(renderableRowIndex, renderableColumnIndex));
|
4146
|
-
if (isScrolled) {
|
4147
|
-
this.view.render();
|
4148
|
-
} else {
|
4149
|
-
this.removeHook('afterScroll', callback);
|
4150
|
-
this._registerImmediate(function () {
|
4151
|
-
return callback();
|
4152
|
-
});
|
4153
|
-
}
|
4154
|
-
};
|
4155
|
-
|
4156
4148
|
/**
|
4157
4149
|
* Removes the table from the DOM and destroys the instance of the Handsontable.
|
4158
4150
|
*
|
@@ -4173,6 +4165,7 @@ function Core(rootElement, userSettings) {
|
|
4173
4165
|
dataSource = null;
|
4174
4166
|
this.getShortcutManager().destroy();
|
4175
4167
|
metaManager.clearCache();
|
4168
|
+
foreignHotInstances.delete(this.guid);
|
4176
4169
|
if ((0, _rootInstance.isRootInstance)(instance)) {
|
4177
4170
|
var licenseInfo = this.rootDocument.querySelector('.hot-display-license-info');
|
4178
4171
|
if (licenseInfo) {
|
package/core.mjs
CHANGED
@@ -10,10 +10,11 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
|
|
10
10
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
11
11
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
12
12
|
import "core-js/modules/es.array.iterator.js";
|
13
|
+
import "core-js/modules/es.map.js";
|
13
14
|
import "core-js/modules/es.object.to-string.js";
|
14
|
-
import "core-js/modules/es.set.js";
|
15
15
|
import "core-js/modules/es.string.iterator.js";
|
16
16
|
import "core-js/modules/web.dom-collections.iterator.js";
|
17
|
+
import "core-js/modules/es.set.js";
|
17
18
|
import "core-js/modules/es.array.includes.js";
|
18
19
|
import "core-js/modules/es.array.concat.js";
|
19
20
|
import "core-js/modules/es.array.sort.js";
|
@@ -26,10 +27,10 @@ import "core-js/modules/es.array.map.js";
|
|
26
27
|
import "core-js/modules/es.regexp.exec.js";
|
27
28
|
import "core-js/modules/es.string.replace.js";
|
28
29
|
import "core-js/modules/es.array.filter.js";
|
30
|
+
import "core-js/modules/web.dom-collections.for-each.js";
|
29
31
|
import "core-js/modules/es.array.from.js";
|
30
32
|
import "core-js/modules/es.array.index-of.js";
|
31
33
|
import "core-js/modules/es.array.reverse.js";
|
32
|
-
import "core-js/modules/web.dom-collections.for-each.js";
|
33
34
|
import "core-js/modules/web.timers.js";
|
34
35
|
import "core-js/modules/web.immediate.js";
|
35
36
|
import "core-js/modules/es.symbol.js";
|
@@ -63,11 +64,21 @@ import { hasLanguageDictionary, getValidLanguageCode, getTranslatedPhrase } from
|
|
63
64
|
import { warnUserAboutLanguageRegistration, normalizeLanguageCode } from "./i18n/utils.mjs";
|
64
65
|
import { Selection } from "./selection/index.mjs";
|
65
66
|
import { MetaManager, DynamicCellMetaMod, ExtendMetaPropertiesMod, replaceData } from "./dataMap/index.mjs";
|
67
|
+
import { installFocusCatcher } from "./core/index.mjs";
|
66
68
|
import { createUniqueMap } from "./utils/dataStructures/uniqueMap.mjs";
|
67
69
|
import { createShortcutManager } from "./shortcuts/index.mjs";
|
68
70
|
import { registerAllShortcutContexts } from "./shortcutContexts/index.mjs";
|
69
71
|
var activeGuid = null;
|
70
72
|
|
73
|
+
/**
|
74
|
+
* Keeps the collection of the all Handsontable instances created on the same page. The
|
75
|
+
* list is then used to trigger the "afterUnlisten" hook when the "listen()" method was
|
76
|
+
* called on another instance.
|
77
|
+
*
|
78
|
+
* @type {Map<string, Core>}
|
79
|
+
*/
|
80
|
+
var foreignHotInstances = new Map();
|
81
|
+
|
71
82
|
/**
|
72
83
|
* A set of deprecated feature names.
|
73
84
|
*
|
@@ -245,6 +256,8 @@ export default function Core(rootElement, userSettings) {
|
|
245
256
|
}
|
246
257
|
this.guid = "ht_".concat(randomString()); // this is the namespace for global events
|
247
258
|
|
259
|
+
foreignHotInstances.set(this.guid, this);
|
260
|
+
|
248
261
|
/**
|
249
262
|
* Instance of index mapper which is responsible for managing the column indexes.
|
250
263
|
*
|
@@ -1101,6 +1114,9 @@ export default function Core(rootElement, userSettings) {
|
|
1101
1114
|
this.updateSettings(tableMeta, true);
|
1102
1115
|
this.view = new TableView(this);
|
1103
1116
|
editorManager = EditorManager.getInstance(instance, tableMeta, selection);
|
1117
|
+
if (isRootInstance(this)) {
|
1118
|
+
installFocusCatcher(instance);
|
1119
|
+
}
|
1104
1120
|
instance.runHooks('init');
|
1105
1121
|
this.forceFullRender = true; // used when data was changed
|
1106
1122
|
this.view.render();
|
@@ -1517,6 +1533,11 @@ export default function Core(rootElement, userSettings) {
|
|
1517
1533
|
*/
|
1518
1534
|
this.listen = function () {
|
1519
1535
|
if (instance && !instance.isListening()) {
|
1536
|
+
foreignHotInstances.forEach(function (foreignHot) {
|
1537
|
+
if (instance !== foreignHot) {
|
1538
|
+
foreignHot.unlisten();
|
1539
|
+
}
|
1540
|
+
});
|
1520
1541
|
activeGuid = instance.guid;
|
1521
1542
|
instance.runHooks('afterListen');
|
1522
1543
|
}
|
@@ -4119,35 +4140,6 @@ export default function Core(rootElement, userSettings) {
|
|
4119
4140
|
return false;
|
4120
4141
|
};
|
4121
4142
|
|
4122
|
-
/**
|
4123
|
-
* Scrolls the viewport to coordinates specified by the currently focused cell.
|
4124
|
-
*
|
4125
|
-
* @since 14.0.0
|
4126
|
-
* @memberof Core#
|
4127
|
-
* @function scrollToFocusedCell
|
4128
|
-
* @param {Function} callback The callback function to call after the viewport is scrolled.
|
4129
|
-
*/
|
4130
|
-
this.scrollToFocusedCell = function () {
|
4131
|
-
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
|
4132
|
-
if (!this.selection.isSelected()) {
|
4133
|
-
return;
|
4134
|
-
}
|
4135
|
-
this.addHookOnce('afterScroll', callback);
|
4136
|
-
var _this$getSelectedRang = this.getSelectedRangeLast(),
|
4137
|
-
highlight = _this$getSelectedRang.highlight;
|
4138
|
-
var renderableRowIndex = this.rowIndexMapper.getRenderableFromVisualIndex(highlight.row);
|
4139
|
-
var renderableColumnIndex = this.columnIndexMapper.getRenderableFromVisualIndex(highlight.col);
|
4140
|
-
var isScrolled = this.view.scrollViewport(this._createCellCoords(renderableRowIndex, renderableColumnIndex));
|
4141
|
-
if (isScrolled) {
|
4142
|
-
this.view.render();
|
4143
|
-
} else {
|
4144
|
-
this.removeHook('afterScroll', callback);
|
4145
|
-
this._registerImmediate(function () {
|
4146
|
-
return callback();
|
4147
|
-
});
|
4148
|
-
}
|
4149
|
-
};
|
4150
|
-
|
4151
4143
|
/**
|
4152
4144
|
* Removes the table from the DOM and destroys the instance of the Handsontable.
|
4153
4145
|
*
|
@@ -4168,6 +4160,7 @@ export default function Core(rootElement, userSettings) {
|
|
4168
4160
|
dataSource = null;
|
4169
4161
|
this.getShortcutManager().destroy();
|
4170
4162
|
metaManager.clearCache();
|
4163
|
+
foreignHotInstances.delete(this.guid);
|
4171
4164
|
if (isRootInstance(instance)) {
|
4172
4165
|
var licenseInfo = this.rootDocument.querySelector('.hot-display-license-info');
|
4173
4166
|
if (licenseInfo) {
|