@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
563 lines (562 loc) • 28.4 kB
JavaScript
import { keyDown, cut, paste, copy, clearCopy, performUndoRedo, initiateHyperlink, editHyperlink, renderInsertDlg, getRightIdx, getBottomOffset, keyUp } from '../common/index';
import { findDlg, gotoDlg, initiateFilterUI, getFilterRange, performAutoFill, focus, addNote, editNote } from '../common/index';
import { setCellFormat, textDecorationUpdate, getCellIndexes, findToolDlg, getRangeIndexes, hideShow, applyNumberFormatting, insertModel, getSwapRange, getRangeAddress, beginAction, isReadOnlyCells } from '../../workbook/common/index';
import { getColumn, isLocked as isCellLocked, exportDialog, getFormatFromType } from '../../workbook/index';
import { completeAction } from '../../spreadsheet/common/index';
import { setCell, getCell, skipHiddenIdx, selectionComplete, refreshRibbonIcons } from '../../workbook/index';
import { isNullOrUndefined, closest, select, getComponent, EventHandler } from '@syncfusion/ej2-base';
/**
* Represents keyboard shortcut support for Spreadsheet.
*/
var KeyboardShortcut = /** @class */ (function () {
/**
* Constructor for the Spreadsheet Keyboard Shortcut module.
*
* @param {Spreadsheet} parent - Specify the spreadsheet.
* @private
*/
function KeyboardShortcut(parent) {
this.parent = parent;
this.addEventListener();
}
KeyboardShortcut.prototype.addEventListener = function () {
this.parent.on(keyDown, this.keyDownHandler, this);
this.parent.on(keyUp, this.keyUpHandler, this);
};
KeyboardShortcut.prototype.removeEventListener = function () {
if (!this.parent.isDestroyed) {
this.parent.off(keyDown, this.keyDownHandler);
this.parent.off(keyUp, this.keyUpHandler);
}
};
KeyboardShortcut.prototype.isTrgtNotInput = function (e) {
var trgt = e.target;
return (!closest(trgt, '.e-filter-popup')
&& !closest(trgt, '.e-find-dlg') && !closest(trgt, '.e-hyperlink-dlg') &&
!closest(trgt, '.e-sheet-tab') && !closest(trgt, '.e-name-box') && !closest(trgt, '.e-link-dialog'));
};
KeyboardShortcut.prototype.ribbonShortCuts = function (e) {
if (this.parent.showRibbon && e.altKey && !e.ctrlKey && !e.shiftKey) {
var tabObj = getComponent(this.parent.element.querySelector('.e-ribbon .e-tab'), 'tab');
var tabIdx = void 0;
if (e.keyCode === 72) { /*alt + H =home*/
tabIdx = 1;
}
else if (e.keyCode === 78) { /*alt + N =insert */
tabIdx = 2;
}
else if (e.keyCode === 65) { /*alt + A =data */
tabIdx = 4;
}
else if (e.keyCode === 87) { /*alt + W =view*/
tabIdx = 5;
}
else if (e.keyCode === 77) { /*alt + M =formula */
tabIdx = 3;
}
else if (e.keyCode === 70) { /*alt + F =file */
e.preventDefault();
select('#' + this.parent.element.id + '_File', this.parent.element).click();
}
else if (e.keyCode === 18) { /** alt = active tab focus */
e.preventDefault();
var activeCell = getCellIndexes(this.parent.getActiveSheet().activeCell);
var args = { sheetIdx: this.parent.activeSheetIndex };
this.parent.notify(getFilterRange, args);
if (!(args.hasFilter && args.filterRange && args.filterRange[0] === activeCell[0] && args.filterRange[1] <= activeCell[1] &&
args.filterRange[3] >= activeCell[1])) {
var actEle = document.activeElement;
if (!actEle.classList.contains('e-spreadsheet-edit') && !actEle.classList.contains('e-sheet-rename') &&
actEle.id !== this.parent.element.id + "_name_box" && !closest(actEle, '.e-dropdown-btn') &&
!closest(actEle, '.e-split-btn') && !closest(actEle, '.e-popup-open')) {
var cell = this.parent.getCell(activeCell[0], activeCell[1]);
if (cell && cell.querySelector('.e-validation-list')) {
return;
}
if (closest(actEle, '.e-ribbon')) {
focus(this.parent.element);
return;
}
for (var i = 0; i <= this.parent.ribbonModule.ribbon.items.length; i++) {
if (i === this.parent.ribbonModule.ribbon.selectedTab) {
var focusEle = this.parent.element.querySelector('.e-toolbar-items').children[i + 2].children[0];
focusEle.setAttribute('tabindex', '0');
focus(focusEle);
return;
}
}
}
}
}
if (tabIdx) {
if (!tabObj.items[tabIdx].disabled && !tabObj.items[tabIdx].cssClass.includes('e-hide')) {
e.preventDefault();
tabObj.select(tabIdx, Object.assign(e, { isShortcut: true }));
}
else {
focus(this.parent.element);
}
}
}
};
KeyboardShortcut.prototype.keyUpHandler = function (e) {
if (e.keyCode === 37 || e.keyCode === 39) {
var activeEle = document.activeElement;
if (activeEle.classList.contains('e-colorpicker-wrapper') || activeEle.classList.contains('e-split-btn-wrapper')) {
var colorPickerBtn = activeEle.querySelector('.e-split-btn');
if (colorPickerBtn) {
focus(colorPickerBtn);
}
}
}
else if (e.keyCode === 13) {
var target_1 = e.target;
if (target_1.classList.contains('e-scroll-nav')) {
var focusScroll_1 = function () {
if (!target_1.getAttribute('tabindex')) {
target_1.setAttribute('tabindex', '0');
focus(target_1);
}
EventHandler.remove(target_1, 'blur', focusScroll_1);
};
EventHandler.add(target_1, 'blur', focusScroll_1, this);
}
}
};
KeyboardShortcut.prototype.keyDownHandler = function (e) {
var isSelectionNone = this.parent.selectionSettings.mode === 'None';
this.ribbonShortCuts(e);
var sheet = this.parent.getActiveSheet();
var target = e.target;
var textarea = e.target;
if (!isNullOrUndefined(textarea) && textarea.classList.contains('e-addNoteContainer')) {
return;
}
if ((e.ctrlKey || e.metaKey) && this.isTrgtNotInput(e)) {
if (!closest(target, '.e-find-dlg') && !isSelectionNone) {
if ([79, 83].indexOf(e.keyCode) > -1) {
e.preventDefault();
}
else if (e.keyCode === 65 && !this.parent.isEdit) {
e.preventDefault();
}
}
var indexes = getCellIndexes(sheet.activeCell);
if (e.keyCode === 79) { /*Ctrl + O*/
if (this.parent.allowOpen && this.parent.openUrl) {
select('#' + this.parent.element.id + '_fileUpload', this.parent.element).click();
}
}
else if (e.keyCode === 83) { /*Ctrl + S*/
if (this.parent.saveUrl && this.parent.allowSave) {
this.parent.notify(exportDialog, null);
}
}
else if (e.keyCode === 67 && !isSelectionNone) { /*Ctrl + C*/
this.parent.notify(copy, { promise: Promise });
}
else if (e.keyCode === 75 && !isSelectionNone) { /*Ctrl + K*/
var row = sheet.rows[indexes[0]];
var cell = void 0;
e.preventDefault();
if (!isNullOrUndefined(row)) {
cell = row.cells[indexes[1]];
}
if (isNullOrUndefined(cell)) {
setCell(indexes[0], indexes[1], sheet, cell, false);
}
if (cell && cell.hyperlink) {
this.parent.notify(editHyperlink, null);
}
else {
this.parent.notify(initiateHyperlink, null);
}
}
else if (e.keyCode === 90 && !isSelectionNone) { /* Ctrl + Z */
if (!this.parent.isEdit) {
e.preventDefault();
this.parent.notify(performUndoRedo, { isUndo: true });
}
}
else if (e.keyCode === 89 && !isSelectionNone) { /* Ctrl + Y */
if (!this.parent.isEdit) {
e.preventDefault();
this.parent.notify(performUndoRedo, { isUndo: false });
}
}
else if ((e.keyCode === 82 || e.keyCode === 68) && !isSelectionNone) { /* Ctrl + R */ /* Ctrl + D */
e.preventDefault();
var selectRange = getSwapRange(getRangeIndexes(sheet.selectedRange));
var startCell = { colIndex: selectRange[1], rowIndex: selectRange[0] };
var direction = void 0;
var dataRange = void 0;
if (e.keyCode === 68) {
if (selectRange[0] === selectRange[2]) {
startCell.rowIndex = selectRange[0] - 1;
}
else {
selectRange[0] += 1;
}
dataRange = getRangeAddress([startCell.rowIndex, startCell.colIndex, startCell.rowIndex, selectRange[3]]);
direction = 'Down';
}
else {
if (selectRange[1] === selectRange[3]) {
startCell.colIndex = selectRange[1] - 1;
}
else {
selectRange[1] += 1;
}
direction = 'Right';
dataRange = getRangeAddress([startCell.rowIndex, startCell.colIndex, selectRange[2], startCell.colIndex]);
}
if (startCell.rowIndex < 0 || startCell.colIndex < 0) {
return;
}
this.parent.notify(performAutoFill, {
fillType: getCell(startCell.rowIndex, startCell.colIndex, sheet, false, true).formula ? 'FillSeries' : 'CopyCells',
dAutoFillCell: dataRange, rangeInfo: {
direction: direction, startCell: startCell,
endCell: { rowIndex: selectRange[2], colIndex: selectRange[3] }, fillRange: selectRange
}
});
this.parent.notify(selectionComplete, { type: 'mousedown' });
this.parent.notify(refreshRibbonIcons, null);
}
var isLocked = sheet.isProtected && isCellLocked(getCell(indexes[0], indexes[1], sheet), getColumn(sheet, indexes[1]));
if (e.keyCode === 70 && !isSelectionNone && this.parent.allowFindAndReplace) { /* Ctrl + F */
e.preventDefault();
var findInput = document.querySelector('.e-text-findNext-short');
if (findInput) {
findInput.focus();
}
else {
this.parent.notify(findToolDlg, {});
}
}
if ((!isLocked || !sheet.isProtected || e.keyCode === 86) && e.keyCode !== 70 && !isSelectionNone) {
if (e.keyCode === 71) { /* Ctrl + G */
e.preventDefault();
this.parent.notify(gotoDlg, null);
}
else if (e.keyCode === 72) { /* Ctrl + H */
e.preventDefault();
var findInput = document.querySelector('.e-text-findNext');
if (findInput) {
findInput.focus();
}
else {
this.parent.notify(findDlg, null);
}
}
else if (e.keyCode === 88) { /* Ctrl + X */
this.parent.notify(cut, { promise: Promise });
}
else if (e.keyCode === 86) { /* Ctrl + v */
this.parent.notify(paste, { isAction: true });
}
if (e.shiftKey && e.keyCode === 76 && !this.parent.isEdit && !sheet.isProtected) { /* Ctrl + Shift + L */
e.preventDefault();
this.parent.notify(initiateFilterUI, {});
}
}
if (!isSelectionNone && (!sheet.isProtected || sheet.protectSettings.formatCells)) {
if (e.keyCode === 66) { /* Ctrl + B */
e.preventDefault();
var value = this.parent.getCellStyleValue(['fontWeight'], indexes).fontWeight;
value = value === 'bold' ? 'normal' : 'bold';
this.parent.notify(setCellFormat, { style: { fontWeight: value }, onActionUpdate: true, refreshRibbon: true });
}
else if (e.keyCode === 73) { /* Ctrl + I */
e.preventDefault();
var value = this.parent.getCellStyleValue(['fontStyle'], indexes).fontStyle;
value = value === 'italic' ? 'normal' : 'italic';
this.parent.notify(setCellFormat, { style: { fontStyle: value }, onActionUpdate: true, refreshRibbon: true });
}
else if (e.ctrlKey && e.keyCode === 85 && !e.shiftKey) { /* Ctrl + U */
e.preventDefault();
this.parent.notify(textDecorationUpdate, { style: { textDecoration: 'underline' }, refreshRibbon: true });
}
else if (e.ctrlKey && e.keyCode === 53 && !e.shiftKey) { /* Ctrl + 5 */
e.preventDefault();
this.parent.notify(textDecorationUpdate, { style: { textDecoration: 'line-through' }, refreshRibbon: true });
}
}
}
if (e.keyCode === 27) { /*ESC*/
this.parent.notify(clearCopy, null);
}
if ((((e.ctrlKey || e.metaKey) && e.keyCode === 119) || (e.keyCode === 13 && target.classList.contains('e-drop-icon')))
&& this.parent.showRibbon) { /*ctrl + f8 or Enter*/
e.preventDefault();
var expandCollapseIcon = this.parent.element.querySelector('.e-drop-icon');
if (expandCollapseIcon) {
expandCollapseIcon.click();
}
}
//general key actions
if ((e.ctrlKey || e.metaKey) && !isSelectionNone) {
if (e.keyCode === 57) { /*ctrl + 9(row-hide)*/
if (!sheet.isProtected || sheet.protectSettings.formatRows) {
e.preventDefault();
var indexes = getRangeIndexes(sheet.selectedRange);
this.parent.notify(hideShow, { startIndex: indexes[0], endIndex: indexes[2], hide: !e.shiftKey, isCol: false,
actionUpdate: true });
}
}
else if (e.keyCode === 48) { /*ctrl + 0(col-hide)*/
if (!sheet.isProtected || sheet.protectSettings.formatColumns) {
var indexes = getRangeIndexes(sheet.selectedRange);
this.parent.notify(hideShow, { startIndex: indexes[1], endIndex: indexes[3], hide: !e.shiftKey, isCol: true,
actionUpdate: true });
}
}
}
if (e.shiftKey && !isSelectionNone) {
if (e.keyCode === 113 && !sheet.isProtected) { /*shift + F2(Add note)*/
e.preventDefault();
if (e.target.children.length > 0 && typeof e.target.children[e.target.children.length - 1].className === 'string' &&
e.target.children[e.target.children.length - 1].className.indexOf('e-addNoteIndicator') > -1) {
this.parent.notify(editNote, null);
}
else {
this.parent.notify(addNote, null);
}
}
else if (e.keyCode === 114) { /*shift + F3(insert-function dialog)*/
e.preventDefault();
this.parent.notify(renderInsertDlg, null);
}
else if (e.keyCode === 116 && this.parent.allowFindAndReplace) { /* shift + F5 */
e.preventDefault();
this.parent.notify(findToolDlg, {});
}
else if (e.keyCode === 121) { /* Context menu open Shift+F10 */
var className_1 = document.activeElement.className;
if (['e-spreadsheet', 'e-cell', 'e-header-cell', 'e-clipboard', 'e-rowhdr-table', 'e-selectall-table', 'e-main-panel'].some(function (cls) { return className_1.includes(cls); })) {
this.focusTarget(sheet);
}
}
}
if (e.altKey && !isSelectionNone) {
if ((e.ctrlKey || e.metaKey) && e.keyCode === 78) { /*ctrl+alt+N*/
e.preventDefault();
this.parent.refresh(true);
}
else if (e.keyCode === 113 && this.parent.saveUrl) { /*alt + F2*/
e.preventDefault();
this.parent.notify(exportDialog, null);
}
}
//number-formatting
if ((e.ctrlKey || e.metaKey) && e.shiftKey && !isSelectionNone) {
if (!sheet.isProtected || sheet.protectSettings.formatCells) {
var range = sheet.selectedRange;
var format = void 0;
if (e.keyCode === 192) { /*ctrl + shift + ~(General)*/
format = 'General';
}
else if (e.keyCode === 52) { /*ctrl + shift + $(currency)*/
format = getFormatFromType('CurrencyWithColorCode');
}
else if (e.keyCode === 53) { /*ctrl + shift + %(percent)*/
format = '0%';
}
else if (e.keyCode === 54) { /*ctrl + shift + ^(scentific)*/
format = getFormatFromType('Scientific');
}
else if (e.keyCode === 51) { /*ctrl + shift + #(Date)*/
format = 'dd-mmm-yy';
}
else if (e.keyCode === 50) { /*ctrl + shift + @(Time)*/
format = 'h:mm AM/PM';
}
else if (e.keyCode === 49) { /*ctrl + shift + !(Number)*/
format = getFormatFromType('Number');
}
else if (e.keyCode === 55) { /*ctrl + shift + 7*/
e.preventDefault();
var border = '1px solid #000000';
this.parent.notify(setCellFormat, { style: { border: border }, onActionUpdate: true, borderType: 'Outer' });
}
if (format) {
var isReadonly = isReadOnlyCells(this.parent, getSwapRange(getRangeIndexes(range)));
if (!isReadonly) {
var eventArgs = {
format: format, range: range, cancel: false, requestType: 'NumberFormat'
};
var actionArgs = {
range: sheet.name + '!' + eventArgs.range, format: eventArgs.format, requestType: 'NumberFormat'
};
this.parent.trigger('beforeCellFormat', eventArgs);
this.parent.notify(beginAction, { eventArgs: eventArgs, action: 'format' });
if (!eventArgs.cancel) {
this.parent.notify(applyNumberFormatting, eventArgs);
this.parent.notify(selectionComplete, { type: 'mousedown' });
this.parent.notify(completeAction, { eventArgs: actionArgs, action: 'format' });
this.parent.notify(refreshRibbonIcons, null);
}
}
}
}
if (e.keyCode === 85) { /*ctrl + shift + U*/
e.preventDefault();
var formulaExpand = this.parent.element.querySelector('.e-formula-bar-panel .e-drop-icon');
if (formulaExpand) {
formulaExpand.click();
}
}
}
if (e.keyCode === 122 && e.shiftKey && !e.ctrlKey && !this.parent.isProtected) { // shift+f11
this.parent.notify(insertModel, {
model: this.parent, start: this.parent.activeSheetIndex + 1, end: this.parent.activeSheetIndex + 1, modelType: 'Sheet', isAction: true, activeSheetIndex: this.parent.activeSheetIndex + 1
});
}
if (e.shiftKey && e.altKey && e.keyCode === 75 && this.parent.showSheetTabs) { /* Shift + Alt + K*/
this.parent.element.querySelector('.e-sheets-list').click();
}
};
KeyboardShortcut.prototype.focusTarget = function (sheet) {
var indexes = getSwapRange(getRangeIndexes(sheet.selectedRange));
var isRowSelected = (indexes[1] === 0 && indexes[3] === sheet.colCount - 1);
var isColSelected = (indexes[0] === 0 && indexes[2] === sheet.rowCount - 1);
var target;
if (isRowSelected && isColSelected) {
target = this.parent.element.querySelector('.e-selectall');
}
else if (isRowSelected) {
var frozenRow = this.parent.frozenRowCount(sheet);
if (indexes[0] < frozenRow) {
var freezeHdrRow = this.parent.getRow(indexes[0], this.parent.sheetModule.getSelectAllTable());
target = freezeHdrRow && freezeHdrRow.cells[0];
}
else {
indexes[0] = skipHiddenIdx(sheet, indexes[0], true);
var topIdx = skipHiddenIdx(sheet, getRangeIndexes(sheet.paneTopLeftCell)[0], true);
var bottomIdx = getBottomOffset(this.parent, topIdx).index;
var hdrRow = void 0;
if (indexes[0] > topIdx && indexes[0] < bottomIdx) {
hdrRow = this.parent.getRow(indexes[0], this.parent.getRowHeaderTable());
}
else if (indexes[0] >= bottomIdx) {
hdrRow = this.parent.getRow(bottomIdx - 1, this.parent.getRowHeaderTable());
}
else {
hdrRow = this.parent.getRow(topIdx + 1, this.parent.getRowHeaderTable());
}
target = hdrRow && hdrRow.cells[0];
}
}
else if (isColSelected) {
var frozenCol = this.parent.frozenColCount(sheet);
if (indexes[1] < frozenCol) {
var freezeHdrRow = this.parent.element.querySelector('.e-selectall-container .e-header-row');
target = freezeHdrRow && this.parent.getCell(0, indexes[1], freezeHdrRow);
}
else {
indexes[1] = skipHiddenIdx(sheet, indexes[1], true, 'columns');
var leftIdx = skipHiddenIdx(sheet, getRangeIndexes(sheet.paneTopLeftCell)[1], true, 'columns');
var rightIdx = getRightIdx(this.parent, leftIdx);
var hdrRow = this.parent.element.querySelector('.e-column-header .e-header-row');
if (indexes[1] > leftIdx && indexes[1] < rightIdx) {
target = hdrRow && this.parent.getCell(0, indexes[1], hdrRow);
}
else if (indexes[1] >= rightIdx) {
target = hdrRow && this.parent.getCell(0, rightIdx - 1, hdrRow);
}
else {
target = hdrRow && this.parent.getCell(0, leftIdx + 1, hdrRow);
}
}
}
else {
var topLeftIdx = getRangeIndexes(sheet.paneTopLeftCell);
target = this.parent.getCell(indexes[0], indexes[1]);
var frozenRow = this.parent.frozenRowCount(sheet);
var frozenCol = this.parent.frozenColCount(sheet);
if (indexes[0] < frozenRow && indexes[1] < frozenCol) {
target = this.parent.getCell(indexes[0], indexes[1]);
}
else if (indexes[0] < frozenRow) {
var leftIdx = getRangeIndexes(sheet.paneTopLeftCell)[1];
var rightIdx = getRightIdx(this.parent, leftIdx);
if (indexes[1] > leftIdx && indexes[1] < rightIdx) {
target = this.parent.getCell(indexes[0], indexes[1]);
}
else if (indexes[1] >= rightIdx) {
target = this.parent.getCell(indexes[0], rightIdx - 1);
}
else {
target = this.parent.getCell(indexes[0], leftIdx + 1);
}
}
else if (indexes[1] < frozenCol) {
var topIdx = getRangeIndexes(sheet.paneTopLeftCell)[0];
var bottomIdx = getBottomOffset(this.parent, topIdx).index;
if (indexes[0] > topIdx && indexes[0] < bottomIdx) {
target = this.parent.getCell(indexes[0], indexes[1]);
}
else if (indexes[0] >= bottomIdx) {
target = this.parent.getCell(bottomIdx - 1, indexes[1]);
}
else {
target = this.parent.getCell(topIdx + 1, indexes[1]);
}
}
else {
var topIdx = getRangeIndexes(sheet.paneTopLeftCell)[0];
var bottomIdx = getBottomOffset(this.parent, topIdx).index;
var leftIdx = getRangeIndexes(sheet.paneTopLeftCell)[1];
var rightIdx = getRightIdx(this.parent, leftIdx);
if (indexes[0] > topIdx && indexes[0] < bottomIdx) {
if (indexes[1] > leftIdx && indexes[1] < rightIdx) {
target = this.parent.getCell(indexes[0], indexes[1]);
}
else if (indexes[1] >= rightIdx) {
target = this.parent.getCell(indexes[0], rightIdx - 1);
}
else {
target = this.parent.getCell(indexes[0], leftIdx + 1);
}
}
else if (indexes[0] >= bottomIdx) {
if (indexes[1] > leftIdx && indexes[1] < rightIdx) {
target = this.parent.getCell(bottomIdx - 1, indexes[1]);
}
else if (indexes[1] >= rightIdx) {
target = this.parent.getCell(bottomIdx - 1, rightIdx - 1);
}
else {
target = this.parent.getCell(bottomIdx - 1, leftIdx + 1);
}
}
else {
if (indexes[1] > leftIdx && indexes[1] < rightIdx) {
target = this.parent.getCell(topIdx + 1, indexes[1]);
}
else if (indexes[1] >= rightIdx) {
target = this.parent.getCell(topIdx + 1, rightIdx - 1);
}
else {
target = this.parent.getCell(topIdx + 1, leftIdx + 1);
}
}
}
if (!target) {
target = this.parent.getCell(topLeftIdx[0] + 1, topLeftIdx[1] + 1);
}
}
if (target) {
focus(target);
}
};
KeyboardShortcut.prototype.getModuleName = function () {
return 'keyboardShortcut';
};
KeyboardShortcut.prototype.destroy = function () {
this.removeEventListener();
this.parent = null;
};
return KeyboardShortcut;
}());
export { KeyboardShortcut };