@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
JavaScript
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);