UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

886 lines (885 loc) 80.5 kB
import { contentLoaded, mouseDown, virtualContentLoaded, cellNavigate, getUpdateUsingRaf, focusBorder, positionAutoFillElement, hideAutoFillOptions, performAutoFill, selectAutoFillRange, rangeSelectionByKeydown } from '../common/index'; import { showAggregate, refreshOverlayElem, getRowIdxFromClientY, getColIdxFromClientX, hideAutoFillElement, showNote } from '../common/index'; import { updateSelectedRange, getColumnWidth, mergedRange, activeCellMergedRange, getSelectedRange, checkColumnValidation } from '../../workbook/index'; import { getRowHeight, isSingleCell, activeCellChanged, checkIsFormula, getSheetIndex } from '../../workbook/index'; import { EventHandler, addClass, removeClass, isNullOrUndefined, Browser, closest, remove, detach, getComponent } from '@syncfusion/ej2-base'; import { getMoveEvent, getEndEvent, isTouchStart, isMouseUp, isDiscontinuousRange } from '../common/index'; import { isTouchEnd, isTouchMove, getClientX, getClientY, mouseUpAfterSelection, selectRange, rowHeightChanged, completeAction } from '../common/index'; import { colWidthChanged, protectSelection, editOperation, initiateFormulaReference, initiateCur, clearCellRef, getScrollBarWidth } from '../common/index'; import { getRangeIndexes, getCellAddress, getRangeAddress, getCellIndexes, getSwapRange } from '../../workbook/common/address'; import { addressHandle, isMouseDown, isMouseMove, selectionStatus, setPosition, removeRangeEle, removeNoteContainer, setActionData } from '../common/index'; import { isCellReference, getSheetNameFromAddress, isLocked, getColumn, getCell, updateCell, getSheetName } from '../../workbook/index'; import { selectionComplete, parseFormulaArgument, getChartRowIdxFromClientY, getChartColIdxFromClientX, addDPRValue, isRowSelected, isColumnSelected } from '../../workbook/common/index'; import { getIndexesFromAddress, skipHiddenIdx, isHiddenRow, isHiddenCol } from '../../workbook/index'; /** * Represents selection support for Spreadsheet. */ var Selection = /** @class */ (function () { /** * Constructor for the Spreadsheet selection module. * * @param {Spreadsheet} parent - Constructor for the Spreadsheet selection module. * @private */ function Selection(parent) { this.invalidOperators = ['%']; this.formulaRange = []; /** @hidden */ this.isNoteActiveElement = false; this.isNoteTouch = false; this.parent = parent; this.addEventListener(); this.mouseMoveEvt = this.mouseMoveHandler.bind(this); } Selection.prototype.addEventListener = function () { this.parent.on(contentLoaded, this.init, this); this.parent.on(mouseDown, this.mouseDownHandler, this); this.parent.on(virtualContentLoaded, this.virtualContentLoadedHandler, this); this.parent.on(cellNavigate, this.cellNavigateHandler, this); this.parent.on(selectRange, this.selectRange, this); this.parent.on(rowHeightChanged, this.rowHeightChanged, this); this.parent.on(colWidthChanged, this.colWidthChanged, this); this.parent.on(protectSelection, this.protectHandler, this); this.parent.on(initiateFormulaReference, this.initiateFormulaSelection, this); this.parent.on(clearCellRef, this.clearBorder, this); this.parent.on(getRowIdxFromClientY, this.getRowIdxFromClientY, this); this.parent.on(getColIdxFromClientX, this.getColIdxFromClientX, this); this.parent.on(getChartRowIdxFromClientY, this.getRowIdxFromClientY, this); this.parent.on(getChartColIdxFromClientX, this.getColIdxFromClientX, this); this.parent.on(focusBorder, this.chartBorderHandler, this); this.parent.on(selectionStatus, this.isTouchSelectionStarted, this); this.parent.on(rangeSelectionByKeydown, this.selectionByKeydown, this); }; Selection.prototype.removeEventListener = function () { if (!this.parent.isDestroyed) { this.parent.off(contentLoaded, this.init); this.parent.off(mouseDown, this.mouseDownHandler); this.parent.off(virtualContentLoaded, this.virtualContentLoadedHandler); this.parent.off(cellNavigate, this.cellNavigateHandler); this.parent.off(selectRange, this.selectRange); this.parent.off(rowHeightChanged, this.rowHeightChanged); this.parent.off(colWidthChanged, this.colWidthChanged); this.parent.off(protectSelection, this.protectHandler); this.parent.off(initiateFormulaReference, this.initiateFormulaSelection); this.parent.off(clearCellRef, this.clearBorder); this.parent.off(getRowIdxFromClientY, this.getRowIdxFromClientY); this.parent.off(getColIdxFromClientX, this.getColIdxFromClientX); this.parent.off(getChartRowIdxFromClientY, this.getRowIdxFromClientY); this.parent.off(getChartColIdxFromClientX, this.getColIdxFromClientX); this.parent.off(focusBorder, this.chartBorderHandler); this.parent.off(selectionStatus, this.isTouchSelectionStarted); this.parent.off(rangeSelectionByKeydown, this.selectionByKeydown); } }; Selection.prototype.isTouchSelectionStarted = function (args) { args.touchSelectionStarted = this.touchSelectionStarted; }; Selection.prototype.selectionByKeydown = function (args) { this.selectRangeByIdx(args.range, args.e, false, false, false, false, undefined, false); }; Selection.prototype.rowHeightChanged = function (args) { var _this = this; if (!args.threshold) { return; } getUpdateUsingRaf(function () { if (!_this.parent) { return; } var sheet = _this.parent.getActiveSheet(); var ele = _this.getActiveCell(); if (ele && (sheet.frozenRows || sheet.frozenColumns || sheet.selectedRange.includes(' '))) { _this.selectRange({ address: sheet.selectedRange, isRowHeightChanged: true }); return; } var sRange = getSwapRange(getRangeIndexes(sheet.selectedRange)); var mergeArgs = { range: sRange, isActiveCell: false, skipChecking: true }; var isActiveCell; if (ele) { var rowIdx = getCellIndexes(sheet.activeCell)[0]; _this.parent.notify(mergedRange, mergeArgs); if (mergeArgs.isActiveCell) { var cell = getCell(sRange[0], sRange[1], sheet, false, true); isActiveCell = cell.rowSpan > 1 && sRange[0] <= args.rowIdx && sRange[2] >= args.rowIdx; } if (rowIdx === args.rowIdx || isActiveCell) { ele.style.height = parseFloat(ele.style.height) + args.threshold + "px"; } else if (rowIdx > args.rowIdx) { ele.style.top = parseFloat(ele.style.top) + args.threshold + "px"; } } ele = _this.getSelectionElement(); if (ele) { if (isActiveCell || (sRange[0] === sRange[2] && sRange[1] === sRange[3])) { return; } var rowStart = sRange[0]; var rowEnd = sRange[2]; if (rowStart <= args.rowIdx && rowEnd >= args.rowIdx && ele) { ele.style.height = parseFloat(ele.style.height) + args.threshold + "px"; } else if (rowStart > args.rowIdx && ele) { ele.style.top = parseFloat(ele.style.top) + args.threshold + "px"; } } }); }; Selection.prototype.colWidthChanged = function (args) { var _this = this; if (!args.threshold) { return; } getUpdateUsingRaf(function () { if (!_this.parent) { return; } var sheet = _this.parent.getActiveSheet(); var ele = _this.getActiveCell(); var isRtl = _this.parent.enableRtl; if (ele && (sheet.frozenRows || sheet.frozenColumns || sheet.selectedRange.includes(' '))) { _this.selectRange({ address: sheet.selectedRange }); return; } var sRange = getSwapRange(getRangeIndexes(sheet.selectedRange)); var e = { range: sRange, isActiveCell: false, skipChecking: true }; var isActiveCell; if (ele) { _this.parent.notify(mergedRange, e); var colIdx = getCellIndexes(sheet.activeCell)[1]; if (e.isActiveCell) { var cell = getCell(sRange[0], sRange[1], sheet, false, true); isActiveCell = cell.rowSpan > 1 || cell.colSpan > 1; } if (colIdx === args.colIdx || isActiveCell) { ele.style.width = parseFloat(ele.style.width) + args.threshold + "px"; } else if (colIdx > args.colIdx) { if (isRtl) { ele.style.right = parseFloat(ele.style.right) + args.threshold + "px"; } else { ele.style.left = parseFloat(ele.style.left) + args.threshold + "px"; } } } ele = _this.getSelectionElement(); if (!ele || isActiveCell || (sRange[0] === sRange[2] && sRange[1] === sRange[3])) { return; } var colStart = sRange[1]; var colEnd = sRange[3]; if (colStart <= args.colIdx && colEnd >= args.colIdx && ele) { ele.style.width = parseFloat(ele.style.width) + args.threshold + "px"; } else if (colStart > args.colIdx && ele) { if (isRtl) { ele.style.right = parseFloat(ele.style.right) + args.threshold + "px"; } else { ele.style.left = parseFloat(ele.style.left) + args.threshold + "px"; } } }); }; Selection.prototype.selectRange = function (args) { args.address = this.parent.selectionSettings.mode === 'Single' ? getRangeAddress(getCellIndexes(args.address)) : args.address; this.selectMultiRange(args.address, null, null, args.skipChecking, args.isRowHeightChanged); }; Selection.prototype.init = function () { this.createSelectionElement(); var sheet = this.parent.getActiveSheet(); var sRange = getSwapRange(getRangeIndexes(sheet.selectedRange)); var actRange = getCellIndexes(sheet.activeCell); var inRange = sRange[0] <= actRange[0] && sRange[2] >= actRange[0] && sRange[1] <= actRange[1] && sRange[3] >= actRange[1]; this.selectMultiRange(sheet.selectedRange, true, inRange); }; Selection.prototype.selectMultiRange = function (address, isInit, inRange, skipChecking, isisRowHeightChanged) { var _this = this; var sheetIdx = this.parent.activeSheetIndex; if (address.indexOf('!') > -1) { sheetIdx = getSheetIndex(this.parent, getSheetNameFromAddress(address)); address = address.substring(address.lastIndexOf('!') + 1); } if (this.parent.activeSheetIndex === sheetIdx) { address.split(' ').forEach(function (rng, idx) { _this.selectRangeByIdx(getRangeIndexes(rng), { type: 'mousedown', ctrlKey: idx !== 0 }, null, inRange, isInit, skipChecking, undefined, false, isisRowHeightChanged); }); } else { updateSelectedRange(this.parent, address, this.parent.sheets[sheetIdx]); } }; Selection.prototype.createSelectionElement = function () { var content = this.parent.getMainContent(); var ele = this.parent.createElement('div', { className: 'e-selection' }); content.appendChild(ele); ele = this.parent.createElement('div', { className: 'e-active-cell' }); content.appendChild(ele); }; Selection.prototype.isMergeActiveCell = function (sheet, activeIdx, rowIdx, colIdx) { var cell = getCell(rowIdx, colIdx, sheet, false, true); if ((!!cell.rowSpan && cell.rowSpan !== 1) || (!!cell.colSpan && cell.colSpan !== 1)) { var mergeArgs = { range: [rowIdx, colIdx, rowIdx, colIdx] }; this.parent.notify(activeCellMergedRange, mergeArgs); var mergeRange = mergeArgs.range; return mergeRange[0] === activeIdx[0] && mergeRange[1] === activeIdx[1]; } return false; }; Selection.prototype.mouseDownHandler = function (e) { var _this = this; this.isNoteActiveElement = !isNullOrUndefined(document) && !isNullOrUndefined(document.activeElement) && typeof document.activeElement.className === 'string' && document.activeElement.className.indexOf('e-addNoteContainer') > -1; if (closest(e.target, '.e-scrollbar') || e.target.classList.contains('e-main-panel') || e.target.classList.contains('e-sheet')) { return; } var eventArgs = { action: 'getCurrentEditValue', editedValue: '' }; var sheet = this.parent.getActiveSheet(); this.parent.notify(editOperation, eventArgs); var isFormulaEdit = checkIsFormula(eventArgs.editedValue, true); var isNoteCellIndex = this.parent.enableNotes && !isNullOrUndefined(this.parent.spreadsheetNoteModule.noteCellIndexes); var cellIndexes = isNoteCellIndex ? this.parent.spreadsheetNoteModule.noteCellIndexes : getCellIndexes(this.parent.getActiveSheet().activeCell); var targetElement = this.parent.getCell(cellIndexes[0], cellIndexes[1]); if (!isNullOrUndefined(targetElement) && targetElement.children !== null && targetElement.children.length > 0 && this.isNoteActiveElement && targetElement.children[targetElement.children.length - 1].classList.contains('e-addNoteIndicator')) { var cell = getCell(cellIndexes[0], cellIndexes[1], sheet); var eventAction = !isNullOrUndefined(cell) && cell.notes ? 'editNote' : 'addNote'; var noteContainer = document.getElementsByClassName('e-addNoteContainer')[0]; var address = getSheetName(this.parent, this.parent.activeSheetIndex) + '!' + getRangeAddress(cellIndexes); if (!isNullOrUndefined(noteContainer) && !isNullOrUndefined(noteContainer.value) && e.target.className !== 'e-addNoteContainer' && ((isNullOrUndefined(cell) || isNullOrUndefined(cell.notes)) || (cell.notes !== noteContainer.value))) { this.parent.notify(setActionData, { args: { action: 'beforeCellSave', eventArgs: { address: address } } }); updateCell(this.parent, this.parent.getActiveSheet(), { rowIdx: cellIndexes[0], colIdx: cellIndexes[1], preventEvt: true, cell: { notes: noteContainer.value, isNoteEditable: false } }); var eventArgs_1 = { notes: noteContainer.value, address: address }; this.parent.notify(completeAction, { eventArgs: eventArgs_1, action: eventAction }); } else if (e.target.className !== 'e-addNoteContainer') { updateCell(this.parent, this.parent.getActiveSheet(), { rowIdx: cellIndexes[0], colIdx: cellIndexes[1], preventEvt: true, cell: { isNoteEditable: false } }); } this.parent.spreadsheetNoteModule.isShowNote = null; } if (!this.isNoteTouch && e.target.className !== 'e-addNoteContainer' && document.getElementsByClassName('e-addNoteContainer') && document.getElementsByClassName('e-addNoteContainer').length > 0) { this.parent.notify(removeNoteContainer, ''); } if (this.isNoteTouch && e.type.indexOf('mouse') > -1) { this.isNoteTouch = false; } if (!this.parent.isEdit || isFormulaEdit) { var overlayElem = document.getElementById(this.parent.element.id + '_overlay'); if (typeof (e.target.className) === 'string') { if (e.target.className.indexOf('e-ss-overlay') > -1) { return; } } else if (overlayElem) { overlayElem.classList.remove('e-ss-overlay-active'); } if (closest(e.target, '.e-datavisualization-chart')) { return; } if (sheet.isProtected && !sheet.protectSettings.selectCells && !sheet.protectSettings.selectUnLockedCells) { return; } if (!(closest(e.target, '.e-findtool-dlg') || closest(e.target, '.e-dragfill-ddb'))) { if (this.getSheetElement().contains(e.target) && !e.target.classList.contains('e-colresize') && !e.target.classList.contains('e-rowresize')) { var sheet_1 = this.parent.getActiveSheet(); var mode = this.parent.selectionSettings.mode; var mouseClientX = getClientX(e); var mouseClientY = getClientY(e); var rowIdx = this.getRowIdxFromClientY({ clientY: mouseClientY, target: e.target }); var colIdx = this.getColIdxFromClientX({ clientX: mouseClientX, target: e.target }); var activeIdx = getCellIndexes(sheet_1.activeCell); var isRowSelected_1; var isColSelected = void 0; if (sheet_1.showHeaders) { var trgt = e.target; if (sheet_1.frozenColumns || sheet_1.frozenRows) { var headerEle = this.parent.getSelectAllContent().querySelector('thead'); if (headerEle) { isColSelected = (this.parent.getColumnHeaderContent().contains(trgt) || headerEle.contains(trgt)) && trgt.classList.contains('e-header-cell') || (trgt.classList.contains('e-selectall-table') && rowIdx < 0 && colIdx >= this.parent.frozenColCount(sheet_1)); } else { isColSelected = this.parent.getColumnHeaderContent().contains(trgt) && trgt.classList.contains('e-header-cell'); } headerEle = this.parent.getSelectAllContent().querySelector('tbody'); if (headerEle) { isRowSelected_1 = (this.parent.getRowHeaderContent().contains(trgt) || headerEle.contains(trgt)) && trgt.classList.contains('e-header-cell') || (trgt.classList.contains('e-selectall-table') && colIdx < 0 && rowIdx >= this.parent.frozenRowCount(sheet_1)); } else { isRowSelected_1 = this.parent.getRowHeaderContent().contains(trgt) && trgt.classList.contains('e-header-cell'); } if (rowIdx === -1) { rowIdx = 0; } if (colIdx === -1) { colIdx = 0; } } else { isRowSelected_1 = this.parent.getRowHeaderContent().contains(e.target); isColSelected = this.parent.getColumnHeaderContent().contains(e.target); } } if ((sheet_1.frozenRows || sheet_1.frozenColumns) && !isColSelected && !isRowSelected_1) { var trgt_1 = e.target; var idx = ['e-rowhdr-table', 'e-selectall-table', 'e-colhdr-table'].findIndex(function (cls) { return trgt_1.classList.contains(cls); }); if (idx > -1) { var selector = ['.e-row-header', '.e-selectall-container', '.e-column-header'][idx]; var closestEle = closest(trgt_1, selector); if (closestEle && closestEle.style.zIndex) { var cell = getCell(rowIdx, colIdx, sheet_1); if ((cell && cell.validation && cell.validation.type === 'List') || (checkColumnValidation(sheet_1.columns[colIdx], rowIdx, colIdx) && sheet_1.columns[colIdx].validation.type === 'List')) { var td = this.parent.getCell(rowIdx, colIdx); if (td) { var listEle = td.querySelector('.e-validation-list'); if (listEle) { var listEleRect = listEle.getBoundingClientRect(); var dropdownClicked = mouseClientX >= listEleRect.left && mouseClientX <= listEleRect.right && mouseClientY >= listEleRect.top && mouseClientY <= listEleRect.bottom; if (dropdownClicked) { var ddlEle = listEle.querySelector('.e-dropdownlist'); if (ddlEle) { var ddlInst = getComponent(ddlEle, 'dropdownlist'); if (ddlInst) { ddlInst.showPopup(); } } } } } } } } } if (e.which === 3 && this.isSelected(rowIdx, colIdx)) { return; } if (e.target.classList.contains('e-autofill')) { this.isautoFillClicked = true; var autoFillDdb = e.target.parentElement.querySelector('.e-dragfill-ddb'); if (!autoFillDdb || autoFillDdb.classList.contains('e-hide')) { this.dAutoFillCell = sheet_1.selectedRange; } } var topLeftIdx = getRangeIndexes(sheet_1.topLeftCell); var range = void 0; if (isRowSelected_1) { this.isRowSelected = true; if (!e.shiftKey || mode === 'Single') { this.startCell = [rowIdx, 0]; } else if (!this.startCell) { this.startCell = [topLeftIdx[0], 0]; } range = [this.startCell[0], sheet_1.frozenColumns ? topLeftIdx[1] : 0, rowIdx, sheet_1.colCount - 1]; } else if (isColSelected) { this.isColSelected = true; if (!e.shiftKey || mode === 'Single') { this.startCell = [0, colIdx]; } else if (!this.startCell) { this.startCell = [0, topLeftIdx[1]]; } range = [sheet_1.frozenRows ? topLeftIdx[0] : 0, this.startCell[1], sheet_1.rowCount - 1, colIdx]; } else if (closest(e.target, '.e-select-all-cell')) { this.startCell = [sheet_1.frozenRows ? topLeftIdx[0] : 0, sheet_1.frozenColumns ? topLeftIdx[1] : 0]; range = [].concat(this.startCell, [sheet_1.rowCount - 1, sheet_1.colCount - 1]); } else if (!e.target.classList.contains('e-sheet-content')) { if (!e.shiftKey || mode === 'Single') { this.startCell = [rowIdx, colIdx]; } if (!this.isautoFillClicked && !closest(e.target, '.e-filloption')) { range = [].concat(this.startCell ? this.startCell : getCellIndexes(sheet_1.activeCell), [rowIdx, colIdx]); } } if (isTouchStart(e) && !(isRowSelected_1 || isColSelected) && range) { var colRowSelectArgs = this.isRowColSelected(range); this.isRowSelected = colRowSelectArgs.isRowSelected; this.isColSelected = colRowSelectArgs.isColSelected; } var preventEvt = e.ctrlKey && range && sheet_1.selectedRange.includes(getRangeAddress(range)); if (!preventEvt && mode === 'Multiple' && (!isTouchEnd(e) && (!isTouchStart(e) || (isTouchStart(e) && ((activeIdx[0] === rowIdx && activeIdx[1] === colIdx) || this.isMergeActiveCell(sheet_1, activeIdx, rowIdx, colIdx)))) || isColSelected || isRowSelected_1)) { document.addEventListener(getMoveEvent().split(' ')[0], this.mouseMoveEvt); if (!Browser.isPointer) { if (Browser.isIos && isTouchStart(e) && e.target && e.target.classList.contains('e-cell')) { e.preventDefault(); } document.addEventListener(getMoveEvent().split(' ')[1], this.mouseMoveEvt, { passive: false }); } this.touchSelectionStarted = true; } else { this.touchSelectionStarted = false; } if (!isTouchEnd(e)) { if (preventEvt) { if (this.parent.isEdit) { var updateFormulaCurPos_1 = function (e) { EventHandler.remove(document, getEndEvent(), updateFormulaCurPos_1); _this.updateFormulaCursorPosition(e); }; EventHandler.add(document, getEndEvent(), updateFormulaCurPos_1, this); } } else { EventHandler.add(document, getEndEvent(), this.mouseUpHandler, this); } } var targetElement_1 = e.target; var isNoteAvailable = targetElement_1.className === 'e-addNoteIndicator'; if (!isNoteAvailable && targetElement_1.children.length > 0) { var className = targetElement_1.children[targetElement_1.childElementCount - 1].className; isNoteAvailable = typeof className === 'string' && className.indexOf('e-addNoteIndicator') > -1; } if (isTouchStart(e) && isNoteAvailable) { var cellIndexes_1 = getCellIndexes(getRangeAddress(range).split(':')[0]); this.parent.notify(showNote, { rowIndex: cellIndexes_1[0], columnIndex: cellIndexes_1[1], isNoteEditable: false }); this.isNoteTouch = true; this.parent.spreadsheetNoteModule.isNoteVisibleOnTouch = true; } if (isTouchStart(e) && !(isColSelected || isRowSelected_1)) { this.touchEvt = e; return; } var isMobileContextMenuTrigger = isTouchEnd(e) && this.isMobileContextMenuOpening(e); if (isMobileContextMenuTrigger) { if (Browser.isDevice && !Browser.isAndroid) { e.preventDefault(); } } else if (range) { this.selectRangeByIdx(range, e); } if (!this.isNoteTouch && e.type.indexOf('mouse') > -1 && isNoteAvailable) { var cellIndexes_2 = getCellIndexes(getRangeAddress(range).split(':')[0]); this.parent.notify(showNote, { rowIndex: cellIndexes_2[0], columnIndex: cellIndexes_2[1], isNoteEditable: false }); this.parent.spreadsheetNoteModule.isNoteVisible = true; } if (this.parent.isMobileView()) { this.parent.element.classList.add('e-mobile-focused'); this.parent.renderModule.setSheetPanelSize(); } } } } if (isFormulaEdit && this.parent.isEdit) { var targetElement_2 = e.target; var validSelectors = ['e-cell', 'e-wrap-content', 'e-header-cell', 'e-cf-databar', 'e-databar', 'e-databar-value', 'e-fill-before', 'e-fill', 'e-fill-sec', 'e-hyperlink', 'e-iconsetspan']; if (validSelectors.some(function (cls) { return targetElement_2.classList.contains(cls); })) { var range = this.parent.getActiveSheet().selectedRange; var lastRange = range.split(' '); range = isSingleCell(getIndexesFromAddress(lastRange[lastRange.length - 1])) ? lastRange[lastRange.length - 1].split(':')[0] : lastRange[lastRange.length - 1]; this.parent.notify(addressHandle, { range: range, isSelect: false, isMouseDown: e.ctrlKey }); } } }; Selection.prototype.mouseMoveHandler = function (e) { var _this = this; var sheet = this.parent.getActiveSheet(); if (isTouchMove(e)) { e.preventDefault(); } var eventArgs = { action: 'getCurrentEditValue', editedValue: '' }; this.parent.notify(editOperation, eventArgs); var isFormulaEdit = checkIsFormula(eventArgs.editedValue, true); var verticalContent = this.parent.getMainContent().parentElement; var horizontalContent = this.parent.element.getElementsByClassName('e-scroller')[0]; var clientRect = verticalContent.getBoundingClientRect(); var frozenCol = this.parent.frozenColCount(sheet); var left = clientRect.left + this.parent.sheetModule.getRowHeaderWidth(sheet, false, true); var right = clientRect.right - getScrollBarWidth(); var top = clientRect.top; var bottom = clientRect.bottom; var clientX = getClientX(e); var clientY = getClientY(e); // remove math.min or handle top and left auto scroll var colIdx = this.isRowSelected ? sheet.colCount - 1 : this.getColIdxFromClientX({ clientX: clientX, target: e.target, mouseMove: true }); var rowIdx = this.isColSelected ? sheet.rowCount - 1 : this.getRowIdxFromClientY({ clientY: clientY, target: e.target, mouseMove: true }); var prevIndex; var rangeIndex; if (e.ctrlKey) { var selRanges = sheet.selectedRange.split(' '); prevIndex = getRangeIndexes(selRanges[selRanges.length - 1]); } else { prevIndex = getRangeIndexes(sheet.selectedRange); } if (Browser.isDevice) { var screenWidth = screen.availWidth; if (right >= screenWidth - 40) { right -= (40 - (screenWidth - right)); } if (!sheet.showHeaders && left < 40) { left += (40 - left); } } var mergeArgs = { range: [rowIdx, colIdx, rowIdx, colIdx] }; this.parent.notify(activeCellMergedRange, mergeArgs); if (mergeArgs.range[2] === prevIndex[2] && mergeArgs.range[3] === prevIndex[3] && clientY <= bottom && clientY >= top && clientX <= right && clientX >= left) { return; } var frozenRow = this.parent.frozenRowCount(sheet); if (!isFormulaEdit && !this.isColSelected && !this.isRowSelected) { prevIndex = getCellIndexes(sheet.activeCell); } var isScrollDown = clientY > bottom && !this.isColSelected && rowIdx < sheet.rowCount; var isScrollUp = clientY < top && rowIdx >= 0 && !this.isColSelected && !!verticalContent.scrollTop && (!frozenRow || prevIndex[0] >= frozenRow); var isScrollRight = clientX > right && !this.isRowSelected && colIdx < sheet.colCount; var isScrollLeft = clientX < left && colIdx >= 0 && !this.isRowSelected && !!horizontalContent.scrollLeft && (!frozenCol || prevIndex[1] >= frozenCol); this.clearInterval(); var scrollUpRowIdx; var scrollUpColIdx; if (isScrollDown || isScrollUp || isScrollRight || isScrollLeft) { if (isScrollUp || isScrollLeft) { scrollUpRowIdx = rowIdx; scrollUpColIdx = colIdx; } var scrollSelection_1 = function () { if (isScrollDown || isScrollUp) { rowIdx = _this.getRowIdxFromClientY({ clientY: isScrollDown ? bottom : top }); if (rowIdx >= sheet.rowCount) { // clear interval when scroll up _this.clearInterval(); return; } verticalContent.scrollTop += (isScrollDown ? 1 : -1) * getRowHeight(sheet, rowIdx); } if (isScrollRight || isScrollLeft) { colIdx = _this.getColIdxFromClientX({ clientX: isScrollRight ? right : left, isFScroll: true }); if (colIdx >= sheet.colCount) { // clear interval when scroll left _this.clearInterval(); return; } horizontalContent.scrollLeft += (isScrollRight ? 1 : -1) * getColumnWidth(sheet, colIdx); } if ((isScrollUp && sheet.frozenRows && !verticalContent.scrollTop) || (isScrollLeft && sheet.frozenColumns && !horizontalContent.scrollLeft)) { _this.selectRangeByIdx([].concat(prevIndex[0], prevIndex[1], [scrollUpRowIdx, scrollUpColIdx]), e); _this.clearInterval(); return; } _this.selectRangeByIdx([].concat(prevIndex[0], prevIndex[1], [rowIdx, colIdx]), e); }; scrollSelection_1(); this.scrollInterval = setInterval(function () { scrollSelection_1(); _this.clearInterval(); _this.scrollInterval = setInterval(scrollSelection_1, 100); }); } else { var indexes = [].concat(prevIndex[0], prevIndex[1], [rowIdx, colIdx]); if (frozenRow && indexes[0] < frozenRow && indexes[2] >= frozenRow && verticalContent.scrollTop && !this.isColSelected) { verticalContent.scrollTop = 0; indexes[2] = frozenRow; } if (frozenCol && indexes[1] < frozenCol && indexes[3] >= frozenCol && horizontalContent.scrollLeft && !this.isRowSelected) { horizontalContent.scrollLeft = 0; indexes[3] = frozenCol; } if (this.isautoFillClicked) { if (e.target.classList.contains('e-autofill')) { this.dAutoFillCell = sheet.selectedRange; } var args = { e: e, indexes: null }; this.parent.notify(selectAutoFillRange, args); indexes = args.indexes; rangeIndex = indexes; } this.selectRangeByIdx(indexes, e); } if (isFormulaEdit && this.parent.isEdit && !closest(e.target, '#' + this.parent.element.id + '_edit')) { var range = void 0; if (this.isautoFillClicked) { range = getRangeAddress(rangeIndex); } else { range = this.parent.getActiveSheet().selectedRange; } var lastRange = range.split(' '); this.parent.notify(addressHandle, { range: lastRange[lastRange.length - 1], isSelect: false }); } }; Selection.prototype.mouseUpHandler = function (e) { var rowIdx = this.getRowIdxFromClientY({ clientY: getClientY(e), target: e.target }); var colIdx = this.getColIdxFromClientX({ clientX: getClientX(e), target: e.target }); this.clearInterval(); if (isTouchEnd(e) && !(this.isColSelected || this.isRowSelected) && (this.getRowIdxFromClientY({ clientY: getClientY(this.touchEvt), target: e.target }) === rowIdx && this.getColIdxFromClientX({ clientX: getClientX(this.touchEvt), target: e.target }) === colIdx)) { this.mouseDownHandler(e); } document.removeEventListener(getMoveEvent().split(' ')[0], this.mouseMoveEvt); if (!Browser.isPointer) { document.removeEventListener(getMoveEvent().split(' ')[1], this.mouseMoveEvt); } EventHandler.remove(document, getEndEvent(), this.mouseUpHandler); var sheet = this.parent.getActiveSheet(); if (sheet.frozenRows || sheet.frozenColumns) { removeRangeEle(this.parent.element, null, 'e-cur-selection', true, true); } this.parent.notify(mouseUpAfterSelection, e); if (this.isautoFillClicked) { var sheet_2 = this.parent.getActiveSheet(); var indexes = getRangeIndexes(sheet_2.selectedRange); var isRowSelect = isRowSelected(sheet_2, indexes); var isColumnSelect = isColumnSelected(sheet_2, indexes); if (!(isColumnSelect && indexes[1] === colIdx) && !(isRowSelect && indexes[0] === rowIdx)) { if (e.target.parentElement) { var autoFillDdb = e.target.parentElement.querySelector('.e-dragfill-ddb'); if (!autoFillDdb || autoFillDdb.classList.contains('e-hide')) { this.dAutoFillCell = sheet_2.selectedRange; } } this.parent.notify(performAutoFill, { event: e, dAutoFillCell: this.dAutoFillCell }); } this.isautoFillClicked = false; } else if (!e.ctrlKey && !isDiscontinuousRange(getSelectedRange(this.parent.getActiveSheet())) || this.parent.selectionSettings.mode === 'Single') { this.parent.notify(positionAutoFillElement, null); } else { this.parent.notify(hideAutoFillElement, null); } this.updateFormulaCursorPosition(e); }; Selection.prototype.updateFormulaCursorPosition = function (e) { if (this.parent.isEdit) { var eventArgs = { action: 'getCurrentEditValue', editedValue: '' }; this.parent.notify(editOperation, eventArgs); var isFormulaEdit = checkIsFormula(eventArgs.editedValue, true); if (isFormulaEdit) { this.parent.notify(initiateCur, { isCellEdit: e.target.classList.contains('e-spreadsheet-edit') }); } } }; Selection.prototype.isSelected = function (rowIdx, colIdx) { var isSelected = false; var indexes; var ranges = this.parent.getActiveSheet().selectedRange.split(' '); for (var i = 0; i < ranges.length; i++) { indexes = getSwapRange(getRangeIndexes(ranges[i])); if (indexes[0] <= rowIdx && rowIdx <= indexes[2] && indexes[1] <= colIdx && colIdx <= indexes[3]) { isSelected = true; break; } } return isSelected; }; Selection.prototype.virtualContentLoadedHandler = function (args) { var _this = this; var sheet = this.parent.getActiveSheet(); var indexes; var isColSelected; var isRowSelected; sheet.selectedRange.split(' ').forEach(function (rng, idx) { indexes = getRangeIndexes(rng); isRowSelected = (indexes[1] === 0 && indexes[3] === args.prevRowColCnt.colCount - 1); isColSelected = (indexes[0] === 0 && indexes[2] === args.prevRowColCnt.rowCount - 1); if (isRowSelected || isColSelected) { if (isColSelected && isRowSelected) { indexes = [0, 0, sheet.rowCount - 1, sheet.colCount - 1]; } else if (isColSelected) { indexes = [0, indexes[1], sheet.rowCount - 1, indexes[3]]; } else { indexes = [indexes[0], 0, indexes[2], sheet.colCount - 1]; } if (sheet.frozenRows || sheet.frozenColumns) { _this.selectRangeByIdx(indexes, { type: 'mousedown', ctrlKey: idx !== 0 }, false, false, false, false, undefined, true); } else { _this.selectRangeByIdx(indexes, null, true, null, null, null, idx); } } else { indexes = getRangeIndexes(rng); var topIdx = _this.parent.viewport.topIndex + _this.parent.frozenRowCount(sheet); var leftIdx = _this.parent.viewport.leftIndex + _this.parent.frozenColCount(sheet); _this.highlightHdr(indexes, idx === 0 ? false : true, indexes[0] >= topIdx || indexes[2] >= topIdx, indexes[1] >= leftIdx || indexes[3] >= leftIdx); } }); }; Selection.prototype.clearInterval = function () { if (this.scrollInterval) { clearInterval(this.scrollInterval); this.scrollInterval = null; } }; Selection.prototype.getScrollLeft = function () { return this.parent.scrollModule ? this.parent.scrollModule.prevScroll.scrollLeft : 0; }; Selection.prototype.cellNavigateHandler = function (args) { var sheet = this.parent.getActiveSheet(); if (sheet.isProtected && !sheet.protectSettings.selectCells && !sheet.protectSettings.selectUnLockedCells) { return; } args.type = 'mousedown'; this.selectRangeByIdx(args.range, args, false, false, false, false, undefined, args.preventAnimation); }; Selection.prototype.getColIdxFromClientX = function (e) { var _this = this; var width = 0; var sheet = this.parent.getActiveSheet(); var left = 0; if (e.isImage) { left = e.clientX; } else { var cliRect = document.getElementById(this.parent.element.id + '_sheet').getBoundingClientRect(); if (this.parent.enableRtl) { left = (cliRect.right - this.parent.sheetModule.getRowHeaderWidth(sheet, true, true)) - e.clientX; } else { left = e.clientX - (cliRect.left + this.parent.sheetModule.getRowHeaderWidth(sheet, true, true)); } left += this.parent.viewport.beforeFreezeWidth; var frozenColPosition = function () { var frozenCol = _this.parent.element.querySelector('.e-frozen-column'); return parseInt(frozenCol.style[_this.parent.enableRtl ? 'right' : 'left'], 10) / _this.parent.viewport.scaleX; }; if ((!e.target || (!closest(e.target, '.e-row-header') && !closest(e.target, '.e-selectall-container')) || this.isScrollableArea(e.clientX, e.target, true)) && (!this.parent.frozenColCount(sheet) || left > frozenColPosition() || e.isFScroll)) { left += (this.getScrollLeft() / this.parent.viewport.scaleX); } if (sheet.frozenRows && left < 0 && sheet.showHeaders) { if (e.mouseMove) { return 0; } return -1; } } var size; for (var i = 0;; i++) { size = width += getColumnWidth(sheet, i, null, !e.isImage) / this.parent.viewport.scaleX; if (left < (e.isImage ? Number(addDPRValue(size).toFixed(2)) : size) || (this.parent.scrollSettings.isFinite && i === sheet.colCount - 1)) { if (!e.isImage) { e.size = left; } e.clientX = i; return i; } } }; Selection.prototype.isScrollableArea = function (offset, target, isclientX) { if (!target.classList.contains('e-table')) { return false; } if (isclientX) { return offset > this.parent.getMainContent().getBoundingClientRect().left; } else { return offset > this.parent.getMainContent().parentElement.getBoundingClientRect().top; } }; Selection.prototype.getRowIdxFromClientY = function (args) { var height = 0; var sheet = this.parent.getActiveSheet(); var top = 0; if (args.isImage) { top = args.clientY; } else { var sheetEle = document.getElementById(this.parent.element.id + '_sheet'); top = args.clientY + this.parent.viewport.beforeFreezeHeight - (sheetEle.getBoundingClientRect().top + (sheet.showHeaders ? (args.isOverlay ? 30 : 31) / this.parent.viewport.scaleY : 0)); if (!args.target || !closest(args.target, '.e-header-panel') || this.isScrollableArea(args.clientY, args.target)) { top += (this.parent.getMainContent().parentElement.scrollTop / this.parent.viewport.scaleY); } if (sheet.frozenColumns && top < 0 && sheet.showHeaders) { if (args.mouseMove) { return 0; } return -1; } } var size; for (var i = 0;; i++) { size = height += getRowHeight(sheet, i, !args.isImage) / this.parent.viewport.scaleY; if (top < (args.isImage ? Number(addDPRValue(size).toFixed(2)) : size) || (this.parent.scrollSettings.isFinite && i === sheet.rowCount - 1)) { if (!args.isImage) { args.size = top; } args.clientY = i; return i; } } }; Selection.prototype.initFormulaReferenceIndicator = function (range) { if (this.parent.isEdit) { var forRefIndicator = this.parent.createElement('div', { className: 'e-formularef-indicator' }); forRefIndicator.appendChild(this.parent.createElement('div', { className: 'e-top' })); forRefIndicator.appendChild(this.parent.createElement('div', { className: 'e-bottom' })); forRefIndicator.appendChild(this.parent.createElement('div', { className: 'e-left' })); forRefIndicator.appendChild(this.parent.createElement('div', { className: 'e-right' })); this.parent.getMainContent().appendChild(forRefIndicator); setPosition(this.parent, forRefIndicator, range, 'e-formularef-indicator'); } }; Selection.prototype.isMouseEvent = function (e) { return isMouseDown(e) || isMouseUp(e) || isMouseMove(e); }; Selection.prototype.selectRangeByIdx = function (range, e, isScrollRefresh, isActCellChanged, isInit, skipChecking, selectedRowColIdx, preventAnimation, isisRowHeightChanged) { var _this = this; var isMouseEvent = e && this.isMouseEvent(e); if (e && e.target && isMouseEvent && closest(e.target, '#' + this.parent.element.id + '_edit')) { return; } var eventArgs = { action: 'getCurrentEditValue', editedValue: '', endFormulaRef: false }; this.parent.notify(editOperation, eventArgs); var isFormulaEdit = (this.parent.isEdit ? checkIsFormula(eventArgs.editedValue, true) : false) && !eventArgs.endFormulaRef; var isMultiRange = e && e.ctrlKey && isMouseDown(e) && this.parent.selectionSettings.mode !== 'Single'; var ele; if (!isMultiRange) { ele = this.getSelectionElement(e, selectedRowColIdx); } var sheet = this.parent.getActiveSheet(); var topLeftIdx = getRangeIndexes(sheet.topLeftCell); var formulaRefIndicator = this.parent.element.querySelector('.e-formularef-indicator'); var mergeArgs = { range: [].slice.call(range), isActiveCell: false, skipChecking: skipChecking }; var isMergeRange; var rowColSelectArgs = this.isRowColSelected(range); if (!rowColSelectArgs.isColSelected && !rowColSelectArgs.isRowSelected) { this.parent.notify(mergedRange, mergeArgs); } if (range !== mergeArgs.range) { isMergeRange = true; } range = mergeArgs.range; var promise = new Promise(function (resolve) { resolve((function () { })()); }); var args = { range: getRangeAddress(range), cancel: false }; if (sheet.isProtected) { var protectCell = getCell(range[2], range[3], sheet);