123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- import { CellCoords } from './3rdparty/walkontable/src';
- import { KEY_CODES, isMetaKey, isCtrlKey } from './helpers/unicode';
- import { stopPropagation, stopImmediatePropagation, isImmediatePropagationStopped } from './helpers/dom/event';
- import { getEditorInstance } from './editors';
- import EventManager from './eventManager';
- import { EditorState } from './editors/_baseEditor';
- function EditorManager(instance, priv, selection) {
- var _this = this,
- destroyed = false,
- eventManager,
- activeEditor;
- eventManager = new EventManager(instance);
- function moveSelectionAfterEnter(shiftKey) {
- selection.setSelectedHeaders(false, false, false);
- var enterMoves = typeof priv.settings.enterMoves === 'function' ? priv.settings.enterMoves(event) : priv.settings.enterMoves;
- if (shiftKey) {
- // move selection up
- selection.transformStart(-enterMoves.row, -enterMoves.col);
- } else {
- // move selection down (add a new row if needed)
- selection.transformStart(enterMoves.row, enterMoves.col, true);
- }
- }
- function moveSelectionUp(shiftKey) {
- if (shiftKey) {
- if (selection.selectedHeader.cols) {
- selection.setSelectedHeaders(selection.selectedHeader.rows, false, false);
- }
- selection.transformEnd(-1, 0);
- } else {
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(-1, 0);
- }
- }
- function moveSelectionDown(shiftKey) {
- if (shiftKey) {
- // expanding selection down with shift
- selection.transformEnd(1, 0);
- } else {
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(1, 0);
- }
- }
- function moveSelectionRight(shiftKey) {
- if (shiftKey) {
- selection.transformEnd(0, 1);
- } else {
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(0, 1);
- }
- }
- function moveSelectionLeft(shiftKey) {
- if (shiftKey) {
- if (selection.selectedHeader.rows) {
- selection.setSelectedHeaders(false, selection.selectedHeader.cols, false);
- }
- selection.transformEnd(0, -1);
- } else {
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(0, -1);
- }
- }
- function onKeyDown(event) {
- var ctrlDown, rangeModifier;
- if (!instance.isListening()) {
- return;
- }
- instance.runHooks('beforeKeyDown', event);
- if (destroyed) {
- return;
- }
- if (isImmediatePropagationStopped(event)) {
- return;
- }
- priv.lastKeyCode = event.keyCode;
- if (!selection.isSelected()) {
- return;
- }
- // catch CTRL but not right ALT (which in some systems triggers ALT+CTRL)
- ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey;
- if (activeEditor && !activeEditor.isWaiting()) {
- if (!isMetaKey(event.keyCode) && !isCtrlKey(event.keyCode) && !ctrlDown && !_this.isEditorOpened()) {
- _this.openEditor('', event);
- return;
- }
- }
- rangeModifier = event.shiftKey ? selection.setRangeEnd : selection.setRangeStart;
- switch (event.keyCode) {
- case KEY_CODES.A:
- if (!_this.isEditorOpened() && ctrlDown) {
- selection.selectAll();
- event.preventDefault();
- stopPropagation(event);
- }
- break;
- case KEY_CODES.ARROW_UP:
- if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
- _this.closeEditorAndSaveChanges(ctrlDown);
- }
- moveSelectionUp(event.shiftKey);
- event.preventDefault();
- stopPropagation(event);
- break;
- case KEY_CODES.ARROW_DOWN:
- if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
- _this.closeEditorAndSaveChanges(ctrlDown);
- }
- moveSelectionDown(event.shiftKey);
- event.preventDefault();
- stopPropagation(event);
- break;
- case KEY_CODES.ARROW_RIGHT:
- if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
- _this.closeEditorAndSaveChanges(ctrlDown);
- }
- moveSelectionRight(event.shiftKey);
- event.preventDefault();
- stopPropagation(event);
- break;
- case KEY_CODES.ARROW_LEFT:
- if (_this.isEditorOpened() && !activeEditor.isWaiting()) {
- _this.closeEditorAndSaveChanges(ctrlDown);
- }
- moveSelectionLeft(event.shiftKey);
- event.preventDefault();
- stopPropagation(event);
- break;
- case KEY_CODES.TAB:
- selection.setSelectedHeaders(false, false, false);
- var tabMoves = typeof priv.settings.tabMoves === 'function' ? priv.settings.tabMoves(event) : priv.settings.tabMoves;
- if (event.shiftKey) {
- // move selection left
- selection.transformStart(-tabMoves.row, -tabMoves.col);
- } else {
- // move selection right (add a new column if needed)
- selection.transformStart(tabMoves.row, tabMoves.col, true);
- }
- event.preventDefault();
- stopPropagation(event);
- break;
- case KEY_CODES.BACKSPACE:
- case KEY_CODES.DELETE:
- selection.empty(event);
- _this.prepareEditor();
- event.preventDefault();
- break;
- case KEY_CODES.F2:
- /* F2 */
- _this.openEditor(null, event);
- if (activeEditor) {
- activeEditor.enableFullEditMode();
- }
- event.preventDefault(); // prevent Opera from opening 'Go to Page dialog'
- break;
- case KEY_CODES.ENTER:
- /* return/enter */
- if (_this.isEditorOpened()) {
- if (activeEditor && activeEditor.state !== EditorState.WAITING) {
- _this.closeEditorAndSaveChanges(ctrlDown);
- }
- moveSelectionAfterEnter(event.shiftKey);
- } else if (instance.getSettings().enterBeginsEditing) {
- _this.openEditor(null, event);
- if (activeEditor) {
- activeEditor.enableFullEditMode();
- }
- } else {
- moveSelectionAfterEnter(event.shiftKey);
- }
- event.preventDefault(); // don't add newline to field
- stopImmediatePropagation(event); // required by HandsontableEditor
- break;
- case KEY_CODES.ESCAPE:
- if (_this.isEditorOpened()) {
- _this.closeEditorAndRestoreOriginalValue(ctrlDown);
- }
- event.preventDefault();
- break;
- case KEY_CODES.HOME:
- selection.setSelectedHeaders(false, false, false);
- if (event.ctrlKey || event.metaKey) {
- rangeModifier(new CellCoords(0, priv.selRange.from.col));
- } else {
- rangeModifier(new CellCoords(priv.selRange.from.row, 0));
- }
- event.preventDefault(); // don't scroll the window
- stopPropagation(event);
- break;
- case KEY_CODES.END:
- selection.setSelectedHeaders(false, false, false);
- if (event.ctrlKey || event.metaKey) {
- rangeModifier(new CellCoords(instance.countRows() - 1, priv.selRange.from.col));
- } else {
- rangeModifier(new CellCoords(priv.selRange.from.row, instance.countCols() - 1));
- }
- event.preventDefault(); // don't scroll the window
- stopPropagation(event);
- break;
- case KEY_CODES.PAGE_UP:
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(-instance.countVisibleRows(), 0);
- event.preventDefault(); // don't page up the window
- stopPropagation(event);
- break;
- case KEY_CODES.PAGE_DOWN:
- selection.setSelectedHeaders(false, false, false);
- selection.transformStart(instance.countVisibleRows(), 0);
- event.preventDefault(); // don't page down the window
- stopPropagation(event);
- break;
- default:
- break;
- }
- }
- function init() {
- instance.addHook('afterDocumentKeyDown', onKeyDown);
- eventManager.addEventListener(document.documentElement, 'keydown', function (event) {
- if (!destroyed) {
- instance.runHooks('afterDocumentKeyDown', event);
- }
- });
- function onDblClick(event, coords, elem) {
- // may be TD or TH
- if (elem.nodeName == 'TD') {
- _this.openEditor();
- if (activeEditor) {
- activeEditor.enableFullEditMode();
- }
- }
- }
- instance.view.wt.update('onCellDblClick', onDblClick);
- instance.addHook('afterDestroy', function () {
- destroyed = true;
- });
- }
- /**
- * Destroy current editor, if exists.
- *
- * @function destroyEditor
- * @memberof! Handsontable.EditorManager#
- * @param {Boolean} revertOriginal
- */
- this.destroyEditor = function (revertOriginal) {
- this.closeEditor(revertOriginal);
- };
- /**
- * Get active editor.
- *
- * @function getActiveEditor
- * @memberof! Handsontable.EditorManager#
- * @returns {*}
- */
- this.getActiveEditor = function () {
- return activeEditor;
- };
- /**
- * Prepare text input to be displayed at given grid cell.
- *
- * @function prepareEditor
- * @memberof! Handsontable.EditorManager#
- */
- this.prepareEditor = function () {
- var row, col, prop, td, originalValue, cellProperties, editorClass;
- if (activeEditor && activeEditor.isWaiting()) {
- this.closeEditor(false, false, function (dataSaved) {
- if (dataSaved) {
- _this.prepareEditor();
- }
- });
- return;
- }
- row = priv.selRange.highlight.row;
- col = priv.selRange.highlight.col;
- prop = instance.colToProp(col);
- td = instance.getCell(row, col);
- originalValue = instance.getSourceDataAtCell(instance.runHooks('modifyRow', row), col);
- cellProperties = instance.getCellMeta(row, col);
- editorClass = instance.getCellEditor(cellProperties);
- if (editorClass) {
- activeEditor = getEditorInstance(editorClass, instance);
- activeEditor.prepare(row, col, prop, td, originalValue, cellProperties);
- } else {
- activeEditor = void 0;
- }
- };
- /**
- * Check is editor is opened/showed.
- *
- * @function isEditorOpened
- * @memberof! Handsontable.EditorManager#
- * @returns {Boolean}
- */
- this.isEditorOpened = function () {
- return activeEditor && activeEditor.isOpened();
- };
- /**
- * Open editor with initial value.
- *
- * @function openEditor
- * @memberof! Handsontable.EditorManager#
- * @param {String} initialValue
- * @param {DOMEvent} event
- */
- this.openEditor = function (initialValue, event) {
- if (activeEditor && !activeEditor.cellProperties.readOnly) {
- activeEditor.beginEditing(initialValue, event);
- } else if (activeEditor && activeEditor.cellProperties.readOnly) {
- // move the selection after opening the editor with ENTER key
- if (event && event.keyCode === KEY_CODES.ENTER) {
- moveSelectionAfterEnter();
- }
- }
- };
- /**
- * Close editor, finish editing cell.
- *
- * @function closeEditor
- * @memberof! Handsontable.EditorManager#
- * @param {Boolean} restoreOriginalValue
- * @param {Boolean} [ctrlDown]
- * @param {Function} [callback]
- */
- this.closeEditor = function (restoreOriginalValue, ctrlDown, callback) {
- if (activeEditor) {
- activeEditor.finishEditing(restoreOriginalValue, ctrlDown, callback);
- } else if (callback) {
- callback(false);
- }
- };
- /**
- * Close editor and save changes.
- *
- * @function closeEditorAndSaveChanges
- * @memberof! Handsontable.EditorManager#
- * @param {Boolean} ctrlDown
- */
- this.closeEditorAndSaveChanges = function (ctrlDown) {
- return this.closeEditor(false, ctrlDown);
- };
- /**
- * Close editor and restore original value.
- *
- * @function closeEditorAndRestoreOriginalValue
- * @memberof! Handsontable.EditorManager#
- * @param {Boolean} ctrlDown
- */
- this.closeEditorAndRestoreOriginalValue = function (ctrlDown) {
- return this.closeEditor(true, ctrlDown);
- };
- init();
- }
- export default EditorManager;
|