{ "version": 3, "sources": ["../../../src/plugins/slick.cellselectionmodel.ts"], "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\nimport { SlickCellRangeSelector as SlickCellRangeSelector_ } from './slick.cellrangeselector';\nimport type { OnActiveCellChangedEventArgs } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst SlickCellRangeSelector = IIFE_ONLY ? Slick.CellRangeSelector : SlickCellRangeSelector_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nexport interface CellSelectionModelOption {\n selectActiveCell: boolean;\n cellRangeSelector?: SlickCellRangeSelector_;\n}\n\nexport class SlickCellSelectionModel {\n // --\n // public API\n pluginName = 'CellSelectionModel' as const;\n onSelectedRangesChanged = new SlickEvent('onSelectedRangesChanged');\n\n // --\n // protected props\n protected _cachedPageRowCount = 0;\n protected _dataView?: SlickDataView;\n protected _grid!: SlickGrid;\n protected _prevSelectedRow?: number;\n protected _prevKeyDown = '';\n protected _ranges: SlickRange_[] = [];\n protected _selector: SlickCellRangeSelector_;\n protected _options?: CellSelectionModelOption;\n protected _defaults: CellSelectionModelOption = {\n selectActiveCell: true\n };\n\n constructor(options?: { selectActiveCell: boolean; cellRangeSelector: SlickCellRangeSelector_; }) {\n if (options === undefined || options.cellRangeSelector === undefined) {\n this._selector = new SlickCellRangeSelector({ selectionCss: { border: '2px solid black' } as CSSStyleDeclaration });\n } else {\n this._selector = options.cellRangeSelector;\n }\n }\n\n init(grid: SlickGrid) {\n this._options = Utils.extend(true, {}, this._defaults, this._options);\n this._grid = grid;\n if (grid.hasDataView()) {\n this._dataView = grid.getData();\n }\n this._grid.onActiveCellChanged.subscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n grid.registerPlugin(this._selector);\n this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));\n }\n\n destroy() {\n this._grid.onActiveCellChanged.unsubscribe(this.handleActiveCellChange.bind(this));\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this));\n this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this));\n this._grid.unregisterPlugin(this._selector);\n this._selector?.destroy();\n }\n\n protected removeInvalidRanges(ranges: SlickRange_[]) {\n const result: SlickRange_[] = [];\n\n for (let i = 0; i < ranges.length; i++) {\n const r = ranges[i];\n if (this._grid.canCellBeSelected(r.fromRow, r.fromCell) && this._grid.canCellBeSelected(r.toRow, r.toCell)) {\n result.push(r);\n }\n }\n\n return result;\n }\n\n protected rangesAreEqual(range1: SlickRange_[], range2: SlickRange_[]) {\n let areDifferent = (range1.length !== range2.length);\n if (!areDifferent) {\n for (let i = 0; i < range1.length; i++) {\n if (\n range1[i].fromCell !== range2[i].fromCell\n || range1[i].fromRow !== range2[i].fromRow\n || range1[i].toCell !== range2[i].toCell\n || range1[i].toRow !== range2[i].toRow\n ) {\n areDifferent = true;\n break;\n }\n }\n }\n return !areDifferent;\n }\n\n /** Provide a way to force a recalculation of page row count (for example on grid resize) */\n resetPageRowCount() {\n this._cachedPageRowCount = 0;\n }\n\n setSelectedRanges(ranges: SlickRange_[], caller = 'SlickCellSelectionModel.setSelectedRanges') {\n // simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged\n if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }\n\n // if range has not changed, don't fire onSelectedRangesChanged\n const rangeHasChanged = !this.rangesAreEqual(this._ranges, ranges);\n\n this._ranges = this.removeInvalidRanges(ranges);\n if (rangeHasChanged) {\n // provide extra \"caller\" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range\n const eventData = new SlickEventData(null, this._ranges);\n Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || 'SlickCellSelectionModel.setSelectedRanges' } });\n this.onSelectedRangesChanged.notify(this._ranges, eventData);\n }\n }\n\n getSelectedRanges() {\n return this._ranges;\n }\n\n refreshSelections() {\n this.setSelectedRanges(this.getSelectedRanges());\n }\n\n protected handleBeforeCellRangeSelected(e: Event): boolean | void {\n if (this._grid.getEditorLock().isActive()) {\n e.stopPropagation();\n return false;\n }\n }\n\n protected handleCellRangeSelected(_e: any, args: { range: SlickRange_; }) {\n this._grid.setActiveCell(args.range.fromRow, args.range.fromCell, false, false, true);\n this.setSelectedRanges([args.range]);\n }\n\n protected handleActiveCellChange(_e: Event, args: OnActiveCellChangedEventArgs) {\n this._prevSelectedRow = undefined;\n const isCellDefined = Utils.isDefined(args.cell);\n const isRowDefined = Utils.isDefined(args.row);\n\n if (this._options?.selectActiveCell && isRowDefined && isCellDefined) {\n this.setSelectedRanges([new SlickRange(args.row, args.cell)]);\n } else if (!this._options?.selectActiveCell || (!isRowDefined && !isCellDefined)) {\n // clear the previous selection once the cell changes\n this.setSelectedRanges([]);\n }\n }\n\n protected isKeyAllowed(key: string) {\n return ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageDown', 'PageUp', 'Home', 'End'].some(k => k === key);\n }\n\n protected handleKeyDown(e: KeyboardEvent) {\n let ranges: SlickRange_[], last: SlickRange_;\n const colLn = this._grid.getColumns().length;\n const active = this._grid.getActiveCell();\n let dataLn = 0;\n if (this._dataView) {\n dataLn = this._dataView?.getPagingInfo().pageSize || this._dataView.getLength();\n } else {\n dataLn = this._grid.getDataLength();\n }\n\n if (active && (e.shiftKey || e.ctrlKey) && !e.altKey && this.isKeyAllowed(e.key)) {\n ranges = this.getSelectedRanges().slice();\n if (!ranges.length) {\n ranges.push(new SlickRange(active.row, active.cell));\n }\n // keyboard can work with last range only\n last = ranges.pop() as SlickRange_;\n\n // can't handle selection out of active cell\n if (!last.contains(active.row, active.cell)) {\n last = new SlickRange(active.row, active.cell);\n }\n\n let dRow = last.toRow - last.fromRow;\n let dCell = last.toCell - last.fromCell;\n\n // walking direction\n const dirRow = active.row === last.fromRow ? 1 : -1;\n const dirCell = active.cell === last.fromCell ? 1 : -1;\n const isSingleKeyMove = e.key.startsWith('Arrow');\n let toCell: undefined | number = undefined;\n let toRow = 0;\n\n if (isSingleKeyMove && !e.ctrlKey) {\n // single cell move: (Arrow{Up/ArrowDown/ArrowLeft/ArrowRight})\n if (e.key === 'ArrowLeft') {\n dCell -= dirCell;\n } else if (e.key === 'ArrowRight') {\n dCell += dirCell;\n } else if (e.key === 'ArrowUp') {\n dRow -= dirRow;\n } else if (e.key === 'ArrowDown') {\n dRow += dirRow;\n }\n toRow = active.row + dirRow * dRow;\n } else {\n // multiple cell moves: (Home, End, Page{Up/Down})\n if (this._cachedPageRowCount < 1) {\n this._cachedPageRowCount = this._grid.getViewportRowCount();\n }\n if (this._prevSelectedRow === undefined) {\n this._prevSelectedRow = active.row;\n }\n\n if (e.shiftKey && !e.ctrlKey && e.key === 'Home') {\n toCell = 0;\n toRow = active.row;\n } else if (e.shiftKey && !e.ctrlKey && e.key === 'End') {\n toCell = colLn - 1;\n toRow = active.row;\n } else if (e.ctrlKey && e.shiftKey && e.key === 'Home') {\n toCell = 0;\n toRow = 0;\n } else if (e.ctrlKey && e.shiftKey && e.key === 'End') {\n toCell = colLn - 1;\n toRow = dataLn - 1;\n } else if (e.key === 'PageUp') {\n if (this._prevSelectedRow >= 0) {\n toRow = this._prevSelectedRow - this._cachedPageRowCount;\n }\n if (toRow < 0) {\n toRow = 0;\n }\n } else if (e.key === 'PageDown') {\n if (this._prevSelectedRow <= dataLn - 1) {\n toRow = this._prevSelectedRow + this._cachedPageRowCount;\n }\n if (toRow > dataLn - 1) {\n toRow = dataLn - 1;\n }\n }\n this._prevSelectedRow = toRow;\n }\n\n // define new selection range\n toCell ??= active.cell + dirCell * dCell;\n const new_last = new SlickRange(active.row, active.cell, toRow, toCell);\n if (this.removeInvalidRanges([new_last]).length) {\n ranges.push(new_last);\n const viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow;\n const viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;\n\n if (isSingleKeyMove) {\n this._grid.scrollRowIntoView(viewRow);\n this._grid.scrollCellIntoView(viewRow, viewCell);\n } else {\n this._grid.scrollRowIntoView(toRow);\n this._grid.scrollCellIntoView(toRow, viewCell);\n }\n } else {\n ranges.push(last);\n }\n\n this.setSelectedRanges(ranges);\n\n e.preventDefault();\n e.stopPropagation();\n this._prevKeyDown = e.key;\n }\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellSelectionModel: SlickCellSelectionModel\n }\n });\n}\n"], "mappings": "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", "names": [] }