From 54bb8d5d9a18689d671e5b43b454ae49f3c2d972 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Sat, 21 Sep 2024 15:25:29 -0400 Subject: [PATCH 1/3] chore(release): publish version 5.13.0 --- CHANGELOG.md | 11 ++ dist/browser/slick.dataview.js | 16 +- dist/browser/slick.dataview.js.map | 4 +- dist/browser/slick.grid.js | 6 +- dist/browser/slick.grid.js.map | 4 +- dist/cjs/index.js | 20 ++- dist/cjs/index.js.map | 4 +- dist/esm/index.js | 20 ++- dist/esm/index.js.map | 4 +- dist/styles/sass/_variables.scss | 8 +- dist/types/slick.dataview.d.ts.map | 2 +- dist/types/slick.grid.d.ts | 2 +- dist/types/slick.grid.d.ts.map | 2 +- package-lock.json | 242 ++--------------------------- package.json | 4 +- src/slick.grid.ts | 4 +- 16 files changed, 90 insertions(+), 263 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ea302df..38f4e981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.13.0](https://github.com/6pac/SlickGrid/compare/5.12.1...5.13.0) (2024-09-21) + +### Bug Fixes + +* SASS deprecated `lighten` and `darken` methods ([#1063](https://github.com/6pac/SlickGrid/issues/1063)) ([74713b5](https://github.com/6pac/SlickGrid/commit/74713b51461bae8217bd1fab65b100b2dc05869d)) + +### Performance Improvements + +* Optimize SlickGrid handleSelectedRangesChanged by using Set ([#1061](https://github.com/6pac/SlickGrid/issues/1061)) ([8ff354b](https://github.com/6pac/SlickGrid/commit/8ff354bb458b6a96ae92ced7c30748cc5bb3c494)) +* Reduce iterative time complexity ([#1060](https://github.com/6pac/SlickGrid/issues/1060)) ([0d07e60](https://github.com/6pac/SlickGrid/commit/0d07e60a36d81f6dd68eb3091b2508c3036357b0)) + ## [5.12.1](https://github.com/6pac/SlickGrid/compare/5.12.0...5.12.1) (2024-09-07) ### Bug Fixes diff --git a/dist/browser/slick.dataview.js b/dist/browser/slick.dataview.js index 97b817f7..0e8f7a73 100644 --- a/dist/browser/slick.dataview.js +++ b/dist/browser/slick.dataview.js @@ -761,13 +761,20 @@ }), new SlickEventData(), this); } }), this.preSelectedRowIdsChangeFn = (args) => { - var _a2; + var _a2, _b2; if (!inHandler) { if (inHandler = !0, typeof args.added == "undefined") setSelectedRowIds(args.ids); else { let rowIds; - args.added ? preserveHiddenOnSelectionChange && grid.getOptions().multiSelect ? rowIds = ((_a2 = this.selectedRowIds) == null ? void 0 : _a2.filter((id) => this.getRowById(id) === void 0)).concat(args.ids) : rowIds = args.ids : preserveHiddenOnSelectionChange && grid.getOptions().multiSelect ? rowIds = this.selectedRowIds.filter((id) => args.ids.indexOf(id) === -1) : rowIds = [], setSelectedRowIds(rowIds); + if (args.added) + preserveHiddenOnSelectionChange && grid.getOptions().multiSelect ? rowIds = ((_a2 = this.selectedRowIds) == null ? void 0 : _a2.filter((id) => this.getRowById(id) === void 0)).concat(args.ids) : rowIds = args.ids; + else if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) { + let argsIdsSet = new Set(args.ids); + rowIds = (_b2 = this.selectedRowIds) == null ? void 0 : _b2.filter((id) => !argsIdsSet.has(id)); + } else + rowIds = []; + setSelectedRowIds(rowIds); } inHandler = !1; } @@ -828,7 +835,10 @@ * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true. */ getAllSelectedFilteredItems() { - return Array.isArray(this.selectedRowIds) ? this.filteredItems.filter((a) => this.selectedRowIds.some((b) => a[this.idProperty] === b)) || [] : []; + if (!Array.isArray(this.selectedRowIds)) + return []; + let selectedRowIdSet = new Set(this.selectedRowIds); + return this.filteredItems.filter((a) => selectedRowIdSet.has(a[this.idProperty])) || []; } syncGridCellCssStyles(grid, key) { let hashById, inHandler, storeCellCssStyles = (hash) => { diff --git a/dist/browser/slick.dataview.js.map b/dist/browser/slick.dataview.js.map index 72fd060b..44e025c3 100644 --- a/dist/browser/slick.dataview.js.map +++ b/dist/browser/slick.dataview.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.dataview.ts"], - "sourcesContent": ["import type {\r\n Aggregator,\r\n AnyFunction,\r\n CssStyleHash,\r\n CustomDataView,\r\n DataViewHints,\r\n Grouping,\r\n GroupingFormatterItem,\r\n ItemMetadata,\r\n OnGroupCollapsedEventArgs,\r\n OnGroupExpandedEventArgs,\r\n OnRowCountChangedEventArgs,\r\n OnRowsChangedEventArgs,\r\n OnRowsOrCountChangedEventArgs,\r\n OnSelectedRowIdsChangedEventArgs,\r\n OnSetItemsCalledEventArgs,\r\n PagingInfo,\r\n SlickGridModel,\r\n} from './models/index';\r\nimport {\r\n type BasePubSub,\r\n SlickEvent as SlickEvent_,\r\n SlickEventData as SlickEventData_,\r\n SlickGroup as SlickGroup_,\r\n SlickGroupTotals as SlickGroupTotals_,\r\n Utils as Utils_,\r\n type SlickNonDataItem,\r\n} from './slick.core';\r\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\r\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\r\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\r\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\r\n\r\nexport interface DataViewOption {\r\n /** Optionally provide a GroupItemMetadataProvider in order to use Grouping/DraggableGrouping features */\r\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\r\n\r\n /** defaults to false, are we using inline filters? */\r\n inlineFilters: boolean;\r\n\r\n /**\r\n * defaults to false, option to use CSP Safe approach,\r\n * Note: it is an opt-in option because it is slightly slower (perf impact) when compared to the non-CSP safe approach.\r\n */\r\n useCSPSafeFilter: boolean;\r\n}\r\nexport type FilterFn = (item: T, args: any) => boolean;\r\nexport type FilterCspFn = (item: T[], args: any) => T[];\r\nexport type FilterWithCspCachingFn = (item: T[], args: any, filterCache: any[]) => T[];\r\nexport type DataIdType = number | string;\r\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\r\nexport type GroupGetterFn = (val: any) => string | number;\r\n\r\n/**\r\n * A simple Model implementation.\r\n * Provides a filtered view of the underlying data.\r\n * Relies on the data item having an \"id\" property uniquely identifying it.\r\n */\r\nexport class SlickDataView implements CustomDataView {\r\n protected defaults: DataViewOption = {\r\n groupItemMetadataProvider: null,\r\n inlineFilters: false,\r\n useCSPSafeFilter: false,\r\n };\r\n\r\n // private\r\n protected idProperty = 'id'; // property holding a unique row id\r\n protected items: TData[] = []; // data by index\r\n protected rows: TData[] = []; // data by row\r\n protected idxById = new Map(); // indexes by id\r\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\r\n protected filter: FilterFn | null = null; // filter function\r\n protected filterCSPSafe: FilterFn | null = null; // filter function\r\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\r\n protected suspend = false; // suspends the recalculation\r\n protected isBulkSuspend = false; // delays protectedious operations like the\r\n // index update and delete to efficient\r\n // versions at endUpdate\r\n protected bulkDeleteIds = new Map();\r\n protected sortAsc: boolean | undefined = true;\r\n protected fastSortField?: string | null | (() => string);\r\n protected sortComparer!: ((a: TData, b: TData) => number);\r\n protected refreshHints: DataViewHints = {};\r\n protected prevRefreshHints: DataViewHints = {};\r\n protected filterArgs: any;\r\n protected filteredItems: TData[] = [];\r\n protected compiledFilter?: FilterFn | null;\r\n protected compiledFilterCSPSafe?: FilterCspFn | null;\r\n protected compiledFilterWithCaching?: FilterFn | null;\r\n protected compiledFilterWithCachingCSPSafe?: FilterWithCspCachingFn | null;\r\n protected filterCache: any[] = [];\r\n protected _grid?: SlickGridModel; // grid object will be defined only after using \"syncGridSelection()\" method\"\r\n\r\n // grouping\r\n protected groupingInfoDefaults: Grouping = {\r\n getter: undefined,\r\n formatter: undefined,\r\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\r\n predefinedValues: [],\r\n aggregators: [],\r\n aggregateEmpty: false,\r\n aggregateCollapsed: false,\r\n aggregateChildGroups: false,\r\n collapsed: false,\r\n displayTotalsRow: true,\r\n lazyTotalsCalculation: false\r\n };\r\n protected groupingInfos: Array = [];\r\n protected groups: SlickGroup_[] = [];\r\n protected toggledGroupsByLevel: any[] = [];\r\n protected groupingDelimiter = ':|:';\r\n protected selectedRowIds: DataIdType[] = [];\r\n protected preSelectedRowIdsChangeFn?: (args?: any) => void;\r\n\r\n protected pagesize = 0;\r\n protected pagenum = 0;\r\n protected totalRows = 0;\r\n protected _options: DataViewOption;\r\n protected _container?: HTMLElement;\r\n\r\n // public events\r\n onBeforePagingInfoChanged: SlickEvent_;\r\n onGroupExpanded: SlickEvent_;\r\n onGroupCollapsed: SlickEvent_;\r\n onPagingInfoChanged: SlickEvent_;\r\n onRowCountChanged: SlickEvent_;\r\n onRowsChanged: SlickEvent_;\r\n onRowsOrCountChanged: SlickEvent_;\r\n onSelectedRowIdsChanged: SlickEvent_;\r\n onSetItemsCalled: SlickEvent_;\r\n\r\n constructor(options?: Partial, protected externalPubSub?: BasePubSub) {\r\n this.onBeforePagingInfoChanged = new SlickEvent('onBeforePagingInfoChanged', externalPubSub);\r\n this.onGroupExpanded = new SlickEvent('onGroupExpanded', externalPubSub);\r\n this.onGroupCollapsed = new SlickEvent('onGroupCollapsed', externalPubSub);\r\n this.onPagingInfoChanged = new SlickEvent('onPagingInfoChanged', externalPubSub);\r\n this.onRowCountChanged = new SlickEvent('onRowCountChanged', externalPubSub);\r\n this.onRowsChanged = new SlickEvent('onRowsChanged', externalPubSub);\r\n this.onRowsOrCountChanged = new SlickEvent('onRowsOrCountChanged', externalPubSub);\r\n this.onSelectedRowIdsChanged = new SlickEvent('onSelectedRowIdsChanged', externalPubSub);\r\n this.onSetItemsCalled = new SlickEvent('onSetItemsCalled', externalPubSub);\r\n\r\n this._options = Utils.extend(true, {}, this.defaults, options);\r\n }\r\n\r\n /**\r\n * Begins a bached update of the items in the data view.\r\n * including deletes and the related events are postponed to the endUpdate call.\r\n * As certain operations are postponed during this update, some methods might not\r\n * deliver fully consistent information.\r\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\r\n */\r\n beginUpdate(bulkUpdate?: boolean) {\r\n this.suspend = true;\r\n this.isBulkSuspend = bulkUpdate === true;\r\n }\r\n\r\n endUpdate() {\r\n const wasBulkSuspend = this.isBulkSuspend;\r\n this.isBulkSuspend = false;\r\n this.suspend = false;\r\n if (wasBulkSuspend) {\r\n this.processBulkDelete();\r\n this.ensureIdUniqueness();\r\n }\r\n this.refresh();\r\n }\r\n\r\n destroy() {\r\n this.items = [];\r\n this.idxById = null as any;\r\n this.rowsById = null as any;\r\n this.filter = null as any;\r\n this.filterCSPSafe = null as any;\r\n this.updated = null as any;\r\n this.sortComparer = null as any;\r\n this.filterCache = [];\r\n this.filteredItems = [];\r\n this.compiledFilter = null;\r\n this.compiledFilterCSPSafe = null;\r\n this.compiledFilterWithCaching = null;\r\n this.compiledFilterWithCachingCSPSafe = null;\r\n\r\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\r\n this._grid.onSelectedRowsChanged.unsubscribe();\r\n this._grid.onCellCssStylesChanged.unsubscribe();\r\n }\r\n if (this.onRowsOrCountChanged) {\r\n this.onRowsOrCountChanged.unsubscribe();\r\n }\r\n }\r\n\r\n /** provide some refresh hints as to what to rows needs refresh */\r\n setRefreshHints(hints: DataViewHints) {\r\n this.refreshHints = hints;\r\n }\r\n\r\n /** get extra filter arguments of the filter method */\r\n getFilterArgs() {\r\n return this.filterArgs;\r\n }\r\n\r\n /** add extra filter arguments to the filter method */\r\n setFilterArgs(args: any) {\r\n this.filterArgs = args;\r\n }\r\n\r\n /**\r\n * Processes all delete requests placed during bulk update\r\n * by recomputing the items and idxById members.\r\n */\r\n protected processBulkDelete() {\r\n if (!this.idxById) { return; }\r\n\r\n // the bulk update is processed by\r\n // recomputing the whole items array and the index lookup in one go.\r\n // this is done by placing the not-deleted items\r\n // from left to right into the array and shrink the array the the new\r\n // size afterwards.\r\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\r\n\r\n let id: DataIdType, item, newIdx = 0;\r\n for (let i = 0, l = this.items.length; i < l; i++) {\r\n item = this.items[i];\r\n id = item[this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n\r\n // if items have been marked as deleted we skip them for the new final items array\r\n // and we remove them from the lookup table.\r\n if (this.bulkDeleteIds.has(id)) {\r\n this.idxById.delete(id);\r\n } else {\r\n // for items which are not deleted, we add them to the\r\n // next free position in the array and register the index in the lookup.\r\n this.items[newIdx] = item;\r\n this.idxById.set(id, newIdx);\r\n ++newIdx;\r\n }\r\n }\r\n\r\n // here we shrink down the full item array to the ones actually\r\n // inserted in the cleanup loop above.\r\n this.items.length = newIdx;\r\n // and finally cleanup the deleted ids to start cleanly on the next update.\r\n this.bulkDeleteIds = new Map();\r\n }\r\n\r\n protected updateIdxById(startingIndex?: number) {\r\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\r\n return;\r\n }\r\n startingIndex = startingIndex || 0;\r\n let id: DataIdType;\r\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\r\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n this.idxById.set(id, i);\r\n }\r\n }\r\n\r\n protected ensureIdUniqueness() {\r\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\r\n return;\r\n }\r\n let id: DataIdType;\r\n for (let i = 0, l = this.items.length; i < l; i++) {\r\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined || this.idxById.get(id) !== i) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n }\r\n }\r\n\r\n /** Get all DataView Items */\r\n getItems() {\r\n return this.items;\r\n }\r\n\r\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\r\n getIdPropertyName() {\r\n return this.idProperty;\r\n }\r\n\r\n /**\r\n * Set the Items with a new Dataset and optionally pass a different Id property name\r\n * @param {Array<*>} data - array of data\r\n * @param {String} [objectIdProperty] - optional id property to use as primary id\r\n */\r\n setItems(data: TData[], objectIdProperty?: string) {\r\n if (objectIdProperty !== undefined) {\r\n this.idProperty = objectIdProperty;\r\n }\r\n this.items = this.filteredItems = data;\r\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.ensureIdUniqueness();\r\n this.refresh();\r\n }\r\n\r\n /** Set Paging Options */\r\n setPagingOptions(args: Partial) {\r\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\r\n if (Utils.isDefined(args.pageSize)) {\r\n this.pagesize = args.pageSize;\r\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\r\n }\r\n\r\n if (Utils.isDefined(args.pageNum)) {\r\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\r\n }\r\n\r\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\r\n\r\n this.refresh();\r\n }\r\n }\r\n\r\n /** Get Paging Options */\r\n getPagingInfo(): PagingInfo {\r\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\r\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages, dataView: this as SlickDataView };\r\n }\r\n\r\n /** Sort Method to use by the DataView */\r\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\r\n this.sortAsc = ascending;\r\n this.sortComparer = comparer;\r\n this.fastSortField = null;\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.items.sort(comparer);\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Provides a workaround for the extremely slow sorting in IE.\r\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\r\n * to return the value of that field and then doing a native Array.sort().\r\n */\r\n fastSort(field: string | (() => string), ascending?: boolean) {\r\n this.sortAsc = ascending;\r\n this.fastSortField = field;\r\n this.sortComparer = null as any;\r\n const oldToString = Object.prototype.toString;\r\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\r\n // @ts-ignore\r\n return this[field];\r\n };\r\n // an extra reversal for descending sort keeps the sort stable\r\n // (assuming a stable native sort implementation, which isn't true in some cases)\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.items.sort();\r\n Object.prototype.toString = oldToString;\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.refresh();\r\n }\r\n\r\n /** Re-Sort the dataset */\r\n reSort() {\r\n if (this.sortComparer) {\r\n this.sort(this.sortComparer, this.sortAsc);\r\n } else if (this.fastSortField) {\r\n this.fastSort(this.fastSortField, this.sortAsc);\r\n }\r\n }\r\n\r\n /** Get only the DataView filtered items */\r\n getFilteredItems() {\r\n return this.filteredItems as T[];\r\n }\r\n\r\n /** Get the array length (count) of only the DataView filtered items */\r\n getFilteredItemCount() {\r\n return this.filteredItems.length;\r\n }\r\n\r\n /** Get current Filter used by the DataView */\r\n getFilter() {\r\n return this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter;\r\n }\r\n\r\n /**\r\n * Set a Filter that will be used by the DataView\r\n * @param {Function} fn - filter callback function\r\n */\r\n setFilter(filterFn: FilterFn) {\r\n this.filterCSPSafe = filterFn;\r\n this.filter = filterFn;\r\n if (this._options.inlineFilters) {\r\n this.compiledFilterCSPSafe = this.compileFilterCSPSafe;\r\n this.compiledFilterWithCachingCSPSafe = this.compileFilterWithCachingCSPSafe;\r\n this.compiledFilter = this.compileFilter(this._options.useCSPSafeFilter);\r\n this.compiledFilterWithCaching = this.compileFilterWithCaching(this._options.useCSPSafeFilter);\r\n }\r\n this.refresh();\r\n }\r\n\r\n /** Get current Grouping info */\r\n getGrouping(): Grouping[] {\r\n return this.groupingInfos;\r\n }\r\n\r\n /** Set some Grouping */\r\n setGrouping(groupingInfo: Grouping | Grouping[]) {\r\n if (!this._options.groupItemMetadataProvider) {\r\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\r\n }\r\n\r\n this.groups = [];\r\n this.toggledGroupsByLevel = [];\r\n groupingInfo = groupingInfo || [];\r\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\r\n\r\n for (let i = 0; i < this.groupingInfos.length; i++) {\r\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\r\n gi.getterIsAFn = typeof gi.getter === 'function';\r\n\r\n // pre-compile accumulator loops\r\n gi.compiledAccumulators = [];\r\n let idx = gi.aggregators.length;\r\n while (idx--) {\r\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoopCSPSafe(gi.aggregators[idx]);\r\n }\r\n\r\n this.toggledGroupsByLevel[i] = {};\r\n }\r\n\r\n this.refresh();\r\n }\r\n\r\n /** Get an item in the DataView by its row index */\r\n getItemByIdx(i: number) {\r\n return this.items[i] as T;\r\n }\r\n\r\n /** Get row index in the DataView by its Id */\r\n getIdxById(id: DataIdType) {\r\n return this.idxById?.get(id);\r\n }\r\n\r\n protected ensureRowsByIdCache() {\r\n if (!this.rowsById) {\r\n this.rowsById = {};\r\n for (let i = 0, l = this.rows.length; i < l; i++) {\r\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\r\n }\r\n }\r\n }\r\n\r\n /** Get row number in the grid by its item object */\r\n getRowByItem(item: TData) {\r\n this.ensureRowsByIdCache();\r\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\r\n }\r\n\r\n /** Get row number in the grid by its Id */\r\n getRowById(id: DataIdType) {\r\n this.ensureRowsByIdCache();\r\n return this.rowsById?.[id];\r\n }\r\n\r\n /** Get an item in the DataView by its Id */\r\n getItemById(id: DataIdType) {\r\n return this.items[(this.idxById.get(id) as number)] as T;\r\n }\r\n\r\n /** From the items array provided, return the mapped rows */\r\n mapItemsToRows(itemArray: TData[]) {\r\n const rows: number[] = [];\r\n this.ensureRowsByIdCache();\r\n for (let i = 0, l = itemArray.length; i < l; i++) {\r\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\r\n if (Utils.isDefined(row)) {\r\n rows[rows.length] = row as number;\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n /** From the Ids array provided, return the mapped rows */\r\n mapIdsToRows(idArray: DataIdType[]) {\r\n const rows: number[] = [];\r\n this.ensureRowsByIdCache();\r\n for (let i = 0, l = idArray.length; i < l; i++) {\r\n const row = this.rowsById?.[idArray[i]];\r\n if (Utils.isDefined(row)) {\r\n rows[rows.length] = row as number;\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n /** From the rows array provided, return the mapped Ids */\r\n mapRowsToIds(rowArray: number[]) {\r\n const ids: DataIdType[] = [];\r\n for (let i = 0, l = rowArray.length; i < l; i++) {\r\n if (rowArray[i] < this.rows.length) {\r\n const rowItem = this.rows[rowArray[i]];\r\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\r\n }\r\n }\r\n return ids;\r\n }\r\n\r\n /**\r\n * Performs the update operations of a single item by id without\r\n * triggering any events or refresh operations.\r\n * @param id The new id of the item.\r\n * @param item The item which should be the new value for the given id.\r\n */\r\n updateSingleItem(id: DataIdType, item: TData) {\r\n if (!this.idxById) { return; }\r\n\r\n // see also https://github.com/mleibman/SlickGrid/issues/1082\r\n if (!this.idxById.has(id)) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n\r\n // What if the specified item also has an updated idProperty?\r\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\r\n if (id !== item[this.idProperty as keyof TData]) {\r\n // make sure the new id is unique:\r\n const newId = item[this.idProperty as keyof TData] as DataIdType;\r\n if (!Utils.isDefined(newId)) {\r\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\r\n }\r\n if (this.idxById.has(newId)) {\r\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\r\n }\r\n this.idxById.set(newId, this.idxById.get(id) as number);\r\n this.idxById.delete(id);\r\n\r\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\r\n if (this.updated?.[id]) {\r\n delete this.updated[id];\r\n }\r\n\r\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\r\n\r\n id = newId;\r\n }\r\n this.items[this.idxById.get(id) as number] = item;\r\n\r\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\r\n\r\n if (!this.updated) {\r\n this.updated = {};\r\n }\r\n this.updated[id] = true;\r\n }\r\n\r\n /**\r\n * Updates a single item in the data view given the id and new value.\r\n * @param id The new id of the item.\r\n * @param item The item which should be the new value for the given id.\r\n */\r\n updateItem(id: DataIdType, item: T) {\r\n this.updateSingleItem(id, item);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Updates multiple items in the data view given the new ids and new values.\r\n * @param id {Array} The array of new ids which is in the same order as the items.\r\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\r\n */\r\n updateItems(ids: DataIdType[], newItems: T[]) {\r\n if (ids.length !== newItems.length) {\r\n throw new Error('[SlickGrid DataView] Mismatch on the length of ids and items provided to update');\r\n }\r\n for (let i = 0, l = newItems.length; i < l; i++) {\r\n this.updateSingleItem(ids[i], newItems[i]);\r\n }\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Inserts a single item into the data view at the given position.\r\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\r\n * @param item The item to insert.\r\n */\r\n insertItem(insertBefore: number, item: TData) {\r\n this.items.splice(insertBefore, 0, item);\r\n this.updateIdxById(insertBefore);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Inserts multiple items into the data view at the given position.\r\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\r\n * @param newItems {Array} The items to insert.\r\n */\r\n insertItems(insertBefore: number, newItems: TData[]) {\r\n // @ts-ignore\r\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\r\n this.updateIdxById(insertBefore);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Adds a single item at the end of the data view.\r\n * @param item The item to add at the end.\r\n */\r\n addItem(item: TData) {\r\n this.items.push(item);\r\n this.updateIdxById(this.items.length - 1);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Adds multiple items at the end of the data view.\r\n * @param {Array} newItems The items to add at the end.\r\n */\r\n addItems(newItems: TData[]) {\r\n this.items = this.items.concat(newItems);\r\n this.updateIdxById(this.items.length - newItems.length);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Deletes a single item identified by the given id from the data view.\r\n * @param {String|Number} id The id identifying the object to delete.\r\n */\r\n deleteItem(id: DataIdType) {\r\n if (!this.idxById) { return; }\r\n if (this.isBulkSuspend) {\r\n this.bulkDeleteIds.set(id, true);\r\n } else {\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.idxById.delete(id);\r\n this.items.splice(idx, 1);\r\n this.updateIdxById(idx);\r\n this.refresh();\r\n }\r\n }\r\n\r\n /**\r\n * Deletes multiple item identified by the given ids from the data view.\r\n * @param {Array} ids The ids of the items to delete.\r\n */\r\n deleteItems(ids: DataIdType[]) {\r\n if (ids.length === 0 || !this.idxById) {\r\n return;\r\n }\r\n\r\n if (this.isBulkSuspend) {\r\n for (let i = 0, l = ids.length; i < l; i++) {\r\n const id = ids[i];\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.bulkDeleteIds.set(id, true);\r\n }\r\n } else {\r\n // collect all indexes\r\n const indexesToDelete: number[] = [];\r\n for (let i = 0, l = ids.length; i < l; i++) {\r\n const id = ids[i];\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.idxById.delete(id);\r\n indexesToDelete.push(idx);\r\n }\r\n\r\n // Remove from back to front\r\n indexesToDelete.sort();\r\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\r\n this.items.splice(indexesToDelete[i], 1);\r\n }\r\n\r\n // update lookup from front to back\r\n this.updateIdxById(indexesToDelete[0]);\r\n this.refresh();\r\n }\r\n }\r\n\r\n /** Add an item in a sorted dataset (a Sort function must be defined) */\r\n sortedAddItem(item: TData) {\r\n if (!this.sortComparer) {\r\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\r\n }\r\n this.insertItem(this.sortedIndex(item), item);\r\n }\r\n\r\n /** Update an item in a sorted dataset (a Sort function must be defined) */\r\n sortedUpdateItem(id: string | number, item: TData) {\r\n if (!this.idxById) { return; }\r\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\r\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\r\n }\r\n if (!this.sortComparer) {\r\n throw new Error('[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()');\r\n }\r\n const oldItem = this.getItemById(id);\r\n if (this.sortComparer(oldItem, item) !== 0) {\r\n // item affects sorting -> must use sorted add\r\n this.deleteItem(id);\r\n this.sortedAddItem(item);\r\n } else { // update does not affect sorting -> regular update works fine\r\n this.updateItem(id, item);\r\n }\r\n }\r\n\r\n protected sortedIndex(searchItem: TData) {\r\n let low = 0;\r\n let high = this.items.length;\r\n\r\n while (low < high) {\r\n const mid = low + high >>> 1;\r\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\r\n low = mid + 1;\r\n } else {\r\n high = mid;\r\n }\r\n }\r\n return low;\r\n }\r\n\r\n /** Get item count, that is the full dataset lenght of the DataView */\r\n getItemCount() {\r\n return this.items.length;\r\n }\r\n\r\n /** Get row count (rows displayed in current page) */\r\n getLength() {\r\n return this.rows.length;\r\n }\r\n\r\n /** Retrieve an item from the DataView at specific index */\r\n getItem(i: number) {\r\n const item = this.rows[i] as T;\r\n\r\n // if this is a group row, make sure totals are calculated and update the title\r\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\r\n const gi = this.groupingInfos[(item as SlickGroup_).level];\r\n if (!gi.displayTotalsRow) {\r\n this.calculateTotals((item as SlickGroup_).totals);\r\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\r\n }\r\n }\r\n // if this is a totals row, make sure it's calculated\r\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\r\n this.calculateTotals(item as SlickGroupTotals_);\r\n }\r\n\r\n return item;\r\n }\r\n\r\n getItemMetadata(i: number): ItemMetadata | null {\r\n const item = this.rows[i];\r\n if (item === undefined) {\r\n return null;\r\n }\r\n\r\n // overrides for grouping rows\r\n if ((item as SlickGroup_).__group) {\r\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\r\n }\r\n\r\n // overrides for totals rows\r\n if ((item as SlickGroupTotals_).__groupTotals) {\r\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\r\n }\r\n\r\n return null;\r\n }\r\n\r\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\r\n if (!Utils.isDefined(level)) {\r\n for (let i = 0; i < this.groupingInfos.length; i++) {\r\n this.toggledGroupsByLevel[i] = {};\r\n this.groupingInfos[i].collapsed = collapse;\r\n\r\n if (collapse === true) {\r\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\r\n } else {\r\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\r\n }\r\n }\r\n } else {\r\n this.toggledGroupsByLevel[level] = {};\r\n this.groupingInfos[level].collapsed = collapse;\r\n\r\n if (collapse === true) {\r\n this.onGroupCollapsed.notify({ level, groupingKey: null });\r\n } else {\r\n this.onGroupExpanded.notify({ level, groupingKey: null });\r\n }\r\n }\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\r\n */\r\n collapseAllGroups(level?: number) {\r\n this.expandCollapseAllGroups(level, true);\r\n }\r\n\r\n /**\r\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\r\n */\r\n expandAllGroups(level?: number) {\r\n this.expandCollapseAllGroups(level, false);\r\n }\r\n\r\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\r\n // @ts-ignore\r\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * variable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n collapseGroup(...args: any) {\r\n const calledArgs = Array.prototype.slice.call(args);\r\n const arg0 = calledArgs[0];\r\n let groupingKey: string;\r\n let level: number;\r\n\r\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\r\n groupingKey = arg0;\r\n level = arg0.split(this.groupingDelimiter).length - 1;\r\n } else {\r\n groupingKey = args.join(this.groupingDelimiter);\r\n level = args.length - 1;\r\n }\r\n\r\n this.expandCollapseGroup(level, groupingKey, true);\r\n this.onGroupCollapsed.notify({ level, groupingKey });\r\n }\r\n\r\n /**\r\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * variable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n expandGroup(...args: any) {\r\n const calledArgs = Array.prototype.slice.call(args);\r\n const arg0 = calledArgs[0];\r\n let groupingKey: string;\r\n let level: number;\r\n\r\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\r\n level = arg0.split(this.groupingDelimiter).length - 1;\r\n groupingKey = arg0;\r\n } else {\r\n level = args.length - 1;\r\n groupingKey = args.join(this.groupingDelimiter);\r\n }\r\n\r\n this.expandCollapseGroup(level, groupingKey, false);\r\n this.onGroupExpanded.notify({ level, groupingKey });\r\n }\r\n\r\n getGroups() {\r\n return this.groups;\r\n }\r\n\r\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\r\n let group: SlickGroup_;\r\n let val: any;\r\n const groups: SlickGroup_[] = [];\r\n const groupsByVal: any = {};\r\n let r;\r\n const level = parentGroup ? parentGroup.level + 1 : 0;\r\n const gi = this.groupingInfos[level];\r\n\r\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\r\n val = gi.predefinedValues?.[i];\r\n group = groupsByVal[val];\r\n if (!group) {\r\n group = new SlickGroup();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n }\r\n\r\n for (let i = 0, l = rows.length; i < l; i++) {\r\n r = rows[i];\r\n val = gi.getterIsAFn ? (gi.getter as GroupGetterFn)(r) : r[gi.getter as keyof TData];\r\n group = groupsByVal[val];\r\n if (!group) {\r\n group = new SlickGroup();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n\r\n group.rows[group.count++] = r;\r\n }\r\n\r\n if (level < this.groupingInfos.length - 1) {\r\n for (let i = 0; i < groups.length; i++) {\r\n group = groups[i];\r\n group.groups = this.extractGroups(group.rows, group);\r\n }\r\n }\r\n\r\n if (groups.length) {\r\n this.addTotals(groups, level);\r\n }\r\n\r\n groups.sort(this.groupingInfos[level].comparer);\r\n\r\n return groups;\r\n }\r\n\r\n /** claculate Group Totals */\r\n protected calculateTotals(totals: SlickGroupTotals_) {\r\n const group = totals.group;\r\n const gi = this.groupingInfos[group.level ?? 0];\r\n const isLeafLevel = (group.level === this.groupingInfos.length);\r\n let agg: Aggregator;\r\n let idx = gi.aggregators.length;\r\n\r\n if (!isLeafLevel && gi.aggregateChildGroups) {\r\n // make sure all the subgroups are calculated\r\n let i = group.groups?.length ?? 0;\r\n while (i--) {\r\n if (!group.groups[i].totals.initialized) {\r\n this.calculateTotals(group.groups[i].totals);\r\n }\r\n }\r\n }\r\n\r\n while (idx--) {\r\n agg = gi.aggregators[idx];\r\n agg.init();\r\n if (!isLeafLevel && gi.aggregateChildGroups) {\r\n gi.compiledAccumulators[idx].call(agg, group.groups);\r\n } else {\r\n gi.compiledAccumulators[idx].call(agg, group.rows);\r\n }\r\n agg.storeResult(totals);\r\n }\r\n totals.initialized = true;\r\n }\r\n\r\n protected addGroupTotals(group: SlickGroup_) {\r\n const gi = this.groupingInfos[group.level];\r\n const totals = new SlickGroupTotals();\r\n totals.group = group;\r\n group.totals = totals;\r\n if (!gi.lazyTotalsCalculation) {\r\n this.calculateTotals(totals);\r\n }\r\n }\r\n\r\n protected addTotals(groups: SlickGroup_[], level?: number) {\r\n level = level || 0;\r\n const gi = this.groupingInfos[level];\r\n const groupCollapsed = gi.collapsed;\r\n const toggledGroups = this.toggledGroupsByLevel[level];\r\n let idx = groups.length, g;\r\n while (idx--) {\r\n g = groups[idx];\r\n\r\n if (g.collapsed && !gi.aggregateCollapsed) {\r\n continue;\r\n }\r\n\r\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\r\n if (g.groups) {\r\n this.addTotals(g.groups, level + 1);\r\n }\r\n\r\n if (gi.aggregators?.length && (\r\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\r\n this.addGroupTotals(g);\r\n }\r\n\r\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\r\n g.title = gi.formatter ? gi.formatter(g) : g.value;\r\n }\r\n }\r\n\r\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\r\n level = level || 0;\r\n const gi = this.groupingInfos[level];\r\n const groupedRows: any[] = [];\r\n let rows: any[];\r\n let gl = 0;\r\n let g;\r\n for (let i = 0, l = groups.length; i < l; i++) {\r\n g = groups[i];\r\n groupedRows[gl++] = g;\r\n\r\n if (!g.collapsed) {\r\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\r\n for (let j = 0, jj = rows.length; j < jj; j++) {\r\n groupedRows[gl++] = rows[j];\r\n }\r\n }\r\n\r\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\r\n groupedRows[gl++] = g.totals;\r\n }\r\n }\r\n return groupedRows;\r\n }\r\n\r\n protected compileAccumulatorLoopCSPSafe(aggregator: Aggregator) {\r\n if (aggregator.accumulate) {\r\n return function (items: any[]) {\r\n let result;\r\n for (let i = 0; i < items.length; i++) {\r\n const item = items[i];\r\n result = aggregator.accumulate!.call(aggregator, item);\r\n }\r\n return result;\r\n };\r\n } else {\r\n return function noAccumulator() { };\r\n }\r\n }\r\n\r\n protected compileFilterCSPSafe(items: TData[], args: any): TData[] {\r\n if (typeof this.filterCSPSafe !== 'function') {\r\n return [];\r\n }\r\n const _retval: TData[] = [];\r\n const _il = items.length;\r\n\r\n for (let _i = 0; _i < _il; _i++) {\r\n if (this.filterCSPSafe(items[_i], args)) {\r\n _retval.push(items[_i]);\r\n }\r\n }\r\n\r\n return _retval;\r\n }\r\n\r\n protected compileFilter(stopRunningIfCSPSafeIsActive = false): FilterFn | null {\r\n if (stopRunningIfCSPSafeIsActive) {\r\n return null as any;\r\n }\r\n const filterInfo = Utils.getFunctionDetails(this.filter as FilterFn);\r\n\r\n const filterPath1 = '{ continue _coreloop; }$1';\r\n const filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n const filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // 'function(_items, _args) { ',\r\n 'var _retval = [], _idx = 0; ',\r\n 'var $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (var _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // '}'\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n const fn: any = new Function('_items,_args', tpl);\r\n const fnName = 'compiledFilter';\r\n fn.displayName = fnName;\r\n fn.name = this.setFunctionName(fn, fnName);\r\n return fn;\r\n }\r\n\r\n protected compileFilterWithCaching(stopRunningIfCSPSafeIsActive = false) {\r\n if (stopRunningIfCSPSafeIsActive) {\r\n return null as any;\r\n }\r\n\r\n const filterInfo = Utils.getFunctionDetails(this.filter as FilterFn);\r\n\r\n const filterPath1 = '{ continue _coreloop; }$1';\r\n const filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n const filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // 'function(_items, _args, _cache) { ',\r\n 'var _retval = [], _idx = 0; ',\r\n 'var $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (var _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n 'if (_cache[_i]) { ',\r\n '_retval[_idx++] = $item$; ',\r\n 'continue _coreloop; ',\r\n '} ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // '}'\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n\r\n const fn: any = new Function('_items,_args,_cache', tpl);\r\n const fnName = 'compiledFilterWithCaching';\r\n fn.displayName = fnName;\r\n fn.name = this.setFunctionName(fn, fnName);\r\n return fn;\r\n }\r\n\r\n protected compileFilterWithCachingCSPSafe(items: TData[], args: any, filterCache: any[]): TData[] {\r\n if (typeof this.filterCSPSafe !== 'function') {\r\n return [];\r\n }\r\n\r\n const retval: TData[] = [];\r\n const il = items.length;\r\n\r\n for (let _i = 0; _i < il; _i++) {\r\n if (filterCache[_i] || this.filterCSPSafe(items[_i], args)) {\r\n retval.push(items[_i]);\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n /**\r\n * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently\r\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\r\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\r\n * @param {*} fn\r\n * @param {string} fnName\r\n */\r\n protected setFunctionName(fn: any, fnName: string) {\r\n try {\r\n Object.defineProperty(fn, 'name', { writable: true, value: fnName });\r\n } catch (err) {\r\n fn.name = fnName;\r\n }\r\n }\r\n\r\n protected uncompiledFilter(items: TData[], args: any) {\r\n const retval: any[] = [];\r\n let idx = 0;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++) {\r\n if (this.filter?.(items[i], args)) {\r\n retval[idx++] = items[i];\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\r\n const retval: any[] = [];\r\n let idx = 0,\r\n item: TData;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++) {\r\n item = items[i];\r\n if (cache[i]) {\r\n retval[idx++] = item;\r\n } else if (this.filter?.(item, args)) {\r\n retval[idx++] = item;\r\n cache[i] = true;\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n protected getFilteredAndPagedItems(items: TData[]) {\r\n if (this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter) {\r\n let batchFilter: AnyFunction;\r\n let batchFilterWithCaching: AnyFunction;\r\n if (this._options.useCSPSafeFilter) {\r\n batchFilter = (this._options.inlineFilters ? this.compiledFilterCSPSafe : this.uncompiledFilter) as AnyFunction;\r\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingCSPSafe : this.uncompiledFilterWithCaching) as AnyFunction;\r\n } else {\r\n batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as AnyFunction;\r\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as AnyFunction;\r\n }\r\n if (this.refreshHints.isFilterNarrowing) {\r\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\r\n } else if (this.refreshHints.isFilterExpanding) {\r\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\r\n } else if (!this.refreshHints.isFilterUnchanged) {\r\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\r\n }\r\n } else {\r\n // special case: if not filtering and not paging, the resulting\r\n // rows collection needs to be a copy so that changes due to sort\r\n // can be caught\r\n this.filteredItems = this.pagesize ? items : items.concat();\r\n }\r\n\r\n // get the current page\r\n let paged: TData[];\r\n if (this.pagesize) {\r\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\r\n if (this.filteredItems.length === 0) {\r\n this.pagenum = 0;\r\n } else {\r\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\r\n }\r\n }\r\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\r\n } else {\r\n paged = this.filteredItems;\r\n }\r\n return { totalRows: this.filteredItems.length, rows: paged };\r\n }\r\n\r\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\r\n let item: TData | SlickNonDataItem | SlickDataItem | SlickGroup_;\r\n let r;\r\n let eitherIsNonData;\r\n const diff: number[] = [];\r\n let from = 0;\r\n let to = Math.max(newRows.length, rows.length);\r\n\r\n if (this.refreshHints?.ignoreDiffsBefore) {\r\n from = Math.max(0,\r\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\r\n }\r\n\r\n if (this.refreshHints?.ignoreDiffsAfter) {\r\n to = Math.min(newRows.length,\r\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\r\n }\r\n\r\n for (let i = from, rl = rows.length; i < to; i++) {\r\n if (i >= rl) {\r\n diff[diff.length] = i;\r\n } else {\r\n item = newRows[i];\r\n r = rows[i];\r\n\r\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\r\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\r\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\r\n || (eitherIsNonData &&\r\n // no good way to compare totals since they are arbitrary DTOs\r\n // deep object comparison is pretty expensive\r\n // always considering them 'dirty' seems easier for the time being\r\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\r\n || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData]\r\n || (this.updated?.[item[this.idProperty as keyof TData]])\r\n ) {\r\n diff[diff.length] = i;\r\n }\r\n }\r\n }\r\n return diff;\r\n }\r\n\r\n protected recalc(_items: TData[]) {\r\n this.rowsById = undefined;\r\n\r\n if (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing ||\r\n this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) {\r\n this.filterCache = [];\r\n }\r\n\r\n const filteredItems = this.getFilteredAndPagedItems(_items);\r\n this.totalRows = filteredItems.totalRows;\r\n let newRows: TData[] = filteredItems.rows;\r\n\r\n this.groups = [];\r\n if (this.groupingInfos.length) {\r\n this.groups = this.extractGroups(newRows);\r\n if (this.groups.length) {\r\n newRows = this.flattenGroupedRows(this.groups);\r\n }\r\n }\r\n\r\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\r\n\r\n this.rows = newRows as TData[];\r\n\r\n return diff;\r\n }\r\n\r\n refresh() {\r\n if (this.suspend) {\r\n return;\r\n }\r\n\r\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\r\n\r\n const countBefore = this.rows.length;\r\n const totalRowsBefore = this.totalRows;\r\n\r\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\r\n\r\n // if the current page is no longer valid, go to last page and recalc\r\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\r\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\r\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\r\n diff = this.recalc(this.items);\r\n }\r\n\r\n this.updated = null;\r\n this.prevRefreshHints = this.refreshHints;\r\n this.refreshHints = {};\r\n\r\n if (totalRowsBefore !== this.totalRows) {\r\n // use the previously saved paging info\r\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\r\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\r\n }\r\n }\r\n if (countBefore !== this.rows.length) {\r\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\r\n }\r\n if (diff.length > 0) {\r\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\r\n }\r\n if (countBefore !== this.rows.length || diff.length > 0) {\r\n this.onRowsOrCountChanged.notify({\r\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\r\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\r\n }, null, this);\r\n }\r\n }\r\n\r\n /**\r\n * Wires the grid and the DataView together to keep row selection tied to item ids.\r\n * This is useful since, without it, the grid only knows about rows, so if the items\r\n * move around, the same rows stay selected instead of the selection moving along\r\n * with the items.\r\n *\r\n * NOTE: This doesn't work with cell selection model.\r\n *\r\n * @param {SlickGrid} grid - The grid to sync selection with.\r\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\r\n * view due to them getting filtered out.\r\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\r\n * that are currently out of the view (see preserveHidden) as selected when selection\r\n * changes.\r\n * @return {Event} An event that notifies when an internal list of selected row ids\r\n * changes. This is useful since, in combination with the above two options, it allows\r\n * access to the full list selected row ids, and not just the ones visible to the grid.\r\n * @method syncGridSelection\r\n */\r\n syncGridSelection(grid: SlickGridModel, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\r\n this._grid = grid;\r\n let inHandler: boolean;\r\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\r\n\r\n /** @param {Array} rowIds */\r\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\r\n if (rowIds === false) {\r\n this.selectedRowIds = [];\r\n } else {\r\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\r\n this.selectedRowIds = rowIds;\r\n }\r\n }\r\n };\r\n\r\n const update = () => {\r\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\r\n inHandler = true;\r\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\r\n if (!preserveHidden) {\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: this.mapRowsToIds(selectedRows),\r\n rows: selectedRows,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n grid.setSelectedRows(selectedRows);\r\n inHandler = false;\r\n }\r\n };\r\n\r\n grid.onSelectedRowsChanged.subscribe((_e: SlickEventData_, args: { rows: number[]; }) => {\r\n if (!inHandler) {\r\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: newSelectedRowIds,\r\n rows: args.rows,\r\n added: true,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n });\r\n\r\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\r\n if (!inHandler) {\r\n inHandler = true;\r\n const overwrite = (typeof args.added === typeof undefined);\r\n\r\n if (overwrite) {\r\n setSelectedRowIds(args.ids);\r\n } else {\r\n let rowIds: DataIdType[];\r\n if (args.added) {\r\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\r\n // find the ones that are hidden\r\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\r\n // add the newly selected ones\r\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\r\n } else {\r\n rowIds = args.ids;\r\n }\r\n } else {\r\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\r\n // remove rows whose id is on the list\r\n rowIds = this.selectedRowIds!.filter((id) => args.ids.indexOf(id) === -1);\r\n } else {\r\n rowIds = [];\r\n }\r\n }\r\n setSelectedRowIds(rowIds);\r\n }\r\n inHandler = false;\r\n }\r\n };\r\n\r\n this.onRowsOrCountChanged.subscribe(update.bind(this));\r\n\r\n return this.onSelectedRowIdsChanged;\r\n }\r\n\r\n /**\r\n * Get all selected IDs\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedIds() {\r\n return this.selectedRowIds;\r\n }\r\n\r\n /**\r\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedFilteredIds() {\r\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\r\n }\r\n\r\n /**\r\n * Set current row selected IDs array (regardless of Pagination)\r\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\r\n * \"grid.setSelectedRows(rows)\"\r\n * @param {Array} selectedIds - list of IDs which have been selected for this action\r\n * @param {Object} options\r\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\r\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\r\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\r\n */\r\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\r\n let isRowBeingAdded = options?.isRowBeingAdded;\r\n const shouldTriggerEvent = options?.shouldTriggerEvent;\r\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\r\n\r\n if (isRowBeingAdded !== false) {\r\n isRowBeingAdded = true;\r\n }\r\n const selectedRows = this.mapIdsToRows(selectedIds);\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: selectedIds,\r\n rows: selectedRows,\r\n added: isRowBeingAdded,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\r\n\r\n if (shouldTriggerEvent !== false) {\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n\r\n // should we also apply the row selection in to the grid (UI) as well?\r\n if (applyRowSelectionToGrid !== false && this._grid) {\r\n this._grid.setSelectedRows(selectedRows);\r\n }\r\n }\r\n\r\n /**\r\n * Get all selected dataContext items\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedItems() {\r\n const selectedData: TData[] = [];\r\n const selectedIds = this.getAllSelectedIds();\r\n selectedIds!.forEach((id) => {\r\n selectedData.push(this.getItemById(id));\r\n });\r\n return selectedData as T[];\r\n }\r\n\r\n /**\r\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedFilteredItems() {\r\n if (!Array.isArray(this.selectedRowIds)) {\r\n return [];\r\n }\r\n\r\n const intersection = this.filteredItems.filter((a) => this.selectedRowIds!.some((b) => a[this.idProperty as keyof TData] === b));\r\n return (intersection || []) as T[];\r\n }\r\n\r\n syncGridCellCssStyles(grid: SlickGridModel, key: string) {\r\n let hashById: any;\r\n let inHandler: boolean;\r\n\r\n const storeCellCssStyles = (hash: CssStyleHash) => {\r\n hashById = {};\r\n if (typeof hash === 'object') {\r\n Object.keys(hash).forEach(row => {\r\n if (hash) {\r\n const id = this.rows[row as any][this.idProperty as keyof TData];\r\n hashById[id] = hash[row];\r\n }\r\n });\r\n }\r\n };\r\n\r\n // since this method can be called after the cell styles have been set,\r\n // get the existing ones right away\r\n storeCellCssStyles(grid.getCellCssStyles(key));\r\n\r\n const update = () => {\r\n if (typeof hashById === 'object') {\r\n inHandler = true;\r\n this.ensureRowsByIdCache();\r\n const newHash: CssStyleHash = {};\r\n Object.keys(hashById).forEach(id => {\r\n const row = this.rowsById?.[id];\r\n if (Utils.isDefined(row)) {\r\n newHash[row as number] = hashById[id];\r\n }\r\n });\r\n grid.setCellCssStyles(key, newHash);\r\n inHandler = false;\r\n }\r\n };\r\n\r\n grid.onCellCssStylesChanged.subscribe((_e: SlickEventData_, args: any) => {\r\n if (inHandler) { return; }\r\n if (key !== args.key) { return; }\r\n if (args.hash) {\r\n storeCellCssStyles(args.hash);\r\n } else {\r\n grid.onCellCssStylesChanged.unsubscribe();\r\n this.onRowsOrCountChanged.unsubscribe(update);\r\n }\r\n });\r\n\r\n this.onRowsOrCountChanged.subscribe(update.bind(this));\r\n }\r\n}\r\n\r\nexport class AvgAggregator implements Aggregator {\r\n private _nonNullCount = 0;\r\n private _sum = 0;\r\n private _field: number | string;\r\n private _type = 'avg' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n this._nonNullCount = 0;\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n this._nonNullCount++;\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n (groupTotals as any)[this._type] = {};\r\n }\r\n if (this._nonNullCount !== 0) {\r\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\r\n }\r\n }\r\n}\r\n\r\nexport class MinAggregator implements Aggregator {\r\n private _min: number | null = null;\r\n private _field: number | string;\r\n private _type = 'min' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init() {\r\n this._min = null;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n if (this._min === null || val < this._min) {\r\n this._min = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._min;\r\n }\r\n}\r\n\r\nexport class MaxAggregator implements Aggregator {\r\n private _max: number | null = null;\r\n private _field: number | string;\r\n private _type = 'max' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n this._max = null;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n if (this._max === null || val > this._max) {\r\n this._max = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._max;\r\n }\r\n}\r\n\r\nexport class SumAggregator implements Aggregator {\r\n private _sum = 0;\r\n private _field: number | string;\r\n private _type = 'sum' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init() {\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._sum;\r\n }\r\n}\r\n\r\nexport class CountAggregator implements Aggregator {\r\n private _field: number | string;\r\n private _type = 'count' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\r\n }\r\n}\r\n\r\n// TODO: add more built-in aggregators\r\n// TODO: merge common aggregators in one to prevent needless iterating\r\n\r\nexport const Aggregators = {\r\n Avg: AvgAggregator,\r\n Min: MinAggregator,\r\n Max: MaxAggregator,\r\n Sum: SumAggregator,\r\n Count: CountAggregator\r\n};\r\n\r\n// extend Slick namespace on window object when building as iife\r\nif (IIFE_ONLY && window.Slick) {\r\n window.Slick.Data = window.Slick.Data || {};\r\n window.Slick.Data.DataView = SlickDataView;\r\n window.Slick.Data.Aggregators = Aggregators;\r\n}"], - "mappings": "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", + "sourcesContent": ["import type {\r\n Aggregator,\r\n AnyFunction,\r\n CssStyleHash,\r\n CustomDataView,\r\n DataViewHints,\r\n Grouping,\r\n GroupingFormatterItem,\r\n ItemMetadata,\r\n OnGroupCollapsedEventArgs,\r\n OnGroupExpandedEventArgs,\r\n OnRowCountChangedEventArgs,\r\n OnRowsChangedEventArgs,\r\n OnRowsOrCountChangedEventArgs,\r\n OnSelectedRowIdsChangedEventArgs,\r\n OnSetItemsCalledEventArgs,\r\n PagingInfo,\r\n SlickGridModel,\r\n} from './models/index';\r\nimport {\r\n type BasePubSub,\r\n SlickEvent as SlickEvent_,\r\n SlickEventData as SlickEventData_,\r\n SlickGroup as SlickGroup_,\r\n SlickGroupTotals as SlickGroupTotals_,\r\n Utils as Utils_,\r\n type SlickNonDataItem,\r\n} from './slick.core';\r\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\r\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\r\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\r\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\r\n\r\nexport interface DataViewOption {\r\n /** Optionally provide a GroupItemMetadataProvider in order to use Grouping/DraggableGrouping features */\r\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\r\n\r\n /** defaults to false, are we using inline filters? */\r\n inlineFilters: boolean;\r\n\r\n /**\r\n * defaults to false, option to use CSP Safe approach,\r\n * Note: it is an opt-in option because it is slightly slower (perf impact) when compared to the non-CSP safe approach.\r\n */\r\n useCSPSafeFilter: boolean;\r\n}\r\nexport type FilterFn = (item: T, args: any) => boolean;\r\nexport type FilterCspFn = (item: T[], args: any) => T[];\r\nexport type FilterWithCspCachingFn = (item: T[], args: any, filterCache: any[]) => T[];\r\nexport type DataIdType = number | string;\r\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\r\nexport type GroupGetterFn = (val: any) => string | number;\r\n\r\n/**\r\n * A simple Model implementation.\r\n * Provides a filtered view of the underlying data.\r\n * Relies on the data item having an \"id\" property uniquely identifying it.\r\n */\r\nexport class SlickDataView implements CustomDataView {\r\n protected defaults: DataViewOption = {\r\n groupItemMetadataProvider: null,\r\n inlineFilters: false,\r\n useCSPSafeFilter: false,\r\n };\r\n\r\n // private\r\n protected idProperty = 'id'; // property holding a unique row id\r\n protected items: TData[] = []; // data by index\r\n protected rows: TData[] = []; // data by row\r\n protected idxById = new Map(); // indexes by id\r\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\r\n protected filter: FilterFn | null = null; // filter function\r\n protected filterCSPSafe: FilterFn | null = null; // filter function\r\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\r\n protected suspend = false; // suspends the recalculation\r\n protected isBulkSuspend = false; // delays protectedious operations like the\r\n // index update and delete to efficient\r\n // versions at endUpdate\r\n protected bulkDeleteIds = new Map();\r\n protected sortAsc: boolean | undefined = true;\r\n protected fastSortField?: string | null | (() => string);\r\n protected sortComparer!: ((a: TData, b: TData) => number);\r\n protected refreshHints: DataViewHints = {};\r\n protected prevRefreshHints: DataViewHints = {};\r\n protected filterArgs: any;\r\n protected filteredItems: TData[] = [];\r\n protected compiledFilter?: FilterFn | null;\r\n protected compiledFilterCSPSafe?: FilterCspFn | null;\r\n protected compiledFilterWithCaching?: FilterFn | null;\r\n protected compiledFilterWithCachingCSPSafe?: FilterWithCspCachingFn | null;\r\n protected filterCache: any[] = [];\r\n protected _grid?: SlickGridModel; // grid object will be defined only after using \"syncGridSelection()\" method\"\r\n\r\n // grouping\r\n protected groupingInfoDefaults: Grouping = {\r\n getter: undefined,\r\n formatter: undefined,\r\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\r\n predefinedValues: [],\r\n aggregators: [],\r\n aggregateEmpty: false,\r\n aggregateCollapsed: false,\r\n aggregateChildGroups: false,\r\n collapsed: false,\r\n displayTotalsRow: true,\r\n lazyTotalsCalculation: false\r\n };\r\n protected groupingInfos: Array = [];\r\n protected groups: SlickGroup_[] = [];\r\n protected toggledGroupsByLevel: any[] = [];\r\n protected groupingDelimiter = ':|:';\r\n protected selectedRowIds: DataIdType[] = [];\r\n protected preSelectedRowIdsChangeFn?: (args?: any) => void;\r\n\r\n protected pagesize = 0;\r\n protected pagenum = 0;\r\n protected totalRows = 0;\r\n protected _options: DataViewOption;\r\n protected _container?: HTMLElement;\r\n\r\n // public events\r\n onBeforePagingInfoChanged: SlickEvent_;\r\n onGroupExpanded: SlickEvent_;\r\n onGroupCollapsed: SlickEvent_;\r\n onPagingInfoChanged: SlickEvent_;\r\n onRowCountChanged: SlickEvent_;\r\n onRowsChanged: SlickEvent_;\r\n onRowsOrCountChanged: SlickEvent_;\r\n onSelectedRowIdsChanged: SlickEvent_;\r\n onSetItemsCalled: SlickEvent_;\r\n\r\n constructor(options?: Partial, protected externalPubSub?: BasePubSub) {\r\n this.onBeforePagingInfoChanged = new SlickEvent('onBeforePagingInfoChanged', externalPubSub);\r\n this.onGroupExpanded = new SlickEvent('onGroupExpanded', externalPubSub);\r\n this.onGroupCollapsed = new SlickEvent('onGroupCollapsed', externalPubSub);\r\n this.onPagingInfoChanged = new SlickEvent('onPagingInfoChanged', externalPubSub);\r\n this.onRowCountChanged = new SlickEvent('onRowCountChanged', externalPubSub);\r\n this.onRowsChanged = new SlickEvent('onRowsChanged', externalPubSub);\r\n this.onRowsOrCountChanged = new SlickEvent('onRowsOrCountChanged', externalPubSub);\r\n this.onSelectedRowIdsChanged = new SlickEvent('onSelectedRowIdsChanged', externalPubSub);\r\n this.onSetItemsCalled = new SlickEvent('onSetItemsCalled', externalPubSub);\r\n\r\n this._options = Utils.extend(true, {}, this.defaults, options);\r\n }\r\n\r\n /**\r\n * Begins a bached update of the items in the data view.\r\n * including deletes and the related events are postponed to the endUpdate call.\r\n * As certain operations are postponed during this update, some methods might not\r\n * deliver fully consistent information.\r\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\r\n */\r\n beginUpdate(bulkUpdate?: boolean) {\r\n this.suspend = true;\r\n this.isBulkSuspend = bulkUpdate === true;\r\n }\r\n\r\n endUpdate() {\r\n const wasBulkSuspend = this.isBulkSuspend;\r\n this.isBulkSuspend = false;\r\n this.suspend = false;\r\n if (wasBulkSuspend) {\r\n this.processBulkDelete();\r\n this.ensureIdUniqueness();\r\n }\r\n this.refresh();\r\n }\r\n\r\n destroy() {\r\n this.items = [];\r\n this.idxById = null as any;\r\n this.rowsById = null as any;\r\n this.filter = null as any;\r\n this.filterCSPSafe = null as any;\r\n this.updated = null as any;\r\n this.sortComparer = null as any;\r\n this.filterCache = [];\r\n this.filteredItems = [];\r\n this.compiledFilter = null;\r\n this.compiledFilterCSPSafe = null;\r\n this.compiledFilterWithCaching = null;\r\n this.compiledFilterWithCachingCSPSafe = null;\r\n\r\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\r\n this._grid.onSelectedRowsChanged.unsubscribe();\r\n this._grid.onCellCssStylesChanged.unsubscribe();\r\n }\r\n if (this.onRowsOrCountChanged) {\r\n this.onRowsOrCountChanged.unsubscribe();\r\n }\r\n }\r\n\r\n /** provide some refresh hints as to what to rows needs refresh */\r\n setRefreshHints(hints: DataViewHints) {\r\n this.refreshHints = hints;\r\n }\r\n\r\n /** get extra filter arguments of the filter method */\r\n getFilterArgs() {\r\n return this.filterArgs;\r\n }\r\n\r\n /** add extra filter arguments to the filter method */\r\n setFilterArgs(args: any) {\r\n this.filterArgs = args;\r\n }\r\n\r\n /**\r\n * Processes all delete requests placed during bulk update\r\n * by recomputing the items and idxById members.\r\n */\r\n protected processBulkDelete() {\r\n if (!this.idxById) { return; }\r\n\r\n // the bulk update is processed by\r\n // recomputing the whole items array and the index lookup in one go.\r\n // this is done by placing the not-deleted items\r\n // from left to right into the array and shrink the array the the new\r\n // size afterwards.\r\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\r\n\r\n let id: DataIdType, item, newIdx = 0;\r\n for (let i = 0, l = this.items.length; i < l; i++) {\r\n item = this.items[i];\r\n id = item[this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n\r\n // if items have been marked as deleted we skip them for the new final items array\r\n // and we remove them from the lookup table.\r\n if (this.bulkDeleteIds.has(id)) {\r\n this.idxById.delete(id);\r\n } else {\r\n // for items which are not deleted, we add them to the\r\n // next free position in the array and register the index in the lookup.\r\n this.items[newIdx] = item;\r\n this.idxById.set(id, newIdx);\r\n ++newIdx;\r\n }\r\n }\r\n\r\n // here we shrink down the full item array to the ones actually\r\n // inserted in the cleanup loop above.\r\n this.items.length = newIdx;\r\n // and finally cleanup the deleted ids to start cleanly on the next update.\r\n this.bulkDeleteIds = new Map();\r\n }\r\n\r\n protected updateIdxById(startingIndex?: number) {\r\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\r\n return;\r\n }\r\n startingIndex = startingIndex || 0;\r\n let id: DataIdType;\r\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\r\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n this.idxById.set(id, i);\r\n }\r\n }\r\n\r\n protected ensureIdUniqueness() {\r\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\r\n return;\r\n }\r\n let id: DataIdType;\r\n for (let i = 0, l = this.items.length; i < l; i++) {\r\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\r\n if (id === undefined || this.idxById.get(id) !== i) {\r\n throw new Error(`[SlickGrid DataView] Each data element must implement a unique 'id' property`);\r\n }\r\n }\r\n }\r\n\r\n /** Get all DataView Items */\r\n getItems() {\r\n return this.items;\r\n }\r\n\r\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\r\n getIdPropertyName() {\r\n return this.idProperty;\r\n }\r\n\r\n /**\r\n * Set the Items with a new Dataset and optionally pass a different Id property name\r\n * @param {Array<*>} data - array of data\r\n * @param {String} [objectIdProperty] - optional id property to use as primary id\r\n */\r\n setItems(data: TData[], objectIdProperty?: string) {\r\n if (objectIdProperty !== undefined) {\r\n this.idProperty = objectIdProperty;\r\n }\r\n this.items = this.filteredItems = data;\r\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.ensureIdUniqueness();\r\n this.refresh();\r\n }\r\n\r\n /** Set Paging Options */\r\n setPagingOptions(args: Partial) {\r\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\r\n if (Utils.isDefined(args.pageSize)) {\r\n this.pagesize = args.pageSize;\r\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\r\n }\r\n\r\n if (Utils.isDefined(args.pageNum)) {\r\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\r\n }\r\n\r\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\r\n\r\n this.refresh();\r\n }\r\n }\r\n\r\n /** Get Paging Options */\r\n getPagingInfo(): PagingInfo {\r\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\r\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages, dataView: this as SlickDataView };\r\n }\r\n\r\n /** Sort Method to use by the DataView */\r\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\r\n this.sortAsc = ascending;\r\n this.sortComparer = comparer;\r\n this.fastSortField = null;\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.items.sort(comparer);\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Provides a workaround for the extremely slow sorting in IE.\r\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\r\n * to return the value of that field and then doing a native Array.sort().\r\n */\r\n fastSort(field: string | (() => string), ascending?: boolean) {\r\n this.sortAsc = ascending;\r\n this.fastSortField = field;\r\n this.sortComparer = null as any;\r\n const oldToString = Object.prototype.toString;\r\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\r\n // @ts-ignore\r\n return this[field];\r\n };\r\n // an extra reversal for descending sort keeps the sort stable\r\n // (assuming a stable native sort implementation, which isn't true in some cases)\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.items.sort();\r\n Object.prototype.toString = oldToString;\r\n if (ascending === false) {\r\n this.items.reverse();\r\n }\r\n this.idxById = new Map();\r\n this.updateIdxById();\r\n this.refresh();\r\n }\r\n\r\n /** Re-Sort the dataset */\r\n reSort() {\r\n if (this.sortComparer) {\r\n this.sort(this.sortComparer, this.sortAsc);\r\n } else if (this.fastSortField) {\r\n this.fastSort(this.fastSortField, this.sortAsc);\r\n }\r\n }\r\n\r\n /** Get only the DataView filtered items */\r\n getFilteredItems() {\r\n return this.filteredItems as T[];\r\n }\r\n\r\n /** Get the array length (count) of only the DataView filtered items */\r\n getFilteredItemCount() {\r\n return this.filteredItems.length;\r\n }\r\n\r\n /** Get current Filter used by the DataView */\r\n getFilter() {\r\n return this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter;\r\n }\r\n\r\n /**\r\n * Set a Filter that will be used by the DataView\r\n * @param {Function} fn - filter callback function\r\n */\r\n setFilter(filterFn: FilterFn) {\r\n this.filterCSPSafe = filterFn;\r\n this.filter = filterFn;\r\n if (this._options.inlineFilters) {\r\n this.compiledFilterCSPSafe = this.compileFilterCSPSafe;\r\n this.compiledFilterWithCachingCSPSafe = this.compileFilterWithCachingCSPSafe;\r\n this.compiledFilter = this.compileFilter(this._options.useCSPSafeFilter);\r\n this.compiledFilterWithCaching = this.compileFilterWithCaching(this._options.useCSPSafeFilter);\r\n }\r\n this.refresh();\r\n }\r\n\r\n /** Get current Grouping info */\r\n getGrouping(): Grouping[] {\r\n return this.groupingInfos;\r\n }\r\n\r\n /** Set some Grouping */\r\n setGrouping(groupingInfo: Grouping | Grouping[]) {\r\n if (!this._options.groupItemMetadataProvider) {\r\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\r\n }\r\n\r\n this.groups = [];\r\n this.toggledGroupsByLevel = [];\r\n groupingInfo = groupingInfo || [];\r\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\r\n\r\n for (let i = 0; i < this.groupingInfos.length; i++) {\r\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\r\n gi.getterIsAFn = typeof gi.getter === 'function';\r\n\r\n // pre-compile accumulator loops\r\n gi.compiledAccumulators = [];\r\n let idx = gi.aggregators.length;\r\n while (idx--) {\r\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoopCSPSafe(gi.aggregators[idx]);\r\n }\r\n\r\n this.toggledGroupsByLevel[i] = {};\r\n }\r\n\r\n this.refresh();\r\n }\r\n\r\n /** Get an item in the DataView by its row index */\r\n getItemByIdx(i: number) {\r\n return this.items[i] as T;\r\n }\r\n\r\n /** Get row index in the DataView by its Id */\r\n getIdxById(id: DataIdType) {\r\n return this.idxById?.get(id);\r\n }\r\n\r\n protected ensureRowsByIdCache() {\r\n if (!this.rowsById) {\r\n this.rowsById = {};\r\n for (let i = 0, l = this.rows.length; i < l; i++) {\r\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\r\n }\r\n }\r\n }\r\n\r\n /** Get row number in the grid by its item object */\r\n getRowByItem(item: TData) {\r\n this.ensureRowsByIdCache();\r\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\r\n }\r\n\r\n /** Get row number in the grid by its Id */\r\n getRowById(id: DataIdType) {\r\n this.ensureRowsByIdCache();\r\n return this.rowsById?.[id];\r\n }\r\n\r\n /** Get an item in the DataView by its Id */\r\n getItemById(id: DataIdType) {\r\n return this.items[(this.idxById.get(id) as number)] as T;\r\n }\r\n\r\n /** From the items array provided, return the mapped rows */\r\n mapItemsToRows(itemArray: TData[]) {\r\n const rows: number[] = [];\r\n this.ensureRowsByIdCache();\r\n for (let i = 0, l = itemArray.length; i < l; i++) {\r\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\r\n if (Utils.isDefined(row)) {\r\n rows[rows.length] = row as number;\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n /** From the Ids array provided, return the mapped rows */\r\n mapIdsToRows(idArray: DataIdType[]) {\r\n const rows: number[] = [];\r\n this.ensureRowsByIdCache();\r\n for (let i = 0, l = idArray.length; i < l; i++) {\r\n const row = this.rowsById?.[idArray[i]];\r\n if (Utils.isDefined(row)) {\r\n rows[rows.length] = row as number;\r\n }\r\n }\r\n return rows;\r\n }\r\n\r\n /** From the rows array provided, return the mapped Ids */\r\n mapRowsToIds(rowArray: number[]) {\r\n const ids: DataIdType[] = [];\r\n for (let i = 0, l = rowArray.length; i < l; i++) {\r\n if (rowArray[i] < this.rows.length) {\r\n const rowItem = this.rows[rowArray[i]];\r\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\r\n }\r\n }\r\n return ids;\r\n }\r\n\r\n /**\r\n * Performs the update operations of a single item by id without\r\n * triggering any events or refresh operations.\r\n * @param id The new id of the item.\r\n * @param item The item which should be the new value for the given id.\r\n */\r\n updateSingleItem(id: DataIdType, item: TData) {\r\n if (!this.idxById) { return; }\r\n\r\n // see also https://github.com/mleibman/SlickGrid/issues/1082\r\n if (!this.idxById.has(id)) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n\r\n // What if the specified item also has an updated idProperty?\r\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\r\n if (id !== item[this.idProperty as keyof TData]) {\r\n // make sure the new id is unique:\r\n const newId = item[this.idProperty as keyof TData] as DataIdType;\r\n if (!Utils.isDefined(newId)) {\r\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\r\n }\r\n if (this.idxById.has(newId)) {\r\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\r\n }\r\n this.idxById.set(newId, this.idxById.get(id) as number);\r\n this.idxById.delete(id);\r\n\r\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\r\n if (this.updated?.[id]) {\r\n delete this.updated[id];\r\n }\r\n\r\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\r\n\r\n id = newId;\r\n }\r\n this.items[this.idxById.get(id) as number] = item;\r\n\r\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\r\n\r\n if (!this.updated) {\r\n this.updated = {};\r\n }\r\n this.updated[id] = true;\r\n }\r\n\r\n /**\r\n * Updates a single item in the data view given the id and new value.\r\n * @param id The new id of the item.\r\n * @param item The item which should be the new value for the given id.\r\n */\r\n updateItem(id: DataIdType, item: T) {\r\n this.updateSingleItem(id, item);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Updates multiple items in the data view given the new ids and new values.\r\n * @param id {Array} The array of new ids which is in the same order as the items.\r\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\r\n */\r\n updateItems(ids: DataIdType[], newItems: T[]) {\r\n if (ids.length !== newItems.length) {\r\n throw new Error('[SlickGrid DataView] Mismatch on the length of ids and items provided to update');\r\n }\r\n for (let i = 0, l = newItems.length; i < l; i++) {\r\n this.updateSingleItem(ids[i], newItems[i]);\r\n }\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Inserts a single item into the data view at the given position.\r\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\r\n * @param item The item to insert.\r\n */\r\n insertItem(insertBefore: number, item: TData) {\r\n this.items.splice(insertBefore, 0, item);\r\n this.updateIdxById(insertBefore);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Inserts multiple items into the data view at the given position.\r\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\r\n * @param newItems {Array} The items to insert.\r\n */\r\n insertItems(insertBefore: number, newItems: TData[]) {\r\n // @ts-ignore\r\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\r\n this.updateIdxById(insertBefore);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Adds a single item at the end of the data view.\r\n * @param item The item to add at the end.\r\n */\r\n addItem(item: TData) {\r\n this.items.push(item);\r\n this.updateIdxById(this.items.length - 1);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Adds multiple items at the end of the data view.\r\n * @param {Array} newItems The items to add at the end.\r\n */\r\n addItems(newItems: TData[]) {\r\n this.items = this.items.concat(newItems);\r\n this.updateIdxById(this.items.length - newItems.length);\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * Deletes a single item identified by the given id from the data view.\r\n * @param {String|Number} id The id identifying the object to delete.\r\n */\r\n deleteItem(id: DataIdType) {\r\n if (!this.idxById) { return; }\r\n if (this.isBulkSuspend) {\r\n this.bulkDeleteIds.set(id, true);\r\n } else {\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.idxById.delete(id);\r\n this.items.splice(idx, 1);\r\n this.updateIdxById(idx);\r\n this.refresh();\r\n }\r\n }\r\n\r\n /**\r\n * Deletes multiple item identified by the given ids from the data view.\r\n * @param {Array} ids The ids of the items to delete.\r\n */\r\n deleteItems(ids: DataIdType[]) {\r\n if (ids.length === 0 || !this.idxById) {\r\n return;\r\n }\r\n\r\n if (this.isBulkSuspend) {\r\n for (let i = 0, l = ids.length; i < l; i++) {\r\n const id = ids[i];\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.bulkDeleteIds.set(id, true);\r\n }\r\n } else {\r\n // collect all indexes\r\n const indexesToDelete: number[] = [];\r\n for (let i = 0, l = ids.length; i < l; i++) {\r\n const id = ids[i];\r\n const idx = this.idxById.get(id);\r\n if (idx === undefined) {\r\n throw new Error('[SlickGrid DataView] Invalid id');\r\n }\r\n this.idxById.delete(id);\r\n indexesToDelete.push(idx);\r\n }\r\n\r\n // Remove from back to front\r\n indexesToDelete.sort();\r\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\r\n this.items.splice(indexesToDelete[i], 1);\r\n }\r\n\r\n // update lookup from front to back\r\n this.updateIdxById(indexesToDelete[0]);\r\n this.refresh();\r\n }\r\n }\r\n\r\n /** Add an item in a sorted dataset (a Sort function must be defined) */\r\n sortedAddItem(item: TData) {\r\n if (!this.sortComparer) {\r\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\r\n }\r\n this.insertItem(this.sortedIndex(item), item);\r\n }\r\n\r\n /** Update an item in a sorted dataset (a Sort function must be defined) */\r\n sortedUpdateItem(id: string | number, item: TData) {\r\n if (!this.idxById) { return; }\r\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\r\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\r\n }\r\n if (!this.sortComparer) {\r\n throw new Error('[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()');\r\n }\r\n const oldItem = this.getItemById(id);\r\n if (this.sortComparer(oldItem, item) !== 0) {\r\n // item affects sorting -> must use sorted add\r\n this.deleteItem(id);\r\n this.sortedAddItem(item);\r\n } else { // update does not affect sorting -> regular update works fine\r\n this.updateItem(id, item);\r\n }\r\n }\r\n\r\n protected sortedIndex(searchItem: TData) {\r\n let low = 0;\r\n let high = this.items.length;\r\n\r\n while (low < high) {\r\n const mid = low + high >>> 1;\r\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\r\n low = mid + 1;\r\n } else {\r\n high = mid;\r\n }\r\n }\r\n return low;\r\n }\r\n\r\n /** Get item count, that is the full dataset lenght of the DataView */\r\n getItemCount() {\r\n return this.items.length;\r\n }\r\n\r\n /** Get row count (rows displayed in current page) */\r\n getLength() {\r\n return this.rows.length;\r\n }\r\n\r\n /** Retrieve an item from the DataView at specific index */\r\n getItem(i: number) {\r\n const item = this.rows[i] as T;\r\n\r\n // if this is a group row, make sure totals are calculated and update the title\r\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\r\n const gi = this.groupingInfos[(item as SlickGroup_).level];\r\n if (!gi.displayTotalsRow) {\r\n this.calculateTotals((item as SlickGroup_).totals);\r\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\r\n }\r\n }\r\n // if this is a totals row, make sure it's calculated\r\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\r\n this.calculateTotals(item as SlickGroupTotals_);\r\n }\r\n\r\n return item;\r\n }\r\n\r\n getItemMetadata(i: number): ItemMetadata | null {\r\n const item = this.rows[i];\r\n if (item === undefined) {\r\n return null;\r\n }\r\n\r\n // overrides for grouping rows\r\n if ((item as SlickGroup_).__group) {\r\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\r\n }\r\n\r\n // overrides for totals rows\r\n if ((item as SlickGroupTotals_).__groupTotals) {\r\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\r\n }\r\n\r\n return null;\r\n }\r\n\r\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\r\n if (!Utils.isDefined(level)) {\r\n for (let i = 0; i < this.groupingInfos.length; i++) {\r\n this.toggledGroupsByLevel[i] = {};\r\n this.groupingInfos[i].collapsed = collapse;\r\n\r\n if (collapse === true) {\r\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\r\n } else {\r\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\r\n }\r\n }\r\n } else {\r\n this.toggledGroupsByLevel[level] = {};\r\n this.groupingInfos[level].collapsed = collapse;\r\n\r\n if (collapse === true) {\r\n this.onGroupCollapsed.notify({ level, groupingKey: null });\r\n } else {\r\n this.onGroupExpanded.notify({ level, groupingKey: null });\r\n }\r\n }\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\r\n */\r\n collapseAllGroups(level?: number) {\r\n this.expandCollapseAllGroups(level, true);\r\n }\r\n\r\n /**\r\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\r\n */\r\n expandAllGroups(level?: number) {\r\n this.expandCollapseAllGroups(level, false);\r\n }\r\n\r\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\r\n // @ts-ignore\r\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\r\n this.refresh();\r\n }\r\n\r\n /**\r\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * variable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n collapseGroup(...args: any) {\r\n const calledArgs = Array.prototype.slice.call(args);\r\n const arg0 = calledArgs[0];\r\n let groupingKey: string;\r\n let level: number;\r\n\r\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\r\n groupingKey = arg0;\r\n level = arg0.split(this.groupingDelimiter).length - 1;\r\n } else {\r\n groupingKey = args.join(this.groupingDelimiter);\r\n level = args.length - 1;\r\n }\r\n\r\n this.expandCollapseGroup(level, groupingKey, true);\r\n this.onGroupCollapsed.notify({ level, groupingKey });\r\n }\r\n\r\n /**\r\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\r\n * variable argument list of grouping values denoting a unique path to the row. For\r\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\r\n * the 'high' group.\r\n */\r\n expandGroup(...args: any) {\r\n const calledArgs = Array.prototype.slice.call(args);\r\n const arg0 = calledArgs[0];\r\n let groupingKey: string;\r\n let level: number;\r\n\r\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\r\n level = arg0.split(this.groupingDelimiter).length - 1;\r\n groupingKey = arg0;\r\n } else {\r\n level = args.length - 1;\r\n groupingKey = args.join(this.groupingDelimiter);\r\n }\r\n\r\n this.expandCollapseGroup(level, groupingKey, false);\r\n this.onGroupExpanded.notify({ level, groupingKey });\r\n }\r\n\r\n getGroups() {\r\n return this.groups;\r\n }\r\n\r\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\r\n let group: SlickGroup_;\r\n let val: any;\r\n const groups: SlickGroup_[] = [];\r\n const groupsByVal: any = {};\r\n let r;\r\n const level = parentGroup ? parentGroup.level + 1 : 0;\r\n const gi = this.groupingInfos[level];\r\n\r\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\r\n val = gi.predefinedValues?.[i];\r\n group = groupsByVal[val];\r\n if (!group) {\r\n group = new SlickGroup();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n }\r\n\r\n for (let i = 0, l = rows.length; i < l; i++) {\r\n r = rows[i];\r\n val = gi.getterIsAFn ? (gi.getter as GroupGetterFn)(r) : r[gi.getter as keyof TData];\r\n group = groupsByVal[val];\r\n if (!group) {\r\n group = new SlickGroup();\r\n group.value = val;\r\n group.level = level;\r\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\r\n groups[groups.length] = group;\r\n groupsByVal[val] = group;\r\n }\r\n\r\n group.rows[group.count++] = r;\r\n }\r\n\r\n if (level < this.groupingInfos.length - 1) {\r\n for (let i = 0; i < groups.length; i++) {\r\n group = groups[i];\r\n group.groups = this.extractGroups(group.rows, group);\r\n }\r\n }\r\n\r\n if (groups.length) {\r\n this.addTotals(groups, level);\r\n }\r\n\r\n groups.sort(this.groupingInfos[level].comparer);\r\n\r\n return groups;\r\n }\r\n\r\n /** claculate Group Totals */\r\n protected calculateTotals(totals: SlickGroupTotals_) {\r\n const group = totals.group;\r\n const gi = this.groupingInfos[group.level ?? 0];\r\n const isLeafLevel = (group.level === this.groupingInfos.length);\r\n let agg: Aggregator;\r\n let idx = gi.aggregators.length;\r\n\r\n if (!isLeafLevel && gi.aggregateChildGroups) {\r\n // make sure all the subgroups are calculated\r\n let i = group.groups?.length ?? 0;\r\n while (i--) {\r\n if (!group.groups[i].totals.initialized) {\r\n this.calculateTotals(group.groups[i].totals);\r\n }\r\n }\r\n }\r\n\r\n while (idx--) {\r\n agg = gi.aggregators[idx];\r\n agg.init();\r\n if (!isLeafLevel && gi.aggregateChildGroups) {\r\n gi.compiledAccumulators[idx].call(agg, group.groups);\r\n } else {\r\n gi.compiledAccumulators[idx].call(agg, group.rows);\r\n }\r\n agg.storeResult(totals);\r\n }\r\n totals.initialized = true;\r\n }\r\n\r\n protected addGroupTotals(group: SlickGroup_) {\r\n const gi = this.groupingInfos[group.level];\r\n const totals = new SlickGroupTotals();\r\n totals.group = group;\r\n group.totals = totals;\r\n if (!gi.lazyTotalsCalculation) {\r\n this.calculateTotals(totals);\r\n }\r\n }\r\n\r\n protected addTotals(groups: SlickGroup_[], level?: number) {\r\n level = level || 0;\r\n const gi = this.groupingInfos[level];\r\n const groupCollapsed = gi.collapsed;\r\n const toggledGroups = this.toggledGroupsByLevel[level];\r\n let idx = groups.length, g;\r\n while (idx--) {\r\n g = groups[idx];\r\n\r\n if (g.collapsed && !gi.aggregateCollapsed) {\r\n continue;\r\n }\r\n\r\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\r\n if (g.groups) {\r\n this.addTotals(g.groups, level + 1);\r\n }\r\n\r\n if (gi.aggregators?.length && (\r\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\r\n this.addGroupTotals(g);\r\n }\r\n\r\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\r\n g.title = gi.formatter ? gi.formatter(g) : g.value;\r\n }\r\n }\r\n\r\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\r\n level = level || 0;\r\n const gi = this.groupingInfos[level];\r\n const groupedRows: any[] = [];\r\n let rows: any[];\r\n let gl = 0;\r\n let g;\r\n for (let i = 0, l = groups.length; i < l; i++) {\r\n g = groups[i];\r\n groupedRows[gl++] = g;\r\n\r\n if (!g.collapsed) {\r\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\r\n for (let j = 0, jj = rows.length; j < jj; j++) {\r\n groupedRows[gl++] = rows[j];\r\n }\r\n }\r\n\r\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\r\n groupedRows[gl++] = g.totals;\r\n }\r\n }\r\n return groupedRows;\r\n }\r\n\r\n protected compileAccumulatorLoopCSPSafe(aggregator: Aggregator) {\r\n if (aggregator.accumulate) {\r\n return function (items: any[]) {\r\n let result;\r\n for (let i = 0; i < items.length; i++) {\r\n const item = items[i];\r\n result = aggregator.accumulate!.call(aggregator, item);\r\n }\r\n return result;\r\n };\r\n } else {\r\n return function noAccumulator() { };\r\n }\r\n }\r\n\r\n protected compileFilterCSPSafe(items: TData[], args: any): TData[] {\r\n if (typeof this.filterCSPSafe !== 'function') {\r\n return [];\r\n }\r\n const _retval: TData[] = [];\r\n const _il = items.length;\r\n\r\n for (let _i = 0; _i < _il; _i++) {\r\n if (this.filterCSPSafe(items[_i], args)) {\r\n _retval.push(items[_i]);\r\n }\r\n }\r\n\r\n return _retval;\r\n }\r\n\r\n protected compileFilter(stopRunningIfCSPSafeIsActive = false): FilterFn | null {\r\n if (stopRunningIfCSPSafeIsActive) {\r\n return null as any;\r\n }\r\n const filterInfo = Utils.getFunctionDetails(this.filter as FilterFn);\r\n\r\n const filterPath1 = '{ continue _coreloop; }$1';\r\n const filterPath2 = '{ _retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n const filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // 'function(_items, _args) { ',\r\n 'var _retval = [], _idx = 0; ',\r\n 'var $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (var _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // '}'\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n const fn: any = new Function('_items,_args', tpl);\r\n const fnName = 'compiledFilter';\r\n fn.displayName = fnName;\r\n fn.name = this.setFunctionName(fn, fnName);\r\n return fn;\r\n }\r\n\r\n protected compileFilterWithCaching(stopRunningIfCSPSafeIsActive = false) {\r\n if (stopRunningIfCSPSafeIsActive) {\r\n return null as any;\r\n }\r\n\r\n const filterInfo = Utils.getFunctionDetails(this.filter as FilterFn);\r\n\r\n const filterPath1 = '{ continue _coreloop; }$1';\r\n const filterPath2 = '{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1';\r\n // make some allowances for minification - there's only so far we can go with RegEx\r\n const filterBody = filterInfo.body\r\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\r\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\r\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\r\n '{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2');\r\n\r\n // This preserves the function template code after JS compression,\r\n // so that replace() commands still work as expected.\r\n let tpl = [\r\n // 'function(_items, _args, _cache) { ',\r\n 'var _retval = [], _idx = 0; ',\r\n 'var $item$, $args$ = _args; ',\r\n '_coreloop: ',\r\n 'for (var _i = 0, _il = _items.length; _i < _il; _i++) { ',\r\n '$item$ = _items[_i]; ',\r\n 'if (_cache[_i]) { ',\r\n '_retval[_idx++] = $item$; ',\r\n 'continue _coreloop; ',\r\n '} ',\r\n '$filter$; ',\r\n '} ',\r\n 'return _retval; '\r\n // '}'\r\n ].join('');\r\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\r\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\r\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\r\n\r\n const fn: any = new Function('_items,_args,_cache', tpl);\r\n const fnName = 'compiledFilterWithCaching';\r\n fn.displayName = fnName;\r\n fn.name = this.setFunctionName(fn, fnName);\r\n return fn;\r\n }\r\n\r\n protected compileFilterWithCachingCSPSafe(items: TData[], args: any, filterCache: any[]): TData[] {\r\n if (typeof this.filterCSPSafe !== 'function') {\r\n return [];\r\n }\r\n\r\n const retval: TData[] = [];\r\n const il = items.length;\r\n\r\n for (let _i = 0; _i < il; _i++) {\r\n if (filterCache[_i] || this.filterCSPSafe(items[_i], args)) {\r\n retval.push(items[_i]);\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n /**\r\n * In ES5 we could set the function name on the fly but in ES6 this is forbidden and we need to set it through differently\r\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\r\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\r\n * @param {*} fn\r\n * @param {string} fnName\r\n */\r\n protected setFunctionName(fn: any, fnName: string) {\r\n try {\r\n Object.defineProperty(fn, 'name', { writable: true, value: fnName });\r\n } catch (err) {\r\n fn.name = fnName;\r\n }\r\n }\r\n\r\n protected uncompiledFilter(items: TData[], args: any) {\r\n const retval: any[] = [];\r\n let idx = 0;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++) {\r\n if (this.filter?.(items[i], args)) {\r\n retval[idx++] = items[i];\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\r\n const retval: any[] = [];\r\n let idx = 0,\r\n item: TData;\r\n\r\n for (let i = 0, ii = items.length; i < ii; i++) {\r\n item = items[i];\r\n if (cache[i]) {\r\n retval[idx++] = item;\r\n } else if (this.filter?.(item, args)) {\r\n retval[idx++] = item;\r\n cache[i] = true;\r\n }\r\n }\r\n\r\n return retval;\r\n }\r\n\r\n protected getFilteredAndPagedItems(items: TData[]) {\r\n if (this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter) {\r\n let batchFilter: AnyFunction;\r\n let batchFilterWithCaching: AnyFunction;\r\n if (this._options.useCSPSafeFilter) {\r\n batchFilter = (this._options.inlineFilters ? this.compiledFilterCSPSafe : this.uncompiledFilter) as AnyFunction;\r\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingCSPSafe : this.uncompiledFilterWithCaching) as AnyFunction;\r\n } else {\r\n batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as AnyFunction;\r\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as AnyFunction;\r\n }\r\n if (this.refreshHints.isFilterNarrowing) {\r\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\r\n } else if (this.refreshHints.isFilterExpanding) {\r\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\r\n } else if (!this.refreshHints.isFilterUnchanged) {\r\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\r\n }\r\n } else {\r\n // special case: if not filtering and not paging, the resulting\r\n // rows collection needs to be a copy so that changes due to sort\r\n // can be caught\r\n this.filteredItems = this.pagesize ? items : items.concat();\r\n }\r\n\r\n // get the current page\r\n let paged: TData[];\r\n if (this.pagesize) {\r\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\r\n if (this.filteredItems.length === 0) {\r\n this.pagenum = 0;\r\n } else {\r\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\r\n }\r\n }\r\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\r\n } else {\r\n paged = this.filteredItems;\r\n }\r\n return { totalRows: this.filteredItems.length, rows: paged };\r\n }\r\n\r\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\r\n let item: TData | SlickNonDataItem | SlickDataItem | SlickGroup_;\r\n let r;\r\n let eitherIsNonData;\r\n const diff: number[] = [];\r\n let from = 0;\r\n let to = Math.max(newRows.length, rows.length);\r\n\r\n if (this.refreshHints?.ignoreDiffsBefore) {\r\n from = Math.max(0,\r\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\r\n }\r\n\r\n if (this.refreshHints?.ignoreDiffsAfter) {\r\n to = Math.min(newRows.length,\r\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\r\n }\r\n\r\n for (let i = from, rl = rows.length; i < to; i++) {\r\n if (i >= rl) {\r\n diff[diff.length] = i;\r\n } else {\r\n item = newRows[i];\r\n r = rows[i];\r\n\r\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\r\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\r\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\r\n || (eitherIsNonData &&\r\n // no good way to compare totals since they are arbitrary DTOs\r\n // deep object comparison is pretty expensive\r\n // always considering them 'dirty' seems easier for the time being\r\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\r\n || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData]\r\n || (this.updated?.[item[this.idProperty as keyof TData]])\r\n ) {\r\n diff[diff.length] = i;\r\n }\r\n }\r\n }\r\n return diff;\r\n }\r\n\r\n protected recalc(_items: TData[]) {\r\n this.rowsById = undefined;\r\n\r\n if (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing ||\r\n this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) {\r\n this.filterCache = [];\r\n }\r\n\r\n const filteredItems = this.getFilteredAndPagedItems(_items);\r\n this.totalRows = filteredItems.totalRows;\r\n let newRows: TData[] = filteredItems.rows;\r\n\r\n this.groups = [];\r\n if (this.groupingInfos.length) {\r\n this.groups = this.extractGroups(newRows);\r\n if (this.groups.length) {\r\n newRows = this.flattenGroupedRows(this.groups);\r\n }\r\n }\r\n\r\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\r\n\r\n this.rows = newRows as TData[];\r\n\r\n return diff;\r\n }\r\n\r\n refresh() {\r\n if (this.suspend) {\r\n return;\r\n }\r\n\r\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\r\n\r\n const countBefore = this.rows.length;\r\n const totalRowsBefore = this.totalRows;\r\n\r\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\r\n\r\n // if the current page is no longer valid, go to last page and recalc\r\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\r\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\r\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\r\n diff = this.recalc(this.items);\r\n }\r\n\r\n this.updated = null;\r\n this.prevRefreshHints = this.refreshHints;\r\n this.refreshHints = {};\r\n\r\n if (totalRowsBefore !== this.totalRows) {\r\n // use the previously saved paging info\r\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\r\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\r\n }\r\n }\r\n if (countBefore !== this.rows.length) {\r\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\r\n }\r\n if (diff.length > 0) {\r\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\r\n }\r\n if (countBefore !== this.rows.length || diff.length > 0) {\r\n this.onRowsOrCountChanged.notify({\r\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\r\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\r\n }, null, this);\r\n }\r\n }\r\n\r\n /**\r\n * Wires the grid and the DataView together to keep row selection tied to item ids.\r\n * This is useful since, without it, the grid only knows about rows, so if the items\r\n * move around, the same rows stay selected instead of the selection moving along\r\n * with the items.\r\n *\r\n * NOTE: This doesn't work with cell selection model.\r\n *\r\n * @param {SlickGrid} grid - The grid to sync selection with.\r\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\r\n * view due to them getting filtered out.\r\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\r\n * that are currently out of the view (see preserveHidden) as selected when selection\r\n * changes.\r\n * @return {Event} An event that notifies when an internal list of selected row ids\r\n * changes. This is useful since, in combination with the above two options, it allows\r\n * access to the full list selected row ids, and not just the ones visible to the grid.\r\n * @method syncGridSelection\r\n */\r\n syncGridSelection(grid: SlickGridModel, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\r\n this._grid = grid;\r\n let inHandler: boolean;\r\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\r\n\r\n /** @param {Array} rowIds */\r\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\r\n if (rowIds === false) {\r\n this.selectedRowIds = [];\r\n } else {\r\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\r\n this.selectedRowIds = rowIds;\r\n }\r\n }\r\n };\r\n\r\n const update = () => {\r\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\r\n inHandler = true;\r\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\r\n if (!preserveHidden) {\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: this.mapRowsToIds(selectedRows),\r\n rows: selectedRows,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n grid.setSelectedRows(selectedRows);\r\n inHandler = false;\r\n }\r\n };\r\n\r\n grid.onSelectedRowsChanged.subscribe((_e: SlickEventData_, args: { rows: number[]; }) => {\r\n if (!inHandler) {\r\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: newSelectedRowIds,\r\n rows: args.rows,\r\n added: true,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n });\r\n\r\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\r\n if (!inHandler) {\r\n inHandler = true;\r\n const overwrite = (typeof args.added === typeof undefined);\r\n\r\n if (overwrite) {\r\n setSelectedRowIds(args.ids);\r\n } else {\r\n let rowIds: DataIdType[];\r\n if (args.added) {\r\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\r\n // find the ones that are hidden\r\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\r\n // add the newly selected ones\r\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\r\n } else {\r\n rowIds = args.ids;\r\n }\r\n } else {\r\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\r\n // remove rows whose id is on the list\r\n const argsIdsSet = new Set(args.ids);\r\n rowIds = this.selectedRowIds?.filter((id) => !argsIdsSet.has(id));\r\n } else {\r\n rowIds = [];\r\n }\r\n }\r\n setSelectedRowIds(rowIds);\r\n }\r\n inHandler = false;\r\n }\r\n };\r\n\r\n this.onRowsOrCountChanged.subscribe(update.bind(this));\r\n\r\n return this.onSelectedRowIdsChanged;\r\n }\r\n\r\n /**\r\n * Get all selected IDs\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedIds() {\r\n return this.selectedRowIds;\r\n }\r\n\r\n /**\r\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedFilteredIds() {\r\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\r\n }\r\n\r\n /**\r\n * Set current row selected IDs array (regardless of Pagination)\r\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\r\n * \"grid.setSelectedRows(rows)\"\r\n * @param {Array} selectedIds - list of IDs which have been selected for this action\r\n * @param {Object} options\r\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\r\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\r\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\r\n */\r\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\r\n let isRowBeingAdded = options?.isRowBeingAdded;\r\n const shouldTriggerEvent = options?.shouldTriggerEvent;\r\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\r\n\r\n if (isRowBeingAdded !== false) {\r\n isRowBeingAdded = true;\r\n }\r\n const selectedRows = this.mapIdsToRows(selectedIds);\r\n const selectedRowsChangedArgs = {\r\n grid: this._grid,\r\n ids: selectedIds,\r\n rows: selectedRows,\r\n added: isRowBeingAdded,\r\n dataView: this\r\n };\r\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\r\n\r\n if (shouldTriggerEvent !== false) {\r\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\r\n selectedRowIds: this.selectedRowIds,\r\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\r\n }), new SlickEventData(), this);\r\n }\r\n\r\n // should we also apply the row selection in to the grid (UI) as well?\r\n if (applyRowSelectionToGrid !== false && this._grid) {\r\n this._grid.setSelectedRows(selectedRows);\r\n }\r\n }\r\n\r\n /**\r\n * Get all selected dataContext items\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedItems() {\r\n const selectedData: TData[] = [];\r\n const selectedIds = this.getAllSelectedIds();\r\n selectedIds!.forEach((id) => {\r\n selectedData.push(this.getItemById(id));\r\n });\r\n return selectedData as T[];\r\n }\r\n\r\n /**\r\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\r\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\r\n */\r\n getAllSelectedFilteredItems() {\r\n if (!Array.isArray(this.selectedRowIds)) {\r\n return [];\r\n }\r\n\r\n const selectedRowIdSet = new Set(this.selectedRowIds);\r\n const intersection = this.filteredItems.filter((a) => selectedRowIdSet.has(a[this.idProperty as keyof TData] as DataIdType));\r\n return (intersection || []) as T[];\r\n }\r\n\r\n syncGridCellCssStyles(grid: SlickGridModel, key: string) {\r\n let hashById: any;\r\n let inHandler: boolean;\r\n\r\n const storeCellCssStyles = (hash: CssStyleHash) => {\r\n hashById = {};\r\n if (typeof hash === 'object') {\r\n Object.keys(hash).forEach(row => {\r\n if (hash) {\r\n const id = this.rows[row as any][this.idProperty as keyof TData];\r\n hashById[id] = hash[row];\r\n }\r\n });\r\n }\r\n };\r\n\r\n // since this method can be called after the cell styles have been set,\r\n // get the existing ones right away\r\n storeCellCssStyles(grid.getCellCssStyles(key));\r\n\r\n const update = () => {\r\n if (typeof hashById === 'object') {\r\n inHandler = true;\r\n this.ensureRowsByIdCache();\r\n const newHash: CssStyleHash = {};\r\n Object.keys(hashById).forEach(id => {\r\n const row = this.rowsById?.[id];\r\n if (Utils.isDefined(row)) {\r\n newHash[row as number] = hashById[id];\r\n }\r\n });\r\n grid.setCellCssStyles(key, newHash);\r\n inHandler = false;\r\n }\r\n };\r\n\r\n grid.onCellCssStylesChanged.subscribe((_e: SlickEventData_, args: any) => {\r\n if (inHandler) { return; }\r\n if (key !== args.key) { return; }\r\n if (args.hash) {\r\n storeCellCssStyles(args.hash);\r\n } else {\r\n grid.onCellCssStylesChanged.unsubscribe();\r\n this.onRowsOrCountChanged.unsubscribe(update);\r\n }\r\n });\r\n\r\n this.onRowsOrCountChanged.subscribe(update.bind(this));\r\n }\r\n}\r\n\r\nexport class AvgAggregator implements Aggregator {\r\n private _nonNullCount = 0;\r\n private _sum = 0;\r\n private _field: number | string;\r\n private _type = 'avg' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n this._nonNullCount = 0;\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n this._nonNullCount++;\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n (groupTotals as any)[this._type] = {};\r\n }\r\n if (this._nonNullCount !== 0) {\r\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\r\n }\r\n }\r\n}\r\n\r\nexport class MinAggregator implements Aggregator {\r\n private _min: number | null = null;\r\n private _field: number | string;\r\n private _type = 'min' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init() {\r\n this._min = null;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n if (this._min === null || val < this._min) {\r\n this._min = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._min;\r\n }\r\n}\r\n\r\nexport class MaxAggregator implements Aggregator {\r\n private _max: number | null = null;\r\n private _field: number | string;\r\n private _type = 'max' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n this._max = null;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n if (this._max === null || val > this._max) {\r\n this._max = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._max;\r\n }\r\n}\r\n\r\nexport class SumAggregator implements Aggregator {\r\n private _sum = 0;\r\n private _field: number | string;\r\n private _type = 'sum' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init() {\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: T) {\r\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\r\n if (val !== null && val !== '' && !isNaN(val)) {\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = this._sum;\r\n }\r\n}\r\n\r\nexport class CountAggregator implements Aggregator {\r\n private _field: number | string;\r\n private _type = 'count' as const;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n get field(): number | string {\r\n return this._field;\r\n }\r\n\r\n get type(): string {\r\n return this._type;\r\n }\r\n\r\n init(): void {\r\n }\r\n\r\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\r\n if (!groupTotals || groupTotals[this._type] === undefined) {\r\n groupTotals[this._type] = {};\r\n }\r\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\r\n }\r\n}\r\n\r\n// TODO: add more built-in aggregators\r\n// TODO: merge common aggregators in one to prevent needless iterating\r\n\r\nexport const Aggregators = {\r\n Avg: AvgAggregator,\r\n Min: MinAggregator,\r\n Max: MaxAggregator,\r\n Sum: SumAggregator,\r\n Count: CountAggregator\r\n};\r\n\r\n// extend Slick namespace on window object when building as iife\r\nif (IIFE_ONLY && window.Slick) {\r\n window.Slick.Data = window.Slick.Data || {};\r\n window.Slick.Data.DataView = SlickDataView;\r\n window.Slick.Data.Aggregators = Aggregators;\r\n}"], + "mappings": "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", "names": ["_a", "_b"] } diff --git a/dist/browser/slick.grid.js b/dist/browser/slick.grid.js index 997e0daf..388b249e 100644 --- a/dist/browser/slick.grid.js +++ b/dist/browser/slick.grid.js @@ -24,7 +24,7 @@ this.externalPubSub = externalPubSub; ////////////////////////////////////////////////////////////////////////////////////////////// // Public API - __publicField(this, "slickGridVersion", "5.12.1"); + __publicField(this, "slickGridVersion", "5.13.0"); /** optional grid state clientId */ __publicField(this, "cid", ""); // Events @@ -1480,7 +1480,7 @@ this.canCellBeSelected(j, k) && (hash[j][this.columns[k].id] = this._options.selectedCellCssClass); } if (this.setCellCssStyles(this._options.selectedCellCssClass || "", hash), this.simpleArrayEquals(previousSelectedRows, this.selectedRows)) { - let caller = (_b = (_a = ne == null ? void 0 : ne.detail) == null ? void 0 : _a.caller) != null ? _b : "click", newSelectedAdditions = this.getSelectedRows().filter((i) => previousSelectedRows.indexOf(i) < 0), newSelectedDeletions = previousSelectedRows.filter((i) => this.getSelectedRows().indexOf(i) < 0); + let caller = (_b = (_a = ne == null ? void 0 : ne.detail) == null ? void 0 : _a.caller) != null ? _b : "click", selectedRowsSet = new Set(this.getSelectedRows()), previousSelectedRowsSet = new Set(previousSelectedRows), newSelectedAdditions = Array.from(selectedRowsSet).filter((i) => !previousSelectedRowsSet.has(i)), newSelectedDeletions = Array.from(previousSelectedRowsSet).filter((i) => !selectedRowsSet.has(i)); this.trigger(this.onSelectedRowsChanged, { rows: this.getSelectedRows(), previousSelectedRows, @@ -3114,7 +3114,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v5.12.1 + * SlickGrid v5.13.0 * * NOTES: * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods. diff --git a/dist/browser/slick.grid.js.map b/dist/browser/slick.grid.js.map index 766ef7cd..14e2f292 100644 --- a/dist/browser/slick.grid.js.map +++ b/dist/browser/slick.grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.grid.ts"], - "sourcesContent": ["// @ts-ignore\r\nimport type SortableInstance from 'sortablejs';\r\n\r\nimport type {\r\n AutoSize,\r\n CellViewportRange,\r\n Column,\r\n ColumnSort,\r\n CssStyleHash,\r\n CSSStyleDeclarationWritable,\r\n CustomDataView,\r\n DOMEvent,\r\n DragPosition,\r\n DragRowMove,\r\n Editor,\r\n EditorArguments,\r\n EditorConstructor,\r\n EditController,\r\n Formatter,\r\n FormatterOverrideCallback,\r\n FormatterResultObject,\r\n FormatterResultWithHtml,\r\n FormatterResultWithText,\r\n GridOption as BaseGridOption,\r\n InteractionBase,\r\n ItemMetadata,\r\n MenuCommandItemCallbackArgs,\r\n MultiColumnSort,\r\n OnActivateChangedOptionsEventArgs,\r\n OnActiveCellChangedEventArgs,\r\n OnAddNewRowEventArgs,\r\n OnAutosizeColumnsEventArgs,\r\n OnBeforeUpdateColumnsEventArgs,\r\n OnBeforeAppendCellEventArgs,\r\n OnBeforeCellEditorDestroyEventArgs,\r\n OnBeforeColumnsResizeEventArgs,\r\n OnBeforeEditCellEventArgs,\r\n OnBeforeHeaderCellDestroyEventArgs,\r\n OnBeforeHeaderRowCellDestroyEventArgs,\r\n OnBeforeFooterRowCellDestroyEventArgs,\r\n OnBeforeSetColumnsEventArgs,\r\n OnCellChangeEventArgs,\r\n OnCellCssStylesChangedEventArgs,\r\n OnClickEventArgs,\r\n OnColumnsDragEventArgs,\r\n OnColumnsReorderedEventArgs,\r\n OnColumnsResizedEventArgs,\r\n OnColumnsResizeDblClickEventArgs,\r\n OnCompositeEditorChangeEventArgs,\r\n OnDblClickEventArgs,\r\n OnFooterContextMenuEventArgs,\r\n OnFooterRowCellRenderedEventArgs,\r\n OnHeaderCellRenderedEventArgs,\r\n OnFooterClickEventArgs,\r\n OnHeaderClickEventArgs,\r\n OnHeaderContextMenuEventArgs,\r\n OnHeaderMouseEventArgs,\r\n OnHeaderRowCellRenderedEventArgs,\r\n OnKeyDownEventArgs,\r\n OnPreHeaderContextMenuEventArgs,\r\n OnPreHeaderClickEventArgs,\r\n OnRenderedEventArgs,\r\n OnSelectedRowsChangedEventArgs,\r\n OnSetOptionsEventArgs,\r\n OnScrollEventArgs,\r\n OnValidationErrorEventArgs,\r\n PagingInfo,\r\n RowInfo,\r\n SelectionModel,\r\n SingleColumnSort,\r\n SlickGridModel,\r\n SlickPlugin,\r\n} from './models/index';\r\nimport {\r\n type BasePubSub,\r\n BindingEventService as BindingEventService_,\r\n ColAutosizeMode as ColAutosizeMode_,\r\n GlobalEditorLock as GlobalEditorLock_,\r\n GridAutosizeColsMode as GridAutosizeColsMode_,\r\n keyCode as keyCode_,\r\n preClickClassName as preClickClassName_,\r\n RowSelectionMode as RowSelectionMode_,\r\n type SlickEditorLock,\r\n SlickEvent as SlickEvent_,\r\n SlickEventData as SlickEventData_,\r\n SlickRange as SlickRange_,\r\n Utils as Utils_,\r\n ValueFilterMode as ValueFilterMode_,\r\n WidthEvalMode as WidthEvalMode_,\r\n} from './slick.core';\r\nimport { Draggable as Draggable_, MouseWheel as MouseWheel_, Resizable as Resizable_ } from './slick.interactions';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\r\nconst ColAutosizeMode = IIFE_ONLY ? Slick.ColAutosizeMode : ColAutosizeMode_;\r\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\r\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\r\nconst GlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : GlobalEditorLock_;\r\nconst GridAutosizeColsMode = IIFE_ONLY ? Slick.GridAutosizeColsMode : GridAutosizeColsMode_;\r\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\r\nconst preClickClassName = IIFE_ONLY ? Slick.preClickClassName : preClickClassName_;\r\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\r\nconst RowSelectionMode = IIFE_ONLY ? Slick.RowSelectionMode : RowSelectionMode_;\r\nconst ValueFilterMode = IIFE_ONLY ? Slick.ValueFilterMode : ValueFilterMode_;\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\nconst WidthEvalMode = IIFE_ONLY ? Slick.WidthEvalMode : WidthEvalMode_;\r\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\r\nconst MouseWheel = IIFE_ONLY ? Slick.MouseWheel : MouseWheel_;\r\nconst Resizable = IIFE_ONLY ? Slick.Resizable : Resizable_;\r\n\r\n/**\r\n * @license\r\n * (c) 2009-present Michael Leibman\r\n * michael{dot}leibman{at}gmail{dot}com\r\n * http://github.com/mleibman/slickgrid\r\n *\r\n * Distributed under MIT license.\r\n * All rights reserved.\r\n *\r\n * SlickGrid v5.12.1\r\n *\r\n * NOTES:\r\n * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods.\r\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n * and do proper cleanup.\r\n */\r\n\r\n//////////////////////////////////////////////////////////////////////////////////////////////\r\n// SlickGrid class implementation (available as SlickGrid)\r\n\r\ninterface RowCaching {\r\n rowNode: HTMLElement[] | null,\r\n cellColSpans: Array;\r\n cellNodesByColumnIdx: HTMLElement[];\r\n cellRenderQueue: any[];\r\n}\r\n\r\nexport class SlickGrid = Column, O extends BaseGridOption = BaseGridOption> {\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Public API\r\n slickGridVersion = '5.12.1';\r\n\r\n /** optional grid state clientId */\r\n cid = '';\r\n\r\n // Events\r\n onActiveCellChanged: SlickEvent_;\r\n onActiveCellPositionChanged: SlickEvent_<{ grid: SlickGrid; }>;\r\n onAddNewRow: SlickEvent_;\r\n onAutosizeColumns: SlickEvent_;\r\n onBeforeAppendCell: SlickEvent_;\r\n onBeforeCellEditorDestroy: SlickEvent_;\r\n onBeforeColumnsResize: SlickEvent_;\r\n onBeforeDestroy: SlickEvent_<{ grid: SlickGrid; }>;\r\n onBeforeEditCell: SlickEvent_;\r\n onBeforeFooterRowCellDestroy: SlickEvent_;\r\n onBeforeHeaderCellDestroy: SlickEvent_;\r\n onBeforeHeaderRowCellDestroy: SlickEvent_;\r\n onBeforeSetColumns: SlickEvent_;\r\n onBeforeSort: SlickEvent_;\r\n onBeforeUpdateColumns: SlickEvent_;\r\n onCellChange: SlickEvent_;\r\n onCellCssStylesChanged: SlickEvent_;\r\n onClick: SlickEvent_;\r\n onColumnsReordered: SlickEvent_;\r\n onColumnsDrag: SlickEvent_;\r\n onColumnsResized: SlickEvent_;\r\n onColumnsResizeDblClick: SlickEvent_;\r\n onCompositeEditorChange: SlickEvent_;\r\n onContextMenu: SlickEvent_;\r\n onDrag: SlickEvent_;\r\n onDblClick: SlickEvent_;\r\n onDragInit: SlickEvent_;\r\n onDragStart: SlickEvent_;\r\n onDragEnd: SlickEvent_;\r\n onFooterClick: SlickEvent_;\r\n onFooterContextMenu: SlickEvent_;\r\n onFooterRowCellRendered: SlickEvent_;\r\n onHeaderCellRendered: SlickEvent_;\r\n onHeaderClick: SlickEvent_;\r\n onHeaderContextMenu: SlickEvent_;\r\n onHeaderMouseEnter: SlickEvent_;\r\n onHeaderMouseLeave: SlickEvent_;\r\n onHeaderRowCellRendered: SlickEvent_;\r\n onHeaderRowMouseEnter: SlickEvent_;\r\n onHeaderRowMouseLeave: SlickEvent_;\r\n onPreHeaderContextMenu: SlickEvent_;\r\n onPreHeaderClick: SlickEvent_;\r\n onKeyDown: SlickEvent_;\r\n onMouseEnter: SlickEvent_;\r\n onMouseLeave: SlickEvent_;\r\n onRendered: SlickEvent_;\r\n onScroll: SlickEvent_;\r\n onSelectedRowsChanged: SlickEvent_;\r\n onSetOptions: SlickEvent_;\r\n onActivateChangedOptions: SlickEvent_;\r\n onSort: SlickEvent_;\r\n onValidationError: SlickEvent_;\r\n onViewportChanged: SlickEvent_<{ grid: SlickGrid; }>;\r\n\r\n // ---\r\n // protected variables\r\n\r\n // shared across all grids on the page\r\n protected scrollbarDimensions?: { height: number; width: number; };\r\n protected maxSupportedCssHeight!: number; // browser's breaking point\r\n\r\n protected canvas: HTMLCanvasElement | null = null;\r\n protected canvas_context: CanvasRenderingContext2D | null = null;\r\n\r\n // settings\r\n protected _options!: O;\r\n protected _defaults: BaseGridOption = {\r\n alwaysShowVerticalScroll: false,\r\n alwaysAllowHorizontalScroll: false,\r\n explicitInitialization: false,\r\n rowHeight: 25,\r\n defaultColumnWidth: 80,\r\n enableHtmlRendering: true,\r\n enableAddRow: false,\r\n leaveSpaceForNewRows: false,\r\n editable: false,\r\n autoEdit: true,\r\n autoEditNewRow: true,\r\n autoCommitEdit: false,\r\n suppressActiveCellChangeOnEdit: false,\r\n enableCellNavigation: true,\r\n enableColumnReorder: true,\r\n unorderableColumnCssClass: 'unorderable',\r\n asyncEditorLoading: false,\r\n asyncEditorLoadDelay: 100,\r\n forceFitColumns: false,\r\n enableAsyncPostRender: false,\r\n asyncPostRenderDelay: 50,\r\n enableAsyncPostRenderCleanup: false,\r\n asyncPostRenderCleanupDelay: 40,\r\n auto: false,\r\n nonce: '',\r\n editorLock: GlobalEditorLock,\r\n showColumnHeader: true,\r\n showHeaderRow: false,\r\n headerRowHeight: 25,\r\n createFooterRow: false,\r\n showFooterRow: false,\r\n footerRowHeight: 25,\r\n createPreHeaderPanel: false,\r\n createTopHeaderPanel: false,\r\n showPreHeaderPanel: false,\r\n showTopHeaderPanel: false,\r\n preHeaderPanelHeight: 25,\r\n showTopPanel: false,\r\n topPanelHeight: 25,\r\n preHeaderPanelWidth: 'auto', // mostly useful for Draggable Grouping dropzone to take full width\r\n topHeaderPanelHeight: 25,\r\n topHeaderPanelWidth: 'auto', // mostly useful for Draggable Grouping dropzone to take full width\r\n formatterFactory: null,\r\n editorFactory: null,\r\n cellFlashingCssClass: 'flashing',\r\n rowHighlightCssClass: 'highlight-animate',\r\n rowHighlightDuration: 400,\r\n selectedCellCssClass: 'selected',\r\n multiSelect: true,\r\n enableTextSelectionOnCells: false,\r\n dataItemColumnValueExtractor: null,\r\n frozenBottom: false,\r\n frozenColumn: -1,\r\n frozenRow: -1,\r\n frozenRightViewportMinWidth: 100,\r\n throwWhenFrozenNotAllViewable: false,\r\n fullWidthRows: false,\r\n multiColumnSort: false,\r\n numberedMultiColumnSort: false,\r\n tristateMultiColumnSort: false,\r\n sortColNumberInSeparateSpan: false,\r\n defaultFormatter: this.defaultFormatter,\r\n forceSyncScrolling: false,\r\n addNewRowCssClass: 'new-row',\r\n preserveCopiedSelectionOnPaste: false,\r\n preventDragFromKeys: ['ctrlKey', 'metaKey'],\r\n showCellSelection: true,\r\n viewportClass: undefined,\r\n minRowBuffer: 3,\r\n emulatePagingWhenScrolling: true, // when scrolling off bottom of viewport, place new row at top of viewport\r\n editorCellNavOnLRKeys: false,\r\n enableMouseWheelScrollHandler: true,\r\n doPaging: true,\r\n autosizeColsMode: GridAutosizeColsMode.LegacyOff,\r\n autosizeColPaddingPx: 4,\r\n rowTopOffsetRenderType: 'top',\r\n scrollRenderThrottling: 10,\r\n autosizeTextAvgToMWidthRatio: 0.75,\r\n viewportSwitchToScrollModeWidthPercent: undefined,\r\n viewportMinWidthPx: undefined,\r\n viewportMaxWidthPx: undefined,\r\n suppressCssChangesOnHiddenInit: false,\r\n ffMaxSupportedCssHeight: 6000000,\r\n maxSupportedCssHeight: 1000000000,\r\n sanitizer: undefined, // sanitize function, built in basic sanitizer is: Slick.RegexSanitizer(dirtyHtml)\r\n logSanitizedHtml: false, // log to console when sanitised - recommend true for testing of dev and production\r\n mixinDefaults: true,\r\n shadowRoot: undefined\r\n };\r\n\r\n protected _columnDefaults = {\r\n name: '',\r\n headerCssClass: null,\r\n defaultSortAsc: true,\r\n focusable: true,\r\n hidden: false,\r\n minWidth: 30,\r\n maxWidth: undefined,\r\n rerenderOnResize: false,\r\n reorderable: true,\r\n resizable: true,\r\n sortable: false,\r\n selectable: true,\r\n } as Partial;\r\n\r\n protected _columnAutosizeDefaults: AutoSize = {\r\n ignoreHeaderText: false,\r\n colValueArray: undefined,\r\n allowAddlPercent: undefined,\r\n formatterOverride: undefined,\r\n autosizeMode: ColAutosizeMode.ContentIntelligent,\r\n rowSelectionModeOnInit: undefined,\r\n rowSelectionMode: RowSelectionMode.FirstNRows,\r\n rowSelectionCount: 100,\r\n valueFilterMode: ValueFilterMode.None,\r\n widthEvalMode: WidthEvalMode.Auto,\r\n sizeToRemaining: undefined,\r\n widthPx: undefined,\r\n contentSizePx: 0,\r\n headerWidthPx: 0,\r\n colDataTypeOf: undefined\r\n };\r\n\r\n protected _columnResizeTimer?: number;\r\n protected _executionBlockTimer?: number;\r\n protected _flashCellTimer?: number;\r\n protected _highlightRowTimer?: number;\r\n\r\n // scroller\r\n protected th!: number; // virtual height\r\n protected h!: number; // real scrollable height\r\n protected ph!: number; // page height\r\n protected n!: number; // number of pages\r\n protected cj!: number; // \"jumpiness\" coefficient\r\n\r\n protected page = 0; // current page\r\n protected offset = 0; // current page offset\r\n protected vScrollDir = 1;\r\n protected _bindingEventService = new BindingEventService();\r\n protected initialized = false;\r\n protected _container!: HTMLElement;\r\n protected uid = `slickgrid_${Math.round(1000000 * Math.random())}`;\r\n protected _focusSink!: HTMLDivElement;\r\n protected _focusSink2!: HTMLDivElement;\r\n protected _groupHeaders: HTMLDivElement[] = [];\r\n protected _headerScroller: HTMLDivElement[] = [];\r\n protected _headers: HTMLDivElement[] = [];\r\n protected _headerRows!: HTMLDivElement[];\r\n protected _headerRowScroller!: HTMLDivElement[];\r\n protected _headerRowSpacerL!: HTMLDivElement;\r\n protected _headerRowSpacerR!: HTMLDivElement;\r\n protected _footerRow!: HTMLDivElement[];\r\n protected _footerRowScroller!: HTMLDivElement[];\r\n protected _footerRowSpacerL!: HTMLDivElement;\r\n protected _footerRowSpacerR!: HTMLDivElement;\r\n protected _preHeaderPanel!: HTMLDivElement;\r\n protected _preHeaderPanelScroller!: HTMLDivElement;\r\n protected _preHeaderPanelSpacer!: HTMLDivElement;\r\n protected _preHeaderPanelR!: HTMLDivElement;\r\n protected _preHeaderPanelScrollerR!: HTMLDivElement;\r\n protected _preHeaderPanelSpacerR!: HTMLDivElement;\r\n protected _topHeaderPanel!: HTMLDivElement;\r\n protected _topHeaderPanelScroller!: HTMLDivElement;\r\n protected _topHeaderPanelSpacer!: HTMLDivElement;\r\n protected _topPanelScrollers!: HTMLDivElement[];\r\n protected _topPanels!: HTMLDivElement[];\r\n protected _viewport!: HTMLDivElement[];\r\n protected _canvas!: HTMLDivElement[];\r\n protected _style?: HTMLStyleElement;\r\n protected _boundAncestors: HTMLElement[] = [];\r\n protected stylesheet?: { cssRules: Array<{ selectorText: string; }>; rules: Array<{ selectorText: string; }>; } | null;\r\n protected columnCssRulesL?: Array<{ selectorText: string; }>;\r\n protected columnCssRulesR?: Array<{ selectorText: string; }>;\r\n protected viewportH = 0;\r\n protected viewportW = 0;\r\n protected canvasWidth = 0;\r\n protected canvasWidthL = 0;\r\n protected canvasWidthR = 0;\r\n protected headersWidth = 0;\r\n protected headersWidthL = 0;\r\n protected headersWidthR = 0;\r\n protected viewportHasHScroll = false;\r\n protected viewportHasVScroll = false;\r\n protected headerColumnWidthDiff = 0;\r\n protected headerColumnHeightDiff = 0; // border+padding\r\n protected cellWidthDiff = 0;\r\n protected cellHeightDiff = 0;\r\n protected absoluteColumnMinWidth!: number;\r\n protected hasFrozenRows = false;\r\n protected frozenRowsHeight = 0;\r\n protected actualFrozenRow = -1;\r\n protected paneTopH = 0;\r\n protected paneBottomH = 0;\r\n protected viewportTopH = 0;\r\n protected viewportBottomH = 0;\r\n protected topPanelH = 0;\r\n protected headerRowH = 0;\r\n protected footerRowH = 0;\r\n\r\n protected tabbingDirection = 1;\r\n protected _activeCanvasNode!: HTMLDivElement;\r\n protected _activeViewportNode!: HTMLDivElement;\r\n protected activePosX!: number;\r\n protected activeRow!: number;\r\n protected activeCell!: number;\r\n protected activeCellNode: HTMLDivElement | null = null;\r\n protected currentEditor: Editor | null = null;\r\n protected serializedEditorValue: any;\r\n protected editController?: EditController;\r\n\r\n protected rowsCache: Array = {} as any;\r\n protected renderedRows = 0;\r\n protected numVisibleRows = 0;\r\n protected prevScrollTop = 0;\r\n protected scrollHeight = 0;\r\n protected scrollTop = 0;\r\n protected lastRenderedScrollTop = 0;\r\n protected lastRenderedScrollLeft = 0;\r\n protected prevScrollLeft = 0;\r\n protected scrollLeft = 0;\r\n\r\n protected selectionModel?: SelectionModel;\r\n protected selectedRows: number[] = [];\r\n\r\n protected plugins: SlickPlugin[] = [];\r\n protected cellCssClasses: CssStyleHash = {};\r\n\r\n protected columnsById: Record = {};\r\n protected sortColumns: ColumnSort[] = [];\r\n protected columnPosLeft: number[] = [];\r\n protected columnPosRight: number[] = [];\r\n\r\n protected pagingActive = false;\r\n protected pagingIsLastPage = false;\r\n\r\n protected scrollThrottle!: { enqueue: () => void; dequeue: () => void; };\r\n\r\n // async call handles\r\n protected h_editorLoader?: number;\r\n protected h_render = null;\r\n protected h_postrender?: number;\r\n protected h_postrenderCleanup?: number;\r\n protected postProcessedRows: any = {};\r\n protected postProcessToRow: number = null as any;\r\n protected postProcessFromRow: number = null as any;\r\n protected postProcessedCleanupQueue: Array<{\r\n actionType: string;\r\n groupId: number;\r\n node: HTMLElement | HTMLElement[];\r\n columnIdx?: number;\r\n rowIdx?: number;\r\n }> = [];\r\n protected postProcessgroupId = 0;\r\n\r\n // perf counters\r\n protected counter_rows_rendered = 0;\r\n protected counter_rows_removed = 0;\r\n\r\n protected _paneHeaderL!: HTMLDivElement;\r\n protected _paneHeaderR!: HTMLDivElement;\r\n protected _paneTopL!: HTMLDivElement;\r\n protected _paneTopR!: HTMLDivElement;\r\n protected _paneBottomL!: HTMLDivElement;\r\n protected _paneBottomR!: HTMLDivElement;\r\n protected _headerScrollerL!: HTMLDivElement;\r\n protected _headerScrollerR!: HTMLDivElement;\r\n protected _headerL!: HTMLDivElement;\r\n protected _headerR!: HTMLDivElement;\r\n protected _groupHeadersL!: HTMLDivElement;\r\n protected _groupHeadersR!: HTMLDivElement;\r\n protected _headerRowScrollerL!: HTMLDivElement;\r\n protected _headerRowScrollerR!: HTMLDivElement;\r\n protected _footerRowScrollerL!: HTMLDivElement;\r\n protected _footerRowScrollerR!: HTMLDivElement;\r\n protected _headerRowL!: HTMLDivElement;\r\n protected _headerRowR!: HTMLDivElement;\r\n protected _footerRowL!: HTMLDivElement;\r\n protected _footerRowR!: HTMLDivElement;\r\n protected _topPanelScrollerL!: HTMLDivElement;\r\n protected _topPanelScrollerR!: HTMLDivElement;\r\n protected _topPanelL!: HTMLDivElement;\r\n protected _topPanelR!: HTMLDivElement;\r\n protected _viewportTopL!: HTMLDivElement;\r\n protected _viewportTopR!: HTMLDivElement;\r\n protected _viewportBottomL!: HTMLDivElement;\r\n protected _viewportBottomR!: HTMLDivElement;\r\n protected _canvasTopL!: HTMLDivElement;\r\n protected _canvasTopR!: HTMLDivElement;\r\n protected _canvasBottomL!: HTMLDivElement;\r\n protected _canvasBottomR!: HTMLDivElement;\r\n protected _viewportScrollContainerX!: HTMLDivElement;\r\n protected _viewportScrollContainerY!: HTMLDivElement;\r\n protected _headerScrollContainer!: HTMLDivElement;\r\n protected _headerRowScrollContainer!: HTMLDivElement;\r\n protected _footerRowScrollContainer!: HTMLDivElement;\r\n\r\n // store css attributes if display:none is active in container or parent\r\n protected cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\r\n protected _hiddenParents: HTMLElement[] = [];\r\n protected oldProps: Array> = [];\r\n protected enforceFrozenRowHeightRecalc = false;\r\n protected columnResizeDragging = false;\r\n protected slickDraggableInstance: InteractionBase | null = null;\r\n protected slickMouseWheelInstances: Array = [];\r\n protected slickResizableInstances: Array = [];\r\n protected sortableSideLeftInstance?: SortableInstance;\r\n protected sortableSideRightInstance?: SortableInstance;\r\n protected logMessageCount = 0;\r\n protected logMessageMaxCount = 30;\r\n protected _pubSubService?: BasePubSub;\r\n\r\n /**\r\n * Creates a new instance of the grid.\r\n * @class SlickGrid\r\n * @constructor\r\n * @param {Node} container - Container node to create the grid in.\r\n * @param {Array|Object} data - An array of objects for databinding or an external DataView.\r\n * @param {Array} columns - An array of column definitions.\r\n * @param {Object} [options] - Grid Options\r\n * @param {Object} [externalPubSub] - optional External PubSub Service to use by SlickEvent\r\n **/\r\n constructor(protected readonly container: HTMLElement | string, protected data: CustomDataView | TData[], protected columns: C[], options: Partial, protected readonly externalPubSub?: BasePubSub) {\r\n this._container = typeof this.container === 'string'\r\n ? document.querySelector(this.container) as HTMLDivElement\r\n : this.container;\r\n\r\n if (!this._container) {\r\n throw new Error(`SlickGrid requires a valid container, ${this.container} does not exist in the DOM.`);\r\n }\r\n\r\n this._pubSubService = externalPubSub;\r\n this.onActiveCellChanged = new SlickEvent('onActiveCellChanged', externalPubSub);\r\n this.onActiveCellPositionChanged = new SlickEvent<{ grid: SlickGrid; }>('onActiveCellPositionChanged', externalPubSub);\r\n this.onAddNewRow = new SlickEvent('onAddNewRow', externalPubSub);\r\n this.onAutosizeColumns = new SlickEvent('onAutosizeColumns', externalPubSub);\r\n this.onBeforeAppendCell = new SlickEvent('onBeforeAppendCell', externalPubSub);\r\n this.onBeforeCellEditorDestroy = new SlickEvent('onBeforeCellEditorDestroy', externalPubSub);\r\n this.onBeforeColumnsResize = new SlickEvent('onBeforeColumnsResize', externalPubSub);\r\n this.onBeforeDestroy = new SlickEvent<{ grid: SlickGrid; }>('onBeforeDestroy', externalPubSub);\r\n this.onBeforeEditCell = new SlickEvent('onBeforeEditCell', externalPubSub);\r\n this.onBeforeFooterRowCellDestroy = new SlickEvent('onBeforeFooterRowCellDestroy', externalPubSub);\r\n this.onBeforeHeaderCellDestroy = new SlickEvent('onBeforeHeaderCellDestroy', externalPubSub);\r\n this.onBeforeHeaderRowCellDestroy = new SlickEvent('onBeforeHeaderRowCellDestroy', externalPubSub);\r\n this.onBeforeSetColumns = new SlickEvent('onBeforeSetColumns', externalPubSub);\r\n this.onBeforeSort = new SlickEvent('onBeforeSort', externalPubSub);\r\n this.onBeforeUpdateColumns = new SlickEvent('onBeforeUpdateColumns', externalPubSub);\r\n this.onCellChange = new SlickEvent('onCellChange', externalPubSub);\r\n this.onCellCssStylesChanged = new SlickEvent('onCellCssStylesChanged', externalPubSub);\r\n this.onClick = new SlickEvent('onClick', externalPubSub);\r\n this.onColumnsReordered = new SlickEvent('onColumnsReordered', externalPubSub);\r\n this.onColumnsDrag = new SlickEvent('onColumnsDrag', externalPubSub);\r\n this.onColumnsResized = new SlickEvent('onColumnsResized', externalPubSub);\r\n this.onColumnsResizeDblClick = new SlickEvent('onColumnsResizeDblClick', externalPubSub);\r\n this.onCompositeEditorChange = new SlickEvent('onCompositeEditorChange', externalPubSub);\r\n this.onContextMenu = new SlickEvent('onContextMenu', externalPubSub);\r\n this.onDrag = new SlickEvent('onDrag', externalPubSub);\r\n this.onDblClick = new SlickEvent('onDblClick', externalPubSub);\r\n this.onDragInit = new SlickEvent('onDragInit', externalPubSub);\r\n this.onDragStart = new SlickEvent('onDragStart', externalPubSub);\r\n this.onDragEnd = new SlickEvent('onDragEnd', externalPubSub);\r\n this.onFooterClick = new SlickEvent('onFooterClick', externalPubSub);\r\n this.onFooterContextMenu = new SlickEvent('onFooterContextMenu', externalPubSub);\r\n this.onFooterRowCellRendered = new SlickEvent('onFooterRowCellRendered', externalPubSub);\r\n this.onHeaderCellRendered = new SlickEvent('onHeaderCellRendered', externalPubSub);\r\n this.onHeaderClick = new SlickEvent('onHeaderClick', externalPubSub);\r\n this.onHeaderContextMenu = new SlickEvent('onHeaderContextMenu', externalPubSub);\r\n this.onHeaderMouseEnter = new SlickEvent('onHeaderMouseEnter', externalPubSub);\r\n this.onHeaderMouseLeave = new SlickEvent('onHeaderMouseLeave', externalPubSub);\r\n this.onHeaderRowCellRendered = new SlickEvent('onHeaderRowCellRendered', externalPubSub);\r\n this.onHeaderRowMouseEnter = new SlickEvent('onHeaderRowMouseEnter', externalPubSub);\r\n this.onHeaderRowMouseLeave = new SlickEvent('onHeaderRowMouseLeave', externalPubSub);\r\n this.onPreHeaderClick = new SlickEvent('onPreHeaderClick', externalPubSub);\r\n this.onPreHeaderContextMenu = new SlickEvent('onPreHeaderContextMenu', externalPubSub);\r\n this.onKeyDown = new SlickEvent('onKeyDown', externalPubSub);\r\n this.onMouseEnter = new SlickEvent('onMouseEnter', externalPubSub);\r\n this.onMouseLeave = new SlickEvent('onMouseLeave', externalPubSub);\r\n this.onRendered = new SlickEvent('onRendered', externalPubSub);\r\n this.onScroll = new SlickEvent('onScroll', externalPubSub);\r\n this.onSelectedRowsChanged = new SlickEvent('onSelectedRowsChanged', externalPubSub);\r\n this.onSetOptions = new SlickEvent('onSetOptions', externalPubSub);\r\n this.onActivateChangedOptions = new SlickEvent('onActivateChangedOptions', externalPubSub);\r\n this.onSort = new SlickEvent('onSort', externalPubSub);\r\n this.onValidationError = new SlickEvent('onValidationError', externalPubSub);\r\n this.onViewportChanged = new SlickEvent<{ grid: SlickGrid; }>('onViewportChanged', externalPubSub);\r\n\r\n this.initialize(options);\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Initialization\r\n\r\n /** Initializes the grid. */\r\n init() {\r\n this.finishInitialization();\r\n }\r\n\r\n /**\r\n * Apply HTML code by 3 different ways depending on what is provided as input and what options are enabled.\r\n * 1. value is an HTMLElement or DocumentFragment, then first empty the target and simply append the HTML to the target element.\r\n * 2. value is string and `enableHtmlRendering` is enabled, then use `target.innerHTML = value;`\r\n * 3. value is string and `enableHtmlRendering` is disabled, then use `target.textContent = value;`\r\n * @param target - target element to apply to\r\n * @param val - input value can be either a string or an HTMLElement\r\n * @param options -\r\n * `emptyTarget`, defaults to true, will empty the target.\r\n * `skipEmptyReassignment`, defaults to true, when enabled it will not try to reapply an empty value when the target is already empty\r\n */\r\n applyHtmlCode(target: HTMLElement, val: string | HTMLElement | DocumentFragment, options?: { emptyTarget?: boolean; skipEmptyReassignment?: boolean; }) {\r\n if (target) {\r\n if (val instanceof HTMLElement || val instanceof DocumentFragment) {\r\n // first empty target and then append new HTML element\r\n const emptyTarget = options?.emptyTarget !== false;\r\n if (emptyTarget) {\r\n Utils.emptyElement(target);\r\n }\r\n target.appendChild(val);\r\n } else {\r\n // when it's already empty and we try to reassign empty, it's probably ok to skip the assignment\r\n const skipEmptyReassignment = options?.skipEmptyReassignment !== false;\r\n if (skipEmptyReassignment && !Utils.isDefined(val) && !target.innerHTML) {\r\n return;\r\n }\r\n\r\n let sanitizedText = val;\r\n if (typeof sanitizedText === 'number' || typeof sanitizedText === 'boolean') {\r\n target.textContent = sanitizedText;\r\n } else {\r\n sanitizedText = this.sanitizeHtmlString(val as string);\r\n\r\n // apply HTML when enableHtmlRendering is enabled but make sure we do have a value (without a value, it will simply use `textContent` to clear text content)\r\n if (this._options.enableHtmlRendering && sanitizedText) {\r\n target.innerHTML = sanitizedText;\r\n } else {\r\n target.textContent = sanitizedText;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected initialize(options: Partial) {\r\n // calculate these only once and share between grid instances\r\n if (options?.mixinDefaults) {\r\n // use provided options and then assign defaults\r\n if (!this._options) { this._options = options as O; }\r\n Utils.applyDefaults(this._options, this._defaults);\r\n } else {\r\n this._options = Utils.extend(true, {}, this._defaults, options);\r\n }\r\n this.scrollThrottle = this.actionThrottle(this.render.bind(this), this._options.scrollRenderThrottling as number);\r\n this.maxSupportedCssHeight = this.maxSupportedCssHeight || this.getMaxSupportedCssHeight();\r\n this.validateAndEnforceOptions();\r\n this._columnDefaults.width = this._options.defaultColumnWidth;\r\n\r\n if (!this._options.suppressCssChangesOnHiddenInit) {\r\n this.cacheCssForHiddenInit();\r\n }\r\n\r\n this.updateColumnProps();\r\n\r\n // validate loaded JavaScript modules against requested options\r\n if (this._options.enableColumnReorder && (!Sortable || !Sortable.create)) {\r\n throw new Error('SlickGrid requires Sortable.js module to be loaded');\r\n }\r\n\r\n this.editController = {\r\n commitCurrentEdit: this.commitCurrentEdit.bind(this),\r\n cancelCurrentEdit: this.cancelCurrentEdit.bind(this),\r\n };\r\n\r\n Utils.emptyElement(this._container);\r\n this._container.style.outline = String(0);\r\n this._container.classList.add(this.uid);\r\n this._container.classList.add('ui-widget');\r\n this._container.setAttribute('role', 'grid');\r\n\r\n const containerStyles = window.getComputedStyle(this._container);\r\n if (!(/relative|absolute|fixed/).test(containerStyles.position)) {\r\n this._container.style.position = 'relative';\r\n }\r\n\r\n this._focusSink = Utils.createDomElement('div', { tabIndex: 0, style: { position: 'fixed', width: '0px', height: '0px', top: '0px', left: '0px', outline: '0px' } }, this._container);\r\n\r\n if (this._options.createTopHeaderPanel) {\r\n this._topHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-topheader-panel slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._container);\r\n this._topHeaderPanelScroller.appendChild(document.createElement('div'));\r\n this._topHeaderPanel = Utils.createDomElement('div', null, this._topHeaderPanelScroller);\r\n this._topHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._topHeaderPanelScroller);\r\n\r\n if (!this._options.showTopHeaderPanel) {\r\n Utils.hide(this._topHeaderPanelScroller);\r\n }\r\n }\r\n\r\n // Containers used for scrolling frozen columns and rows\r\n this._paneHeaderL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneHeaderR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-right', tabIndex: 0 }, this._container);\r\n this._paneTopL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneTopR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-right', tabIndex: 0 }, this._container);\r\n this._paneBottomL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneBottomR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-right', tabIndex: 0 }, this._container);\r\n\r\n if (this._options.createPreHeaderPanel) {\r\n this._preHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);\r\n this._preHeaderPanelScroller.appendChild(document.createElement('div'));\r\n this._preHeaderPanel = Utils.createDomElement('div', null, this._preHeaderPanelScroller);\r\n this._preHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScroller);\r\n\r\n this._preHeaderPanelScrollerR = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);\r\n this._preHeaderPanelR = Utils.createDomElement('div', null, this._preHeaderPanelScrollerR);\r\n this._preHeaderPanelSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScrollerR);\r\n\r\n if (!this._options.showPreHeaderPanel) {\r\n Utils.hide(this._preHeaderPanelScroller);\r\n Utils.hide(this._preHeaderPanelScrollerR);\r\n }\r\n }\r\n\r\n // Append the header scroller containers\r\n this._headerScrollerL = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-left' }, this._paneHeaderL);\r\n this._headerScrollerR = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-right' }, this._paneHeaderR);\r\n\r\n // Cache the header scroller containers\r\n this._headerScroller.push(this._headerScrollerL);\r\n this._headerScroller.push(this._headerScrollerR);\r\n\r\n // Append the columnn containers to the headers\r\n this._headerL = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-left', role: 'row', style: { left: '-1000px' } }, this._headerScrollerL);\r\n this._headerR = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-right', role: 'row', style: { left: '-1000px' } }, this._headerScrollerR);\r\n\r\n // Cache the header columns\r\n this._headers = [this._headerL, this._headerR];\r\n\r\n this._headerRowScrollerL = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopL);\r\n this._headerRowScrollerR = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopR);\r\n\r\n this._headerRowScroller = [this._headerRowScrollerL, this._headerRowScrollerR];\r\n\r\n this._headerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerL);\r\n this._headerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerR);\r\n\r\n this._headerRowL = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-left' }, this._headerRowScrollerL);\r\n this._headerRowR = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-right' }, this._headerRowScrollerR);\r\n\r\n this._headerRows = [this._headerRowL, this._headerRowR];\r\n\r\n // Append the top panel scroller\r\n this._topPanelScrollerL = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopL);\r\n this._topPanelScrollerR = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopR);\r\n\r\n this._topPanelScrollers = [this._topPanelScrollerL, this._topPanelScrollerR];\r\n\r\n // Append the top panel\r\n this._topPanelL = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerL);\r\n this._topPanelR = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerR);\r\n\r\n this._topPanels = [this._topPanelL, this._topPanelR];\r\n\r\n if (!this._options.showColumnHeader) {\r\n this._headerScroller.forEach((el) => {\r\n Utils.hide(el);\r\n });\r\n }\r\n\r\n if (!this._options.showTopPanel) {\r\n this._topPanelScrollers.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n\r\n if (!this._options.showHeaderRow) {\r\n this._headerRowScroller.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n\r\n // Append the viewport containers\r\n this._viewportTopL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-left', tabIndex: 0 }, this._paneTopL);\r\n this._viewportTopR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-right', tabIndex: 0 }, this._paneTopR);\r\n this._viewportBottomL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-left', tabIndex: 0 }, this._paneBottomL);\r\n this._viewportBottomR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-right', tabIndex: 0 }, this._paneBottomR);\r\n\r\n // Cache the viewports\r\n this._viewport = [this._viewportTopL, this._viewportTopR, this._viewportBottomL, this._viewportBottomR];\r\n if (this._options.viewportClass) {\r\n this._viewport.forEach((view) => {\r\n view.classList.add(...Utils.classNameToList((this._options.viewportClass)));\r\n });\r\n }\r\n\r\n // Default the active viewport to the top left\r\n this._activeViewportNode = this._viewportTopL;\r\n\r\n // Append the canvas containers\r\n this._canvasTopL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-left', tabIndex: 0 }, this._viewportTopL);\r\n this._canvasTopR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-right', tabIndex: 0 }, this._viewportTopR);\r\n this._canvasBottomL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-left', tabIndex: 0 }, this._viewportBottomL);\r\n this._canvasBottomR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-right', tabIndex: 0 }, this._viewportBottomR);\r\n\r\n // Cache the canvases\r\n this._canvas = [this._canvasTopL, this._canvasTopR, this._canvasBottomL, this._canvasBottomR];\r\n\r\n this.scrollbarDimensions = this.scrollbarDimensions || this.measureScrollbar();\r\n\r\n // Default the active canvas to the top left\r\n this._activeCanvasNode = this._canvasTopL;\r\n\r\n // top-header\r\n if (this._topHeaderPanelSpacer) {\r\n Utils.width(this._topHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n }\r\n\r\n // pre-header\r\n if (this._preHeaderPanelSpacer) {\r\n Utils.width(this._preHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n }\r\n\r\n this._headers.forEach((el) => {\r\n Utils.width(el, this.getHeadersWidth());\r\n });\r\n\r\n Utils.width(this._headerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n Utils.width(this._headerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n\r\n // footer Row\r\n if (this._options.createFooterRow) {\r\n this._footerRowScrollerR = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopR);\r\n this._footerRowScrollerL = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopL);\r\n\r\n this._footerRowScroller = [this._footerRowScrollerL, this._footerRowScrollerR];\r\n\r\n this._footerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerL);\r\n Utils.width(this._footerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n this._footerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerR);\r\n Utils.width(this._footerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n\r\n this._footerRowL = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-left' }, this._footerRowScrollerL);\r\n this._footerRowR = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-right' }, this._footerRowScrollerR);\r\n\r\n this._footerRow = [this._footerRowL, this._footerRowR];\r\n\r\n if (!this._options.showFooterRow) {\r\n this._footerRowScroller.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n }\r\n\r\n this._focusSink2 = this._focusSink.cloneNode(true) as HTMLDivElement;\r\n this._container.appendChild(this._focusSink2);\r\n\r\n if (!this._options.explicitInitialization) {\r\n this.finishInitialization();\r\n }\r\n }\r\n\r\n protected finishInitialization() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n\r\n this.getViewportWidth();\r\n this.getViewportHeight();\r\n\r\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\r\n // calculate the diff so we can set consistent sizes\r\n this.measureCellPaddingAndBorder();\r\n\r\n // for usability reasons, all text selection in SlickGrid is disabled\r\n // with the exception of input and textarea elements (selection must\r\n // be enabled there so that editors work as expected); note that\r\n // selection in grid cells (grid body) is already unavailable in\r\n // all browsers except IE\r\n this.disableSelection(this._headers); // disable all text selection in header (including input and textarea)\r\n\r\n if (!this._options.enableTextSelectionOnCells) {\r\n // disable text selection in grid cells except in input and textarea elements\r\n // (this is IE-specific, because selectstart event will only fire in IE)\r\n this._viewport.forEach((view) => {\r\n this._bindingEventService.bind(view, 'selectstart', (event) => {\r\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\r\n return;\r\n }\r\n });\r\n });\r\n }\r\n\r\n this.setFrozenOptions();\r\n this.setPaneVisibility();\r\n this.setScroller();\r\n this.setOverflow();\r\n\r\n this.updateColumnCaches();\r\n this.createColumnHeaders();\r\n this.createColumnFooter();\r\n this.setupColumnSort();\r\n this.createCssRules();\r\n this.resizeCanvas();\r\n this.bindAncestorScrollEvents();\r\n\r\n this._bindingEventService.bind(this._container, 'resize', this.resizeCanvas.bind(this));\r\n this._viewport.forEach((view) => {\r\n this._bindingEventService.bind(view, 'scroll', this.handleScroll.bind(this));\r\n });\r\n\r\n if (this._options.enableMouseWheelScrollHandler) {\r\n this._viewport.forEach((view) => {\r\n this.slickMouseWheelInstances.push(MouseWheel({\r\n element: view,\r\n onMouseWheel: this.handleMouseWheel.bind(this)\r\n }));\r\n });\r\n }\r\n\r\n this._headerScroller.forEach((el) => {\r\n this._bindingEventService.bind(el, 'contextmenu', this.handleHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(el, 'click', this.handleHeaderClick.bind(this) as EventListener);\r\n });\r\n\r\n this._headerRowScroller.forEach((scroller) => {\r\n this._bindingEventService.bind(scroller, 'scroll', this.handleHeaderRowScroll.bind(this) as EventListener);\r\n });\r\n\r\n if (this._options.createFooterRow) {\r\n this._footerRow.forEach((footer) => {\r\n this._bindingEventService.bind(footer, 'contextmenu', this.handleFooterContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(footer, 'click', this.handleFooterClick.bind(this) as EventListener);\r\n });\r\n\r\n this._footerRowScroller.forEach((scroller) => {\r\n this._bindingEventService.bind(scroller, 'scroll', this.handleFooterRowScroll.bind(this) as EventListener);\r\n });\r\n }\r\n\r\n if (this._options.createTopHeaderPanel) {\r\n this._bindingEventService.bind(this._topHeaderPanelScroller, 'scroll', this.handleTopHeaderPanelScroll.bind(this) as EventListener);\r\n }\r\n\r\n if (this._options.createPreHeaderPanel) {\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'scroll', this.handlePreHeaderPanelScroll.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'contextmenu', this.handlePreHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScrollerR, 'contextmenu', this.handlePreHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'click', this.handlePreHeaderClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScrollerR, 'click', this.handlePreHeaderClick.bind(this) as EventListener);\r\n }\r\n\r\n this._bindingEventService.bind(this._focusSink, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._focusSink2, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n\r\n this._canvas.forEach((element) => {\r\n this._bindingEventService.bind(element, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'click', this.handleClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'dblclick', this.handleDblClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'contextmenu', this.handleContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'mouseover', this.handleCellMouseOver.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'mouseout', this.handleCellMouseOut.bind(this) as EventListener);\r\n });\r\n\r\n if (Draggable) {\r\n this.slickDraggableInstance = Draggable({\r\n containerElement: this._container,\r\n allowDragFrom: 'div.slick-cell',\r\n // the slick cell parent must always contain `.dnd` and/or `.cell-reorder` class to be identified as draggable\r\n allowDragFromClosest: 'div.slick-cell.dnd, div.slick-cell.cell-reorder',\r\n preventDragFromKeys: this._options.preventDragFromKeys,\r\n onDragInit: this.handleDragInit.bind(this),\r\n onDragStart: this.handleDragStart.bind(this),\r\n onDrag: this.handleDrag.bind(this),\r\n onDragEnd: this.handleDragEnd.bind(this)\r\n });\r\n }\r\n\r\n if (!this._options.suppressCssChangesOnHiddenInit) {\r\n this.restoreCssFromHiddenInit();\r\n }\r\n }\r\n }\r\n\r\n /** handles \"display:none\" on container or container parents, related to issue: https://github.com/6pac/SlickGrid/issues/568 */\r\n cacheCssForHiddenInit() {\r\n this._hiddenParents = Utils.parents(this._container, ':hidden') as HTMLElement[];\r\n this._hiddenParents.forEach(el => {\r\n const old: Partial = {};\r\n Object.keys(this.cssShow).forEach(name => {\r\n if (this.cssShow) {\r\n old[name as any] = el.style[name as 'position' | 'visibility' | 'display'];\r\n el.style[name as any] = this.cssShow[name as 'position' | 'visibility' | 'display'];\r\n }\r\n });\r\n this.oldProps.push(old);\r\n });\r\n }\r\n\r\n restoreCssFromHiddenInit() {\r\n // finish handle display:none on container or container parents\r\n // - put values back the way they were\r\n let i = 0;\r\n if (this._hiddenParents) {\r\n this._hiddenParents.forEach(el => {\r\n const old = this.oldProps[i++];\r\n Object.keys(this.cssShow).forEach(name => {\r\n if (this.cssShow) {\r\n el.style[name as CSSStyleDeclarationWritable] = (old as any)[name];\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected hasFrozenColumns() {\r\n return this._options.frozenColumn! > -1;\r\n }\r\n\r\n /** Register an external Plugin */\r\n registerPlugin(plugin: T) {\r\n this.plugins.unshift(plugin);\r\n plugin.init(this as unknown as SlickGridModel);\r\n }\r\n\r\n /** Unregister (destroy) an external Plugin */\r\n unregisterPlugin(plugin: SlickPlugin) {\r\n for (let i = this.plugins.length; i >= 0; i--) {\r\n if (this.plugins[i] === plugin) {\r\n this.plugins[i]?.destroy();\r\n this.plugins.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /** Get a Plugin (addon) by its name */\r\n getPluginByName

(name: string) {\r\n for (let i = this.plugins.length - 1; i >= 0; i--) {\r\n if (this.plugins[i]?.pluginName === name) {\r\n return this.plugins[i] as P;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Unregisters a current selection model and registers a new one. See the definition of SelectionModel for more information.\r\n * @param {Object} selectionModel A SelectionModel.\r\n */\r\n setSelectionModel(model: SelectionModel) {\r\n if (this.selectionModel) {\r\n this.selectionModel.onSelectedRangesChanged.unsubscribe(this.handleSelectedRangesChanged.bind(this));\r\n if (this.selectionModel.destroy) {\r\n this.selectionModel.destroy();\r\n }\r\n }\r\n\r\n this.selectionModel = model;\r\n if (this.selectionModel) {\r\n this.selectionModel.init(this as unknown as SlickGridModel);\r\n this.selectionModel.onSelectedRangesChanged.subscribe(this.handleSelectedRangesChanged.bind(this));\r\n }\r\n }\r\n\r\n /** Returns the current SelectionModel. See here for more information about SelectionModels. */\r\n getSelectionModel() {\r\n return this.selectionModel;\r\n }\r\n\r\n /** Get Grid Canvas Node DOM Element */\r\n getCanvasNode(columnIdOrIdx?: number | string, rowIndex?: number) {\r\n return this._getContainerElement(this.getCanvases(), columnIdOrIdx, rowIndex) as HTMLDivElement;\r\n }\r\n\r\n /** Get the canvas DOM element */\r\n getActiveCanvasNode(e?: Event | SlickEventData_) {\r\n if (e === undefined) {\r\n return this._activeCanvasNode;\r\n }\r\n\r\n if (e instanceof SlickEventData) {\r\n e = e.getNativeEvent();\r\n }\r\n\r\n this._activeCanvasNode = (e as any)?.target.closest('.grid-canvas');\r\n return this._activeCanvasNode;\r\n }\r\n\r\n /** Get the canvas DOM element */\r\n getCanvases() {\r\n return this._canvas;\r\n }\r\n\r\n /** Get the Viewport DOM node element */\r\n getViewportNode(columnIdOrIdx?: number | string, rowIndex?: number) {\r\n return this._getContainerElement(this.getViewports(), columnIdOrIdx, rowIndex);\r\n }\r\n\r\n /** Get all the Viewport node elements */\r\n getViewports() {\r\n return this._viewport;\r\n }\r\n\r\n getActiveViewportNode(e: Event | SlickEventData_) {\r\n this.setActiveViewportNode(e);\r\n\r\n return this._activeViewportNode;\r\n }\r\n\r\n /** Sets an active viewport node */\r\n setActiveViewportNode(e: Event | SlickEventData_) {\r\n if (e instanceof SlickEventData) {\r\n e = e.getNativeEvent();\r\n }\r\n this._activeViewportNode = (e as any)?.target.closest('.slick-viewport');\r\n return this._activeViewportNode;\r\n }\r\n\r\n protected _getContainerElement(targetContainers: HTMLElement[], columnIdOrIdx?: number | string, rowIndex?: number) {\r\n if (!targetContainers) { return; }\r\n if (!columnIdOrIdx) { columnIdOrIdx = 0; }\r\n if (!rowIndex) { rowIndex = 0; }\r\n\r\n const idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\r\n\r\n const isBottomSide = this.hasFrozenRows && rowIndex >= this.actualFrozenRow + (this._options.frozenBottom ? 0 : 1);\r\n const isRightSide = this.hasFrozenColumns() && idx > this._options.frozenColumn!;\r\n\r\n return targetContainers[(isBottomSide ? 2 : 0) + (isRightSide ? 1 : 0)];\r\n }\r\n\r\n protected measureScrollbar() {\r\n let className = '';\r\n this._viewport.forEach(v => className += v.className);\r\n const outerdiv = Utils.createDomElement('div', { className, style: { position: 'absolute', top: '-10000px', left: '-10000px', overflow: 'auto', width: '100px', height: '100px' } }, document.body);\r\n const innerdiv = Utils.createDomElement('div', { style: { width: '200px', height: '200px', overflow: 'auto' } }, outerdiv);\r\n const dim = {\r\n width: outerdiv.offsetWidth - outerdiv.clientWidth,\r\n height: outerdiv.offsetHeight - outerdiv.clientHeight\r\n };\r\n innerdiv.remove();\r\n outerdiv.remove();\r\n return dim;\r\n }\r\n\r\n /** Get the headers width in pixel */\r\n getHeadersWidth() {\r\n this.headersWidth = this.headersWidthL = this.headersWidthR = 0;\r\n const includeScrollbar = !this._options.autoHeight;\r\n\r\n let i = 0;\r\n const ii = this.columns.length;\r\n for (i = 0; i < ii; i++) {\r\n if (!this.columns[i] || this.columns[i].hidden) { continue; }\r\n\r\n const width = this.columns[i].width;\r\n\r\n if ((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!)) {\r\n this.headersWidthR += width || 0;\r\n } else {\r\n this.headersWidthL += width || 0;\r\n }\r\n }\r\n\r\n if (includeScrollbar) {\r\n if ((this._options.frozenColumn!) > -1 && (i > this._options.frozenColumn!)) {\r\n this.headersWidthR += this.scrollbarDimensions?.width ?? 0;\r\n } else {\r\n this.headersWidthL += this.scrollbarDimensions?.width ?? 0;\r\n }\r\n }\r\n\r\n if (this.hasFrozenColumns()) {\r\n this.headersWidthL = this.headersWidthL + 1000;\r\n\r\n this.headersWidthR = Math.max(this.headersWidthR, this.viewportW) + this.headersWidthL;\r\n this.headersWidthR += this.scrollbarDimensions?.width ?? 0;\r\n } else {\r\n this.headersWidthL += this.scrollbarDimensions?.width ?? 0;\r\n this.headersWidthL = Math.max(this.headersWidthL, this.viewportW) + 1000;\r\n }\r\n\r\n this.headersWidth = this.headersWidthL + this.headersWidthR;\r\n return Math.max(this.headersWidth, this.viewportW) + 1000;\r\n }\r\n\r\n /** Get the grid canvas width */\r\n getCanvasWidth(): number {\r\n const availableWidth = this.viewportHasVScroll ? this.viewportW - (this.scrollbarDimensions?.width ?? 0) : this.viewportW;\r\n let i = this.columns.length;\r\n\r\n this.canvasWidthL = this.canvasWidthR = 0;\r\n\r\n while (i--) {\r\n if (!this.columns[i] || this.columns[i].hidden) { continue; }\r\n\r\n if (this.hasFrozenColumns() && (i > this._options.frozenColumn!)) {\r\n this.canvasWidthR += this.columns[i].width || 0;\r\n } else {\r\n this.canvasWidthL += this.columns[i].width || 0;\r\n }\r\n }\r\n let totalRowWidth = this.canvasWidthL + this.canvasWidthR;\r\n if (this._options.fullWidthRows) {\r\n const extraWidth = Math.max(totalRowWidth, availableWidth) - totalRowWidth;\r\n if (extraWidth > 0) {\r\n totalRowWidth += extraWidth;\r\n if (this.hasFrozenColumns()) {\r\n this.canvasWidthR += extraWidth;\r\n } else {\r\n this.canvasWidthL += extraWidth;\r\n }\r\n }\r\n }\r\n return totalRowWidth;\r\n }\r\n\r\n protected updateCanvasWidth(forceColumnWidthsUpdate?: boolean) {\r\n const oldCanvasWidth = this.canvasWidth;\r\n const oldCanvasWidthL = this.canvasWidthL;\r\n const oldCanvasWidthR = this.canvasWidthR;\r\n this.canvasWidth = this.getCanvasWidth();\r\n\r\n if (this._options.createTopHeaderPanel) {\r\n Utils.width(this._topHeaderPanel, this._options.topHeaderPanelWidth ?? this.canvasWidth);\r\n }\r\n\r\n const widthChanged = this.canvasWidth !== oldCanvasWidth || this.canvasWidthL !== oldCanvasWidthL || this.canvasWidthR !== oldCanvasWidthR;\r\n\r\n if (widthChanged || this.hasFrozenColumns() || this.hasFrozenRows) {\r\n Utils.width(this._canvasTopL, this.canvasWidthL);\r\n\r\n this.getHeadersWidth();\r\n\r\n Utils.width(this._headerL, this.headersWidthL);\r\n Utils.width(this._headerR, this.headersWidthR);\r\n\r\n if (this.hasFrozenColumns()) {\r\n const cWidth = Utils.width(this._container) || 0;\r\n if (cWidth > 0 && this.canvasWidthL > cWidth && this._options.throwWhenFrozenNotAllViewable) {\r\n throw new Error('[SlickGrid] Frozen columns cannot be wider than the actual grid container width. '\r\n + 'Make sure to have less columns freezed or make your grid container wider');\r\n }\r\n Utils.width(this._canvasTopR, this.canvasWidthR);\r\n\r\n Utils.width(this._paneHeaderL, this.canvasWidthL);\r\n Utils.setStyleSize(this._paneHeaderR, 'left', this.canvasWidthL);\r\n Utils.setStyleSize(this._paneHeaderR, 'width', this.viewportW - this.canvasWidthL);\r\n\r\n Utils.width(this._paneTopL, this.canvasWidthL);\r\n Utils.setStyleSize(this._paneTopR, 'left', this.canvasWidthL);\r\n Utils.width(this._paneTopR, this.viewportW - this.canvasWidthL);\r\n\r\n Utils.width(this._headerRowScrollerL, this.canvasWidthL);\r\n Utils.width(this._headerRowScrollerR, this.viewportW - this.canvasWidthL);\r\n\r\n Utils.width(this._headerRowL, this.canvasWidthL);\r\n Utils.width(this._headerRowR, this.canvasWidthR);\r\n\r\n if (this._options.createFooterRow) {\r\n Utils.width(this._footerRowScrollerL, this.canvasWidthL);\r\n Utils.width(this._footerRowScrollerR, this.viewportW - this.canvasWidthL);\r\n\r\n Utils.width(this._footerRowL, this.canvasWidthL);\r\n Utils.width(this._footerRowR, this.canvasWidthR);\r\n }\r\n if (this._options.createPreHeaderPanel) {\r\n Utils.width(this._preHeaderPanel, this._options.preHeaderPanelWidth ?? this.canvasWidth);\r\n }\r\n Utils.width(this._viewportTopL, this.canvasWidthL);\r\n Utils.width(this._viewportTopR, this.viewportW - this.canvasWidthL);\r\n\r\n if (this.hasFrozenRows) {\r\n Utils.width(this._paneBottomL, this.canvasWidthL);\r\n Utils.setStyleSize(this._paneBottomR, 'left', this.canvasWidthL);\r\n\r\n Utils.width(this._viewportBottomL, this.canvasWidthL);\r\n Utils.width(this._viewportBottomR, this.viewportW - this.canvasWidthL);\r\n\r\n Utils.width(this._canvasBottomL, this.canvasWidthL);\r\n Utils.width(this._canvasBottomR, this.canvasWidthR);\r\n }\r\n } else {\r\n Utils.width(this._paneHeaderL, '100%');\r\n Utils.width(this._paneTopL, '100%');\r\n Utils.width(this._headerRowScrollerL, '100%');\r\n Utils.width(this._headerRowL, this.canvasWidth);\r\n\r\n if (this._options.createFooterRow) {\r\n Utils.width(this._footerRowScrollerL, '100%');\r\n Utils.width(this._footerRowL, this.canvasWidth);\r\n }\r\n\r\n if (this._options.createPreHeaderPanel) {\r\n Utils.width(this._preHeaderPanel, this._options.preHeaderPanelWidth ?? this.canvasWidth);\r\n }\r\n Utils.width(this._viewportTopL, '100%');\r\n\r\n if (this.hasFrozenRows) {\r\n Utils.width(this._viewportBottomL, '100%');\r\n Utils.width(this._canvasBottomL, this.canvasWidthL);\r\n }\r\n }\r\n }\r\n\r\n this.viewportHasHScroll = (this.canvasWidth >= this.viewportW - (this.scrollbarDimensions?.width ?? 0));\r\n\r\n Utils.width(this._headerRowSpacerL, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\r\n Utils.width(this._headerRowSpacerR, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\r\n\r\n if (this._options.createFooterRow) {\r\n Utils.width(this._footerRowSpacerL, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\r\n Utils.width(this._footerRowSpacerR, this.canvasWidth + (this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0));\r\n }\r\n\r\n if (widthChanged || forceColumnWidthsUpdate) {\r\n this.applyColumnWidths();\r\n }\r\n }\r\n\r\n protected disableSelection(target: HTMLElement[]) {\r\n target.forEach((el) => {\r\n el.setAttribute('unselectable', 'on');\r\n (el.style as any).mozUserSelect = 'none';\r\n this._bindingEventService.bind(el, 'selectstart', () => false);\r\n });\r\n }\r\n\r\n protected getMaxSupportedCssHeight() {\r\n let supportedHeight = 1000000;\r\n // FF reports the height back but still renders blank after ~6M px\r\n // let testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? 6000000 : 1000000000;\r\n const testUpTo = navigator.userAgent.toLowerCase().match(/firefox/) ? this._options.ffMaxSupportedCssHeight : this._options.maxSupportedCssHeight;\r\n const div = Utils.createDomElement('div', { style: { display: 'hidden' } }, document.body);\r\n\r\n while (true) {\r\n const test = supportedHeight * 2;\r\n Utils.height(div, test);\r\n const height = Utils.height(div);\r\n\r\n if (test > testUpTo! || height !== test) {\r\n break;\r\n } else {\r\n supportedHeight = test;\r\n }\r\n }\r\n\r\n div.remove();\r\n return supportedHeight;\r\n }\r\n\r\n /** Get grid unique identifier */\r\n getUID() {\r\n return this.uid;\r\n }\r\n\r\n /** Get Header Column Width Difference in pixel */\r\n getHeaderColumnWidthDiff() {\r\n return this.headerColumnWidthDiff;\r\n }\r\n\r\n /** Get scrollbar dimensions */\r\n getScrollbarDimensions() {\r\n return this.scrollbarDimensions;\r\n }\r\n\r\n /** Get the displayed scrollbar dimensions */\r\n getDisplayedScrollbarDimensions() {\r\n return {\r\n width: this.viewportHasVScroll ? (this.scrollbarDimensions?.width ?? 0) : 0,\r\n height: this.viewportHasHScroll ? (this.scrollbarDimensions?.height ?? 0) : 0\r\n };\r\n }\r\n\r\n /** Get the absolute column minimum width */\r\n getAbsoluteColumnMinWidth(): number {\r\n return this.absoluteColumnMinWidth;\r\n }\r\n\r\n getPubSubService(): BasePubSub | undefined {\r\n return this._pubSubService;\r\n }\r\n\r\n // TODO: this is static. need to handle page mutation.\r\n protected bindAncestorScrollEvents() {\r\n let elem: HTMLElement | null = (this.hasFrozenRows && !this._options.frozenBottom) ? this._canvasBottomL : this._canvasTopL;\r\n while ((elem = elem!.parentNode as HTMLElement) !== document.body && elem) {\r\n // bind to scroll containers only\r\n if (elem === this._viewportTopL || elem.scrollWidth !== elem.clientWidth || elem.scrollHeight !== elem.clientHeight) {\r\n this._boundAncestors.push(elem);\r\n this._bindingEventService.bind(elem, 'scroll', this.handleActiveCellPositionChange.bind(this));\r\n }\r\n }\r\n }\r\n\r\n protected unbindAncestorScrollEvents() {\r\n this._boundAncestors.forEach((ancestor) => {\r\n this._bindingEventService.unbindByEventName(ancestor, 'scroll');\r\n });\r\n this._boundAncestors = [];\r\n }\r\n\r\n /**\r\n * Updates an existing column definition and a corresponding header DOM element with the new title and tooltip.\r\n * @param {Number|String} columnId Column id.\r\n * @param {string | HTMLElement | DocumentFragment} [title] New column name.\r\n * @param {String} [toolTip] New column tooltip.\r\n */\r\n updateColumnHeader(columnId: number | string, title?: string | HTMLElement | DocumentFragment, toolTip?: string) {\r\n if (this.initialized) {\r\n const idx = this.getColumnIndex(columnId);\r\n if (!Utils.isDefined(idx)) {\r\n return;\r\n }\r\n\r\n const columnDef = this.columns[idx];\r\n const header: HTMLElement | undefined = this.getColumnByIndex(idx);\r\n if (header) {\r\n if (title !== undefined) {\r\n this.columns[idx].name = title;\r\n }\r\n if (toolTip !== undefined) {\r\n this.columns[idx].toolTip = toolTip;\r\n }\r\n\r\n this.trigger(this.onBeforeHeaderCellDestroy, {\r\n node: header,\r\n column: columnDef,\r\n grid: this\r\n });\r\n\r\n header.setAttribute('title', toolTip || '');\r\n if (title !== undefined) {\r\n this.applyHtmlCode(header.children[0] as HTMLElement, title);\r\n }\r\n\r\n this.trigger(this.onHeaderCellRendered, {\r\n node: header,\r\n column: columnDef,\r\n grid: this\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get the Header DOM element\r\n * @param {C} columnDef - column definition\r\n */\r\n getHeader(columnDef: C) {\r\n if (!columnDef) {\r\n return this.hasFrozenColumns() ? this._headers : this._headerL;\r\n }\r\n const idx = this.getColumnIndex(columnDef.id);\r\n return this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\r\n }\r\n\r\n /**\r\n * Get a specific Header Column DOM element by its column Id or index\r\n * @param {Number|String} columnIdOrIdx - column Id or index\r\n */\r\n getHeaderColumn(columnIdOrIdx: number | string) {\r\n const idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\r\n const targetHeader = this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\r\n const targetIndex = this.hasFrozenColumns() ? ((idx <= this._options.frozenColumn!) ? idx : idx - this._options.frozenColumn! - 1) : idx;\r\n\r\n return targetHeader.children[targetIndex] as HTMLDivElement;\r\n }\r\n\r\n /** Get the Header Row DOM element */\r\n getHeaderRow() {\r\n return this.hasFrozenColumns() ? this._headerRows : this._headerRows[0];\r\n }\r\n\r\n /** Get the Footer DOM element */\r\n getFooterRow() {\r\n return this.hasFrozenColumns() ? this._footerRow : this._footerRow[0];\r\n }\r\n\r\n /** @alias `getPreHeaderPanelLeft` */\r\n getPreHeaderPanel() {\r\n return this._preHeaderPanel;\r\n }\r\n\r\n /** Get the Pre-Header Panel Left DOM node element */\r\n getPreHeaderPanelLeft() {\r\n return this._preHeaderPanel;\r\n }\r\n\r\n /** Get the Pre-Header Panel Right DOM node element */\r\n getPreHeaderPanelRight() {\r\n return this._preHeaderPanelR;\r\n }\r\n\r\n /** Get the Top-Header Panel DOM node element */\r\n getTopHeaderPanel() {\r\n return this._topHeaderPanel;\r\n }\r\n\r\n /**\r\n * Get Header Row Column DOM element by its column Id or index\r\n * @param {Number|String} columnIdOrIdx - column Id or index\r\n */\r\n getHeaderRowColumn(columnIdOrIdx: number | string) {\r\n let idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\r\n let headerRowTarget: HTMLDivElement;\r\n\r\n if (this.hasFrozenColumns()) {\r\n if (idx <= this._options.frozenColumn!) {\r\n headerRowTarget = this._headerRowL;\r\n } else {\r\n headerRowTarget = this._headerRowR;\r\n idx -= this._options.frozenColumn! + 1;\r\n }\r\n } else {\r\n headerRowTarget = this._headerRowL;\r\n }\r\n\r\n return headerRowTarget.children[idx] as HTMLDivElement;\r\n }\r\n\r\n /**\r\n * Get the Footer Row Column DOM element by its column Id or index\r\n * @param {Number|String} columnIdOrIdx - column Id or index\r\n */\r\n getFooterRowColumn(columnIdOrIdx: number | string) {\r\n let idx = (typeof columnIdOrIdx === 'number' ? columnIdOrIdx : this.getColumnIndex(columnIdOrIdx));\r\n let footerRowTarget: HTMLDivElement;\r\n\r\n if (this.hasFrozenColumns()) {\r\n if (idx <= this._options.frozenColumn!) {\r\n footerRowTarget = this._footerRowL;\r\n } else {\r\n footerRowTarget = this._footerRowR;\r\n\r\n idx -= this._options.frozenColumn! + 1;\r\n }\r\n } else {\r\n footerRowTarget = this._footerRowL;\r\n }\r\n\r\n return footerRowTarget.children[idx] as HTMLDivElement;\r\n }\r\n\r\n protected createColumnFooter() {\r\n if (this._options.createFooterRow) {\r\n this._footerRow.forEach((footer) => {\r\n const columnElements = footer.querySelectorAll('.slick-footerrow-column');\r\n columnElements.forEach((column) => {\r\n const columnDef = Utils.storage.get(column, 'column');\r\n this.trigger(this.onBeforeFooterRowCellDestroy, {\r\n node: column,\r\n column: columnDef,\r\n grid: this\r\n });\r\n });\r\n });\r\n\r\n Utils.emptyElement(this._footerRowL);\r\n Utils.emptyElement(this._footerRowR);\r\n\r\n for (let i = 0; i < this.columns.length; i++) {\r\n const m = this.columns[i];\r\n if (!m || m.hidden) { continue; }\r\n\r\n const footerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, this.hasFrozenColumns() && (i > this._options.frozenColumn!) ? this._footerRowR : this._footerRowL);\r\n const className = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\r\n if (className) {\r\n footerRowCell.classList.add(className);\r\n }\r\n\r\n Utils.storage.put(footerRowCell, 'column', m);\r\n\r\n this.trigger(this.onFooterRowCellRendered, {\r\n node: footerRowCell,\r\n column: m,\r\n grid: this\r\n });\r\n }\r\n }\r\n }\r\n\r\n protected handleHeaderMouseHoverOn(e: Event | SlickEventData_) {\r\n (e as any)?.target.classList.add('ui-state-hover', 'slick-state-hover');\r\n }\r\n\r\n protected handleHeaderMouseHoverOff(e: Event | SlickEventData_) {\r\n (e as any)?.target.classList.remove('ui-state-hover', 'slick-state-hover');\r\n }\r\n\r\n protected createColumnHeaders() {\r\n this._headers.forEach((header) => {\r\n const columnElements = header.querySelectorAll('.slick-header-column');\r\n columnElements.forEach((column) => {\r\n const columnDef = Utils.storage.get(column, 'column');\r\n if (columnDef) {\r\n this.trigger(this.onBeforeHeaderCellDestroy, {\r\n node: column,\r\n column: columnDef,\r\n grid: this\r\n });\r\n }\r\n });\r\n });\r\n\r\n Utils.emptyElement(this._headerL);\r\n Utils.emptyElement(this._headerR);\r\n\r\n this.getHeadersWidth();\r\n\r\n Utils.width(this._headerL, this.headersWidthL);\r\n Utils.width(this._headerR, this.headersWidthR);\r\n\r\n this._headerRows.forEach((row) => {\r\n const columnElements = row.querySelectorAll('.slick-headerrow-column');\r\n columnElements.forEach((column) => {\r\n const columnDef = Utils.storage.get(column, 'column');\r\n if (columnDef) {\r\n this.trigger(this.onBeforeHeaderRowCellDestroy, {\r\n node: this,\r\n column: columnDef,\r\n grid: this\r\n });\r\n }\r\n });\r\n });\r\n\r\n Utils.emptyElement(this._headerRowL);\r\n Utils.emptyElement(this._headerRowR);\r\n\r\n if (this._options.createFooterRow) {\r\n const footerRowLColumnElements = this._footerRowL.querySelectorAll('.slick-footerrow-column');\r\n footerRowLColumnElements.forEach((column) => {\r\n const columnDef = Utils.storage.get(column, 'column');\r\n if (columnDef) {\r\n this.trigger(this.onBeforeFooterRowCellDestroy, {\r\n node: this,\r\n column: columnDef,\r\n grid: this\r\n });\r\n }\r\n });\r\n Utils.emptyElement(this._footerRowL);\r\n\r\n if (this.hasFrozenColumns()) {\r\n const footerRowRColumnElements = this._footerRowR.querySelectorAll('.slick-footerrow-column');\r\n footerRowRColumnElements.forEach((column) => {\r\n const columnDef = Utils.storage.get(column, 'column');\r\n if (columnDef) {\r\n this.trigger(this.onBeforeFooterRowCellDestroy, {\r\n node: this,\r\n column: columnDef,\r\n grid: this\r\n });\r\n }\r\n });\r\n Utils.emptyElement(this._footerRowR);\r\n }\r\n }\r\n\r\n for (let i = 0; i < this.columns.length; i++) {\r\n const m: C = this.columns[i];\r\n if (m.hidden) { continue; }\r\n\r\n const headerTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerL : this._headerR) : this._headerL;\r\n const headerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._headerRowL : this._headerRowR) : this._headerRowL;\r\n\r\n const header = Utils.createDomElement('div', { id: `${this.uid + m.id}`, dataset: { id: String(m.id) }, role: 'columnheader', className: 'ui-state-default slick-state-default slick-header-column' }, headerTarget);\r\n if (m.toolTip) {\r\n header.title = m.toolTip;\r\n }\r\n if (!m.reorderable) {\r\n header.classList.add(this._options.unorderableColumnCssClass!);\r\n }\r\n const colNameElm = Utils.createDomElement('span', { className: 'slick-column-name' }, header);\r\n this.applyHtmlCode(colNameElm, m.name as string);\r\n\r\n Utils.width(header, m.width! - this.headerColumnWidthDiff);\r\n\r\n let classname = m.headerCssClass || null;\r\n if (classname) {\r\n header.classList.add(...Utils.classNameToList(classname));\r\n }\r\n classname = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\r\n if (classname) {\r\n header.classList.add(classname);\r\n }\r\n\r\n this._bindingEventService.bind(header, 'mouseenter', this.handleHeaderMouseEnter.bind(this) as EventListener);\r\n this._bindingEventService.bind(header, 'mouseleave', this.handleHeaderMouseLeave.bind(this) as EventListener);\r\n\r\n Utils.storage.put(header, 'column', m);\r\n\r\n if (this._options.enableColumnReorder || m.sortable) {\r\n this._bindingEventService.bind(header, 'mouseenter', this.handleHeaderMouseHoverOn.bind(this) as EventListener);\r\n this._bindingEventService.bind(header, 'mouseleave', this.handleHeaderMouseHoverOff.bind(this) as EventListener);\r\n }\r\n\r\n if (m.hasOwnProperty('headerCellAttrs') && m.headerCellAttrs instanceof Object) {\r\n Object.keys(m.headerCellAttrs).forEach(key => {\r\n if (m.headerCellAttrs.hasOwnProperty(key)) {\r\n header.setAttribute(key, m.headerCellAttrs[key]);\r\n }\r\n });\r\n }\r\n\r\n if (m.sortable) {\r\n header.classList.add('slick-header-sortable');\r\n Utils.createDomElement('div', { className: `slick-sort-indicator ${this._options.numberedMultiColumnSort && !this._options.sortColNumberInSeparateSpan ? ' slick-sort-indicator-numbered' : ''}` }, header);\r\n if (this._options.numberedMultiColumnSort && this._options.sortColNumberInSeparateSpan) {\r\n Utils.createDomElement('div', { className: 'slick-sort-indicator-numbered' }, header);\r\n }\r\n }\r\n\r\n this.trigger(this.onHeaderCellRendered, {\r\n node: header,\r\n column: m,\r\n grid: this\r\n });\r\n\r\n if (this._options.showHeaderRow) {\r\n const headerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-headerrow-column l${i} r${i}` }, headerRowTarget);\r\n const frozenClasses = this.hasFrozenColumns() && i <= this._options.frozenColumn! ? 'frozen' : null;\r\n if (frozenClasses) {\r\n headerRowCell.classList.add(frozenClasses);\r\n }\r\n\r\n this._bindingEventService.bind(headerRowCell, 'mouseenter', this.handleHeaderRowMouseEnter.bind(this) as EventListener);\r\n this._bindingEventService.bind(headerRowCell, 'mouseleave', this.handleHeaderRowMouseLeave.bind(this) as EventListener);\r\n\r\n Utils.storage.put(headerRowCell, 'column', m);\r\n\r\n this.trigger(this.onHeaderRowCellRendered, {\r\n node: headerRowCell,\r\n column: m,\r\n grid: this\r\n });\r\n }\r\n if (this._options.createFooterRow && this._options.showFooterRow) {\r\n const footerRowTarget = this.hasFrozenColumns() ? ((i <= this._options.frozenColumn!) ? this._footerRow[0] : this._footerRow[1]) : this._footerRow[0];\r\n const footerRowCell = Utils.createDomElement('div', { className: `ui-state-default slick-state-default slick-footerrow-column l${i} r${i}` }, footerRowTarget);\r\n Utils.storage.put(footerRowCell, 'column', m);\r\n\r\n this.trigger(this.onFooterRowCellRendered, {\r\n node: footerRowCell,\r\n column: m,\r\n grid: this\r\n });\r\n }\r\n }\r\n\r\n this.setSortColumns(this.sortColumns);\r\n this.setupColumnResize();\r\n if (this._options.enableColumnReorder) {\r\n if (typeof this._options.enableColumnReorder === 'function') {\r\n this._options.enableColumnReorder(this as unknown as SlickGridModel, this._headers, this.headerColumnWidthDiff, this.setColumns as any, this.setupColumnResize, this.columns, this.getColumnIndex, this.uid, this.trigger);\r\n } else {\r\n this.setupColumnReorder();\r\n }\r\n }\r\n }\r\n\r\n protected setupColumnSort() {\r\n this._headers.forEach((header) => {\r\n this._bindingEventService.bind(header, 'click', (e: any) => {\r\n if (this.columnResizeDragging) {\r\n return;\r\n }\r\n\r\n if (e.target.classList.contains('slick-resizable-handle')) {\r\n return;\r\n }\r\n\r\n const coll = e.target.closest('.slick-header-column');\r\n if (!coll) {\r\n return;\r\n }\r\n\r\n const column = Utils.storage.get(coll, 'column');\r\n if (column.sortable) {\r\n if (!this.getEditorLock()?.commitCurrentEdit()) {\r\n return;\r\n }\r\n\r\n const previousSortColumns = this.sortColumns.slice();\r\n let sortColumn: ColumnSort | null = null;\r\n let i = 0;\r\n for (; i < this.sortColumns.length; i++) {\r\n if (this.sortColumns[i].columnId === column.id) {\r\n sortColumn = this.sortColumns[i];\r\n sortColumn.sortAsc = !sortColumn.sortAsc;\r\n break;\r\n }\r\n }\r\n const hadSortCol = !!sortColumn;\r\n\r\n if (this._options.tristateMultiColumnSort) {\r\n if (!sortColumn) {\r\n sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc, sortCol: column };\r\n }\r\n if (hadSortCol && sortColumn.sortAsc) {\r\n // three state: remove sort rather than go back to ASC\r\n this.sortColumns.splice(i, 1);\r\n sortColumn = null;\r\n }\r\n if (!this._options.multiColumnSort) {\r\n this.sortColumns = [];\r\n }\r\n if (sortColumn && (!hadSortCol || !this._options.multiColumnSort)) {\r\n this.sortColumns.push(sortColumn);\r\n }\r\n } else {\r\n // legacy behaviour\r\n if (e.metaKey && this._options.multiColumnSort) {\r\n if (sortColumn) {\r\n this.sortColumns.splice(i, 1);\r\n }\r\n } else {\r\n if ((!e.shiftKey && !e.metaKey) || !this._options.multiColumnSort) {\r\n this.sortColumns = [];\r\n }\r\n\r\n if (!sortColumn) {\r\n sortColumn = { columnId: column.id, sortAsc: column.defaultSortAsc, sortCol: column };\r\n this.sortColumns.push(sortColumn);\r\n } else if (this.sortColumns.length === 0) {\r\n this.sortColumns.push(sortColumn);\r\n }\r\n }\r\n }\r\n\r\n let onSortArgs;\r\n if (!this._options.multiColumnSort) {\r\n onSortArgs = {\r\n multiColumnSort: false,\r\n previousSortColumns,\r\n columnId: (this.sortColumns.length > 0 ? column.id : null),\r\n sortCol: (this.sortColumns.length > 0 ? column : null),\r\n sortAsc: (this.sortColumns.length > 0 ? this.sortColumns[0].sortAsc : true)\r\n };\r\n } else {\r\n onSortArgs = {\r\n multiColumnSort: true,\r\n previousSortColumns,\r\n sortCols: this.sortColumns.map((col) => {\r\n const tempCol = this.columns[this.getColumnIndex(col.columnId)];\r\n return !tempCol || tempCol.hidden ? null : { columnId: tempCol.id, sortCol: tempCol, sortAsc: col.sortAsc };\r\n }).filter((el) => el)\r\n };\r\n }\r\n\r\n if (this.trigger(this.onBeforeSort, onSortArgs, e).getReturnValue() !== false) {\r\n this.setSortColumns(this.sortColumns);\r\n this.trigger(this.onSort, onSortArgs, e);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n protected setupColumnReorder() {\r\n this.sortableSideLeftInstance?.destroy();\r\n this.sortableSideRightInstance?.destroy();\r\n\r\n let columnScrollTimer: any = null;\r\n\r\n const scrollColumnsRight = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft + 10;\r\n const scrollColumnsLeft = () => this._viewportScrollContainerX.scrollLeft = this._viewportScrollContainerX.scrollLeft - 10;\r\n\r\n let canDragScroll = false;\r\n const sortableOptions = {\r\n animation: 50,\r\n direction: 'horizontal',\r\n chosenClass: 'slick-header-column-active',\r\n ghostClass: 'slick-sortable-placeholder',\r\n draggable: '.slick-header-column',\r\n dragoverBubble: false,\r\n revertClone: true,\r\n scroll: !this.hasFrozenColumns(), // enable auto-scroll\r\n // lock unorderable columns by using a combo of filter + onMove\r\n filter: `.${this._options.unorderableColumnCssClass}`,\r\n onMove: (event: MouseEvent & { related: HTMLElement; }) => {\r\n return !event.related.classList.contains(this._options.unorderableColumnCssClass as string);\r\n },\r\n onStart: (e: { item: any; originalEvent: MouseEvent; }) => {\r\n canDragScroll = !this.hasFrozenColumns() ||\r\n Utils.offset(e.item)!.left > Utils.offset(this._viewportScrollContainerX)!.left;\r\n\r\n if (canDragScroll && e.originalEvent.pageX > this._container.clientWidth) {\r\n if (!(columnScrollTimer)) {\r\n columnScrollTimer = window.setInterval(scrollColumnsRight, 100);\r\n }\r\n } else if (canDragScroll && e.originalEvent.pageX < Utils.offset(this._viewportScrollContainerX)!.left) {\r\n if (!(columnScrollTimer)) {\r\n columnScrollTimer = window.setInterval(scrollColumnsLeft, 100);\r\n }\r\n } else {\r\n window.clearInterval(columnScrollTimer);\r\n columnScrollTimer = null;\r\n }\r\n },\r\n onEnd: (e: MouseEvent & { item: any; originalEvent: MouseEvent; }) => {\r\n window.clearInterval(columnScrollTimer);\r\n columnScrollTimer = null;\r\n\r\n if (!this.getEditorLock()?.commitCurrentEdit()) {\r\n return;\r\n }\r\n\r\n let reorderedIds = this.sortableSideLeftInstance?.toArray() ?? [];\r\n reorderedIds = reorderedIds.concat(this.sortableSideRightInstance?.toArray() ?? []);\r\n\r\n const reorderedColumns: C[] = [];\r\n for (let i = 0; i < reorderedIds.length; i++) {\r\n reorderedColumns.push(this.columns[this.getColumnIndex(reorderedIds[i])]);\r\n }\r\n this.setColumns(reorderedColumns);\r\n\r\n this.trigger(this.onColumnsReordered, { impactedColumns: this.columns });\r\n e.stopPropagation();\r\n this.setupColumnResize();\r\n if (this.activeCellNode) {\r\n this.setFocus(); // refocus on active cell\r\n }\r\n }\r\n };\r\n\r\n this.sortableSideLeftInstance = Sortable.create(this._headerL, sortableOptions);\r\n this.sortableSideRightInstance = Sortable.create(this._headerR, sortableOptions);\r\n }\r\n\r\n protected getHeaderChildren() {\r\n const a = Array.from(this._headers[0].children);\r\n const b = Array.from(this._headers[1].children);\r\n return a.concat(b) as HTMLElement[];\r\n }\r\n\r\n protected handleResizeableDoubleClick(evt: MouseEvent & { target: HTMLDivElement; }) {\r\n const triggeredByColumn = evt.target.parentElement!.id.replace(this.uid, '');\r\n this.trigger(this.onColumnsResizeDblClick, { triggeredByColumn });\r\n }\r\n\r\n protected setupColumnResize() {\r\n if (typeof Resizable === 'undefined') {\r\n throw new Error(`Slick.Resizable is undefined, make sure to import \"slick.interactions.js\"`);\r\n }\r\n\r\n let j: number;\r\n let k: number;\r\n let c: C;\r\n let pageX: number;\r\n let minPageX: number;\r\n let maxPageX: number;\r\n let firstResizable: number | undefined;\r\n let lastResizable = -1;\r\n let frozenLeftColMaxWidth = 0;\r\n\r\n const children: HTMLElement[] = this.getHeaderChildren();\r\n const vc = this.getVisibleColumns();\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i];\r\n const handles = child.querySelectorAll('.slick-resizable-handle');\r\n handles.forEach((handle) => handle.remove());\r\n\r\n if (i >= vc.length || !vc[i]) {\r\n continue;\r\n }\r\n\r\n if (vc[i].resizable) {\r\n if (firstResizable === undefined) {\r\n firstResizable = i;\r\n }\r\n lastResizable = i;\r\n }\r\n }\r\n\r\n if (firstResizable === undefined) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < children.length; i++) {\r\n const colElm = children[i];\r\n\r\n if (i >= vc.length || !vc[i]) {\r\n continue;\r\n }\r\n if (i < firstResizable || (this._options.forceFitColumns && i >= lastResizable)) {\r\n continue;\r\n }\r\n\r\n const resizeableHandle = Utils.createDomElement('div', { className: 'slick-resizable-handle', role: 'separator', ariaOrientation: 'horizontal' }, colElm);\r\n this._bindingEventService.bind(resizeableHandle, 'dblclick', this.handleResizeableDoubleClick.bind(this) as EventListener);\r\n\r\n this.slickResizableInstances.push(\r\n Resizable({\r\n resizeableElement: colElm as HTMLElement,\r\n resizeableHandleElement: resizeableHandle,\r\n onResizeStart: (e, resizeElms): boolean | void => {\r\n const targetEvent = (e as TouchEvent).touches ? (e as TouchEvent).changedTouches[0] : e;\r\n if (!this.getEditorLock()?.commitCurrentEdit()) {\r\n return false;\r\n }\r\n pageX = (targetEvent as MouseEvent).pageX;\r\n frozenLeftColMaxWidth = 0;\r\n resizeElms.resizeableElement.classList.add('slick-header-column-active');\r\n let shrinkLeewayOnRight: number | null = null;\r\n let stretchLeewayOnRight: number | null = null;\r\n // lock each column's width option to current width\r\n for (let pw = 0; pw < children.length; pw++) {\r\n if (pw >= vc.length || !vc[pw]) {\r\n continue;\r\n }\r\n vc[pw].previousWidth = children[pw].offsetWidth;\r\n }\r\n if (this._options.forceFitColumns) {\r\n shrinkLeewayOnRight = 0;\r\n stretchLeewayOnRight = 0;\r\n // colums on right affect maxPageX/minPageX\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (c?.resizable) {\r\n if (stretchLeewayOnRight !== null) {\r\n if (c.maxWidth) {\r\n stretchLeewayOnRight += c.maxWidth - (c.previousWidth || 0);\r\n } else {\r\n stretchLeewayOnRight = null;\r\n }\r\n }\r\n shrinkLeewayOnRight += (c.previousWidth || 0) - Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\r\n }\r\n }\r\n }\r\n let shrinkLeewayOnLeft = 0;\r\n let stretchLeewayOnLeft: number | null = 0;\r\n for (j = 0; j <= i; j++) {\r\n // columns on left only affect minPageX\r\n c = vc[j];\r\n if (c?.resizable) {\r\n if (stretchLeewayOnLeft !== null) {\r\n if (c.maxWidth) {\r\n stretchLeewayOnLeft += c.maxWidth - (c.previousWidth || 0);\r\n } else {\r\n stretchLeewayOnLeft = null;\r\n }\r\n }\r\n shrinkLeewayOnLeft += (c.previousWidth || 0) - Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\r\n }\r\n }\r\n if (shrinkLeewayOnRight === null) {\r\n shrinkLeewayOnRight = 100000;\r\n }\r\n if (shrinkLeewayOnLeft === null) {\r\n shrinkLeewayOnLeft = 100000;\r\n }\r\n if (stretchLeewayOnRight === null) {\r\n stretchLeewayOnRight = 100000;\r\n }\r\n if (stretchLeewayOnLeft === null) {\r\n stretchLeewayOnLeft = 100000;\r\n }\r\n maxPageX = pageX + Math.min(shrinkLeewayOnRight, stretchLeewayOnLeft);\r\n minPageX = pageX - Math.min(shrinkLeewayOnLeft, stretchLeewayOnRight);\r\n },\r\n onResize: (e, resizeElms) => {\r\n const targetEvent = (e as TouchEvent).touches ? (e as TouchEvent).changedTouches[0] : e;\r\n this.columnResizeDragging = true;\r\n let actualMinWidth;\r\n const d = Math.min(maxPageX, Math.max(minPageX, (targetEvent as MouseEvent).pageX)) - pageX;\r\n let x;\r\n let newCanvasWidthL = 0;\r\n let newCanvasWidthR = 0;\r\n const viewportWidth = this.viewportHasVScroll ? this.viewportW - (this.scrollbarDimensions?.width ?? 0) : this.viewportW;\r\n\r\n if (d < 0) { // shrink column\r\n x = d;\r\n\r\n for (j = i; j >= 0; j--) {\r\n c = vc[j];\r\n if (c?.resizable && !c.hidden) {\r\n actualMinWidth = Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\r\n if (x && (c.previousWidth || 0) + x < actualMinWidth) {\r\n x += (c.previousWidth || 0) - actualMinWidth;\r\n c.width = actualMinWidth;\r\n } else {\r\n c.width = (c.previousWidth || 0) + x;\r\n x = 0;\r\n }\r\n }\r\n }\r\n\r\n for (k = 0; k <= i; k++) {\r\n c = vc[k];\r\n if (!c || c.hidden) { continue; }\r\n\r\n if (this.hasFrozenColumns() && (k > this._options.frozenColumn!)) {\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n\r\n if (this._options.forceFitColumns) {\r\n x = -d;\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n if (c.resizable) {\r\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\r\n x -= c.maxWidth - (c.previousWidth || 0);\r\n c.width = c.maxWidth;\r\n } else {\r\n c.width = (c.previousWidth || 0) + x;\r\n x = 0;\r\n }\r\n\r\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n }\r\n } else {\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n\r\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n }\r\n\r\n if (this._options.forceFitColumns) {\r\n x = -d;\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n if (c.resizable) {\r\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\r\n x -= c.maxWidth - (c.previousWidth || 0);\r\n c.width = c.maxWidth;\r\n } else {\r\n c.width = (c.previousWidth || 0) + x;\r\n x = 0;\r\n }\r\n }\r\n }\r\n }\r\n } else { // stretch column\r\n x = d;\r\n\r\n newCanvasWidthL = 0;\r\n newCanvasWidthR = 0;\r\n\r\n for (j = i; j >= 0; j--) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n if (c.resizable) {\r\n if (x && c.maxWidth && (c.maxWidth - (c.previousWidth || 0) < x)) {\r\n x -= c.maxWidth - (c.previousWidth || 0);\r\n c.width = c.maxWidth;\r\n } else {\r\n const newWidth = (c.previousWidth || 0) + x;\r\n const resizedCanvasWidthL = this.canvasWidthL + x;\r\n\r\n if (this.hasFrozenColumns() && (j <= this._options.frozenColumn!)) {\r\n // if we're on the left frozen side, we need to make sure that our left section width never goes over the total viewport width\r\n if (newWidth > frozenLeftColMaxWidth && resizedCanvasWidthL < (viewportWidth - this._options.frozenRightViewportMinWidth!)) {\r\n frozenLeftColMaxWidth = newWidth; // keep max column width ref, if we go over the limit this number will stop increasing\r\n }\r\n c.width = ((resizedCanvasWidthL + this._options.frozenRightViewportMinWidth!) > viewportWidth) ? frozenLeftColMaxWidth : newWidth;\r\n } else {\r\n c.width = newWidth;\r\n }\r\n x = 0;\r\n }\r\n }\r\n }\r\n\r\n for (k = 0; k <= i; k++) {\r\n c = vc[k];\r\n if (!c || c.hidden) { continue; }\r\n\r\n if (this.hasFrozenColumns() && (k > this._options.frozenColumn!)) {\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n\r\n if (this._options.forceFitColumns) {\r\n x = -d;\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n if (c.resizable) {\r\n actualMinWidth = Math.max(c.minWidth || 0, this.absoluteColumnMinWidth);\r\n if (x && (c.previousWidth || 0) + x < actualMinWidth) {\r\n x += (c.previousWidth || 0) - actualMinWidth;\r\n c.width = actualMinWidth;\r\n } else {\r\n c.width = (c.previousWidth || 0) + x;\r\n x = 0;\r\n }\r\n\r\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n }\r\n } else {\r\n for (j = i + 1; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n\r\n if (this.hasFrozenColumns() && (j > this._options.frozenColumn!)) {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n newCanvasWidthR += c.width || 0;\r\n } else {\r\n newCanvasWidthL += c.width || 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (this.hasFrozenColumns() && newCanvasWidthL !== this.canvasWidthL) {\r\n Utils.width(this._headerL, newCanvasWidthL + 1000);\r\n Utils.setStyleSize(this._paneHeaderR, 'left', newCanvasWidthL);\r\n }\r\n\r\n this.applyColumnHeaderWidths();\r\n if (this._options.syncColumnCellResize) {\r\n this.applyColumnWidths();\r\n }\r\n this.trigger(this.onColumnsDrag, {\r\n triggeredByColumn: resizeElms.resizeableElement,\r\n resizeHandle: resizeElms.resizeableHandleElement\r\n });\r\n },\r\n onResizeEnd: (_e, resizeElms) => {\r\n resizeElms.resizeableElement.classList.remove('slick-header-column-active');\r\n\r\n const triggeredByColumn = resizeElms.resizeableElement.id.replace(this.uid, '');\r\n if (this.trigger(this.onBeforeColumnsResize, { triggeredByColumn }).getReturnValue() === true) {\r\n this.applyColumnHeaderWidths();\r\n }\r\n let newWidth;\r\n for (j = 0; j < vc.length; j++) {\r\n c = vc[j];\r\n if (!c || c.hidden) { continue; }\r\n newWidth = children[j].offsetWidth;\r\n\r\n if (c.previousWidth !== newWidth && c.rerenderOnResize) {\r\n this.invalidateAllRows();\r\n }\r\n }\r\n this.updateCanvasWidth(true);\r\n this.render();\r\n this.trigger(this.onColumnsResized, { triggeredByColumn });\r\n window.clearTimeout(this._columnResizeTimer);\r\n this._columnResizeTimer = window.setTimeout(() => { this.columnResizeDragging = false; }, 300);\r\n }\r\n })\r\n );\r\n }\r\n }\r\n\r\n protected getVBoxDelta(el: HTMLElement) {\r\n const p = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\r\n const styles = getComputedStyle(el);\r\n let delta = 0;\r\n p.forEach((val) => delta += Utils.toFloat(styles[val as any]));\r\n return delta;\r\n }\r\n\r\n protected setFrozenOptions() {\r\n this._options.frozenColumn = (this._options.frozenColumn! >= 0 && this._options.frozenColumn! < this.columns.length)\r\n ? parseInt(this._options.frozenColumn as unknown as string, 10)\r\n : -1;\r\n\r\n if (this._options.frozenRow! > -1) {\r\n this.hasFrozenRows = true;\r\n this.frozenRowsHeight = (this._options.frozenRow!) * this._options.rowHeight!;\r\n const dataLength = this.getDataLength();\r\n\r\n this.actualFrozenRow = (this._options.frozenBottom)\r\n ? (dataLength - this._options.frozenRow!)\r\n : this._options.frozenRow!;\r\n } else {\r\n this.hasFrozenRows = false;\r\n }\r\n }\r\n\r\n protected setPaneVisibility() {\r\n if (this.hasFrozenColumns()) {\r\n Utils.show(this._paneHeaderR);\r\n Utils.show(this._paneTopR);\r\n\r\n if (this.hasFrozenRows) {\r\n Utils.show(this._paneBottomL);\r\n Utils.show(this._paneBottomR);\r\n } else {\r\n Utils.hide(this._paneBottomR);\r\n Utils.hide(this._paneBottomL);\r\n }\r\n } else {\r\n Utils.hide(this._paneHeaderR);\r\n Utils.hide(this._paneTopR);\r\n Utils.hide(this._paneBottomR);\r\n\r\n if (this.hasFrozenRows) {\r\n Utils.show(this._paneBottomL);\r\n } else {\r\n Utils.hide(this._paneBottomR);\r\n Utils.hide(this._paneBottomL);\r\n }\r\n }\r\n }\r\n\r\n protected setOverflow() {\r\n this._viewportTopL.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'scroll') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'auto');\r\n this._viewportTopL.style.overflowY = (!this.hasFrozenColumns() && this._options.alwaysShowVerticalScroll) ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'hidden' : 'hidden') : (this.hasFrozenRows ? 'scroll' : 'auto'));\r\n\r\n this._viewportTopR.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'scroll') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'hidden' : 'auto');\r\n this._viewportTopR.style.overflowY = this._options.alwaysShowVerticalScroll ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'scroll' : 'auto') : (this.hasFrozenRows ? 'scroll' : 'auto'));\r\n\r\n this._viewportBottomL.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'scroll' : 'auto') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'auto' : 'auto');\r\n this._viewportBottomL.style.overflowY = (!this.hasFrozenColumns() && this._options.alwaysShowVerticalScroll) ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'hidden' : 'hidden') : (this.hasFrozenRows ? 'scroll' : 'auto'));\r\n\r\n this._viewportBottomR.style.overflowX = (this.hasFrozenColumns()) ? (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'scroll' : 'auto') : (this.hasFrozenRows && !this._options.alwaysAllowHorizontalScroll ? 'auto' : 'auto');\r\n this._viewportBottomR.style.overflowY = this._options.alwaysShowVerticalScroll ? 'scroll' : ((this.hasFrozenColumns()) ? (this.hasFrozenRows ? 'auto' : 'auto') : (this.hasFrozenRows ? 'auto' : 'auto'));\r\n\r\n if (this._options.viewportClass) {\r\n const viewportClassList = Utils.classNameToList(this._options.viewportClass);\r\n this._viewportTopL.classList.add(...viewportClassList);\r\n this._viewportTopR.classList.add(...viewportClassList);\r\n this._viewportBottomL.classList.add(...viewportClassList);\r\n this._viewportBottomR.classList.add(...viewportClassList);\r\n }\r\n }\r\n\r\n protected setScroller() {\r\n if (this.hasFrozenColumns()) {\r\n this._headerScrollContainer = this._headerScrollerR;\r\n this._headerRowScrollContainer = this._headerRowScrollerR;\r\n this._footerRowScrollContainer = this._footerRowScrollerR;\r\n\r\n if (this.hasFrozenRows) {\r\n if (this._options.frozenBottom) {\r\n this._viewportScrollContainerX = this._viewportBottomR;\r\n this._viewportScrollContainerY = this._viewportTopR;\r\n } else {\r\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportBottomR;\r\n }\r\n } else {\r\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportTopR;\r\n }\r\n } else {\r\n this._headerScrollContainer = this._headerScrollerL;\r\n this._headerRowScrollContainer = this._headerRowScrollerL;\r\n this._footerRowScrollContainer = this._footerRowScrollerL;\r\n\r\n if (this.hasFrozenRows) {\r\n if (this._options.frozenBottom) {\r\n this._viewportScrollContainerX = this._viewportBottomL;\r\n this._viewportScrollContainerY = this._viewportTopL;\r\n } else {\r\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportBottomL;\r\n }\r\n } else {\r\n this._viewportScrollContainerX = this._viewportScrollContainerY = this._viewportTopL;\r\n }\r\n }\r\n }\r\n\r\n protected measureCellPaddingAndBorder() {\r\n const h = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];\r\n const v = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];\r\n const header = this._headers[0];\r\n\r\n this.headerColumnWidthDiff = this.headerColumnHeightDiff = 0;\r\n this.cellWidthDiff = this.cellHeightDiff = 0;\r\n\r\n let el = Utils.createDomElement('div', { className: 'ui-state-default slick-state-default slick-header-column', style: { visibility: 'hidden' }, textContent: '-' }, header);\r\n let style = getComputedStyle(el);\r\n if (style.boxSizing !== 'border-box') {\r\n h.forEach((val) => this.headerColumnWidthDiff += Utils.toFloat(style[val as any]));\r\n v.forEach((val) => this.headerColumnHeightDiff += Utils.toFloat(style[val as any]));\r\n }\r\n el.remove();\r\n\r\n const r = Utils.createDomElement('div', { className: 'slick-row' }, this._canvas[0]);\r\n el = Utils.createDomElement('div', { className: 'slick-cell', id: '', style: { visibility: 'hidden' }, textContent: '-' }, r);\r\n style = getComputedStyle(el);\r\n if (style.boxSizing !== 'border-box') {\r\n h.forEach((val) => this.cellWidthDiff += Utils.toFloat(style[val as any]));\r\n v.forEach((val) => this.cellHeightDiff += Utils.toFloat(style[val as any]));\r\n }\r\n r.remove();\r\n\r\n this.absoluteColumnMinWidth = Math.max(this.headerColumnWidthDiff, this.cellWidthDiff);\r\n }\r\n\r\n protected createCssRules() {\r\n this._style = document.createElement('style');\r\n this._style.nonce = this._options.nonce || '';\r\n (this._options.shadowRoot || document.head).appendChild(this._style);\r\n\r\n const rowHeight = (this._options.rowHeight! - this.cellHeightDiff);\r\n const rules = [\r\n `.${this.uid} .slick-group-header-column { left: 1000px; }`,\r\n `.${this.uid} .slick-header-column { left: 1000px; }`,\r\n `.${this.uid} .slick-top-panel { height: ${this._options.topPanelHeight}px; }`,\r\n `.${this.uid} .slick-preheader-panel { height: ${this._options.preHeaderPanelHeight}px; }`,\r\n `.${this.uid} .slick-topheader-panel { height: ${this._options.topHeaderPanelHeight}px; }`,\r\n `.${this.uid} .slick-headerrow-columns { height: ${this._options.headerRowHeight}px; }`,\r\n `.${this.uid} .slick-footerrow-columns { height: ${this._options.footerRowHeight}px; }`,\r\n `.${this.uid} .slick-cell { height: ${rowHeight}px; }`,\r\n `.${this.uid} .slick-row { height: ${this._options.rowHeight}px; }`,\r\n ];\r\n\r\n const sheet = this._style.sheet;\r\n if (sheet) {\r\n rules.forEach(rule => {\r\n sheet.insertRule(rule);\r\n });\r\n\r\n for (let i = 0; i < this.columns.length; i++) {\r\n if (!this.columns[i] || this.columns[i].hidden) { continue; }\r\n\r\n sheet.insertRule(`.${this.uid} .l${i} { }`);\r\n sheet.insertRule(`.${this.uid} .r${i} { }`);\r\n }\r\n } else {\r\n // fallback in case the 1st approach doesn't work, let's use our previous way of creating the css rules which is what works in Salesforce :(\r\n this.createCssRulesAlternative(rules);\r\n }\r\n }\r\n\r\n /** Create CSS rules via template in case the first approach with createElement('style') doesn't work */\r\n protected createCssRulesAlternative(rules: string[]) {\r\n const template = document.createElement('template');\r\n template.innerHTML = '