From a4fac450ff59f8128c4200f8f492d218f1222699 Mon Sep 17 00:00:00 2001 From: ghiscoding Date: Mon, 13 Nov 2023 21:14:14 -0500 Subject: [PATCH] chore(release): publish version 5.5.0 --- CHANGELOG.md | 14 ++ dist/browser/controls/slick.columnmenu.js | 24 +- dist/browser/controls/slick.columnmenu.js.map | 4 +- dist/browser/controls/slick.columnpicker.js | 24 +- .../controls/slick.columnpicker.js.map | 4 +- dist/browser/controls/slick.gridmenu.js | 32 +-- dist/browser/controls/slick.gridmenu.js.map | 4 +- dist/browser/plugins/slick.autotooltips.js | 6 +- .../browser/plugins/slick.autotooltips.js.map | 4 +- .../plugins/slick.cellexternalcopymanager.js | 4 +- .../slick.cellexternalcopymanager.js.map | 4 +- .../slick.crossgridrowmovemanager.js.map | 4 +- dist/browser/plugins/slick.customtooltip.js | 8 +- .../plugins/slick.customtooltip.js.map | 4 +- .../plugins/slick.rowdetailview.js.map | 4 +- dist/browser/plugins/slick.rowmovemanager.js | 9 +- .../plugins/slick.rowmovemanager.js.map | 4 +- dist/browser/slick.dataview.js | 43 +++- dist/browser/slick.dataview.js.map | 4 +- dist/browser/slick.grid.js | 101 +++++---- dist/browser/slick.grid.js.map | 4 +- dist/cjs/index.js | 210 ++++++++++++------ dist/cjs/index.js.map | 4 +- dist/esm/index.js | 210 ++++++++++++------ dist/esm/index.js.map | 4 +- dist/types/controls/slick.columnmenu.d.ts.map | 2 +- .../controls/slick.columnpicker.d.ts.map | 2 +- dist/types/controls/slick.gridmenu.d.ts.map | 2 +- dist/types/models/column.interface.d.ts | 6 +- dist/types/models/column.interface.d.ts.map | 2 +- .../excelCopyBufferOption.interface.d.ts | 6 +- .../excelCopyBufferOption.interface.d.ts.map | 2 +- dist/types/models/formatter.interface.d.ts | 4 +- .../types/models/formatter.interface.d.ts.map | 2 +- .../formatterResultObject.interface.d.ts | 10 +- .../formatterResultObject.interface.d.ts.map | 2 +- dist/types/models/gridOption.interface.d.ts | 10 + .../models/gridOption.interface.d.ts.map | 2 +- .../rowMoveManagerOption.interface.d.ts | 2 + .../rowMoveManagerOption.interface.d.ts.map | 2 +- .../types/plugins/slick.autotooltips.d.ts.map | 2 +- .../slick.cellexternalcopymanager.d.ts.map | 2 +- .../slick.crossgridrowmovemanager.d.ts | 4 +- .../slick.crossgridrowmovemanager.d.ts.map | 2 +- dist/types/plugins/slick.customtooltip.d.ts | 2 +- .../plugins/slick.customtooltip.d.ts.map | 2 +- dist/types/plugins/slick.rowdetailview.d.ts | 6 +- .../plugins/slick.rowdetailview.d.ts.map | 2 +- dist/types/plugins/slick.rowmovemanager.d.ts | 5 +- .../plugins/slick.rowmovemanager.d.ts.map | 2 +- dist/types/slick.dataview.d.ts | 12 +- dist/types/slick.dataview.d.ts.map | 2 +- dist/types/slick.grid.d.ts | 21 +- dist/types/slick.grid.d.ts.map | 2 +- package-lock.json | 4 +- package.json | 2 +- src/slick.grid.ts | 4 +- 57 files changed, 554 insertions(+), 315 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e2bd60f9..231357db8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.5.0](https://github.com/6pac/SlickGrid/compare/5.4.2...5.5.0) (2023-11-14) + +### Bug Fixes + +* add `nonce` grid option set the nonce value for CSP header ([#902](https://github.com/6pac/SlickGrid/issues/902)) ([fc0af7a](https://github.com/6pac/SlickGrid/commit/fc0af7a33844968ef8392e8c4c17f89e9e644d6f)) +* add `nonce` grid option set the nonce value for CSP header ([#902](https://github.com/6pac/SlickGrid/issues/902)) ([#905](https://github.com/6pac/SlickGrid/issues/905)) ([fb0e4f5](https://github.com/6pac/SlickGrid/commit/fb0e4f5cb8755d9b3351eafdfbcdf2a4e4aa1016)) +* add CSP safe option for DataView filtering and adjusting inline css for CSP ([#908](https://github.com/6pac/SlickGrid/issues/908)) ([ff970c0](https://github.com/6pac/SlickGrid/commit/ff970c077f87f693e2c2d310d1315e26221e1936)) +* add missing RowMoveManager `containerCssClass` option ([#906](https://github.com/6pac/SlickGrid/issues/906)) ([5f85574](https://github.com/6pac/SlickGrid/commit/5f8557498cbd2e60de383a525542893dbe59cdc3)) +* improve build & types exports for all targets, Node, CJS/ESM ([#910](https://github.com/6pac/SlickGrid/issues/910)) ([9013526](https://github.com/6pac/SlickGrid/commit/9013526bcfc0a137817c362ca5a9963e477fa093)) + +### Features + +* add grid option `enableHtmlRendering` to use pure HTML not string ([#894](https://github.com/6pac/SlickGrid/issues/894)) ([448ec4f](https://github.com/6pac/SlickGrid/commit/448ec4f380fd6f25a641d4902f7205d935c41eed)) + ## [5.4.2](https://github.com/6pac/SlickGrid/compare/5.4.1...5.4.2) (2023-11-02) ### Bug Fixes diff --git a/dist/browser/controls/slick.columnmenu.js b/dist/browser/controls/slick.columnmenu.js index 915aebfff..e7149ad6d 100644 --- a/dist/browser/controls/slick.columnmenu.js +++ b/dist/browser/controls/slick.columnmenu.js @@ -28,7 +28,7 @@ hideSyncResizeButton: !1, forceFitTitle: "Force fit columns", syncResizeTitle: "Synchronous resize", - headerColumnValueExtractor: (columnDef) => columnDef.name || "" + headerColumnValueExtractor: (columnDef) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || "" }); this._gridUid = grid.getUID(), this._options = Utils.extend({}, this._defaults, options), this.init(this.grid); } @@ -52,28 +52,30 @@ (this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target)) || e.target.className === "close") && (this._menuElm.setAttribute("aria-expanded", "false"), this._menuElm.style.display = "none"); } handleHeaderContextMenu(e) { - var _a, _b, _c, _d, _e, _f, _g; + var _a, _b, _c, _d, _e, _f; e.preventDefault(), Utils.emptyElement(this._listElm), this.updateColumnOrder(), this._columnCheckboxes = []; let columnId, columnLabel, excludeCssClass; for (let i = 0; i < this.columns.length; i++) { - columnId = this.columns[i].id, excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : ""; + columnId = this.columns[i].id; + let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || ""; + excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : ""; let liElm = document.createElement("li"); - liElm.className = excludeCssClass, liElm.ariaLabel = ((_a = this.columns[i]) == null ? void 0 : _a.name) || ""; + liElm.className = excludeCssClass, liElm.ariaLabel = colName; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._options) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._options); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), columnLabel = (_b = (_a = this._options) == null ? void 0 : _a.columnPicker) != null && _b.headerColumnValueExtractor ? this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options) : this._defaults.headerColumnValueExtractor(this.columns[i], this._options); let labelElm = document.createElement("label"); - labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = columnLabel, liElm.appendChild(labelElm), this._listElm.appendChild(liElm); + labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel), liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } - if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_d = this._options.columnPicker) != null && _d.hideForceFitButton)) { - let forceFitTitle = ((_e = this._options.columnPicker) == null ? void 0 : _e.forceFitTitle) || this._options.forceFitTitle, liElm = document.createElement("li"); + if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_c = this._options.columnPicker) != null && _c.hideForceFitButton)) { + let forceFitTitle = ((_d = this._options.columnPicker) == null ? void 0 : _d.forceFitTitle) || this._options.forceFitTitle, liElm = document.createElement("li"); liElm.ariaLabel = forceFitTitle || "", this._listElm.appendChild(liElm); let forceFitCheckboxElm = document.createElement("input"); forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`, labelElm.textContent = forceFitTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0); } - if (!((_f = this._options.columnPicker) != null && _f.hideSyncResizeButton)) { - let syncResizeTitle = ((_g = this._options.columnPicker) == null ? void 0 : _g.syncResizeTitle) || this._options.syncResizeTitle, liElm = document.createElement("li"); + if (!((_e = this._options.columnPicker) != null && _e.hideSyncResizeButton)) { + let syncResizeTitle = ((_f = this._options.columnPicker) == null ? void 0 : _f.syncResizeTitle) || this._options.syncResizeTitle, liElm = document.createElement("li"); liElm.ariaLabel = syncResizeTitle || "", this._listElm.appendChild(liElm); let syncResizeCheckboxElm = document.createElement("input"); syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm); @@ -96,7 +98,7 @@ /** Update the Titles of each sections (command, customTitle, ...) */ updateAllTitles(pickerOptions) { var _a; - (_a = this._columnTitleElm) != null && _a.innerHTML && (this._columnTitleElm.innerHTML = pickerOptions.columnTitle); + (_a = this._columnTitleElm) != null && _a.innerHTML && (this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(pickerOptions.columnTitle)); } updateColumn(e) { if (e.target.dataset.option === "autoresize") { diff --git a/dist/browser/controls/slick.columnmenu.js.map b/dist/browser/controls/slick.columnmenu.js.map index 32b132546..deb39fe43 100644 --- a/dist/browser/controls/slick.columnmenu.js.map +++ b/dist/browser/controls/slick.columnmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.columnmenu.ts"], - "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this a simplified and updated version of slick.columnpicker.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnMenu {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _options: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, options: GridOption) {\n this._gridUid = grid.getUID();\n this._options = Utils.extend({}, this._defaults, options);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._options.columnPickerTitle || (this._options.columnPicker?.columnTitle)) {\n const columnTitle = this._options.columnPickerTitle || this._options.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target))) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? \"hidden\" : \"\";\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._options?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._options);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!this._options.columnPicker?.hideForceFitButton) {\n const forceFitTitle = this._options.columnPicker?.forceFitTitle || this._options.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!this._options.columnPicker?.hideSyncResizeButton) {\n const syncResizeTitle = this._options.columnPicker?.syncResizeTitle || this._options.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent = event?.touches?.[0] || event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns: Column[] = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnMenu;\n}\n"], - "mappings": "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", + "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this a simplified and updated version of slick.columnpicker.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnMenu {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _options: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, options: GridOption) {\n this._gridUid = grid.getUID();\n this._options = Utils.extend({}, this._defaults, options);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._options.columnPickerTitle || (this._options.columnPicker?.columnTitle)) {\n const columnTitle = this._options.columnPickerTitle || this._options.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target))) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n const colName: string = this.columns[i].name instanceof HTMLElement\n ? (this.columns[i].name as HTMLElement).innerHTML\n : (this.columns[i].name || '') as string;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? \"hidden\" : \"\";\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = colName;\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n columnLabel = (this._options?.columnPicker?.headerColumnValueExtractor)\n ? this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options)\n : this._defaults.headerColumnValueExtractor!(this.columns[i], this._options);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel);\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!this._options.columnPicker?.hideForceFitButton) {\n const forceFitTitle = this._options.columnPicker?.forceFitTitle || this._options.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!this._options.columnPicker?.hideSyncResizeButton) {\n const syncResizeTitle = this._options.columnPicker?.syncResizeTitle || this._options.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent = event?.touches?.[0] || event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(pickerOptions.columnTitle);\n }\n }\n\n updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns: Column[] = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnMenu;\n}\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/controls/slick.columnpicker.js b/dist/browser/controls/slick.columnpicker.js index 4459debb8..0e53adcb6 100644 --- a/dist/browser/controls/slick.columnpicker.js +++ b/dist/browser/controls/slick.columnpicker.js @@ -28,7 +28,7 @@ hideSyncResizeButton: !1, forceFitTitle: "Force fit columns", syncResizeTitle: "Synchronous resize", - headerColumnValueExtractor: (columnDef) => columnDef.name || "" + headerColumnValueExtractor: (columnDef) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || "" }); this._gridUid = grid.getUID(), this._gridOptions = Utils.extend({}, this._defaults, gridOptions), this.init(this.grid); } @@ -53,28 +53,30 @@ (this._menuElm !== e.target && !((_a = this._menuElm) != null && _a.contains(e.target)) || e.target.className === "close") && (this._menuElm.setAttribute("aria-expanded", "false"), this._menuElm.style.display = "none"); } handleHeaderContextMenu(e) { - var _a, _b, _c, _d, _e, _f, _g; + var _a, _b, _c, _d, _e, _f; e.preventDefault(), Utils.emptyElement(this._listElm), this.updateColumnOrder(), this._columnCheckboxes = []; let columnId, columnLabel, excludeCssClass; for (let i = 0; i < this.columns.length; i++) { - columnId = this.columns[i].id, excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : ""; + columnId = this.columns[i].id; + let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || ""; + excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : ""; let liElm = document.createElement("li"); - liElm.className = excludeCssClass, liElm.ariaLabel = ((_a = this.columns[i]) == null ? void 0 : _a.name) || ""; + liElm.className = excludeCssClass, liElm.ariaLabel = colName; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), (_c = (_b = this._gridOptions) == null ? void 0 : _b.columnPicker) != null && _c.headerColumnValueExtractor ? columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i], this._gridOptions); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), columnLabel = (_b = (_a = this._gridOptions) == null ? void 0 : _a.columnPicker) != null && _b.headerColumnValueExtractor ? this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions) : this._defaults.headerColumnValueExtractor(this.columns[i], this._gridOptions); let labelElm = document.createElement("label"); - labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = columnLabel, liElm.appendChild(labelElm), this._listElm.appendChild(liElm); + labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel), liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } - if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_d = this._gridOptions.columnPicker) != null && _d.hideForceFitButton)) { - let forceFitTitle = ((_e = this._gridOptions.columnPicker) == null ? void 0 : _e.forceFitTitle) || this._gridOptions.forceFitTitle, liElm = document.createElement("li"); + if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_c = this._gridOptions.columnPicker) != null && _c.hideForceFitButton)) { + let forceFitTitle = ((_d = this._gridOptions.columnPicker) == null ? void 0 : _d.forceFitTitle) || this._gridOptions.forceFitTitle, liElm = document.createElement("li"); liElm.ariaLabel = forceFitTitle || "", this._listElm.appendChild(liElm); let forceFitCheckboxElm = document.createElement("input"); forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`, labelElm.textContent = forceFitTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0); } - if (!((_f = this._gridOptions.columnPicker) != null && _f.hideSyncResizeButton)) { - let syncResizeTitle = ((_g = this._gridOptions.columnPicker) == null ? void 0 : _g.syncResizeTitle) || this._gridOptions.syncResizeTitle, liElm = document.createElement("li"); + if (!((_e = this._gridOptions.columnPicker) != null && _e.hideSyncResizeButton)) { + let syncResizeTitle = ((_f = this._gridOptions.columnPicker) == null ? void 0 : _f.syncResizeTitle) || this._gridOptions.syncResizeTitle, liElm = document.createElement("li"); liElm.ariaLabel = syncResizeTitle || "", this._listElm.appendChild(liElm); let syncResizeCheckboxElm = document.createElement("input"); syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm); @@ -97,7 +99,7 @@ /** Update the Titles of each sections (command, customTitle, ...) */ updateAllTitles(pickerOptions) { var _a; - (_a = this._columnTitleElm) != null && _a.innerHTML && (this._columnTitleElm.innerHTML = pickerOptions.columnTitle); + (_a = this._columnTitleElm) != null && _a.innerHTML && (this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(pickerOptions.columnTitle)); } updateColumn(e) { if (e.target.dataset.option === "autoresize") { diff --git a/dist/browser/controls/slick.columnpicker.js.map b/dist/browser/controls/slick.columnpicker.js.map index 5841941e4..ca7a6516a 100644 --- a/dist/browser/controls/slick.columnpicker.js.map +++ b/dist/browser/controls/slick.columnpicker.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.columnpicker.ts"], - "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this is the old 'complex' column pciker that hides columns by removing them from the grid\n * for a more modern version that uses the column.hidden property and is a lot simpler, use slick.columnmenu.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnPicker {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _gridOptions: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = Utils.extend({}, this._defaults, gridOptions);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._gridOptions.columnPickerTitle || (this._gridOptions.columnPicker?.columnTitle)) {\n const columnTitle = this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !this._menuElm?.contains(e.target)) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n protected handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n if (this._gridOptions?.columnPicker?.headerColumnValueExtractor) {\n columnLabel = this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i], this._gridOptions);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel;\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridOptions.columnPicker?.hideForceFitButton)) {\n const forceFitTitle = this._gridOptions.columnPicker?.forceFitTitle || this._gridOptions.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridOptions.columnPicker?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridOptions.columnPicker?.syncResizeTitle) || this._gridOptions.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n protected repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent: MouseEvent | Touch = (event as TouchEvent)?.touches?.[0] ?? event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = pickerOptions.columnTitle;\n }\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked: boolean = e.target.checked || false;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnPicker;\n}\n"], - "mappings": "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", + "sourcesContent": ["import { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { Column, ColumnPickerOption, DOMMouseOrTouchEvent, GridOption, OnColumnsChangedArgs } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * A control to add a Column Picker (right+click on any column header to reveal the column picker)\n * NOTE: this is the old 'complex' column pciker that hides columns by removing them from the grid\n * for a more modern version that uses the column.hidden property and is a lot simpler, use slick.columnmenu.js\n *\n * USAGE:\n *\n * Add the slick.columnpicker.(js|css) files and register it with the grid.\n *\n * Available options, by defining a columnPicker object:\n *\n * let options = {\n * enableCellNavigation: true,\n * columnPicker: {\n * columnTitle: \"Columns\", // default to empty string\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\" (default:false)\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\" (default:false)\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * headerColumnValueExtractor: \"Extract the column label\" // default to column.name\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n * }\n * };\n */\n\nexport class SlickColumnPicker {\n // --\n // public API\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _gridUid: string;\n protected _columnTitleElm!: HTMLElement;\n protected _listElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _bindingEventService = new BindingEventService();\n protected _gridOptions: GridOption;\n protected _defaults: ColumnPickerOption = {\n fadeSpeed: 250,\n\n // the last 2 checkboxes titles\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n syncResizeTitle: 'Synchronous resize',\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || ''\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = Utils.extend({}, this._defaults, gridOptions);\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this));\n grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n this._menuElm = document.createElement('div');\n this._menuElm.className = `slick-columnpicker ${this._gridUid}`;\n this._menuElm.style.display = 'none';\n document.body.appendChild(this._menuElm);\n\n const buttonElm = document.createElement('button');\n buttonElm.type = 'button';\n buttonElm.className = 'close';\n buttonElm.dataset.dismiss = 'slick-columnpicker';\n buttonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n buttonElm.appendChild(spanCloseElm);\n this._menuElm.appendChild(buttonElm);\n\n // user could pass a title on top of the columns list\n if (this._gridOptions.columnPickerTitle || (this._gridOptions.columnPicker?.columnTitle)) {\n const columnTitle = this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle;\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'slick-gridmenu-custom';\n this._columnTitleElm.textContent = columnTitle || '';\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-columnpicker-list';\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n destroy() {\n this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this));\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this._bindingEventService.unbindAll();\n this._listElm?.remove();\n this._menuElm?.remove();\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n if ((this._menuElm !== e.target && !this._menuElm?.contains(e.target)) || e.target.className === 'close') {\n this._menuElm.setAttribute('aria-expanded', 'false');\n this._menuElm.style.display = 'none';\n }\n }\n\n protected handleHeaderContextMenu(e: DOMMouseOrTouchEvent) {\n e.preventDefault();\n Utils.emptyElement(this._listElm);\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n const colName: string = this.columns[i].name instanceof HTMLElement\n ? (this.columns[i].name as HTMLElement).innerHTML\n : (this.columns[i].name || '') as string;\n excludeCssClass = this.columns[i].excludeFromColumnPicker ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = colName;\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n this._columnCheckboxes.push(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n columnLabel = (this._gridOptions?.columnPicker?.headerColumnValueExtractor)\n ? this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions)\n : this._defaults.headerColumnValueExtractor!(this.columns[i], this._gridOptions);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`;\n labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel);\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridOptions.columnPicker?.hideForceFitButton)) {\n const forceFitTitle = this._gridOptions.columnPicker?.forceFitTitle || this._gridOptions.forceFitTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle || '';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`;\n labelElm.textContent = forceFitTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridOptions.columnPicker?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridOptions.columnPicker?.syncResizeTitle) || this._gridOptions.syncResizeTitle;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle || '';\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle || '';\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n this.repositionMenu(e);\n }\n\n protected repositionMenu(event: DOMMouseOrTouchEvent) {\n const targetEvent: MouseEvent | Touch = (event as TouchEvent)?.touches?.[0] ?? event;\n this._menuElm.style.top = `${targetEvent.pageY - 10}px`;\n this._menuElm.style.left = `${targetEvent.pageX - 10}px`;\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`;\n this._menuElm.style.display = 'block';\n this._menuElm.setAttribute('aria-expanded', 'true');\n this._menuElm.appendChild(this._listElm);\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n /** Update the Titles of each sections (command, customTitle, ...) */\n updateAllTitles(pickerOptions: { columnTitle: string; }) {\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(pickerOptions.columnTitle);\n }\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked: boolean = e.target.checked || false;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n if (e.target.checked) {\n this.grid.setOptions({ syncColumnCellResize: true });\n } else {\n this.grid.setOptions({ syncColumnCellResize: false });\n }\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (this.columns[idx].hidden !== undefined) { this.columns[idx].hidden = !columnCheckbox.checked; }\n if (columnCheckbox.checked) {\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n }\n\n setColumnVisibiliy(idxOrId: number | string, show: boolean) {\n const idx = typeof idxOrId === 'number' ? idxOrId : this.getColumnIndexbyId(idxOrId);\n let visibleColumns = this.getVisibleColumns();\n const col = this.columns[idx];\n if (show) {\n col.hidden = false;\n visibleColumns.splice(idx, 0, col);\n } else {\n const newVisibleColumns: Column[] = [];\n for (let i = 0; i < visibleColumns.length; i++) {\n if (visibleColumns[i].id !== col.id) { newVisibleColumns.push(visibleColumns[i]); }\n }\n visibleColumns = newVisibleColumns;\n }\n\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n getColumnbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return this.columns[i]; }\n }\n return null;\n }\n\n getColumnIndexbyId(id: number | string) {\n for (let i = 0; i < this.columns.length; i++) {\n if (this.columns[i].id === id) { return i; }\n }\n return -1;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.ColumnPicker = SlickColumnPicker;\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,sBAAkC,MAAM,qBACxC,aAAyB,MAAM,OAC/B,QAAoB,MAAM,OA4BnB,oBAAN,MAAwB;AAAA,IAyB7B,YAAsB,SAAsC,MAAiB,aAAyB;AAAhF;AAAsC;AAtB5D;AAAA;AAAA,8CAAmB,IAAI,WAAiC;AAIxD;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,qBAAwC,CAAC;AACnD,0BAAU,wBAAuB,IAAI,oBAAoB;AACzD,0BAAU;AACV,0BAAU,aAAgC;AAAA,QACxC,WAAW;AAAA;AAAA,QAGX,oBAAoB;AAAA,QACpB,sBAAsB;AAAA,QACtB,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,4BAA4B,CAAC,cAAsB,UAAU,gBAAgB,cAAc,UAAU,KAAK,YAAY,UAAU,QAAQ;AAAA,MAC1I;AAGE,WAAK,WAAW,KAAK,OAAO,GAC5B,KAAK,eAAe,MAAM,OAAO,CAAC,GAAG,KAAK,WAAW,WAAW,GAChE,KAAK,KAAK,KAAK,IAAI;AAAA,IACrB;AAAA,IAEA,KAAK,MAAiB;AAlExB;AAmEI,WAAK,oBAAoB,UAAU,KAAK,wBAAwB,KAAK,IAAI,CAAC,GAC1E,KAAK,mBAAmB,UAAU,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAEnE,KAAK,WAAW,SAAS,cAAc,KAAK,GAC5C,KAAK,SAAS,YAAY,sBAAsB,KAAK,QAAQ,IAC7D,KAAK,SAAS,MAAM,UAAU,QAC9B,SAAS,KAAK,YAAY,KAAK,QAAQ;AAEvC,UAAM,YAAY,SAAS,cAAc,QAAQ;AACjD,gBAAU,OAAO,UACjB,UAAU,YAAY,SACtB,UAAU,QAAQ,UAAU,sBAC5B,UAAU,YAAY;AAEtB,UAAM,eAAe,SAAS,cAAc,MAAM;AAQlD,UAPA,aAAa,YAAY,SACzB,aAAa,aAAa,QAC1B,aAAa,cAAc,QAC3B,UAAU,YAAY,YAAY,GAClC,KAAK,SAAS,YAAY,SAAS,GAG/B,KAAK,aAAa,sBAAsB,UAAK,aAAa,iBAAlB,WAAgC,aAAc;AACxF,YAAM,cAAc,KAAK,aAAa,uBAAqB,UAAK,aAAa,iBAAlB,mBAAgC;AAC3F,aAAK,kBAAkB,SAAS,cAAc,KAAK,GACnD,KAAK,gBAAgB,YAAY,yBACjC,KAAK,gBAAgB,cAAc,eAAe,IAClD,KAAK,SAAS,YAAY,KAAK,eAAe;AAAA,MAChD;AAEA,WAAK,qBAAqB,KAAK,KAAK,UAAU,SAAS,KAAK,aAAa,KAAK,IAAI,CAAkB,GAEpG,KAAK,WAAW,SAAS,cAAc,MAAM,GAC7C,KAAK,SAAS,YAAY,2BAG1B,KAAK,qBAAqB,KAAK,SAAS,MAAM,aAAa,KAAK,oBAAoB,KAAK,IAAI,CAAkB,GAG/G,KAAK,qBAAqB,KAAK,SAAS,MAAM,gBAAgB,KAAK,QAAQ,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,IAEA,UAAU;AA7GZ;AA8GI,WAAK,KAAK,oBAAoB,YAAY,KAAK,wBAAwB,KAAK,IAAI,CAAC,GACjF,KAAK,KAAK,mBAAmB,YAAY,KAAK,kBAAkB,KAAK,IAAI,CAAC,GAC1E,KAAK,qBAAqB,UAAU,IACpC,UAAK,aAAL,WAAe,WACf,UAAK,aAAL,WAAe;AAAA,IACjB;AAAA,IAEU,oBAAoB,GAAsC;AArHtE;AAsHI,OAAK,KAAK,aAAa,EAAE,UAAU,GAAC,UAAK,aAAL,WAAe,SAAS,EAAE,YAAY,EAAE,OAAO,cAAc,aAC/F,KAAK,SAAS,aAAa,iBAAiB,OAAO,GACnD,KAAK,SAAS,MAAM,UAAU;AAAA,IAElC;AAAA,IAEU,wBAAwB,GAAyC;AA5H7E;AA6HI,QAAE,eAAe,GACjB,MAAM,aAAa,KAAK,QAAQ,GAChC,KAAK,kBAAkB,GACvB,KAAK,oBAAoB,CAAC;AAE1B,UAAI,UAAU,aAAa;AAC3B,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,mBAAW,KAAK,QAAQ,CAAC,EAAE;AAC3B,YAAM,UAAkB,KAAK,QAAQ,CAAC,EAAE,gBAAgB,cACnD,KAAK,QAAQ,CAAC,EAAE,KAAqB,YACrC,KAAK,QAAQ,CAAC,EAAE,QAAQ;AAC7B,0BAAkB,KAAK,QAAQ,CAAC,EAAE,0BAA0B,WAAW;AAEvE,YAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAClB,MAAM,YAAY;AAElB,YAAM,cAAc,SAAS,cAAc,OAAO;AAClD,oBAAY,OAAO,YACnB,YAAY,KAAK,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACtD,YAAY,QAAQ,WAAW,OAAO,KAAK,QAAQ,CAAC,EAAE,EAAE,GACxD,MAAM,YAAY,WAAW,GAE7B,KAAK,kBAAkB,KAAK,WAAW,GAEnC,MAAM,UAAU,KAAK,KAAK,eAAe,QAAQ,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,EAAE,WAC1E,YAAY,UAAU,KAGxB,eAAe,gBAAK,iBAAL,mBAAmB,iBAAnB,WAAiC,6BAC5C,KAAK,aAAa,aAAa,2BAA2B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY,IAC5F,KAAK,UAAU,2BAA4B,KAAK,QAAQ,CAAC,GAAG,KAAK,YAAY;AAEjF,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,aAAa,QAAQ,IACxD,SAAS,YAAY,KAAK,KAAK,mBAAmB,WAAW,GAC7D,MAAM,YAAY,QAAQ,GAC1B,KAAK,SAAS,YAAY,KAAK;AAAA,MACjC;AAMA,UAJI,KAAK,aAAa,iBAAiB,CAAC,KAAK,aAAa,aAAa,sBAAsB,CAAC,KAAK,aAAa,aAAa,yBAC3H,KAAK,SAAS,YAAY,SAAS,cAAc,IAAI,CAAC,GAGpD,GAAE,UAAK,aAAa,iBAAlB,WAAgC,qBAAqB;AACzD,YAAM,kBAAgB,UAAK,aAAa,iBAAlB,mBAAgC,kBAAiB,KAAK,aAAa,eAEnF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,iBAAiB,IACnC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,sBAAsB,SAAS,cAAc,OAAO;AAC1D,4BAAoB,OAAO,YAC3B,oBAAoB,KAAK,GAAG,KAAK,QAAQ,sBACzC,oBAAoB,QAAQ,SAAS,cACrC,MAAM,YAAY,mBAAmB;AAErC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,sBACnC,SAAS,cAAc,iBAAiB,IACxC,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,oBACzB,oBAAoB,UAAU;AAAA,MAElC;AAEA,UAAI,GAAE,UAAK,aAAa,iBAAlB,WAAgC,uBAAuB;AAC3D,YAAM,oBAAmB,UAAK,aAAa,iBAAlB,mBAAgC,oBAAoB,KAAK,aAAa,iBAEzF,QAAQ,SAAS,cAAc,IAAI;AACzC,cAAM,YAAY,mBAAmB,IACrC,KAAK,SAAS,YAAY,KAAK;AAE/B,YAAM,wBAAwB,SAAS,cAAc,OAAO;AAC5D,8BAAsB,OAAO,YAC7B,sBAAsB,KAAK,GAAG,KAAK,QAAQ,wBAC3C,sBAAsB,QAAQ,SAAS,cACvC,MAAM,YAAY,qBAAqB;AAEvC,YAAM,WAAW,SAAS,cAAc,OAAO;AAC/C,iBAAS,UAAU,GAAG,KAAK,QAAQ,wBACnC,SAAS,cAAc,mBAAmB,IAC1C,MAAM,YAAY,QAAQ,GAEtB,KAAK,KAAK,WAAW,EAAE,yBACzB,sBAAsB,UAAU;AAAA,MAEpC;AAEA,WAAK,eAAe,CAAC;AAAA,IACvB;AAAA,IAEU,eAAe,OAA6C;AA1NxE;AA2NI,UAAM,eAAmC,0CAAsB,YAAtB,mBAAgC,OAAhC,YAAsC;AAC/E,WAAK,SAAS,MAAM,MAAM,GAAG,YAAY,QAAQ,EAAE,MACnD,KAAK,SAAS,MAAM,OAAO,GAAG,YAAY,QAAQ,EAAE,MACpD,KAAK,SAAS,MAAM,YAAY,GAAG,OAAO,cAAc,YAAY,OAAO,MAC3E,KAAK,SAAS,MAAM,UAAU,SAC9B,KAAK,SAAS,aAAa,iBAAiB,MAAM,GAClD,KAAK,SAAS,YAAY,KAAK,QAAQ;AAAA,IACzC;AAAA,IAEU,oBAAoB;AAO5B,UAAM,UAAU,KAAK,KAAK,WAAW,EAAE,MAAM,CAAC,GACxC,UAAU,IAAI,MAAM,KAAK,QAAQ,MAAM;AAC7C,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ;AAClC,QAAI,KAAK,KAAK,eAAe,KAAK,QAAQ,CAAC,EAAE,EAAE,MAAM,SAGnD,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAG3B,QAAQ,CAAC,IAAI,QAAQ,MAAM;AAG/B,WAAK,UAAU;AAAA,IACjB;AAAA;AAAA,IAGA,gBAAgB,eAAyC;AA3P3D;AA4PI,OAAI,UAAK,oBAAL,WAAsB,cACxB,KAAK,gBAAgB,YAAY,KAAK,KAAK,mBAAmB,cAAc,WAAW;AAAA,IAE3F;AAAA,IAEU,aAAa,GAA2C;AAChE,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAG5C,YAAM,yBAAyB,KAAK,kBAAkB,GAChD,YAAqB,EAAE,OAAO,WAAW;AAC/C,aAAK,KAAK,WAAW,EAAE,iBAAiB,UAAU,CAAC,GACnD,KAAK,KAAK,WAAW,sBAAsB;AAC3C;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,QAAQ,WAAW,cAAc;AAC5C,QAAI,EAAE,OAAO,UACX,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAK,CAAC,IAEnD,KAAK,KAAK,WAAW,EAAE,sBAAsB,GAAM,CAAC;AAEtD;AAAA,MACF;AAEA,UAAI,EAAE,OAAO,SAAS,YAAY;AAChC,YAAM,YAAY,EAAE,OAAO,SACrB,WAAW,EAAE,OAAO,QAAQ,YAAY,IACxC,iBAA2B,CAAC;AAQlC,YAPA,KAAK,kBAAkB,QAAQ,CAAC,gBAAgB,QAAQ;AACtD,UAAI,KAAK,QAAQ,GAAG,EAAE,WAAW,WAAa,KAAK,QAAQ,GAAG,EAAE,SAAS,CAAC,eAAe,UACrF,eAAe,WACjB,eAAe,KAAK,KAAK,QAAQ,GAAG,CAAC;AAAA,QAEzC,CAAC,GAEG,CAAC,eAAe,QAAQ;AAC1B,YAAE,OAAO,UAAU;AACnB;AAAA,QACF;AAEA,aAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAU,SAAS,WAAW,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,MACjJ;AAAA,IACF;AAAA,IAEA,mBAAmB,SAA0B,MAAe;AAC1D,UAAM,MAAM,OAAO,WAAY,WAAW,UAAU,KAAK,mBAAmB,OAAO,GAC/E,iBAAiB,KAAK,kBAAkB,GACtC,MAAM,KAAK,QAAQ,GAAG;AAC5B,UAAI;AACF,YAAI,SAAS,IACb,eAAe,OAAO,KAAK,GAAG,GAAG;AAAA,WAC5B;AACL,YAAM,oBAA8B,CAAC;AACrC,iBAAS,IAAI,GAAG,IAAI,eAAe,QAAQ;AACzC,UAAI,eAAe,CAAC,EAAE,OAAO,IAAI,MAAM,kBAAkB,KAAK,eAAe,CAAC,CAAC;AAEjF,yBAAiB;AAAA,MACnB;AAEA,WAAK,KAAK,WAAW,cAAc,GACnC,KAAK,iBAAiB,OAAO,EAAE,UAAU,IAAI,IAAI,SAAS,MAAM,YAAY,KAAK,SAAS,SAAS,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,CAAC;AAAA,IACpJ;AAAA,IAEA,gBAAgB;AACd,aAAO,KAAK;AAAA,IACd;AAAA,IAEA,cAAc,IAAqB;AACjC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO,KAAK,QAAQ,CAAC;AAExD,aAAO;AAAA,IACT;AAAA,IAEA,mBAAmB,IAAqB;AACtC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ;AACvC,YAAI,KAAK,QAAQ,CAAC,EAAE,OAAO;AAAM,iBAAO;AAE1C,aAAO;AAAA,IACT;AAAA;AAAA,IAGA,oBAAoB;AAClB,aAAO,KAAK,KAAK,WAAW;AAAA,IAC9B;AAAA,EACF;AAGA,EAAiB,OAAO,UACtB,OAAO,MAAM,WAAW,OAAO,MAAM,YAAY,CAAC,GAClD,OAAO,MAAM,SAAS,eAAe;", "names": [] } diff --git a/dist/browser/controls/slick.gridmenu.js b/dist/browser/controls/slick.gridmenu.js index a6f2654a6..447d8654e 100644 --- a/dist/browser/controls/slick.gridmenu.js +++ b/dist/browser/controls/slick.gridmenu.js @@ -44,7 +44,7 @@ subMenuOpenByEvent: "mouseover", syncResizeTitle: "Synchronous resize", useClickToRepositionMenu: !0, - headerColumnValueExtractor: (columnDef) => columnDef.name + headerColumnValueExtractor: (columnDef) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || "" }); this._gridUid = grid.getUID(), this._gridOptions = gridOptions, this._gridMenuOptions = Utils.extend({}, this._defaults, gridOptions.gridMenu), this._bindingEventService = new BindingEventService(), grid.onSetOptions.subscribe((_e, args) => { if (args && args.optionsBefore && args.optionsAfter) { @@ -121,7 +121,7 @@ populateCommandsMenu(commandItems, commandListElm, args) { var _a, _b, _c, _d; let level = (args == null ? void 0 : args.level) || 0, isSubMenu = level > 0; - !isSubMenu && ((_a = this._gridMenuOptions) != null && _a.commandTitle || (_b = this._gridMenuOptions) != null && _b.customTitle) && (this._commandTitleElm = document.createElement("div"), this._commandTitleElm.className = "title", this._commandTitleElm.innerHTML = this._gridMenuOptions.commandTitle || this._gridMenuOptions.customTitle, commandListElm.appendChild(this._commandTitleElm)); + !isSubMenu && ((_a = this._gridMenuOptions) != null && _a.commandTitle || (_b = this._gridMenuOptions) != null && _b.customTitle) && (this._commandTitleElm = document.createElement("div"), this._commandTitleElm.className = "title", this._commandTitleElm.innerHTML = this.grid.sanitizeHtmlString(this._gridMenuOptions.commandTitle || this._gridMenuOptions.customTitle), commandListElm.appendChild(this._commandTitleElm)); for (let i = 0, ln = commandItems.length; i < ln; i++) { let addClickListener = !0, item = commandItems[i], callbackArgs = { grid: this.grid, @@ -137,7 +137,7 @@ let iconElm = document.createElement("div"); iconElm.className = "slick-gridmenu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...item.iconCssClass.split(" ")), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`); let textElm = document.createElement("span"); - if (textElm.className = "slick-gridmenu-content", textElm.innerHTML = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandListElm.appendChild(liElm), addClickListener) { + if (textElm.className = "slick-gridmenu-content", textElm.innerHTML = this.grid.sanitizeHtmlString(item.title || ""), liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...item.textCssClass.split(" ")), commandListElm.appendChild(liElm), addClickListener) { let eventGroup = isSubMenu ? "sub-menu" : "parent-menu"; this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, level), void 0, eventGroup); } @@ -153,14 +153,14 @@ /** Build the column picker, the code comes almost untouched from the file "slick.columnpicker.js" */ populateColumnPicker() { var _a; - this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this)), (_a = this._gridMenuOptions) != null && _a.columnTitle && (this._columnTitleElm = document.createElement("div"), this._columnTitleElm.className = "title", this._columnTitleElm.innerHTML = this._gridMenuOptions.columnTitle, this._menuElm.appendChild(this._columnTitleElm)), this._bindingEventService.bind(this._menuElm, "click", this.updateColumn.bind(this)), this._listElm = document.createElement("span"), this._listElm.className = "slick-gridmenu-list", this._listElm.role = "menu"; + this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this)), (_a = this._gridMenuOptions) != null && _a.columnTitle && (this._columnTitleElm = document.createElement("div"), this._columnTitleElm.className = "title", this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(this._gridMenuOptions.columnTitle), this._menuElm.appendChild(this._columnTitleElm)), this._bindingEventService.bind(this._menuElm, "click", this.updateColumn.bind(this)), this._listElm = document.createElement("span"), this._listElm.className = "slick-gridmenu-list", this._listElm.role = "menu"; } /** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */ recreateGridMenu() { this.deleteMenu(), this.init(this.grid); } showGridMenu(e) { - var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; + var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k; let targetEvent = e.touches ? e.touches[0] : e; e.preventDefault(), Utils.emptyElement(this._listElm), Utils.emptyElement(this._commandListElm); let commandItems = (_d = (_c = (_a = this._gridMenuOptions) == null ? void 0 : _a.commandItems) != null ? _c : (_b = this._gridMenuOptions) == null ? void 0 : _b.customItems) != null ? _d : []; @@ -176,23 +176,23 @@ let columnId, columnLabel, excludeCssClass; for (let i = 0; i < this.columns.length; i++) { columnId = this.columns[i].id, excludeCssClass = this.columns[i].excludeFromGridMenu ? "hidden" : ""; - let liElm = document.createElement("li"); - liElm.className = excludeCssClass, liElm.ariaLabel = ((_e = this.columns[i]) == null ? void 0 : _e.name) || ""; + let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || "", liElm = document.createElement("li"); + liElm.className = excludeCssClass, liElm.ariaLabel = colName; let checkboxElm = document.createElement("input"); - checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden && (checkboxElm.checked = !0), this._columnCheckboxes.push(checkboxElm), (_f = this._gridMenuOptions) != null && _f.headerColumnValueExtractor ? columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions) : columnLabel = this._defaults.headerColumnValueExtractor(this.columns[i]); + checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden && (checkboxElm.checked = !0), this._columnCheckboxes.push(checkboxElm), columnLabel = (_e = this._gridMenuOptions) != null && _e.headerColumnValueExtractor ? this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions) : this._defaults.headerColumnValueExtractor(this.columns[i]); let labelElm = document.createElement("label"); - labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`, labelElm.innerHTML = columnLabel || "", liElm.appendChild(labelElm), this._listElm.appendChild(liElm); + labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`, labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel || ""), liElm.appendChild(labelElm), this._listElm.appendChild(liElm); } - if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_g = this._gridMenuOptions) != null && _g.hideForceFitButton)) { - let forceFitTitle = ((_h = this._gridMenuOptions) == null ? void 0 : _h.forceFitTitle) || this._defaults.forceFitTitle, liElm = document.createElement("li"); + if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !((_f = this._gridMenuOptions) != null && _f.hideForceFitButton)) { + let forceFitTitle = ((_g = this._gridMenuOptions) == null ? void 0 : _g.forceFitTitle) || this._defaults.forceFitTitle, liElm = document.createElement("li"); liElm.ariaLabel = forceFitTitle, liElm.role = "menuitem", this._listElm.appendChild(liElm); let forceFitCheckboxElm = document.createElement("input"); forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm); let labelElm = document.createElement("label"); labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`, labelElm.textContent = forceFitTitle, liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0); } - if (!((_i = this._gridMenuOptions) != null && _i.hideSyncResizeButton)) { - let syncResizeTitle = ((_j = this._gridMenuOptions) == null ? void 0 : _j.syncResizeTitle) || this._defaults.syncResizeTitle, liElm = document.createElement("li"); + if (!((_h = this._gridMenuOptions) != null && _h.hideSyncResizeButton)) { + let syncResizeTitle = ((_i = this._gridMenuOptions) == null ? void 0 : _i.syncResizeTitle) || this._defaults.syncResizeTitle, liElm = document.createElement("li"); liElm.ariaLabel = syncResizeTitle, this._listElm.appendChild(liElm); let syncResizeCheckboxElm = document.createElement("input"); syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm); @@ -201,8 +201,8 @@ } let buttonElm = e.target.nodeName === "BUTTON" ? e.target : e.target.querySelector("button"); buttonElm || (buttonElm = e.target.parentElement), this._menuElm.style.display = "block", this._menuElm.style.opacity = "0", this.repositionMenu(e, this._menuElm, buttonElm); - let menuMarginBottom = ((_k = this._gridMenuOptions) == null ? void 0 : _k.marginBottom) !== void 0 ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom; - ((_l = this._gridMenuOptions) == null ? void 0 : _l.height) !== void 0 ? this._menuElm.style.height = `${this._gridMenuOptions.height}px` : this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`, this._menuElm.style.display = "block", this._menuElm.style.opacity = "1", this._menuElm.appendChild(this._listElm), this._isMenuOpen = !0, typeof e.stopPropagation == "function" && this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue(); + let menuMarginBottom = ((_j = this._gridMenuOptions) == null ? void 0 : _j.marginBottom) !== void 0 ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom; + ((_k = this._gridMenuOptions) == null ? void 0 : _k.height) !== void 0 ? this._menuElm.style.height = `${this._gridMenuOptions.height}px` : this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`, this._menuElm.style.display = "block", this._menuElm.style.opacity = "1", this._menuElm.appendChild(this._listElm), this._isMenuOpen = !0, typeof e.stopPropagation == "function" && this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue(); } getGridUidSelector() { let gridUid = this.grid.getUID() || ""; @@ -249,7 +249,7 @@ /** Update the Titles of each sections (command, commandTitle, ...) */ updateAllTitles(gridMenuOptions) { var _a, _b; - (_a = this._commandTitleElm) != null && _a.innerHTML && (this._commandTitleElm.innerHTML = gridMenuOptions.commandTitle || gridMenuOptions.customTitle || ""), (_b = this._columnTitleElm) != null && _b.innerHTML && (this._columnTitleElm.innerHTML = gridMenuOptions.columnTitle || ""); + (_a = this._commandTitleElm) != null && _a.innerHTML && (this._commandTitleElm.innerHTML = this.grid.sanitizeHtmlString(gridMenuOptions.commandTitle || gridMenuOptions.customTitle || "")), (_b = this._columnTitleElm) != null && _b.innerHTML && (this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(gridMenuOptions.columnTitle || "")); } addSubMenuTitleWhenExists(item, commandOrOptionMenu) { if (item !== "divider" && (item != null && item.subMenuTitle)) { diff --git a/dist/browser/controls/slick.gridmenu.js.map b/dist/browser/controls/slick.gridmenu.js.map index 7470b58ce..f4babf5d0 100644 --- a/dist/browser/controls/slick.gridmenu.js.map +++ b/dist/browser/controls/slick.gridmenu.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/controls/slick.gridmenu.ts"], - "sourcesContent": ["import type {\n Column,\n DOMMouseOrTouchEvent,\n GridMenuCommandItemCallbackArgs,\n GridMenuEventWithElementCallbackArgs,\n GridMenuItem,\n GridMenuOption,\n GridOption,\n MenuCommandItem,\n onGridMenuColumnsChangedCallbackArgs\n} from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A control to add a Grid Menu (hambuger menu on top-right of the grid)\n *\n * USAGE:\n *\n * Add the slick.gridmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * let gridMenuControl = new Slick.Controls.GridMenu(columns, grid, options);\n *\n * Available grid options, by defining a gridMenu object:\n *\n * let options = {\n * enableCellNavigation: true,\n * gridMenu: {\n * commandTitle: \"Command List\", // default to empty string\n * columnTitle: \"Columns\", // default to empty string\n * iconImage: \"some-image.png\", // this is the Grid Menu icon (hamburger icon)\n * iconCssClass: \"fa fa-bars\", // you can provide iconImage OR iconCssClass\n * leaveOpen: false, // do we want to leave the Grid Menu open after a command execution? (false by default)\n * menuWidth: 18, // width (icon) that will be use to resize the column header container (18 by default)\n * contentMinWidth: 0,\t\t\t\t\t\t\t // defaults to 0 (auto), minimum width of grid menu content (command, column list)\n * marginBottom: 15, // defaults to 15, margin to use at the bottom of the grid when using max-height (default)\n * resizeOnShowHeaderRow: false, // false by default\n * showButton: true, // true by default - it allows the user to control if the\n * // default gridMenu button (located on the top right corner by default CSS)\n * // should be created or omitted\n * useClickToRepositionMenu: true, // true by default\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\"\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\"\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n *\n * commandItems: [\n * {\n * // command menu item options\n * },\n * {\n * // command menu item options\n * }\n * ]\n * }\n * };\n *\n *\n * Available menu options:\n * hideForceFitButton: Hide the \"Force fit columns\" button (defaults to false)\n * hideSyncResizeButton: Hide the \"Synchronous resize\" button (defaults to false)\n * forceFitTitle: Text of the title \"Force fit columns\"\n * contentMinWidth:\t\t\t\t\t\tminimum width of grid menu content (command, column list), defaults to 0 (auto)\n * height: Height of the Grid Menu content, when provided it will be used instead of the max-height (defaults to undefined)\n * menuWidth: Grid menu button width (defaults to 18)\n * resizeOnShowHeaderRow: Do we want to resize on the show header row event\n * syncResizeTitle: Text of the title \"Synchronous resize\"\n * useClickToRepositionMenu: Use the Click offset to reposition the Grid Menu (defaults to true), when set to False it will use the icon offset to reposition the grid menu\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * marginBottom: Margin to use at the bottom of the grid menu, only in effect when height is undefined (defaults to 15)\n * subItemChevronClass: CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon)\n * subMenuOpenByEvent: defaults to \"mouseover\", what event type shoud we use to open sub-menu(s), 2 options are available: \"mouseover\" or \"click\"\n *\n * Available command menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * subMenuTitle: Optional sub-menu title that will shows up when sub-menu commmands/options list is opened\n * subMenuTitleCssClass: Optional sub-menu title CSS class to use with `subMenuTitle`\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onMenuClose: Fired when the menu is closing.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n */\n\nexport class SlickGridMenu {\n // --\n // public API\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService: BindingEventService_;\n protected _gridOptions: GridOption;\n protected _gridUid: string;\n protected _isMenuOpen = false;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _columnTitleElm!: HTMLElement;\n protected _commandTitleElm!: HTMLElement;\n protected _commandListElm!: HTMLDivElement;\n protected _headerElm: HTMLDivElement | null = null;\n protected _listElm!: HTMLElement;\n protected _buttonElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _subMenuParentId = '';\n protected _gridMenuOptions: GridMenuOption | null = null;\n protected _defaults: GridMenuOption = {\n showButton: true,\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n marginBottom: 15,\n menuWidth: 18,\n contentMinWidth: 0,\n resizeOnShowHeaderRow: false,\n subMenuOpenByEvent: 'mouseover',\n syncResizeTitle: 'Synchronous resize',\n useClickToRepositionMenu: true,\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name as string,\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = gridOptions;\n this._gridMenuOptions = Utils.extend({}, this._defaults, gridOptions.gridMenu);\n this._bindingEventService = new BindingEventService();\n\n // when a grid optionally changes from a regular grid to a frozen grid, we need to destroy & recreate the grid menu\n // we do this change because the Grid Menu is on the left container for a regular grid, it is however on the right container for a frozen grid\n grid.onSetOptions.subscribe((_e, args) => {\n if (args && args.optionsBefore && args.optionsAfter) {\n const switchedFromRegularToFrozen = args.optionsBefore.frozenColumn! >= 0 && args.optionsAfter.frozenColumn === -1;\n const switchedFromFrozenToRegular = args.optionsBefore.frozenColumn === -1 && args.optionsAfter.frozenColumn! >= 0;\n if (switchedFromRegularToFrozen || switchedFromFrozenToRegular) {\n this.recreateGridMenu();\n }\n }\n });\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n this._gridOptions = grid.getOptions();\n this.createGridMenu();\n\n if (this._gridMenuOptions?.customItems || this._gridMenuOptions?.customTitle) {\n console.warn('[SlickGrid] Grid Menu \"customItems\" and \"customTitle\" were deprecated to align with other Menu plugins, please use \"commandItems\" and \"commandTitle\" instead.');\n }\n\n // subscribe to the grid, when it's destroyed, we should also destroy the Grid Menu\n grid.onBeforeDestroy.subscribe(this.destroy.bind(this));\n }\n\n setOptions(newOptions: GridMenuOption) {\n this._gridMenuOptions = Utils.extend({}, this._gridMenuOptions, newOptions);\n }\n\n protected createGridMenu() {\n const gridMenuWidth = (this._gridMenuOptions?.menuWidth) || this._defaults.menuWidth;\n if (this._gridOptions && this._gridOptions.hasOwnProperty('frozenColumn') && this._gridOptions.frozenColumn! >= 0) {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`);\n } else {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`);\n }\n this._headerElm!.style.width = `calc(100% - ${gridMenuWidth}px)`;\n\n // if header row is enabled, we need to resize its width also\n const enableResizeHeaderRow = (Utils.isDefined(this._gridMenuOptions?.resizeOnShowHeaderRow)) ? this._gridMenuOptions!.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow;\n if (enableResizeHeaderRow && this._gridOptions.showHeaderRow) {\n const headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`);\n if (headerRow) {\n headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`;\n }\n }\n\n const showButton = (this._gridMenuOptions?.showButton !== undefined) ? this._gridMenuOptions.showButton : this._defaults.showButton;\n if (showButton) {\n this._buttonElm = document.createElement('button');\n this._buttonElm.className = 'slick-gridmenu-button';\n this._buttonElm.ariaLabel = 'Grid Menu';\n\n if (this._gridMenuOptions?.iconCssClass) {\n this._buttonElm.classList.add(...this._gridMenuOptions.iconCssClass.split(' '));\n } else {\n const iconImageElm = document.createElement('img');\n iconImageElm.src = (this._gridMenuOptions?.iconImage) ? this._gridMenuOptions.iconImage : '../images/drag-handle.png';\n this._buttonElm.appendChild(iconImageElm);\n }\n\n this._headerElm!.parentElement!.insertBefore(this._buttonElm, this._headerElm!.parentElement!.firstChild);\n\n // add on click handler for the Grid Menu itself\n this._bindingEventService.bind(this._buttonElm, 'click', this.showGridMenu.bind(this) as EventListener);\n }\n\n this._menuElm = this.createMenu(0);\n this.populateColumnPicker();\n document.body.appendChild(this._menuElm);\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n /** Create the menu or sub-menu(s) but without the column picker which is a separate single process */\n createMenu(level = 0, item?: GridMenuItem | MenuCommandItem | 'divider') {\n // create a new cell menu\n const maxHeight = isNaN(this._gridMenuOptions?.maxHeight as number) ? this._gridMenuOptions?.maxHeight : `${this._gridMenuOptions?.maxHeight ?? 0}px`;\n const width = isNaN(this._gridMenuOptions?.width as number) ? this._gridMenuOptions?.width : `${this._gridMenuOptions?.maxWidth ?? 0}px`;\n\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as GridMenuItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n const menuClasses = `slick-gridmenu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-gridmenu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.role = 'menu';\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Grid Menu';\n\n if (width) {\n menuElm.style.width = width as string;\n }\n if (maxHeight) {\n menuElm.style.maxHeight = maxHeight as string;\n }\n\n menuElm.style.display = 'none';\n\n let closeButtonElm: HTMLButtonElement | null = null;\n if (level === 0) {\n closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-gridmenu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n closeButtonElm.appendChild(spanCloseElm);\n menuElm.appendChild(closeButtonElm);\n }\n\n // -- Command List section\n this._commandListElm = document.createElement('div');\n this._commandListElm.className = `slick-gridmenu-custom slick-gridmenu-command-list slick-menu-level-${level}`;\n this._commandListElm.role = 'menu';\n menuElm.appendChild(this._commandListElm);\n\n const commandItems =\n (item as GridMenuItem)?.commandItems\n ?? (item as GridMenuItem)?.customItems\n ?? this._gridMenuOptions?.commandItems\n ?? this._gridMenuOptions?.customItems\n ?? [];\n\n if (commandItems.length > 0) {\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, this._commandListElm); // add sub-menu title when exists\n }\n }\n this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level });\n\n // increment level for possible next sub-menus if exists\n level++;\n\n return menuElm;\n }\n\n /** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onColumnsChanged.unsubscribe();\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this.grid.onBeforeDestroy.unsubscribe();\n this.grid.onSetOptions.unsubscribe();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this.deleteMenu();\n }\n\n /** Delete the menu DOM element but without unsubscribing any events */\n deleteMenu() {\n this._bindingEventService.unbindAll();\n const gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`);\n if (gridMenuElm) {\n gridMenuElm.style.display = 'none';\n }\n if (this._headerElm) {\n // put back original width (fixes width and frozen+gridMenu on left header)\n this._headerElm.style.width = '100%';\n }\n this._buttonElm?.remove();\n this._menuElm?.remove();\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n this._bindingEventService.unbindAll('sub-menu');\n document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Construct the custom command menu items. */\n protected populateCommandsMenu(commandItems: Array, commandListElm: HTMLElement, args: { grid: SlickGrid, level: number }) {\n // user could pass a title on top of the custom section\n const level = args?.level || 0;\n const isSubMenu = level > 0;\n if (!isSubMenu && (this._gridMenuOptions?.commandTitle || this._gridMenuOptions?.customTitle)) {\n this._commandTitleElm = document.createElement('div');\n this._commandTitleElm.className = 'title';\n this._commandTitleElm.innerHTML = (this._gridMenuOptions.commandTitle || this._gridMenuOptions.customTitle) as string;\n commandListElm.appendChild(this._commandTitleElm);\n }\n\n for (let i = 0, ln = commandItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandItems[i];\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n columns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as GridMenuItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-gridmenu-item';\n liElm.role = 'menuitem';\n\n if ((item as GridMenuItem).divider || item === 'divider') {\n liElm.classList.add('slick-gridmenu-item-divider');\n addClickListener = false;\n }\n if ((item as GridMenuItem).disabled) {\n liElm.classList.add('slick-gridmenu-item-disabled');\n }\n\n if ((item as GridMenuItem).hidden) {\n liElm.classList.add('slick-gridmenu-item-hidden');\n }\n\n if ((item as GridMenuItem).cssClass) {\n liElm.classList.add(...(item as GridMenuItem).cssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).tooltip) {\n liElm.title = (item as GridMenuItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-gridmenu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as GridMenuItem).iconCssClass) {\n iconElm.classList.add(...(item as GridMenuItem).iconCssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as GridMenuItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-gridmenu-content';\n textElm.innerHTML = (item as GridMenuItem).title || '';\n\n liElm.appendChild(textElm);\n\n if ((item as GridMenuItem).textCssClass) {\n textElm.classList.add(...(item as GridMenuItem).textCssClass!.split(' '));\n }\n\n commandListElm.appendChild(liElm);\n\n if (addClickListener) {\n const eventGroup = isSubMenu ? 'sub-menu' : 'parent-menu';\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item, level) as EventListener, undefined, eventGroup);\n }\n\n // optionally open sub-menu(s) by mouseover\n if (this._gridMenuOptions?.subMenuOpenByEvent === 'mouseover') {\n this._bindingEventService.bind(liElm, 'mouseover', ((e: DOMMouseOrTouchEvent) => {\n if ((item as GridMenuItem).commandItems || (item as GridMenuItem).customItems) {\n this.repositionSubMenu(item, level, e);\n } else if (!isSubMenu) {\n this.destroySubMenus();\n }\n }) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as GridMenuItem).commandItems || (item as GridMenuItem).customItems) {\n const chevronElm = document.createElement('span');\n chevronElm.className = 'sub-item-chevron';\n if (this._gridMenuOptions?.subItemChevronClass) {\n chevronElm.classList.add(...this._gridMenuOptions.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n liElm.classList.add('slick-submenu-item');\n liElm.appendChild(chevronElm);\n continue;\n }\n }\n }\n\n /** Build the column picker, the code comes almost untouched from the file \"slick.columnpicker.js\" */\n protected populateColumnPicker() {\n this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n // user could pass a title on top of the columns list\n if (this._gridMenuOptions?.columnTitle) {\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'title';\n this._columnTitleElm.innerHTML = this._gridMenuOptions.columnTitle;\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-gridmenu-list';\n this._listElm.role = 'menu';\n }\n\n /** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */\n recreateGridMenu() {\n this.deleteMenu();\n this.init(this.grid);\n }\n\n showGridMenu(e: DOMMouseOrTouchEvent) {\n const targetEvent = e.touches ? e.touches[0] : e;\n e.preventDefault();\n\n // empty both the picker list & the command list\n Utils.emptyElement(this._listElm);\n Utils.emptyElement(this._commandListElm);\n\n const commandItems = this._gridMenuOptions?.commandItems ?? this._gridMenuOptions?.customItems ?? [];\n this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level: 0 });\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run the override function (when defined), if the result is false it won't go further\n if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs)) {\n return;\n }\n\n // notify of the onBeforeMenuShow only works when\n // this mean that we cannot notify when the grid menu is attach to a button event\n if (typeof e.stopPropagation === 'function') {\n if (this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromGridMenu ? 'hidden' : '';\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = this.columns[i]?.name || '';\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n this._columnCheckboxes.push(checkboxElm);\n\n // get the column label from the picker value extractor (user can optionally provide a custom extractor)\n if (this._gridMenuOptions?.headerColumnValueExtractor) {\n columnLabel = this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions);\n } else {\n columnLabel = this._defaults.headerColumnValueExtractor!(this.columns[i]);\n }\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n labelElm.innerHTML = columnLabel || '';\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridMenuOptions?.hideForceFitButton)) {\n const forceFitTitle = (this._gridMenuOptions?.forceFitTitle) || this._defaults.forceFitTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle;\n liElm.role = 'menuitem';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n labelElm.textContent = forceFitTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridMenuOptions?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridMenuOptions?.syncResizeTitle) || this._defaults.syncResizeTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle;\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n let buttonElm = (e.target.nodeName === 'BUTTON' ? e.target : e.target.querySelector('button')) as HTMLButtonElement; // get button element\n if (!buttonElm) {\n buttonElm = e.target.parentElement as HTMLButtonElement; // external grid menu might fall in this last case if wrapped in a span/div\n }\n\n // we need to display the menu to properly calculate its width but we can however make it invisible\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '0';\n\n this.repositionMenu(e, this._menuElm, buttonElm);\n\n // set \"height\" when defined OR ELSE use the \"max-height\" with available window size and optional margin bottom\n const menuMarginBottom = (this._gridMenuOptions?.marginBottom !== undefined) ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom as number;\n if (this._gridMenuOptions?.height !== undefined) {\n this._menuElm.style.height = `${this._gridMenuOptions.height}px`;\n } else {\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`;\n }\n\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '1'; // restore menu visibility\n this._menuElm.appendChild(this._listElm);\n this._isMenuOpen = true;\n\n if (typeof e.stopPropagation === 'function') {\n if (this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n }\n\n protected getGridUidSelector() {\n const gridUid = this.grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if ((this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this._isMenuOpen) || e.target.className === 'close') {\n this.hideMenu(e);\n }\n }\n\n protected handleMenuItemClick(item: GridMenuItem | MenuCommandItem | 'divider', level = 0, e: DOMMouseOrTouchEvent) {\n if (item !== 'divider' && !item.disabled && !item.divider) {\n const command = item.command || '';\n\n if (Utils.isDefined(command) && !item.commandItems && !(item as GridMenuItem).customItems) {\n const callbackArgs: GridMenuCommandItemCallbackArgs = {\n grid: this.grid,\n command,\n item,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n (item as MenuCommandItem).action!.call(this, e, callbackArgs);\n }\n\n // does the user want to leave open the Grid Menu after executing a command?\n const leaveOpen = !!(this._gridMenuOptions?.leaveOpen);\n if (!leaveOpen && !e.defaultPrevented) {\n this.hideMenu(e);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n } else if (item.commandItems || (item as GridMenuItem).customItems) {\n this.repositionSubMenu(item, level, e);\n } else {\n this.destroySubMenus();\n }\n }\n }\n\n hideMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm) {\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n if (this._isMenuOpen && this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n this._isMenuOpen = false;\n Utils.hide(this._menuElm);\n }\n this.destroySubMenus();\n }\n\n /** Update the Titles of each sections (command, commandTitle, ...) */\n updateAllTitles(gridMenuOptions: GridMenuOption) {\n if (this._commandTitleElm?.innerHTML) {\n this._commandTitleElm.innerHTML = gridMenuOptions.commandTitle || gridMenuOptions.customTitle || '';\n }\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = gridMenuOptions.columnTitle || '';\n }\n }\n\n protected addSubMenuTitleWhenExists(item: GridMenuItem | MenuCommandItem | 'divider', commandOrOptionMenu: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandOrOptionMenu.appendChild(subMenuTitleElm);\n }\n }\n\n protected repositionSubMenu(item: GridMenuItem | MenuCommandItem | 'divider', level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-cell')) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu(level + 1, item);\n subMenuElm.style.display = 'block';\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n protected repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLElement, buttonElm?: HTMLButtonElement) {\n const targetEvent = e.touches ? e.touches[0] : e;\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const parentElm = isSubMenu\n ? e.target.closest('.slick-gridmenu-item') as HTMLDivElement\n : targetEvent.target as HTMLElement;\n\n const menuIconOffset = Utils.offset(buttonElm || this._buttonElm); // get button offset position\n const menuWidth = menuElm.offsetWidth;\n const useClickToRepositionMenu = (this._gridMenuOptions?.useClickToRepositionMenu !== undefined) ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu;\n const contentMinWidth = (this._gridMenuOptions?.contentMinWidth) ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth as number;\n const currentMenuWidth = (contentMinWidth > menuWidth) ? contentMinWidth : menuWidth + 5;\n let menuOffsetTop = (useClickToRepositionMenu && targetEvent.pageY > 0) ? targetEvent.pageY : menuIconOffset!.top + 10;\n let menuOffsetLeft = (useClickToRepositionMenu && targetEvent.pageX > 0) ? targetEvent.pageX : menuIconOffset!.left + 10;\n\n if (isSubMenu && parentElm) {\n const parentOffset = Utils.offset(parentElm);\n menuOffsetLeft = parentOffset?.left ?? 0;\n menuOffsetTop = parentOffset?.top ?? 0;\n const gridPos = this.grid.getGridPosition();\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n menuOffsetLeft -= menuWidth;\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += parentElm.offsetWidth;\n }\n }\n } else {\n menuOffsetTop += 10;\n menuOffsetLeft = menuOffsetLeft - currentMenuWidth + 10;\n }\n\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n\n if (contentMinWidth > 0) {\n this._menuElm.style.minWidth = `${contentMinWidth}px`;\n }\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n this.grid.setOptions({ syncColumnCellResize: !!(e.target.checked) });\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (columnCheckbox.checked) {\n if (this.columns[idx].hidden) { this.columns[idx].hidden = false; }\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n const callbackArgs = {\n columnId,\n showing: isChecked,\n grid: this.grid,\n allColumns: this.columns,\n columns: visibleColumns,\n visibleColumns: this.getVisibleColumns()\n };\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify(callbackArgs, e, this);\n }\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.GridMenu = SlickGridMenu;\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type {\n Column,\n DOMMouseOrTouchEvent,\n GridMenuCommandItemCallbackArgs,\n GridMenuEventWithElementCallbackArgs,\n GridMenuItem,\n GridMenuOption,\n GridOption,\n MenuCommandItem,\n onGridMenuColumnsChangedCallbackArgs\n} from '../models/index';\nimport { BindingEventService as BindingEventService_, Event as SlickEvent_, Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A control to add a Grid Menu (hambuger menu on top-right of the grid)\n *\n * USAGE:\n *\n * Add the slick.gridmenu.(js|css) files and register it with the grid.\n *\n * To specify a menu in a column header, extend the column definition like so:\n * let gridMenuControl = new Slick.Controls.GridMenu(columns, grid, options);\n *\n * Available grid options, by defining a gridMenu object:\n *\n * let options = {\n * enableCellNavigation: true,\n * gridMenu: {\n * commandTitle: \"Command List\", // default to empty string\n * columnTitle: \"Columns\", // default to empty string\n * iconImage: \"some-image.png\", // this is the Grid Menu icon (hamburger icon)\n * iconCssClass: \"fa fa-bars\", // you can provide iconImage OR iconCssClass\n * leaveOpen: false, // do we want to leave the Grid Menu open after a command execution? (false by default)\n * menuWidth: 18, // width (icon) that will be use to resize the column header container (18 by default)\n * contentMinWidth: 0,\t\t\t\t\t\t\t // defaults to 0 (auto), minimum width of grid menu content (command, column list)\n * marginBottom: 15, // defaults to 15, margin to use at the bottom of the grid when using max-height (default)\n * resizeOnShowHeaderRow: false, // false by default\n * showButton: true, // true by default - it allows the user to control if the\n * // default gridMenu button (located on the top right corner by default CSS)\n * // should be created or omitted\n * useClickToRepositionMenu: true, // true by default\n *\n * // the last 2 checkboxes titles\n * hideForceFitButton: false, // show/hide checkbox near the end \"Force Fit Columns\"\n * hideSyncResizeButton: false, // show/hide checkbox near the end \"Synchronous Resize\"\n * forceFitTitle: \"Force fit columns\", // default to \"Force fit columns\"\n * syncResizeTitle: \"Synchronous resize\", // default to \"Synchronous resize\"\n *\n * commandItems: [\n * {\n * // command menu item options\n * },\n * {\n * // command menu item options\n * }\n * ]\n * }\n * };\n *\n *\n * Available menu options:\n * hideForceFitButton: Hide the \"Force fit columns\" button (defaults to false)\n * hideSyncResizeButton: Hide the \"Synchronous resize\" button (defaults to false)\n * forceFitTitle: Text of the title \"Force fit columns\"\n * contentMinWidth:\t\t\t\t\t\tminimum width of grid menu content (command, column list), defaults to 0 (auto)\n * height: Height of the Grid Menu content, when provided it will be used instead of the max-height (defaults to undefined)\n * menuWidth: Grid menu button width (defaults to 18)\n * resizeOnShowHeaderRow: Do we want to resize on the show header row event\n * syncResizeTitle: Text of the title \"Synchronous resize\"\n * useClickToRepositionMenu: Use the Click offset to reposition the Grid Menu (defaults to true), when set to False it will use the icon offset to reposition the grid menu\n * menuUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling the menu from being usable (must be combined with a custom formatter)\n * marginBottom: Margin to use at the bottom of the grid menu, only in effect when height is undefined (defaults to 15)\n * subItemChevronClass: CSS class that can be added on the right side of a sub-item parent (typically a chevron-right icon)\n * subMenuOpenByEvent: defaults to \"mouseover\", what event type shoud we use to open sub-menu(s), 2 options are available: \"mouseover\" or \"click\"\n *\n * Available command menu item options:\n * action: Optionally define a callback function that gets executed when item is chosen (and/or use the onCommand event)\n * title: Menu item text.\n * divider: Whether the current item is a divider, not an actual command.\n * disabled: Whether the item/command is disabled.\n * hidden: Whether the item/command is hidden.\n * tooltip: Item tooltip.\n * command: A command identifier to be passed to the onCommand event handlers.\n * cssClass: A CSS class to be added to the menu item container.\n * iconCssClass: A CSS class to be added to the menu item icon.\n * iconImage: A url to the icon image.\n * textCssClass: A CSS class to be added to the menu item text.\n * subMenuTitle: Optional sub-menu title that will shows up when sub-menu commmands/options list is opened\n * subMenuTitleCssClass: Optional sub-menu title CSS class to use with `subMenuTitle`\n * itemVisibilityOverride: Callback method that user can override the default behavior of showing/hiding an item from the list\n * itemUsabilityOverride: Callback method that user can override the default behavior of enabling/disabling an item from the list\n *\n *\n * The plugin exposes the following events:\n *\n * onAfterMenuShow: Fired after the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onBeforeMenuShow: Fired before the menu is shown. You can customize the menu or dismiss it by returning false.\n * * ONLY works with a JS event (as per slick.core code), so we cannot notify when it's a button event (when grid menu is attached to an external button, not the hamburger menu)\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onMenuClose: Fired when the menu is closing.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * menu: Menu options. Note that you can change the menu items here.\n *\n * onCommand: Fired on menu item click for buttons with 'command' specified.\n * Event args:\n * grid: Reference to the grid.\n * column: Column definition.\n * command: Button command identified.\n * button: Button options. Note that you can change the button options in your\n * event handler, and the column header will be automatically updated to\n * reflect them. This is useful if you want to implement something like a\n * toggle button.\n */\n\nexport class SlickGridMenu {\n // --\n // public API\n onAfterMenuShow = new SlickEvent();\n onBeforeMenuShow = new SlickEvent();\n onMenuClose = new SlickEvent();\n onCommand = new SlickEvent();\n onColumnsChanged = new SlickEvent();\n\n // --\n // protected props\n protected _bindingEventService: BindingEventService_;\n protected _gridOptions: GridOption;\n protected _gridUid: string;\n protected _isMenuOpen = false;\n protected _columnCheckboxes: HTMLInputElement[] = [];\n protected _columnTitleElm!: HTMLElement;\n protected _commandTitleElm!: HTMLElement;\n protected _commandListElm!: HTMLDivElement;\n protected _headerElm: HTMLDivElement | null = null;\n protected _listElm!: HTMLElement;\n protected _buttonElm!: HTMLElement;\n protected _menuElm!: HTMLElement;\n protected _subMenuParentId = '';\n protected _gridMenuOptions: GridMenuOption | null = null;\n protected _defaults: GridMenuOption = {\n showButton: true,\n hideForceFitButton: false,\n hideSyncResizeButton: false,\n forceFitTitle: 'Force fit columns',\n marginBottom: 15,\n menuWidth: 18,\n contentMinWidth: 0,\n resizeOnShowHeaderRow: false,\n subMenuOpenByEvent: 'mouseover',\n syncResizeTitle: 'Synchronous resize',\n useClickToRepositionMenu: true,\n headerColumnValueExtractor: (columnDef: Column) => columnDef.name instanceof HTMLElement ? columnDef.name.innerHTML : columnDef.name || '',\n };\n\n constructor(protected columns: Column[], protected readonly grid: SlickGrid, gridOptions: GridOption) {\n this._gridUid = grid.getUID();\n this._gridOptions = gridOptions;\n this._gridMenuOptions = Utils.extend({}, this._defaults, gridOptions.gridMenu);\n this._bindingEventService = new BindingEventService();\n\n // when a grid optionally changes from a regular grid to a frozen grid, we need to destroy & recreate the grid menu\n // we do this change because the Grid Menu is on the left container for a regular grid, it is however on the right container for a frozen grid\n grid.onSetOptions.subscribe((_e, args) => {\n if (args && args.optionsBefore && args.optionsAfter) {\n const switchedFromRegularToFrozen = args.optionsBefore.frozenColumn! >= 0 && args.optionsAfter.frozenColumn === -1;\n const switchedFromFrozenToRegular = args.optionsBefore.frozenColumn === -1 && args.optionsAfter.frozenColumn! >= 0;\n if (switchedFromRegularToFrozen || switchedFromFrozenToRegular) {\n this.recreateGridMenu();\n }\n }\n });\n this.init(this.grid);\n }\n\n init(grid: SlickGrid) {\n this._gridOptions = grid.getOptions();\n this.createGridMenu();\n\n if (this._gridMenuOptions?.customItems || this._gridMenuOptions?.customTitle) {\n console.warn('[SlickGrid] Grid Menu \"customItems\" and \"customTitle\" were deprecated to align with other Menu plugins, please use \"commandItems\" and \"commandTitle\" instead.');\n }\n\n // subscribe to the grid, when it's destroyed, we should also destroy the Grid Menu\n grid.onBeforeDestroy.subscribe(this.destroy.bind(this));\n }\n\n setOptions(newOptions: GridMenuOption) {\n this._gridMenuOptions = Utils.extend({}, this._gridMenuOptions, newOptions);\n }\n\n protected createGridMenu() {\n const gridMenuWidth = (this._gridMenuOptions?.menuWidth) || this._defaults.menuWidth;\n if (this._gridOptions && this._gridOptions.hasOwnProperty('frozenColumn') && this._gridOptions.frozenColumn! >= 0) {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`);\n } else {\n this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`);\n }\n this._headerElm!.style.width = `calc(100% - ${gridMenuWidth}px)`;\n\n // if header row is enabled, we need to resize its width also\n const enableResizeHeaderRow = (Utils.isDefined(this._gridMenuOptions?.resizeOnShowHeaderRow)) ? this._gridMenuOptions!.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow;\n if (enableResizeHeaderRow && this._gridOptions.showHeaderRow) {\n const headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`);\n if (headerRow) {\n headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`;\n }\n }\n\n const showButton = (this._gridMenuOptions?.showButton !== undefined) ? this._gridMenuOptions.showButton : this._defaults.showButton;\n if (showButton) {\n this._buttonElm = document.createElement('button');\n this._buttonElm.className = 'slick-gridmenu-button';\n this._buttonElm.ariaLabel = 'Grid Menu';\n\n if (this._gridMenuOptions?.iconCssClass) {\n this._buttonElm.classList.add(...this._gridMenuOptions.iconCssClass.split(' '));\n } else {\n const iconImageElm = document.createElement('img');\n iconImageElm.src = (this._gridMenuOptions?.iconImage) ? this._gridMenuOptions.iconImage : '../images/drag-handle.png';\n this._buttonElm.appendChild(iconImageElm);\n }\n\n this._headerElm!.parentElement!.insertBefore(this._buttonElm, this._headerElm!.parentElement!.firstChild);\n\n // add on click handler for the Grid Menu itself\n this._bindingEventService.bind(this._buttonElm, 'click', this.showGridMenu.bind(this) as EventListener);\n }\n\n this._menuElm = this.createMenu(0);\n this.populateColumnPicker();\n document.body.appendChild(this._menuElm);\n\n // Hide the menu on outside click.\n this._bindingEventService.bind(document.body, 'mousedown', this.handleBodyMouseDown.bind(this) as EventListener);\n\n // destroy the picker if user leaves the page\n this._bindingEventService.bind(document.body, 'beforeunload', this.destroy.bind(this));\n }\n\n /** Create the menu or sub-menu(s) but without the column picker which is a separate single process */\n createMenu(level = 0, item?: GridMenuItem | MenuCommandItem | 'divider') {\n // create a new cell menu\n const maxHeight = isNaN(this._gridMenuOptions?.maxHeight as number) ? this._gridMenuOptions?.maxHeight : `${this._gridMenuOptions?.maxHeight ?? 0}px`;\n const width = isNaN(this._gridMenuOptions?.width as number) ? this._gridMenuOptions?.width : `${this._gridMenuOptions?.maxWidth ?? 0}px`;\n\n // to avoid having multiple sub-menu trees opened,\n // we need to somehow keep trace of which parent menu the tree belongs to\n // and we should keep ref of only the first sub-menu parent, we can use the command name (remove any whitespaces though)\n const subMenuCommand = (item as GridMenuItem)?.command;\n let subMenuId = (level === 1 && subMenuCommand) ? subMenuCommand.replaceAll(' ', '') : '';\n if (subMenuId) {\n this._subMenuParentId = subMenuId;\n }\n if (level > 1) {\n subMenuId = this._subMenuParentId;\n }\n\n const menuClasses = `slick-gridmenu slick-menu-level-${level} ${this._gridUid}`;\n const bodyMenuElm = document.body.querySelector(`.slick-gridmenu.slick-menu-level-${level}${this.getGridUidSelector()}`);\n\n // return menu/sub-menu if it's already opened unless we are on different sub-menu tree if so close them all\n if (bodyMenuElm) {\n if (bodyMenuElm.dataset.subMenuParent === subMenuId) {\n return bodyMenuElm;\n }\n this.destroySubMenus();\n }\n\n const menuElm = document.createElement('div');\n menuElm.role = 'menu';\n menuElm.className = menuClasses;\n if (level > 0) {\n menuElm.classList.add('slick-submenu');\n if (subMenuId) {\n menuElm.dataset.subMenuParent = subMenuId;\n }\n }\n menuElm.ariaLabel = level > 1 ? 'SubMenu' : 'Grid Menu';\n\n if (width) {\n menuElm.style.width = width as string;\n }\n if (maxHeight) {\n menuElm.style.maxHeight = maxHeight as string;\n }\n\n menuElm.style.display = 'none';\n\n let closeButtonElm: HTMLButtonElement | null = null;\n if (level === 0) {\n closeButtonElm = document.createElement('button');\n closeButtonElm.type = 'button';\n closeButtonElm.className = 'close';\n closeButtonElm.dataset.dismiss = 'slick-gridmenu';\n closeButtonElm.ariaLabel = 'Close';\n\n const spanCloseElm = document.createElement('span');\n spanCloseElm.className = 'close';\n spanCloseElm.ariaHidden = 'true';\n spanCloseElm.textContent = '\u00D7';\n closeButtonElm.appendChild(spanCloseElm);\n menuElm.appendChild(closeButtonElm);\n }\n\n // -- Command List section\n this._commandListElm = document.createElement('div');\n this._commandListElm.className = `slick-gridmenu-custom slick-gridmenu-command-list slick-menu-level-${level}`;\n this._commandListElm.role = 'menu';\n menuElm.appendChild(this._commandListElm);\n\n const commandItems =\n (item as GridMenuItem)?.commandItems\n ?? (item as GridMenuItem)?.customItems\n ?? this._gridMenuOptions?.commandItems\n ?? this._gridMenuOptions?.customItems\n ?? [];\n\n if (commandItems.length > 0) {\n\n // when creating sub-menu add its sub-menu title when exists\n if (item && level > 0) {\n this.addSubMenuTitleWhenExists(item, this._commandListElm); // add sub-menu title when exists\n }\n }\n this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level });\n\n // increment level for possible next sub-menus if exists\n level++;\n\n return menuElm;\n }\n\n /** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */\n destroy() {\n this.onAfterMenuShow.unsubscribe();\n this.onBeforeMenuShow.unsubscribe();\n this.onMenuClose.unsubscribe();\n this.onCommand.unsubscribe();\n this.onColumnsChanged.unsubscribe();\n this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this));\n this.grid.onBeforeDestroy.unsubscribe();\n this.grid.onSetOptions.unsubscribe();\n this._bindingEventService.unbindAll();\n this._menuElm?.remove();\n this.deleteMenu();\n }\n\n /** Delete the menu DOM element but without unsubscribing any events */\n deleteMenu() {\n this._bindingEventService.unbindAll();\n const gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`);\n if (gridMenuElm) {\n gridMenuElm.style.display = 'none';\n }\n if (this._headerElm) {\n // put back original width (fixes width and frozen+gridMenu on left header)\n this._headerElm.style.width = '100%';\n }\n this._buttonElm?.remove();\n this._menuElm?.remove();\n }\n\n /** Close and destroy all previously opened sub-menus */\n destroySubMenus() {\n this._bindingEventService.unbindAll('sub-menu');\n document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => subElm.remove());\n }\n\n /** Construct the custom command menu items. */\n protected populateCommandsMenu(commandItems: Array, commandListElm: HTMLElement, args: { grid: SlickGrid, level: number }) {\n // user could pass a title on top of the custom section\n const level = args?.level || 0;\n const isSubMenu = level > 0;\n if (!isSubMenu && (this._gridMenuOptions?.commandTitle || this._gridMenuOptions?.customTitle)) {\n this._commandTitleElm = document.createElement('div');\n this._commandTitleElm.className = 'title';\n this._commandTitleElm.innerHTML = this.grid.sanitizeHtmlString((this._gridMenuOptions.commandTitle || this._gridMenuOptions.customTitle) as string);\n commandListElm.appendChild(this._commandTitleElm);\n }\n\n for (let i = 0, ln = commandItems.length; i < ln; i++) {\n let addClickListener = true;\n const item = commandItems[i];\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n columns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run each override functions to know if the item is visible and usable\n const isItemVisible = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemVisibilityOverride, callbackArgs);\n const isItemUsable = this.runOverrideFunctionWhenExists((item as GridMenuItem).itemUsabilityOverride, callbackArgs);\n\n // if the result is not visible then there's no need to go further\n if (!isItemVisible) {\n continue;\n }\n\n // when the override is defined, we need to use its result to update the disabled property\n // so that \"handleMenuItemClick\" has the correct flag and won't trigger a command clicked event\n if (Object.prototype.hasOwnProperty.call(item, 'itemUsabilityOverride')) {\n (item as GridMenuItem).disabled = isItemUsable ? false : true;\n }\n\n const liElm = document.createElement('div');\n liElm.className = 'slick-gridmenu-item';\n liElm.role = 'menuitem';\n\n if ((item as GridMenuItem).divider || item === 'divider') {\n liElm.classList.add('slick-gridmenu-item-divider');\n addClickListener = false;\n }\n if ((item as GridMenuItem).disabled) {\n liElm.classList.add('slick-gridmenu-item-disabled');\n }\n\n if ((item as GridMenuItem).hidden) {\n liElm.classList.add('slick-gridmenu-item-hidden');\n }\n\n if ((item as GridMenuItem).cssClass) {\n liElm.classList.add(...(item as GridMenuItem).cssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).tooltip) {\n liElm.title = (item as GridMenuItem).tooltip || '';\n }\n\n const iconElm = document.createElement('div');\n iconElm.className = 'slick-gridmenu-icon';\n\n liElm.appendChild(iconElm);\n\n if ((item as GridMenuItem).iconCssClass) {\n iconElm.classList.add(...(item as GridMenuItem).iconCssClass!.split(' '));\n }\n\n if ((item as GridMenuItem).iconImage) {\n iconElm.style.backgroundImage = `url(${(item as GridMenuItem).iconImage})`;\n }\n\n const textElm = document.createElement('span');\n textElm.className = 'slick-gridmenu-content';\n textElm.innerHTML = this.grid.sanitizeHtmlString((item as GridMenuItem).title || '');\n\n liElm.appendChild(textElm);\n\n if ((item as GridMenuItem).textCssClass) {\n textElm.classList.add(...(item as GridMenuItem).textCssClass!.split(' '));\n }\n\n commandListElm.appendChild(liElm);\n\n if (addClickListener) {\n const eventGroup = isSubMenu ? 'sub-menu' : 'parent-menu';\n this._bindingEventService.bind(liElm, 'click', this.handleMenuItemClick.bind(this, item, level) as EventListener, undefined, eventGroup);\n }\n\n // optionally open sub-menu(s) by mouseover\n if (this._gridMenuOptions?.subMenuOpenByEvent === 'mouseover') {\n this._bindingEventService.bind(liElm, 'mouseover', ((e: DOMMouseOrTouchEvent) => {\n if ((item as GridMenuItem).commandItems || (item as GridMenuItem).customItems) {\n this.repositionSubMenu(item, level, e);\n } else if (!isSubMenu) {\n this.destroySubMenus();\n }\n }) as EventListener);\n }\n\n // the option/command item could be a sub-menu if it has another list of commands/options\n if ((item as GridMenuItem).commandItems || (item as GridMenuItem).customItems) {\n const chevronElm = document.createElement('span');\n chevronElm.className = 'sub-item-chevron';\n if (this._gridMenuOptions?.subItemChevronClass) {\n chevronElm.classList.add(...this._gridMenuOptions.subItemChevronClass.split(' '));\n } else {\n chevronElm.textContent = '\u2B9E'; // \u2B9E or \u25B8\n }\n\n liElm.classList.add('slick-submenu-item');\n liElm.appendChild(chevronElm);\n continue;\n }\n }\n }\n\n /** Build the column picker, the code comes almost untouched from the file \"slick.columnpicker.js\" */\n protected populateColumnPicker() {\n this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this));\n\n // user could pass a title on top of the columns list\n if (this._gridMenuOptions?.columnTitle) {\n this._columnTitleElm = document.createElement('div');\n this._columnTitleElm.className = 'title';\n this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(this._gridMenuOptions.columnTitle);\n this._menuElm.appendChild(this._columnTitleElm);\n }\n\n this._bindingEventService.bind(this._menuElm, 'click', this.updateColumn.bind(this) as EventListener);\n this._listElm = document.createElement('span');\n this._listElm.className = 'slick-gridmenu-list';\n this._listElm.role = 'menu';\n }\n\n /** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */\n recreateGridMenu() {\n this.deleteMenu();\n this.init(this.grid);\n }\n\n showGridMenu(e: DOMMouseOrTouchEvent) {\n const targetEvent = e.touches ? e.touches[0] : e;\n e.preventDefault();\n\n // empty both the picker list & the command list\n Utils.emptyElement(this._listElm);\n Utils.emptyElement(this._commandListElm);\n\n const commandItems = this._gridMenuOptions?.commandItems ?? this._gridMenuOptions?.customItems ?? [];\n this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level: 0 });\n this.updateColumnOrder();\n this._columnCheckboxes = [];\n\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n\n // run the override function (when defined), if the result is false it won't go further\n if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs)) {\n return;\n }\n\n // notify of the onBeforeMenuShow only works when\n // this mean that we cannot notify when the grid menu is attach to a button event\n if (typeof e.stopPropagation === 'function') {\n if (this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n\n let columnId, columnLabel, excludeCssClass;\n for (let i = 0; i < this.columns.length; i++) {\n columnId = this.columns[i].id;\n excludeCssClass = this.columns[i].excludeFromGridMenu ? 'hidden' : '';\n const colName: string = this.columns[i].name instanceof HTMLElement\n ? (this.columns[i].name as HTMLElement).innerHTML\n : (this.columns[i].name || '') as string;\n\n const liElm = document.createElement('li');\n liElm.className = excludeCssClass;\n liElm.ariaLabel = colName;\n\n const checkboxElm = document.createElement('input');\n checkboxElm.type = 'checkbox';\n checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n checkboxElm.dataset.columnid = String(this.columns[i].id);\n liElm.appendChild(checkboxElm);\n\n if (Utils.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden) {\n checkboxElm.checked = true;\n }\n\n this._columnCheckboxes.push(checkboxElm);\n\n // get the column label from the picker value extractor (user can optionally provide a custom extractor)\n columnLabel = (this._gridMenuOptions?.headerColumnValueExtractor)\n ? this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions)\n : this._defaults.headerColumnValueExtractor!(this.columns[i]);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`;\n labelElm.innerHTML = this.grid.sanitizeHtmlString(columnLabel || '');\n liElm.appendChild(labelElm);\n this._listElm.appendChild(liElm);\n }\n\n if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton)) {\n this._listElm.appendChild(document.createElement('hr'));\n }\n\n if (!(this._gridMenuOptions?.hideForceFitButton)) {\n const forceFitTitle = (this._gridMenuOptions?.forceFitTitle) || this._defaults.forceFitTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = forceFitTitle;\n liElm.role = 'menuitem';\n this._listElm.appendChild(liElm);\n\n const forceFitCheckboxElm = document.createElement('input');\n forceFitCheckboxElm.type = 'checkbox';\n forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n forceFitCheckboxElm.dataset.option = 'autoresize';\n liElm.appendChild(forceFitCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`;\n labelElm.textContent = forceFitTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().forceFitColumns) {\n forceFitCheckboxElm.checked = true;\n }\n }\n\n if (!(this._gridMenuOptions?.hideSyncResizeButton)) {\n const syncResizeTitle = (this._gridMenuOptions?.syncResizeTitle) || this._defaults.syncResizeTitle as string;\n\n const liElm = document.createElement('li');\n liElm.ariaLabel = syncResizeTitle;\n this._listElm.appendChild(liElm);\n\n const syncResizeCheckboxElm = document.createElement('input');\n syncResizeCheckboxElm.type = 'checkbox';\n syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n syncResizeCheckboxElm.dataset.option = 'syncresize';\n liElm.appendChild(syncResizeCheckboxElm);\n\n const labelElm = document.createElement('label');\n labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`;\n labelElm.textContent = syncResizeTitle;\n liElm.appendChild(labelElm);\n\n if (this.grid.getOptions().syncColumnCellResize) {\n syncResizeCheckboxElm.checked = true;\n }\n }\n\n let buttonElm = (e.target.nodeName === 'BUTTON' ? e.target : e.target.querySelector('button')) as HTMLButtonElement; // get button element\n if (!buttonElm) {\n buttonElm = e.target.parentElement as HTMLButtonElement; // external grid menu might fall in this last case if wrapped in a span/div\n }\n\n // we need to display the menu to properly calculate its width but we can however make it invisible\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '0';\n\n this.repositionMenu(e, this._menuElm, buttonElm);\n\n // set \"height\" when defined OR ELSE use the \"max-height\" with available window size and optional margin bottom\n const menuMarginBottom = (this._gridMenuOptions?.marginBottom !== undefined) ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom as number;\n if (this._gridMenuOptions?.height !== undefined) {\n this._menuElm.style.height = `${this._gridMenuOptions.height}px`;\n } else {\n this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`;\n }\n\n this._menuElm.style.display = 'block';\n this._menuElm.style.opacity = '1'; // restore menu visibility\n this._menuElm.appendChild(this._listElm);\n this._isMenuOpen = true;\n\n if (typeof e.stopPropagation === 'function') {\n if (this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n }\n }\n\n protected getGridUidSelector() {\n const gridUid = this.grid.getUID() || '';\n return gridUid ? `.${gridUid}` : '';\n }\n\n protected handleBodyMouseDown(e: DOMMouseOrTouchEvent) {\n // did we click inside the menu or any of its sub-menu(s)\n let isMenuClicked = false;\n if (this._menuElm?.contains(e.target)) {\n isMenuClicked = true;\n }\n if (!isMenuClicked) {\n document\n .querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`)\n .forEach(subElm => {\n if (subElm.contains(e.target)) {\n isMenuClicked = true;\n }\n });\n }\n\n if ((this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this._isMenuOpen) || e.target.className === 'close') {\n this.hideMenu(e);\n }\n }\n\n protected handleMenuItemClick(item: GridMenuItem | MenuCommandItem | 'divider', level = 0, e: DOMMouseOrTouchEvent) {\n if (item !== 'divider' && !item.disabled && !item.divider) {\n const command = item.command || '';\n\n if (Utils.isDefined(command) && !item.commandItems && !(item as GridMenuItem).customItems) {\n const callbackArgs: GridMenuCommandItemCallbackArgs = {\n grid: this.grid,\n command,\n item,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n this.onCommand.notify(callbackArgs, e, this);\n\n // execute action callback when defined\n if (typeof item.action === 'function') {\n (item as MenuCommandItem).action!.call(this, e, callbackArgs);\n }\n\n // does the user want to leave open the Grid Menu after executing a command?\n const leaveOpen = !!(this._gridMenuOptions?.leaveOpen);\n if (!leaveOpen && !e.defaultPrevented) {\n this.hideMenu(e);\n }\n\n // Stop propagation so that it doesn't register as a header click event.\n e.preventDefault();\n e.stopPropagation();\n } else if (item.commandItems || (item as GridMenuItem).customItems) {\n this.repositionSubMenu(item, level, e);\n } else {\n this.destroySubMenus();\n }\n }\n }\n\n hideMenu(e: DOMMouseOrTouchEvent) {\n if (this._menuElm) {\n const callbackArgs = {\n grid: this.grid,\n menu: this._menuElm,\n allColumns: this.columns,\n visibleColumns: this.getVisibleColumns()\n };\n if (this._isMenuOpen && this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() === false) {\n return;\n }\n this._isMenuOpen = false;\n Utils.hide(this._menuElm);\n }\n this.destroySubMenus();\n }\n\n /** Update the Titles of each sections (command, commandTitle, ...) */\n updateAllTitles(gridMenuOptions: GridMenuOption) {\n if (this._commandTitleElm?.innerHTML) {\n this._commandTitleElm.innerHTML = this.grid.sanitizeHtmlString(gridMenuOptions.commandTitle || gridMenuOptions.customTitle || '');\n }\n if (this._columnTitleElm?.innerHTML) {\n this._columnTitleElm.innerHTML = this.grid.sanitizeHtmlString(gridMenuOptions.columnTitle || '');\n }\n }\n\n protected addSubMenuTitleWhenExists(item: GridMenuItem | MenuCommandItem | 'divider', commandOrOptionMenu: HTMLDivElement) {\n if (item !== 'divider' && item?.subMenuTitle) {\n const subMenuTitleElm = document.createElement('div');\n subMenuTitleElm.className = 'slick-menu-title';\n subMenuTitleElm.textContent = item.subMenuTitle as string;\n const subMenuTitleClass = item.subMenuTitleCssClass as string;\n if (subMenuTitleClass) {\n subMenuTitleElm.classList.add(...subMenuTitleClass.split(' '));\n }\n\n commandOrOptionMenu.appendChild(subMenuTitleElm);\n }\n }\n\n protected repositionSubMenu(item: GridMenuItem | MenuCommandItem | 'divider', level: number, e: DOMMouseOrTouchEvent) {\n // when we're clicking a grid cell OR our last menu type (command/option) differs then we know that we need to start fresh and close any sub-menus that might still be open\n if (e.target.classList.contains('slick-cell')) {\n this.destroySubMenus();\n }\n\n // creating sub-menu, we'll also pass level & the item object since we might have \"subMenuTitle\" to show\n const subMenuElm = this.createMenu(level + 1, item);\n subMenuElm.style.display = 'block';\n document.body.appendChild(subMenuElm);\n this.repositionMenu(e, subMenuElm);\n }\n\n /**\n * Reposition the menu drop (up/down) and the side (left/right)\n * @param {*} event\n */\n protected repositionMenu(e: DOMMouseOrTouchEvent, menuElm: HTMLElement, buttonElm?: HTMLButtonElement) {\n const targetEvent = e.touches ? e.touches[0] : e;\n const isSubMenu = menuElm.classList.contains('slick-submenu');\n const parentElm = isSubMenu\n ? e.target.closest('.slick-gridmenu-item') as HTMLDivElement\n : targetEvent.target as HTMLElement;\n\n const menuIconOffset = Utils.offset(buttonElm || this._buttonElm); // get button offset position\n const menuWidth = menuElm.offsetWidth;\n const useClickToRepositionMenu = (this._gridMenuOptions?.useClickToRepositionMenu !== undefined) ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu;\n const contentMinWidth = (this._gridMenuOptions?.contentMinWidth) ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth as number;\n const currentMenuWidth = (contentMinWidth > menuWidth) ? contentMinWidth : menuWidth + 5;\n let menuOffsetTop = (useClickToRepositionMenu && targetEvent.pageY > 0) ? targetEvent.pageY : menuIconOffset!.top + 10;\n let menuOffsetLeft = (useClickToRepositionMenu && targetEvent.pageX > 0) ? targetEvent.pageX : menuIconOffset!.left + 10;\n\n if (isSubMenu && parentElm) {\n const parentOffset = Utils.offset(parentElm);\n menuOffsetLeft = parentOffset?.left ?? 0;\n menuOffsetTop = parentOffset?.top ?? 0;\n const gridPos = this.grid.getGridPosition();\n let subMenuPosCalc = menuOffsetLeft + Number(menuWidth); // calculate coordinate at caller element far right\n if (isSubMenu) {\n subMenuPosCalc += parentElm.clientWidth;\n }\n const browserWidth = document.documentElement.clientWidth;\n const dropSide = (subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth) ? 'left' : 'right';\n if (dropSide === 'left') {\n menuElm.classList.remove('dropright');\n menuElm.classList.add('dropleft');\n menuOffsetLeft -= menuWidth;\n } else {\n menuElm.classList.remove('dropleft');\n menuElm.classList.add('dropright');\n if (isSubMenu) {\n menuOffsetLeft += parentElm.offsetWidth;\n }\n }\n } else {\n menuOffsetTop += 10;\n menuOffsetLeft = menuOffsetLeft - currentMenuWidth + 10;\n }\n\n menuElm.style.top = `${menuOffsetTop}px`;\n menuElm.style.left = `${menuOffsetLeft}px`;\n\n if (contentMinWidth > 0) {\n this._menuElm.style.minWidth = `${contentMinWidth}px`;\n }\n }\n\n protected updateColumnOrder() {\n // Because columns can be reordered, we have to update the `columns`\n // to reflect the new order, however we can't just take `grid.getColumns()`,\n // as it does not include columns currently hidden by the picker.\n // We create a new `columns` structure by leaving currently-hidden\n // columns in their original ordinal position and interleaving the results\n // of the current column sort.\n const current = this.grid.getColumns().slice(0);\n const ordered = new Array(this.columns.length);\n for (let i = 0; i < ordered.length; i++) {\n if (this.grid.getColumnIndex(this.columns[i].id) === undefined) {\n // If the column doesn't return a value from getColumnIndex,\n // it is hidden. Leave it in this position.\n ordered[i] = this.columns[i];\n } else {\n // Otherwise, grab the next visible column.\n ordered[i] = current.shift();\n }\n }\n this.columns = ordered;\n }\n\n protected updateColumn(e: DOMMouseOrTouchEvent) {\n if (e.target.dataset.option === 'autoresize') {\n // when calling setOptions, it will resize with ALL Columns (even the hidden ones)\n // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after\n const previousVisibleColumns = this.getVisibleColumns();\n const isChecked = e.target.checked;\n this.grid.setOptions({ forceFitColumns: isChecked });\n this.grid.setColumns(previousVisibleColumns);\n return;\n }\n\n if (e.target.dataset.option === 'syncresize') {\n this.grid.setOptions({ syncColumnCellResize: !!(e.target.checked) });\n return;\n }\n\n if (e.target.type === 'checkbox') {\n const isChecked = e.target.checked;\n const columnId = e.target.dataset.columnid || '';\n const visibleColumns: Column[] = [];\n this._columnCheckboxes.forEach((columnCheckbox, idx) => {\n if (columnCheckbox.checked) {\n if (this.columns[idx].hidden) { this.columns[idx].hidden = false; }\n visibleColumns.push(this.columns[idx]);\n }\n });\n\n if (!visibleColumns.length) {\n e.target.checked = true;\n return;\n }\n\n const callbackArgs = {\n columnId,\n showing: isChecked,\n grid: this.grid,\n allColumns: this.columns,\n columns: visibleColumns,\n visibleColumns: this.getVisibleColumns()\n };\n this.grid.setColumns(visibleColumns);\n this.onColumnsChanged.notify(callbackArgs, e, this);\n }\n }\n\n getAllColumns() {\n return this.columns;\n }\n\n /** visible columns, we can simply get them directly from the grid */\n getVisibleColumns() {\n return this.grid.getColumns();\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Controls = window.Slick.Controls || {};\n window.Slick.Controls.GridMenu = SlickGridMenu;\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.autotooltips.js b/dist/browser/plugins/slick.autotooltips.js index c918b7a1a..2c51701cf 100644 --- a/dist/browser/plugins/slick.autotooltips.js +++ b/dist/browser/plugins/slick.autotooltips.js @@ -63,7 +63,11 @@ handleHeaderMouseEnter(event, args) { var _a; let column = args.column, node, targetElm = event.target; - targetElm && (node = targetElm.closest(".slick-header-column"), node && !(column != null && column.toolTip) && (node.title = targetElm.clientWidth < node.clientWidth && (_a = column == null ? void 0 : column.name) != null ? _a : "")), node = null; + if (targetElm && (node = targetElm.closest(".slick-header-column"), node && !(column != null && column.toolTip))) { + let titleVal = targetElm.clientWidth < node.clientWidth && (_a = column == null ? void 0 : column.name) != null ? _a : ""; + node.title = titleVal instanceof HTMLElement ? titleVal.innerHTML : titleVal; + } + node = null; } }; window.Slick && Utils.extend(!0, window, { diff --git a/dist/browser/plugins/slick.autotooltips.js.map b/dist/browser/plugins/slick.autotooltips.js.map index 54c590101..80ec5b15e 100644 --- a/dist/browser/plugins/slick.autotooltips.js.map +++ b/dist/browser/plugins/slick.autotooltips.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.autotooltips.ts"], - "sourcesContent": ["import type { AutoTooltipOption, Column, SlickPlugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n */\nexport class SlickAutoTooltips implements SlickPlugin {\n // --\n // public API\n pluginName = 'AutoTooltips' as const;\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _options?: AutoTooltipOption;\n protected _defaults: AutoTooltipOption = {\n enableForCells: true,\n enableForHeaderCells: false,\n maxToolTipLength: undefined,\n replaceExisting: true\n };\n\n /**\n * Constructor of the SlickGrid 3rd party plugin, it can optionally receive options\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n * @param {boolean} [options.replaceExisting=null] - Allow preventing custom tooltips from being overwritten by auto tooltips\n */\n constructor(options?: AutoTooltipOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.subscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.subscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.unsubscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.unsubscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Handle mouse entering grid cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n */\n protected handleMouseEnter(event: MouseEvent) {\n const cell = this._grid.getCellFromEvent(event);\n if (cell) {\n let node: HTMLElement | null = this._grid.getCellNode(cell.row, cell.cell);\n let text;\n if (this._options && node && (!node.title || this._options?.replaceExisting)) {\n if (node.clientWidth < node.scrollWidth) {\n text = node.textContent?.trim() ?? '';\n if (this._options?.maxToolTipLength && text.length > this._options?.maxToolTipLength) {\n text = text.substring(0, this._options.maxToolTipLength - 3) + '...';\n }\n } else {\n text = '';\n }\n node.title = text;\n }\n node = null;\n }\n }\n\n /**\n * Handle mouse entering header cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n * @param {object} args.column - The column definition\n */\n protected handleHeaderMouseEnter(event: MouseEvent, args: { column: Column; }) {\n const column = args.column;\n let node: HTMLDivElement | null;\n const targetElm = (event.target as HTMLDivElement);\n\n if (targetElm) {\n node = targetElm.closest('.slick-header-column');\n if (node && !(column?.toolTip)) {\n node.title = (targetElm.clientWidth < node.clientWidth) ? column?.name ?? '' : '';\n }\n }\n node = null;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n AutoTooltips: SlickAutoTooltips\n }\n });\n}\n"], - "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAKnB,oBAAN,MAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBpD,YAAY,SAA6B;AApBzC;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAA+B;AAAA,QACvC,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAUE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,MAAiB;AAxCxB;AAyCI,WAAK,QAAQ,OACT,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,UAAU,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAEhE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,UAAU,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAElF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU;AArDZ;AAsDI,OAAI,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,YAAY,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAElE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,YAAY,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAEpF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMU,iBAAiB,OAAmB;AAlEhD;AAmEI,UAAM,OAAO,KAAK,MAAM,iBAAiB,KAAK;AAC9C,UAAI,MAAM;AACR,YAAI,OAA2B,KAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GACrE;AACJ,QAAI,KAAK,YAAY,SAAS,CAAC,KAAK,UAAS,UAAK,aAAL,WAAe,qBACtD,KAAK,cAAc,KAAK,eAC1B,QAAO,gBAAK,gBAAL,mBAAkB,WAAlB,YAA4B,KAC/B,UAAK,aAAL,WAAe,oBAAoB,KAAK,WAAS,UAAK,aAAL,mBAAe,sBAClE,OAAO,KAAK,UAAU,GAAG,KAAK,SAAS,mBAAmB,CAAC,IAAI,UAGjE,OAAO,IAET,KAAK,QAAQ,OAEf,OAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOU,uBAAuB,OAAmB,MAA2B;AA3FjF;AA4FI,UAAM,SAAS,KAAK,QAChB,MACE,YAAa,MAAM;AAEzB,MAAI,cACF,OAAO,UAAU,QAAwB,sBAAsB,GAC3D,QAAQ,EAAE,yBAAQ,aACpB,KAAK,QAAS,UAAU,cAAc,KAAK,gBAAe,sCAAQ,SAAR,YAAqB,MAGnF,OAAO;AAAA,IACT;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;", + "sourcesContent": ["import type { AutoTooltipOption, Column, SlickPlugin } from '../models/index';\nimport { Utils as Utils_ } from '../slick.core';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * AutoTooltips plugin to show/hide tooltips when columns are too narrow to fit content.\n */\nexport class SlickAutoTooltips implements SlickPlugin {\n // --\n // public API\n pluginName = 'AutoTooltips' as const;\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _options?: AutoTooltipOption;\n protected _defaults: AutoTooltipOption = {\n enableForCells: true,\n enableForHeaderCells: false,\n maxToolTipLength: undefined,\n replaceExisting: true\n };\n\n /**\n * Constructor of the SlickGrid 3rd party plugin, it can optionally receive options\n * @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells\n * @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells\n * @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip\n * @param {boolean} [options.replaceExisting=null] - Allow preventing custom tooltips from being overwritten by auto tooltips\n */\n constructor(options?: AutoTooltipOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.subscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.subscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n if (this._options?.enableForCells) {\n this._grid.onMouseEnter.unsubscribe(this.handleMouseEnter.bind(this));\n }\n if (this._options?.enableForHeaderCells) {\n this._grid.onHeaderMouseEnter.unsubscribe(this.handleHeaderMouseEnter.bind(this));\n }\n }\n\n /**\n * Handle mouse entering grid cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n */\n protected handleMouseEnter(event: MouseEvent) {\n const cell = this._grid.getCellFromEvent(event);\n if (cell) {\n let node: HTMLElement | null = this._grid.getCellNode(cell.row, cell.cell);\n let text;\n if (this._options && node && (!node.title || this._options?.replaceExisting)) {\n if (node.clientWidth < node.scrollWidth) {\n text = node.textContent?.trim() ?? '';\n if (this._options?.maxToolTipLength && text.length > this._options?.maxToolTipLength) {\n text = text.substring(0, this._options.maxToolTipLength - 3) + '...';\n }\n } else {\n text = '';\n }\n node.title = text;\n }\n node = null;\n }\n }\n\n /**\n * Handle mouse entering header cell to add/remove tooltip.\n * @param {MouseEvent} event - The event\n * @param {object} args.column - The column definition\n */\n protected handleHeaderMouseEnter(event: MouseEvent, args: { column: Column; }) {\n const column = args.column;\n let node: HTMLDivElement | null;\n const targetElm = (event.target as HTMLDivElement);\n\n if (targetElm) {\n node = targetElm.closest('.slick-header-column');\n if (node && !(column?.toolTip)) {\n const titleVal = (targetElm.clientWidth < node.clientWidth) ? column?.name ?? '' : '';\n node.title = titleVal instanceof HTMLElement ? titleVal.innerHTML : titleVal;\n }\n }\n node = null;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n AutoTooltips: SlickAutoTooltips\n }\n });\n}\n"], + "mappings": ";;;;;;;AAKA,MAAM,QAAoB,MAAM,OAKnB,oBAAN,MAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBpD,YAAY,SAA6B;AApBzC;AAAA;AAAA,wCAAa;AAIb;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAA+B;AAAA,QACvC,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAUE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO;AAAA,IAChE;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,MAAiB;AAxCxB;AAyCI,WAAK,QAAQ,OACT,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,UAAU,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAEhE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,UAAU,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAElF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU;AArDZ;AAsDI,OAAI,UAAK,aAAL,WAAe,kBACjB,KAAK,MAAM,aAAa,YAAY,KAAK,iBAAiB,KAAK,IAAI,CAAC,IAElE,UAAK,aAAL,WAAe,wBACjB,KAAK,MAAM,mBAAmB,YAAY,KAAK,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAEpF;AAAA;AAAA;AAAA;AAAA;AAAA,IAMU,iBAAiB,OAAmB;AAlEhD;AAmEI,UAAM,OAAO,KAAK,MAAM,iBAAiB,KAAK;AAC9C,UAAI,MAAM;AACR,YAAI,OAA2B,KAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,GACrE;AACJ,QAAI,KAAK,YAAY,SAAS,CAAC,KAAK,UAAS,UAAK,aAAL,WAAe,qBACtD,KAAK,cAAc,KAAK,eAC1B,QAAO,gBAAK,gBAAL,mBAAkB,WAAlB,YAA4B,KAC/B,UAAK,aAAL,WAAe,oBAAoB,KAAK,WAAS,UAAK,aAAL,mBAAe,sBAClE,OAAO,KAAK,UAAU,GAAG,KAAK,SAAS,mBAAmB,CAAC,IAAI,UAGjE,OAAO,IAET,KAAK,QAAQ,OAEf,OAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOU,uBAAuB,OAAmB,MAA2B;AA3FjF;AA4FI,UAAM,SAAS,KAAK,QAChB,MACE,YAAa,MAAM;AAEzB,UAAI,cACF,OAAO,UAAU,QAAwB,sBAAsB,GAC3D,QAAQ,EAAE,yBAAQ,WAAU;AAC9B,YAAM,WAAY,UAAU,cAAc,KAAK,gBAAe,sCAAQ,SAAR,YAAqB;AACnF,aAAK,QAAQ,oBAAoB,cAAc,SAAS,YAAY;AAAA,MACtE;AAEF,aAAO;AAAA,IACT;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/plugins/slick.cellexternalcopymanager.js b/dist/browser/plugins/slick.cellexternalcopymanager.js index 2cccfeb18..094e8cfc8 100644 --- a/dist/browser/plugins/slick.cellexternalcopymanager.js +++ b/dist/browser/plugins/slick.cellexternalcopymanager.js @@ -216,11 +216,11 @@ if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) { let clipTextHeaders = []; for (let j = range.fromCell; j < range.toCell + 1; j++) - columns[j].name.length > 0 && !columns[j].hidden && clipTextHeaders.push(this.getHeaderValueForColumn(columns[j])); + (columns[j].name instanceof HTMLElement ? columns[j].name.innerHTML : columns[j].name).length > 0 && !columns[j].hidden && clipTextHeaders.push(this.getHeaderValueForColumn(columns[j])); clipTextRows.push(clipTextHeaders.join(" ")); } for (let j = range.fromCell; j < range.toCell + 1; j++) - columns[j].name.length > 0 && !columns[j].hidden && clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e)); + (columns[j].name instanceof HTMLElement ? columns[j].name.innerHTML : columns[j].name).length > 0 && !columns[j].hidden && clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e)); clipTextRows.push(clipTextCells.join(" ")); } clipText += clipTextRows.join(`\r diff --git a/dist/browser/plugins/slick.cellexternalcopymanager.js.map b/dist/browser/plugins/slick.cellexternalcopymanager.js.map index 4f849a4c8..6a5b2896f 100644 --- a/dist/browser/plugins/slick.cellexternalcopymanager.js.map +++ b/dist/browser/plugins/slick.cellexternalcopymanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.cellexternalcopymanager.ts"], - "sourcesContent": ["import type { CellRange, Column, CssStyleHash, ExcelCopyBufferOption, ExternalCopyClipCommand, SlickPlugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\nimport { SlickEvent as SlickEvent_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nconst CLEAR_COPY_SELECTION_DELAY = 2000;\nconst CLIPBOARD_PASTE_DELAY = 100;\n\n/***\n This manager enables users to copy/paste data from/to an external Spreadsheet application\n such as MS-Excel\u00AE or OpenOffice-Spreadsheet.\n\n Since it is not possible to access directly the clipboard in javascript, the plugin uses\n a trick to do it's job. After detecting the keystroke, we dynamically create a textarea\n where the browser copies/pastes the serialized data.\n\n options:\n copiedCellStyle : sets the css className used for copied cells. default : \"copied\"\n copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : \"copy-manager\"\n dataItemColumnValueExtractor : option to specify a custom column value extractor function\n dataItemColumnValueSetter : option to specify a custom column value setter function\n clipboardCommandHandler : option to specify a custom handler for paste actions\n includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard\n bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.\n onCopyInit: optional handler to run when copy action initializes\n onCopySuccess: optional handler to run when copy action is complete\n newRowCreator: function to add rows to table if paste overflows bottom of table, if this function is not provided new rows will be ignored.\n readOnlyMode: suppresses paste\n headerColumnValueExtractor : option to specify a custom column header value extractor function\n*/\nexport class SlickCellExternalCopyManager implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellExternalCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: CellRange[]; }>();\n onCopyCancelled = new SlickEvent<{ ranges: CellRange[]; }>();\n onPasteCells = new SlickEvent<{ ranges: CellRange[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _bodyElement: HTMLElement;\n protected _copiedRanges: CellRange[] | null = null;\n protected _clearCopyTI?: NodeJS.Timeout;\n protected _copiedCellStyle: string;\n protected _copiedCellStyleLayerKey: string;\n protected _onCopyInit?: () => void;\n protected _onCopySuccess?: (rowCount: number) => void;\n protected _options: ExcelCopyBufferOption;\n\n protected keyCodes = {\n 'C': 67,\n 'V': 86,\n 'ESC': 27,\n 'INSERT': 45\n };\n\n constructor(options: ExcelCopyBufferOption) {\n this._options = options || {};\n this._copiedCellStyleLayerKey = this._options.copiedCellStyleLayerKey || 'copy-manager';\n this._copiedCellStyle = this._options.copiedCellStyle || 'copied';\n this._bodyElement = this._options.bodyElement || document.body;\n this._onCopyInit = this._options.onCopyInit || undefined;\n this._onCopySuccess = this._options.onCopySuccess || undefined;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n\n // we need a cell selection model\n const cellSelectionModel = grid.getSelectionModel();\n if (!cellSelectionModel) {\n throw new Error('Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())');\n }\n // we give focus on the grid when a selection is done on it.\n // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work\n cellSelectionModel.onSelectedRangesChanged.subscribe(() => {\n if (!this._grid.getEditorLock().isActive()) {\n this._grid.focus();\n }\n });\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected getHeaderValueForColumn(columnDef: Column) {\n if (this._options.headerColumnValueExtractor) {\n const val = this._options.headerColumnValueExtractor(columnDef);\n if (val) {\n return val;\n }\n }\n\n return columnDef.name;\n }\n\n protected getDataItemValueForColumn(item: any, columnDef: Column, event: Event): string {\n if (typeof this._options.dataItemColumnValueExtractor === 'function') {\n const val = this._options.dataItemColumnValueExtractor(item, columnDef) as string | null;\n if (val) {\n return val;\n }\n }\n\n let retVal = '';\n\n // if a custom getter is not defined, we call serializeValue of the editor to serialize\n if (columnDef?.editor) {\n const tmpP = document.createElement('p');\n const editor = new (columnDef.editor as any)({\n container: tmpP, // a dummy container\n column: columnDef,\n event,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid,\n });\n editor.loadValue(item);\n retVal = editor.serializeValue();\n editor.destroy();\n tmpP.remove();\n } else {\n retVal = item[columnDef.field || ''];\n }\n\n return retVal;\n }\n\n protected setDataItemValueForColumn(item: any, columnDef: Column, value: string): null | string | void {\n if (columnDef.denyPaste) {\n return null;\n }\n\n if (this._options.dataItemColumnValueSetter) {\n return this._options.dataItemColumnValueSetter(item, columnDef, value) as string;\n }\n\n // if a custom setter is not defined, we call applyValue of the editor to unserialize\n if (columnDef.editor) {\n const tmpDiv = document.createElement('div');\n const editor = new (columnDef.editor as any)({\n container: tmpDiv, // a dummy container\n column: columnDef,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid\n });\n editor.loadValue(item);\n editor.applyValue(item, value);\n editor.destroy();\n tmpDiv.remove();\n } else {\n item[columnDef.field] = value;\n }\n }\n\n\n protected _createTextBox(innerText: string) {\n const ta = document.createElement('textarea');\n ta.style.position = 'absolute';\n ta.style.left = '-1000px';\n ta.style.top = document.body.scrollTop + 'px';\n ta.value = innerText;\n this._bodyElement.appendChild(ta);\n ta.select();\n\n return ta;\n }\n\n protected _decodeTabularData(grid: SlickGrid, ta: HTMLTextAreaElement) {\n const columns = grid.getColumns();\n const clipText = ta.value;\n const clipRows = clipText.split(/[\\n\\f\\r]/);\n // trim trailing CR if present\n if (clipRows[clipRows.length - 1] === '') {\n clipRows.pop();\n }\n\n let j = 0;\n const clippedRange: any[] = [];\n\n this._bodyElement.removeChild(ta);\n for (let i = 0; i < clipRows.length; i++) {\n if (clipRows[i] !== '') {\n clippedRange[j++] = clipRows[i].split('\\t');\n } else {\n clippedRange[j++] = [''];\n }\n }\n const selectedCell = grid.getActiveCell();\n const ranges = grid.getSelectionModel()?.getSelectedRanges();\n const selectedRange = ranges && ranges.length ? ranges[0] : null; // pick only one selection\n let activeRow: number;\n let activeCell: number;\n\n if (selectedRange) {\n activeRow = selectedRange.fromRow;\n activeCell = selectedRange.fromCell;\n } else if (selectedCell) {\n activeRow = selectedCell.row;\n activeCell = selectedCell.cell;\n } else {\n // we don't know where to paste\n return;\n }\n\n let oneCellToMultiple = false;\n let destH = clippedRange.length;\n let destW = clippedRange.length ? clippedRange[0].length : 0;\n if (clippedRange.length === 1 && clippedRange[0].length === 1 && selectedRange) {\n oneCellToMultiple = true;\n destH = selectedRange.toRow - selectedRange.fromRow + 1;\n destW = selectedRange.toCell - selectedRange.fromCell + 1;\n }\n const availableRows = (grid.getData() as any[]).length - (activeRow || 0);\n let addRows = 0;\n\n // ignore new rows if we don't have a \"newRowCreator\"\n if (availableRows < destH && typeof this._options.newRowCreator === 'function') {\n const d = grid.getData();\n for (addRows = 1; addRows <= destH - availableRows; addRows++) {\n d.push({});\n }\n grid.setData(d);\n grid.render();\n }\n\n const overflowsBottomOfGrid = (activeRow || 0) + destH > grid.getDataLength();\n if (this._options.newRowCreator && overflowsBottomOfGrid) {\n const newRowsNeeded = (activeRow || 0) + destH - grid.getDataLength();\n this._options.newRowCreator(newRowsNeeded);\n }\n\n const clipCommand: ExternalCopyClipCommand = {\n isClipboardCommand: true,\n clippedRange,\n oldValues: [],\n cellExternalCopyManager: this,\n _options: this._options,\n setDataItemValueForColumn: this.setDataItemValueForColumn.bind(this),\n markCopySelection: this.markCopySelection.bind(this),\n oneCellToMultiple,\n activeRow,\n activeCell,\n destH,\n destW,\n maxDestY: grid.getDataLength(),\n maxDestX: grid.getColumns().length,\n h: 0,\n w: 0,\n\n execute: () => {\n clipCommand.h = 0;\n for (let y = 0; y < clipCommand.destH; y++) {\n clipCommand.oldValues[y] = [];\n clipCommand.w = 0;\n clipCommand.h++;\n for (let x = 0; x < clipCommand.destW; x++) {\n clipCommand.w++;\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n clipCommand.oldValues[y][x] = dt[columns[destx]['field']];\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n this.onPasteCells.notify({ ranges: [bRange] });\n },\n\n undo: () => {\n for (let y = 0; y < clipCommand.destH; y++) {\n for (let x = 0; x < clipCommand.destW; x++) {\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[y][x]);\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n if (typeof this._options.onPasteCells === 'function') {\n this.onPasteCells.notify({ ranges: [bRange] });\n }\n\n if (addRows > 1) {\n const d = grid.getData();\n for (; addRows > 1; addRows--) {\n d.splice(d.length - 1, 1);\n }\n grid.setData(d);\n grid.render();\n }\n }\n };\n\n if (typeof this._options.clipboardCommandHandler === 'function') {\n this._options.clipboardCommandHandler(clipCommand);\n } else {\n clipCommand.execute();\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent): boolean | void {\n let ranges: CellRange[];\n if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) {\n if (e.which === this.keyCodes.ESC) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if ((e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // CTRL+C or CTRL+INS\n if (typeof this._onCopyInit === 'function') {\n this._onCopyInit.call(this);\n }\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges });\n\n const columns = this._grid.getColumns();\n let clipText = '';\n\n for (let rg = 0; rg < ranges.length; rg++) {\n const range = ranges[rg];\n const clipTextRows: string[] = [];\n for (let i = range.fromRow; i < range.toRow + 1; i++) {\n const clipTextCells: string[] = [];\n const dt = this._grid.getDataItem(i);\n\n if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) {\n const clipTextHeaders: string[] = [];\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]));\n }\n }\n clipTextRows.push(clipTextHeaders.join('\\t'));\n }\n\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n if (columns[j].name!.length > 0 && !columns[j].hidden) {\n clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e));\n }\n }\n clipTextRows.push(clipTextCells.join('\\t'));\n }\n clipText += clipTextRows.join('\\r\\n') + '\\r\\n';\n }\n\n if ((window as any).clipboardData) {\n (window as any).clipboardData.setData('Text', clipText);\n return true;\n }\n else {\n const focusEl = document.activeElement as HTMLElement;\n const ta = this._createTextBox(clipText);\n ta.focus();\n\n setTimeout(() => {\n this._bodyElement.removeChild(ta);\n // restore focus when possible\n focusEl\n ? focusEl.focus()\n : console.log('No element to restore focus to after copy?');\n }, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY);\n\n if (typeof this._onCopySuccess === 'function') {\n let rowCount = 0;\n // If it's cell selection, use the toRow/fromRow fields\n if (ranges.length === 1) {\n rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;\n } else {\n rowCount = ranges.length;\n }\n this._onCopySuccess(rowCount);\n }\n\n return false;\n }\n }\n }\n\n if (!this._options.readOnlyMode && (\n (e.which === this.keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey)\n || (e.which === this.keyCodes.INSERT && e.shiftKey && !e.ctrlKey)\n )) { // CTRL+V or Shift+INS\n const ta = this._createTextBox('');\n setTimeout(() => this._decodeTabularData(this._grid, ta), 100);\n return false;\n }\n }\n }\n\n protected markCopySelection(ranges: CellRange[]) {\n this.clearCopySelection();\n\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell && k < columns.length; k++) {\n hash[j][columns[k].id] = this._copiedCellStyle;\n }\n }\n }\n this._grid.setCellCssStyles(this._copiedCellStyleLayerKey, hash);\n clearTimeout(this._clearCopyTI as NodeJS.Timeout);\n this._clearCopyTI = setTimeout(() => {\n this.clearCopySelection();\n }, this._options?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);\n }\n\n clearCopySelection() {\n this._grid.removeCellCssStyles(this._copiedCellStyleLayerKey);\n }\n\n setIncludeHeaderWhenCopying(includeHeaderWhenCopying: boolean) {\n this._options.includeHeaderWhenCopying = includeHeaderWhenCopying;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellExternalCopyManager: SlickCellExternalCopyManager\n }\n });\n}\n"], - "mappings": "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", + "sourcesContent": ["import type { CellRange, Column, CssStyleHash, ExcelCopyBufferOption, ExternalCopyClipCommand, SlickPlugin } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\nimport { SlickEvent as SlickEvent_, SlickRange as SlickRange_, Utils as Utils_ } from '../slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\nconst CLEAR_COPY_SELECTION_DELAY = 2000;\nconst CLIPBOARD_PASTE_DELAY = 100;\n\n/***\n This manager enables users to copy/paste data from/to an external Spreadsheet application\n such as MS-Excel\u00AE or OpenOffice-Spreadsheet.\n\n Since it is not possible to access directly the clipboard in javascript, the plugin uses\n a trick to do it's job. After detecting the keystroke, we dynamically create a textarea\n where the browser copies/pastes the serialized data.\n\n options:\n copiedCellStyle : sets the css className used for copied cells. default : \"copied\"\n copiedCellStyleLayerKey : sets the layer key for setting css values of copied cells. default : \"copy-manager\"\n dataItemColumnValueExtractor : option to specify a custom column value extractor function\n dataItemColumnValueSetter : option to specify a custom column value setter function\n clipboardCommandHandler : option to specify a custom handler for paste actions\n includeHeaderWhenCopying : set to true and the plugin will take the name property from each column (which is usually what appears in your header) and put that as the first row of the text that's copied to the clipboard\n bodyElement: option to specify a custom DOM element which to will be added the hidden textbox. It's useful if the grid is inside a modal dialog.\n onCopyInit: optional handler to run when copy action initializes\n onCopySuccess: optional handler to run when copy action is complete\n newRowCreator: function to add rows to table if paste overflows bottom of table, if this function is not provided new rows will be ignored.\n readOnlyMode: suppresses paste\n headerColumnValueExtractor : option to specify a custom column header value extractor function\n*/\nexport class SlickCellExternalCopyManager implements SlickPlugin {\n // --\n // public API\n pluginName = 'CellExternalCopyManager' as const;\n onCopyCells = new SlickEvent<{ ranges: CellRange[]; }>();\n onCopyCancelled = new SlickEvent<{ ranges: CellRange[]; }>();\n onPasteCells = new SlickEvent<{ ranges: CellRange[]; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _bodyElement: HTMLElement;\n protected _copiedRanges: CellRange[] | null = null;\n protected _clearCopyTI?: NodeJS.Timeout;\n protected _copiedCellStyle: string;\n protected _copiedCellStyleLayerKey: string;\n protected _onCopyInit?: () => void;\n protected _onCopySuccess?: (rowCount: number) => void;\n protected _options: ExcelCopyBufferOption;\n\n protected keyCodes = {\n 'C': 67,\n 'V': 86,\n 'ESC': 27,\n 'INSERT': 45\n };\n\n constructor(options: ExcelCopyBufferOption) {\n this._options = options || {};\n this._copiedCellStyleLayerKey = this._options.copiedCellStyleLayerKey || 'copy-manager';\n this._copiedCellStyle = this._options.copiedCellStyle || 'copied';\n this._bodyElement = this._options.bodyElement || document.body;\n this._onCopyInit = this._options.onCopyInit || undefined;\n this._onCopySuccess = this._options.onCopySuccess || undefined;\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));\n\n // we need a cell selection model\n const cellSelectionModel = grid.getSelectionModel();\n if (!cellSelectionModel) {\n throw new Error('Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())');\n }\n // we give focus on the grid when a selection is done on it.\n // without this, if the user selects a range of cell without giving focus on a particular cell, the grid doesn't get the focus and key stroke handles (ctrl+c) don't work\n cellSelectionModel.onSelectedRangesChanged.subscribe(() => {\n if (!this._grid.getEditorLock().isActive()) {\n this._grid.focus();\n }\n });\n }\n\n destroy() {\n this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));\n }\n\n protected getHeaderValueForColumn(columnDef: Column) {\n if (this._options.headerColumnValueExtractor) {\n const val = this._options.headerColumnValueExtractor(columnDef);\n if (val) {\n return val;\n }\n }\n\n return columnDef.name;\n }\n\n protected getDataItemValueForColumn(item: any, columnDef: Column, event: Event): string {\n if (typeof this._options.dataItemColumnValueExtractor === 'function') {\n const val = this._options.dataItemColumnValueExtractor(item, columnDef) as string | null;\n if (val) {\n return val;\n }\n }\n\n let retVal = '';\n\n // if a custom getter is not defined, we call serializeValue of the editor to serialize\n if (columnDef?.editor) {\n const tmpP = document.createElement('p');\n const editor = new (columnDef.editor as any)({\n container: tmpP, // a dummy container\n column: columnDef,\n event,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid,\n });\n editor.loadValue(item);\n retVal = editor.serializeValue();\n editor.destroy();\n tmpP.remove();\n } else {\n retVal = item[columnDef.field || ''];\n }\n\n return retVal;\n }\n\n protected setDataItemValueForColumn(item: any, columnDef: Column, value: string): null | string | void {\n if (columnDef.denyPaste) {\n return null;\n }\n\n if (this._options.dataItemColumnValueSetter) {\n return this._options.dataItemColumnValueSetter(item, columnDef, value) as string;\n }\n\n // if a custom setter is not defined, we call applyValue of the editor to unserialize\n if (columnDef.editor) {\n const tmpDiv = document.createElement('div');\n const editor = new (columnDef.editor as any)({\n container: tmpDiv, // a dummy container\n column: columnDef,\n position: { top: 0, left: 0 }, // a dummy position required by some editors\n grid: this._grid\n });\n editor.loadValue(item);\n editor.applyValue(item, value);\n editor.destroy();\n tmpDiv.remove();\n } else {\n item[columnDef.field] = value;\n }\n }\n\n\n protected _createTextBox(innerText: string) {\n const ta = document.createElement('textarea');\n ta.style.position = 'absolute';\n ta.style.left = '-1000px';\n ta.style.top = document.body.scrollTop + 'px';\n ta.value = innerText;\n this._bodyElement.appendChild(ta);\n ta.select();\n\n return ta;\n }\n\n protected _decodeTabularData(grid: SlickGrid, ta: HTMLTextAreaElement) {\n const columns = grid.getColumns();\n const clipText = ta.value;\n const clipRows = clipText.split(/[\\n\\f\\r]/);\n // trim trailing CR if present\n if (clipRows[clipRows.length - 1] === '') {\n clipRows.pop();\n }\n\n let j = 0;\n const clippedRange: any[] = [];\n\n this._bodyElement.removeChild(ta);\n for (let i = 0; i < clipRows.length; i++) {\n if (clipRows[i] !== '') {\n clippedRange[j++] = clipRows[i].split('\\t');\n } else {\n clippedRange[j++] = [''];\n }\n }\n const selectedCell = grid.getActiveCell();\n const ranges = grid.getSelectionModel()?.getSelectedRanges();\n const selectedRange = ranges && ranges.length ? ranges[0] : null; // pick only one selection\n let activeRow: number;\n let activeCell: number;\n\n if (selectedRange) {\n activeRow = selectedRange.fromRow;\n activeCell = selectedRange.fromCell;\n } else if (selectedCell) {\n activeRow = selectedCell.row;\n activeCell = selectedCell.cell;\n } else {\n // we don't know where to paste\n return;\n }\n\n let oneCellToMultiple = false;\n let destH = clippedRange.length;\n let destW = clippedRange.length ? clippedRange[0].length : 0;\n if (clippedRange.length === 1 && clippedRange[0].length === 1 && selectedRange) {\n oneCellToMultiple = true;\n destH = selectedRange.toRow - selectedRange.fromRow + 1;\n destW = selectedRange.toCell - selectedRange.fromCell + 1;\n }\n const availableRows = (grid.getData() as any[]).length - (activeRow || 0);\n let addRows = 0;\n\n // ignore new rows if we don't have a \"newRowCreator\"\n if (availableRows < destH && typeof this._options.newRowCreator === 'function') {\n const d = grid.getData();\n for (addRows = 1; addRows <= destH - availableRows; addRows++) {\n d.push({});\n }\n grid.setData(d);\n grid.render();\n }\n\n const overflowsBottomOfGrid = (activeRow || 0) + destH > grid.getDataLength();\n if (this._options.newRowCreator && overflowsBottomOfGrid) {\n const newRowsNeeded = (activeRow || 0) + destH - grid.getDataLength();\n this._options.newRowCreator(newRowsNeeded);\n }\n\n const clipCommand: ExternalCopyClipCommand = {\n isClipboardCommand: true,\n clippedRange,\n oldValues: [],\n cellExternalCopyManager: this,\n _options: this._options,\n setDataItemValueForColumn: this.setDataItemValueForColumn.bind(this),\n markCopySelection: this.markCopySelection.bind(this),\n oneCellToMultiple,\n activeRow,\n activeCell,\n destH,\n destW,\n maxDestY: grid.getDataLength(),\n maxDestX: grid.getColumns().length,\n h: 0,\n w: 0,\n\n execute: () => {\n clipCommand.h = 0;\n for (let y = 0; y < clipCommand.destH; y++) {\n clipCommand.oldValues[y] = [];\n clipCommand.w = 0;\n clipCommand.h++;\n for (let x = 0; x < clipCommand.destW; x++) {\n clipCommand.w++;\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n clipCommand.oldValues[y][x] = dt[columns[destx]['field']];\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clippedRange[y] ? clippedRange[y][x] : '');\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n this.onPasteCells.notify({ ranges: [bRange] });\n },\n\n undo: () => {\n for (let y = 0; y < clipCommand.destH; y++) {\n for (let x = 0; x < clipCommand.destW; x++) {\n const desty = activeRow + y;\n const destx = activeCell + x;\n\n if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {\n const dt = grid.getDataItem(desty);\n if (oneCellToMultiple) {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[0][0]);\n } else {\n clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[y][x]);\n }\n grid.updateCell(desty, destx);\n grid.onCellChange.notify({\n row: desty,\n cell: destx,\n item: dt,\n grid,\n column: {} as Column\n });\n }\n }\n }\n\n const bRange = new SlickRange(\n activeRow,\n activeCell,\n activeRow + clipCommand.h - 1,\n activeCell + clipCommand.w - 1\n );\n\n this.markCopySelection([bRange]);\n grid.getSelectionModel()?.setSelectedRanges([bRange]);\n if (typeof this._options.onPasteCells === 'function') {\n this.onPasteCells.notify({ ranges: [bRange] });\n }\n\n if (addRows > 1) {\n const d = grid.getData();\n for (; addRows > 1; addRows--) {\n d.splice(d.length - 1, 1);\n }\n grid.setData(d);\n grid.render();\n }\n }\n };\n\n if (typeof this._options.clipboardCommandHandler === 'function') {\n this._options.clipboardCommandHandler(clipCommand);\n } else {\n clipCommand.execute();\n }\n }\n\n protected handleKeyDown(e: KeyboardEvent): boolean | void {\n let ranges: CellRange[];\n if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) {\n if (e.which === this.keyCodes.ESC) {\n if (this._copiedRanges) {\n e.preventDefault();\n this.clearCopySelection();\n this.onCopyCancelled.notify({ ranges: this._copiedRanges });\n this._copiedRanges = null;\n }\n }\n\n if ((e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // CTRL+C or CTRL+INS\n if (typeof this._onCopyInit === 'function') {\n this._onCopyInit.call(this);\n }\n ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [];\n if (ranges.length !== 0) {\n this._copiedRanges = ranges;\n this.markCopySelection(ranges);\n this.onCopyCells.notify({ ranges });\n\n const columns = this._grid.getColumns();\n let clipText = '';\n\n for (let rg = 0; rg < ranges.length; rg++) {\n const range = ranges[rg];\n const clipTextRows: string[] = [];\n for (let i = range.fromRow; i < range.toRow + 1; i++) {\n const clipTextCells: string[] = [];\n const dt = this._grid.getDataItem(i);\n\n if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) {\n const clipTextHeaders: string[] = [];\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n const colName: string = columns[j].name instanceof HTMLElement\n ? (columns[j].name as HTMLElement).innerHTML\n : columns[j].name as string;\n if (colName.length > 0 && !columns[j].hidden) {\n clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]));\n }\n }\n clipTextRows.push(clipTextHeaders.join('\\t'));\n }\n\n for (let j = range.fromCell; j < range.toCell + 1; j++) {\n const colName: string = columns[j].name instanceof HTMLElement\n ? (columns[j].name as HTMLElement).innerHTML\n : columns[j].name as string;\n if (colName.length > 0 && !columns[j].hidden) {\n clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e));\n }\n }\n clipTextRows.push(clipTextCells.join('\\t'));\n }\n clipText += clipTextRows.join('\\r\\n') + '\\r\\n';\n }\n\n if ((window as any).clipboardData) {\n (window as any).clipboardData.setData('Text', clipText);\n return true;\n }\n else {\n const focusEl = document.activeElement as HTMLElement;\n const ta = this._createTextBox(clipText);\n ta.focus();\n\n setTimeout(() => {\n this._bodyElement.removeChild(ta);\n // restore focus when possible\n focusEl\n ? focusEl.focus()\n : console.log('No element to restore focus to after copy?');\n }, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY);\n\n if (typeof this._onCopySuccess === 'function') {\n let rowCount = 0;\n // If it's cell selection, use the toRow/fromRow fields\n if (ranges.length === 1) {\n rowCount = (ranges[0].toRow + 1) - ranges[0].fromRow;\n } else {\n rowCount = ranges.length;\n }\n this._onCopySuccess(rowCount);\n }\n\n return false;\n }\n }\n }\n\n if (!this._options.readOnlyMode && (\n (e.which === this.keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey)\n || (e.which === this.keyCodes.INSERT && e.shiftKey && !e.ctrlKey)\n )) { // CTRL+V or Shift+INS\n const ta = this._createTextBox('');\n setTimeout(() => this._decodeTabularData(this._grid, ta), 100);\n return false;\n }\n }\n }\n\n protected markCopySelection(ranges: CellRange[]) {\n this.clearCopySelection();\n\n const columns = this._grid.getColumns();\n const hash: CssStyleHash = {};\n for (let i = 0; i < ranges.length; i++) {\n for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {\n hash[j] = {};\n for (let k = ranges[i].fromCell; k <= ranges[i].toCell && k < columns.length; k++) {\n hash[j][columns[k].id] = this._copiedCellStyle;\n }\n }\n }\n this._grid.setCellCssStyles(this._copiedCellStyleLayerKey, hash);\n clearTimeout(this._clearCopyTI as NodeJS.Timeout);\n this._clearCopyTI = setTimeout(() => {\n this.clearCopySelection();\n }, this._options?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);\n }\n\n clearCopySelection() {\n this._grid.removeCellCssStyles(this._copiedCellStyleLayerKey);\n }\n\n setIncludeHeaderWhenCopying(includeHeaderWhenCopying: boolean) {\n this._options.includeHeaderWhenCopying = includeHeaderWhenCopying;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CellExternalCopyManager: SlickCellExternalCopyManager\n }\n });\n}\n"], + "mappings": "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", "names": ["_a"] } diff --git a/dist/browser/plugins/slick.crossgridrowmovemanager.js.map b/dist/browser/plugins/slick.crossgridrowmovemanager.js.map index 327fd48c1..0ab415b78 100644 --- a/dist/browser/plugins/slick.crossgridrowmovemanager.js.map +++ b/dist/browser/plugins/slick.crossgridrowmovemanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.crossgridrowmovemanager.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, CrossGridRowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the menu item container.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\nexport class SlickCrossGridRowMoveManager {\n // --\n // public API\n pluginName = 'CrossGridRowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n onMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _toGrid!: SlickGrid;\n protected _toCanvas!: HTMLElement;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _eventHandler: SlickEventHandler_;\n protected _options: CrossGridRowMoveManagerOption;\n protected _defaults: CrossGridRowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n toGrid: undefined as any,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._toGrid = this._options.toGrid;\n this._toCanvas = this._toGrid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: CrossGridRowMoveManagerOption) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove & { fromGrid: SlickGrid; toGrid: SlickGrid; }): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row ?? 0;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const cellNodeElm = this._grid.getCellNode(cell.row, cell.cell);\n const slickRowElm = cellNodeElm?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n selectedRows.sort((a, b) => a - b);\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.fromGrid = this._grid;\n dd.toGrid = this._toGrid;\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._toCanvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._toCanvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._toCanvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._toCanvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._toCanvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._toGrid.getOptions().rowHeight!), this._toGrid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._toGrid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._toGrid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._toGrid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n selectable: false,\n resizable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`.trim(), text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CrossGridRowMoveManager: SlickCrossGridRowMoveManager\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, CrossGridRowMoveManagerOption, FormatterResultWithText, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the menu item container.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\nexport class SlickCrossGridRowMoveManager {\n // --\n // public API\n pluginName = 'CrossGridRowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n onMoveRows = new SlickEvent<{ rows: number[]; insertBefore: number; fromGrid: SlickGrid; toGrid: SlickGrid; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _toGrid!: SlickGrid;\n protected _toCanvas!: HTMLElement;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _eventHandler: SlickEventHandler_;\n protected _options: CrossGridRowMoveManagerOption;\n protected _defaults: CrossGridRowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n toGrid: undefined as any,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n this._toGrid = this._options.toGrid;\n this._toCanvas = this._toGrid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: CrossGridRowMoveManagerOption) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove & { fromGrid: SlickGrid; toGrid: SlickGrid; }): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row ?? 0;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const cellNodeElm = this._grid.getCellNode(cell.row, cell.cell);\n const slickRowElm = cellNodeElm?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n selectedRows.sort((a, b) => a - b);\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.fromGrid = this._grid;\n dd.toGrid = this._toGrid;\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._toCanvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._toCanvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._toCanvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._toCanvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent).touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._toCanvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._toGrid.getOptions().rowHeight!), this._toGrid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._toGrid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._toGrid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._toGrid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n fromGrid: this._grid,\n toGrid: this._toGrid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n selectable: false,\n resizable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultWithText | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`.trim(), text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n CrossGridRowMoveManager: SlickCrossGridRowMoveManager\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.customtooltip.js b/dist/browser/plugins/slick.customtooltip.js index fcda1b5ff..211655366 100644 --- a/dist/browser/plugins/slick.customtooltip.js +++ b/dist/browser/plugins/slick.customtooltip.js @@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => (__defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value), value); // src/plugins/slick.customtooltip.ts - var SlickEventHandler = Slick.EventHandler, Utils = Slick.Utils, CustomTooltip = class { + var SlickEventHandler = Slick.EventHandler, Utils = Slick.Utils, SlickCustomTooltip = class { constructor(tooltipOptions) { this.tooltipOptions = tooltipOptions; // -- @@ -181,8 +181,8 @@ */ parseFormatterAndSanitize(formatterOrText, cell, value, columnDef, item) { if (typeof formatterOrText == "function") { - let tooltipText = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid), formatterText = typeof tooltipText == "object" && (tooltipText != null && tooltipText.text) ? tooltipText.text : typeof tooltipText == "string" ? tooltipText : ""; - return this._grid.sanitizeHtmlString(formatterText); + let tooltipResult = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid), formatterText = Object.prototype.toString.call(tooltipResult) !== "[object Object]" ? tooltipResult : tooltipResult.html || tooltipResult.text; + return formatterText instanceof HTMLElement && (formatterText = formatterText.outerHTML), this._grid.sanitizeHtmlString(formatterText); } else if (typeof formatterOrText == "string") return this._grid.sanitizeHtmlString(formatterOrText); return ""; @@ -211,7 +211,7 @@ window.Slick && Utils.extend(!0, window, { Slick: { Plugins: { - CustomTooltip + CustomTooltip: SlickCustomTooltip } } }); diff --git a/dist/browser/plugins/slick.customtooltip.js.map b/dist/browser/plugins/slick.customtooltip.js.map index c96b3f74c..c5f484083 100644 --- a/dist/browser/plugins/slick.customtooltip.js.map +++ b/dist/browser/plugins/slick.customtooltip.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.customtooltip.ts"], - "sourcesContent": ["import type { CancellablePromiseWrapper, Column, CustomTooltipOption, DOMEvent, Formatter, GridOption } from '../models/index';\nimport { SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Custom Tooltip when hovering a cell, it subscribes to the cell \"onMouseEnter\" and \"onMouseLeave\" events.\n * The \"customTooltip\" is defined in the Column Definition OR Grid Options (the first found will have priority over the second)\n *\n * USAGE:\n *\n * Add the slick.customTooltip.(js|css) files and register it with the grid.\n *\n * To specify a tooltip when hovering a cell, extend the column definition like so:\n * const customTooltipPlugin = new Slick.Plugins.CustomTooltip(columns, grid options);\n *\n * Available plugin options (same options are available in both column definition and/or grid options)\n *\n * Example 1 - via Column Definition\n * const columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * }\n * }\n * ];\n *\n * OR Example 2 - via Grid Options (for all columns), NOTE: the column definition tooltip options will win over the options defined in the grid options\n * const gridOptions = {\n * enableCellNavigation: true,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * },\n * };\n *\n * Available options that can be defined from either a column definition or in grid options (column definition options as precendence)\n * asyncParamsPropName: defaults to \"__params\", optionally change the property name that will be used to merge the data returned by the async method into the `dataContext` object\n * asyncProcess: Async Post method returning a Promise, it must return an object with 1 or more properties. internally the data that will automatically be merged into the `dataContext` object under the `__params` property so that you can use it in your `asyncPostFormatter` formatter.\n * asyncPostFormatter: Formatter to execute once the async process is completed, to displayed the actual text result (used when dealing with an Async API to get data to display later in the tooltip)\n * hideArrow: defaults to False, should we hide the tooltip pointer arrow?\n * className: defaults to \"slick-custom-tooltip\"\n * formatter: Formatter to execute for displaying the data that will show in the tooltip. NOTE: when using `asyncProcess`, this formatter will be executed first and prior to the actual async process.\n * headerFormatter: Formatter to execute when custom tooltip is over a header column\n * headerRowFormatter: Formatter to execute when custom tooltip is over a heade row column (e.g. filter)\n * maxHeight: optional maximum height number (in pixel) of the tooltip container\n * maxWidth: optional maximum width number (in pixel) of the tooltip container\n * offsetLeft: defaults to 0, optional left offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetRight: defaults to 0, optional right offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetTopBottom: defaults to 4, optional top or bottom offset (depending on which side it shows), it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * position: defaults to \"auto\" (available options: 'auto' | 'top' | 'bottom' | 'left-align' | 'right-align'), allows to align the tooltip to the best logical position in the window, by default it will show on top left but if it calculates that it doesn't have enough space it will use bottom (same goes for each side align)\n * regularTooltipWhiteSpace: defaults to `pre-line`, optionally change the style `white-space` when displaying regular text tooltip. NOTE: when using a formatter it will use the `whiteSpace` setting instead\n * whiteSpace: defaults to `normal`, optionally change the style `white-space` when displaying tooltip with formatter (tooltip or regular formatter)\n * useRegularTooltip: defaults to False, when set to True it will try parse through the regular cell formatter and try to find a `title` attribute to show as a regular tooltip (also note: this has precedence over customTooltip formatter defined)\n * useRegularTooltipFromFormatterOnly: defaults to False, optionally force to retrieve the `title` from the Formatter result instead of the cell itself.\n * for example, when used in combo with the AutoTooltip plugin we might want to force the tooltip to read the `title` attribute from the formatter result first instead of the cell itself,\n * make the cell as a 2nd read, in other words check the formatter prior to the cell which the AutoTooltip might have filled.\n * renderRegularTooltipAsHtml: defaults to false, regular \"title\" tooltip won't be rendered as html unless specified via this flag (also \"\\r\\n\" will be replaced by
)\n * tooltipTextMaxLength: defaults to 700 (characters), when defined the text will be truncated to the max length characters provided\n * usabilityOverride: callback method that user can override the default behavior of showing the tooltip. If it returns False, then the tooltip won't show\n *\n * @param options {Object} Custom Tooltip Options\n * @class Slick.Plugins.CustomTooltip\n * @constructor\n */\n\ntype CellType = 'slick-cell' | 'slick-header-column' | 'slick-headerrow-column';\n\n/**\n * CustomTooltip plugin to show/hide tooltips when columns are too narrow to fit content.\n * @constructor\n * @param {boolean} [options.className=\"slick-custom-tooltip\"] - custom tooltip class name\n * @param {boolean} [options.offsetTop=5] - tooltip offset from the top\n */\nexport class CustomTooltip {\n // --\n // public API\n pluginName = 'CustomTooltip' as const;\n\n // --\n // protected props\n protected _cancellablePromise?: CancellablePromiseWrapper;\n protected _cellNodeElm?: HTMLDivElement;\n protected _dataView?: SlickDataView | null;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _tooltipElm?: HTMLDivElement;\n protected _options!: CustomTooltipOption;\n protected _defaults: CustomTooltipOption = {\n className: 'slick-custom-tooltip',\n offsetLeft: 0,\n offsetRight: 0,\n offsetTopBottom: 4,\n hideArrow: false,\n tooltipTextMaxLength: 700,\n regularTooltipWhiteSpace: 'pre-line',\n whiteSpace: 'normal',\n };\n protected _eventHandler = new SlickEventHandler();\n protected _cellTooltipOptions!: CustomTooltipOption;\n\n constructor(protected readonly tooltipOptions: Partial) { }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n const _data = grid?.getData() || [];\n this._dataView = Array.isArray(_data) ? null : _data as SlickDataView;\n this._gridOptions = (grid.getOptions() || {}) as GridOption;\n this._options = Utils.extend(true, {}, this._defaults, this._gridOptions.customTooltip, this.tooltipOptions);\n this._eventHandler\n .subscribe(grid.onMouseEnter, this.handleOnMouseEnter.bind(this))\n .subscribe(grid.onHeaderMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-header-column'))\n .subscribe(grid.onHeaderRowMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-headerrow-column'))\n .subscribe(grid.onMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderRowMouseLeave, () => this.hideTooltip());\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.hideTooltip();\n this._eventHandler.unsubscribeAll();\n }\n\n /** depending on the selector type, execute the necessary handler code */\n protected handleOnHeaderMouseEnterByType(e: DOMEvent, args: any, selector: CellType) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n const cell = {\n row: -1, // negative row to avoid pulling any dataContext while rendering\n cell: this._grid.getColumns().findIndex((col) => args?.column?.id === col.id)\n };\n const columnDef = args.column;\n const item = {};\n const isHeaderRowType = selector === 'slick-headerrow-column';\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = isHeaderRowType ? 'header-row' : 'header';\n\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n if (columnDef && e.target) {\n this._cellNodeElm = (e.target as HTMLDivElement).closest(`.${selector}`) as HTMLDivElement;\n const formatter = isHeaderRowType ? this._cellTooltipOptions.headerRowFormatter : this._cellTooltipOptions.headerFormatter;\n\n if (this._cellTooltipOptions.useRegularTooltip || !formatter) {\n const formatterOrText = !isHeaderRowType ? columnDef.name : this._cellTooltipOptions.useRegularTooltip ? null : formatter;\n this.renderRegularTooltip(formatterOrText, cell, null, columnDef, item);\n } else if (this._cellNodeElm && typeof formatter === 'function') {\n this.renderTooltipFormatter(formatter, cell, null, columnDef, item);\n }\n }\n }\n\n /**\n * Handle mouse entering grid cell to show tooltip.\n * @param {jQuery.Event} e - The event\n */\n protected handleOnMouseEnter(e: DOMEvent, args: any) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n if (this._grid && e) {\n // get cell only when it's possible (ie, Composite Editor will not be able to get cell and so it will never show any tooltip)\n const targetClassName = (event?.target as HTMLDivElement)?.closest('.slick-cell')?.className;\n const cell = (targetClassName && /l\\d+/.exec(targetClassName || '')) ? this._grid.getCellFromEvent(e) : null;\n\n if (cell) {\n const item = this._dataView ? this._dataView.getItem(cell.row) : this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n this._cellNodeElm = this._grid.getCellNode(cell.row, cell.cell) as HTMLDivElement;\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n\n if (item && columnDef) {\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = 'cell';\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n const value = item.hasOwnProperty(columnDef.field) ? item[columnDef.field] : null;\n\n if (this._cellTooltipOptions.useRegularTooltip || !this._cellTooltipOptions.formatter) {\n this.renderRegularTooltip(columnDef.formatter, cell, value, columnDef, item);\n } else {\n if (typeof this._cellTooltipOptions.formatter === 'function') {\n this.renderTooltipFormatter(this._cellTooltipOptions.formatter, cell, value, columnDef, item);\n }\n if (typeof this._cellTooltipOptions.asyncProcess === 'function') {\n const asyncProcess = this._cellTooltipOptions.asyncProcess(cell.row, cell.cell, value, columnDef, item, this._grid);\n if (!this._cellTooltipOptions.asyncPostFormatter) {\n throw new Error('[SlickGrid] when using \"asyncProcess\", you must also provide an \"asyncPostFormatter\" formatter');\n }\n\n if (asyncProcess instanceof Promise) {\n // create a new cancellable promise which will resolve, unless it's cancelled, with the udpated `dataContext` object that includes the `this._this._params`\n this._cancellablePromise = this.cancellablePromise(asyncProcess);\n this._cancellablePromise.promise\n .then((asyncResult) => {\n this.asyncProcessCallback(asyncResult, cell, value, columnDef, item);\n })\n .catch(function (error) {\n // we will throw back any errors, unless it's a cancelled promise which in that case will be disregarded (thrown by the promise wrapper cancel() call)\n if (!(error.isPromiseCancelled)) {\n throw error;\n }\n });\n }\n }\n }\n }\n }\n }\n }\n\n protected findFirstElementAttribute(inputElm: Element | null | undefined, attributes: string[]): string | null {\n if (inputElm) {\n let outputAttrData: string | null = null;\n attributes.forEach((attribute) => {\n const attrData = inputElm.getAttribute(attribute);\n if (attrData) {\n outputAttrData = attrData;\n }\n });\n return outputAttrData;\n }\n return null;\n }\n\n /**\n * Parse the cell formatter and assume it might be html\n * then create a temporary html element to easily retrieve the first [title=\"\"] attribute text content\n * also clear the \"title\" attribute from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected renderRegularTooltip(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: any) {\n const tmpDiv = document.createElement('div');\n tmpDiv.innerHTML = this.parseFormatterAndSanitize(formatterOrText, cell, value, columnDef, item);\n let tooltipText = columnDef.toolTip || '';\n let tmpTitleElm;\n\n if (!tooltipText) {\n if ((this._cellNodeElm && (this._cellNodeElm.clientWidth < this._cellNodeElm.scrollWidth)) && !this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tooltipText = (this._cellNodeElm.textContent || '').trim() || '';\n if (this._cellTooltipOptions.tooltipTextMaxLength && (tooltipText.length > this._cellTooltipOptions.tooltipTextMaxLength)) {\n tooltipText = tooltipText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...';\n }\n tmpTitleElm = this._cellNodeElm;\n } else {\n if (this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tmpTitleElm = tmpDiv.querySelector('[title], [data-slick-tooltip]');\n } else {\n tmpTitleElm = this.findFirstElementAttribute(this._cellNodeElm, ['title', 'data-slick-tooltip']) ? this._cellNodeElm : tmpDiv.querySelector('[title], [data-slick-tooltip]');\n if ((!tmpTitleElm || !this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip'])) && this._cellNodeElm) {\n tmpTitleElm = this._cellNodeElm.querySelector('[title], [data-slick-tooltip]');\n }\n }\n if (!tooltipText || (typeof formatterOrText === 'function' && this._cellTooltipOptions.useRegularTooltipFromFormatterOnly)) {\n tooltipText = this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip']) || '';\n }\n }\n }\n\n if (tooltipText !== '') {\n this.renderTooltipFormatter(formatterOrText, cell, value, columnDef, item, tooltipText);\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(tmpTitleElm, tooltipText);\n }\n\n /**\n * swap and copy the \"title\" attribute into a new custom attribute then clear the \"title\" attribute\n * from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected swapAndClearTitleAttribute(inputTitleElm?: Element | null, tooltipText?: string) {\n // the title attribute might be directly on the slick-cell container element (when formatter returns a result object)\n // OR in a child element (most commonly as a custom formatter)\n const titleElm = inputTitleElm || (this._cellNodeElm && ((this._cellNodeElm.hasAttribute('title') && this._cellNodeElm.getAttribute('title')) ? this._cellNodeElm : this._cellNodeElm.querySelector('[title]')));\n\n // flip tooltip text from `title` to `data-slick-tooltip`\n if (titleElm) {\n titleElm.setAttribute('data-slick-tooltip', tooltipText || '');\n if (titleElm.hasAttribute('title')) {\n titleElm.setAttribute('title', '');\n }\n }\n }\n\n protected asyncProcessCallback(asyncResult: any, cell: { row: number, cell: number }, value: any, columnDef: Column, dataContext: any) {\n this.hideTooltip();\n const itemWithAsyncData = Utils.extend(true, {}, dataContext, { [this._cellTooltipOptions.asyncParamsPropName || '__params']: asyncResult });\n this.renderTooltipFormatter(this._cellTooltipOptions.asyncPostFormatter, cell, value, columnDef, itemWithAsyncData);\n }\n\n protected cancellablePromise(inputPromise: Promise): CancellablePromiseWrapper {\n let hasCancelled = false;\n\n if (inputPromise instanceof Promise) {\n return {\n promise: inputPromise.then(function (result) {\n if (hasCancelled) {\n throw { isPromiseCancelled: true };\n }\n return result;\n }),\n cancel: () => hasCancelled = true\n };\n }\n return inputPromise;\n }\n\n protected getHtmlElementOffset(element?: HTMLElement | null) {\n if (!element) {\n return undefined;\n }\n const rect = element.getBoundingClientRect();\n let left = 0;\n let top = 0;\n let bottom = 0;\n let right = 0;\n\n if (rect.top !== undefined && rect.left !== undefined) {\n top = rect.top + window.pageYOffset;\n left = rect.left + window.pageXOffset;\n right = rect.right;\n bottom = rect.bottom;\n }\n return { top, left, bottom, right };\n }\n\n /**\n * hide (remove) tooltip from the DOM,\n * when using async process, it will also cancel any opened Promise/Observable that might still be opened/pending.\n */\n hideTooltip() {\n this._cancellablePromise?.cancel();\n const prevTooltip = document.body.querySelector(`.${this._cellTooltipOptions?.className ?? this._defaults.className}.${this._grid.getUID()}`);\n prevTooltip?.remove();\n }\n\n /**\n * Reposition the Tooltip to be top-left position over the cell.\n * By default we use an \"auto\" mode which will allow to position the Tooltip to the best logical position in the window, also when we mention position, we are talking about the relative position against the grid cell.\n * We can assume that in 80% of the time the default position is top-right, the default is \"auto\" but we can also override it and use a specific position.\n * Most of the time positioning of the tooltip will be to the \"top-right\" of the cell is ok but if our column is completely on the right side then we'll want to change the position to \"left\" align.\n * Same goes for the top/bottom position, Most of the time positioning the tooltip to the \"top\" but if we are hovering a cell at the top of the grid and there's no room to display it then we might need to reposition to \"bottom\" instead.\n */\n protected reposition(cell: { row: number; cell: number; }) {\n if (this._tooltipElm) {\n this._cellNodeElm = (this._cellNodeElm || this._grid.getCellNode(cell.row, cell.cell)) as HTMLDivElement;\n const cellPosition = this.getHtmlElementOffset(this._cellNodeElm);\n const cellContainerWidth = this._cellNodeElm.offsetWidth;\n const calculatedTooltipHeight = this._tooltipElm.getBoundingClientRect().height;\n const calculatedTooltipWidth = this._tooltipElm.getBoundingClientRect().width;\n const calculatedBodyWidth = document.body.offsetWidth || window.innerWidth;\n\n // first calculate the default (top/left) position\n let newPositionTop = (cellPosition?.top || 0) - this._tooltipElm.offsetHeight - (this._cellTooltipOptions.offsetTopBottom ?? 0);\n let newPositionLeft = (cellPosition?.left || 0) - (this._cellTooltipOptions.offsetRight ?? 0);\n\n // user could explicitely use a \"left-align\" arrow position, (when user knows his column is completely on the right in the grid)\n // or when using \"auto\" and we detect not enough available space then we'll position to the \"left\" of the cell\n const position = this._cellTooltipOptions.position || 'auto';\n if (position === 'center') {\n newPositionLeft += (cellContainerWidth / 2) - (calculatedTooltipWidth / 2) + (this._cellTooltipOptions.offsetRight || 0);\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-center-align');\n\n } else if (position === 'right-align' || ((position === 'auto' || position !== 'left-align') && (newPositionLeft + calculatedTooltipWidth) > calculatedBodyWidth)) {\n newPositionLeft -= (calculatedTooltipWidth - cellContainerWidth - (this._cellTooltipOptions.offsetLeft || 0));\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.add('arrow-right-align');\n } else {\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-left-align');\n }\n\n // do the same calculation/reposition with top/bottom (default is top of the cell or in other word starting from the cell going down)\n if (position === 'bottom' || (position === 'auto' && calculatedTooltipHeight > Utils.calculateAvailableSpace(this._cellNodeElm).top)) {\n newPositionTop = (cellPosition?.top || 0) + (this._gridOptions.rowHeight || 0) + (this._cellTooltipOptions.offsetTopBottom || 0);\n this._tooltipElm.classList.remove('arrow-down');\n this._tooltipElm.classList.add('arrow-up');\n } else {\n this._tooltipElm.classList.add('arrow-down');\n this._tooltipElm.classList.remove('arrow-up');\n }\n\n // reposition the tooltip over the cell (90% of the time this will end up using a position on the \"right\" of the cell)\n this._tooltipElm.style.top = newPositionTop + 'px';\n this._tooltipElm.style.left = newPositionLeft + 'px';\n }\n }\n\n /**\n * Parse the Custom Formatter (when provided) or return directly the text when it is already a string.\n * We will also sanitize the text in both cases before returning it so that it can be used safely.\n */\n protected parseFormatterAndSanitize(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown): string {\n if (typeof formatterOrText === 'function') {\n const tooltipText = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid);\n const formatterText = (typeof tooltipText === 'object' && tooltipText?.text) ? tooltipText.text : (typeof tooltipText === 'string' ? tooltipText : '');\n return this._grid.sanitizeHtmlString(formatterText);\n } else if (typeof formatterOrText === 'string') {\n return this._grid.sanitizeHtmlString(formatterOrText);\n }\n return '';\n }\n\n\n protected renderTooltipFormatter(formatter: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown, tooltipText?: string, inputTitleElm?: Element | null) {\n // create the tooltip DOM element with the text returned by the Formatter\n this._tooltipElm = document.createElement('div');\n this._tooltipElm.className = (this._cellTooltipOptions.className || this._defaults.className) as string;\n this._tooltipElm.classList.add(this._grid.getUID());\n this._tooltipElm.classList.add('l' + cell.cell);\n this._tooltipElm.classList.add('r' + cell.cell);\n let outputText = tooltipText || this.parseFormatterAndSanitize(formatter, cell, value, columnDef, item) || '';\n outputText = (this._cellTooltipOptions.tooltipTextMaxLength && outputText.length > this._cellTooltipOptions.tooltipTextMaxLength) ? outputText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...' : outputText;\n\n let finalOutputText = '';\n if (!tooltipText || (this._cellTooltipOptions?.renderRegularTooltipAsHtml)) {\n finalOutputText = this._grid.sanitizeHtmlString(outputText);\n this._tooltipElm.innerHTML = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.whiteSpace ?? this._defaults.whiteSpace as string;\n } else {\n finalOutputText = outputText || '';\n this._tooltipElm.textContent = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.regularTooltipWhiteSpace ?? this._defaults.regularTooltipWhiteSpace as string; // use `pre` so that sequences of white space are collapsed. Lines are broken at newline characters\n }\n\n // optional max height/width of the tooltip container\n if (this._cellTooltipOptions.maxHeight) {\n this._tooltipElm.style.maxHeight = this._cellTooltipOptions.maxHeight + 'px';\n }\n if (this._cellTooltipOptions.maxWidth) {\n this._tooltipElm.style.maxWidth = this._cellTooltipOptions.maxWidth + 'px';\n }\n\n // when do have text to show, then append the new tooltip to the html body & reposition the tooltip\n if (finalOutputText) {\n document.body.appendChild(this._tooltipElm);\n\n // reposition the tooltip on top of the cell that triggered the mouse over event\n this.reposition(cell);\n\n // user could optionally hide the tooltip arrow (we can simply update the CSS variables, that's the only way we have to update CSS pseudo)\n if (!this._cellTooltipOptions.hideArrow) {\n this._tooltipElm.classList.add('tooltip-arrow');\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(inputTitleElm, outputText);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CustomTooltip\n }\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import type { CancellablePromiseWrapper, Column, CustomTooltipOption, DOMEvent, Formatter, FormatterResultWithHtml, FormatterResultWithText, GridOption } from '../models/index';\nimport { SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add Custom Tooltip when hovering a cell, it subscribes to the cell \"onMouseEnter\" and \"onMouseLeave\" events.\n * The \"customTooltip\" is defined in the Column Definition OR Grid Options (the first found will have priority over the second)\n *\n * USAGE:\n *\n * Add the slick.customTooltip.(js|css) files and register it with the grid.\n *\n * To specify a tooltip when hovering a cell, extend the column definition like so:\n * const customTooltipPlugin = new Slick.Plugins.CustomTooltip(columns, grid options);\n *\n * Available plugin options (same options are available in both column definition and/or grid options)\n *\n * Example 1 - via Column Definition\n * const columns = [\n * {\n * id: \"action\", name: \"Action\", field: \"action\", formatter: fakeButtonFormatter,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * }\n * }\n * ];\n *\n * OR Example 2 - via Grid Options (for all columns), NOTE: the column definition tooltip options will win over the options defined in the grid options\n * const gridOptions = {\n * enableCellNavigation: true,\n * customTooltip: {\n * formatter: tooltipTaskFormatter,\n * usabilityOverride: (args) => !!(args.dataContext.id % 2) // show it only every second row\n * },\n * };\n *\n * Available options that can be defined from either a column definition or in grid options (column definition options as precendence)\n * asyncParamsPropName: defaults to \"__params\", optionally change the property name that will be used to merge the data returned by the async method into the `dataContext` object\n * asyncProcess: Async Post method returning a Promise, it must return an object with 1 or more properties. internally the data that will automatically be merged into the `dataContext` object under the `__params` property so that you can use it in your `asyncPostFormatter` formatter.\n * asyncPostFormatter: Formatter to execute once the async process is completed, to displayed the actual text result (used when dealing with an Async API to get data to display later in the tooltip)\n * hideArrow: defaults to False, should we hide the tooltip pointer arrow?\n * className: defaults to \"slick-custom-tooltip\"\n * formatter: Formatter to execute for displaying the data that will show in the tooltip. NOTE: when using `asyncProcess`, this formatter will be executed first and prior to the actual async process.\n * headerFormatter: Formatter to execute when custom tooltip is over a header column\n * headerRowFormatter: Formatter to execute when custom tooltip is over a heade row column (e.g. filter)\n * maxHeight: optional maximum height number (in pixel) of the tooltip container\n * maxWidth: optional maximum width number (in pixel) of the tooltip container\n * offsetLeft: defaults to 0, optional left offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetRight: defaults to 0, optional right offset, it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * offsetTopBottom: defaults to 4, optional top or bottom offset (depending on which side it shows), it must be a positive/negative number (in pixel) that will be added to the offset position calculation of the tooltip container.\n * position: defaults to \"auto\" (available options: 'auto' | 'top' | 'bottom' | 'left-align' | 'right-align'), allows to align the tooltip to the best logical position in the window, by default it will show on top left but if it calculates that it doesn't have enough space it will use bottom (same goes for each side align)\n * regularTooltipWhiteSpace: defaults to `pre-line`, optionally change the style `white-space` when displaying regular text tooltip. NOTE: when using a formatter it will use the `whiteSpace` setting instead\n * whiteSpace: defaults to `normal`, optionally change the style `white-space` when displaying tooltip with formatter (tooltip or regular formatter)\n * useRegularTooltip: defaults to False, when set to True it will try parse through the regular cell formatter and try to find a `title` attribute to show as a regular tooltip (also note: this has precedence over customTooltip formatter defined)\n * useRegularTooltipFromFormatterOnly: defaults to False, optionally force to retrieve the `title` from the Formatter result instead of the cell itself.\n * for example, when used in combo with the AutoTooltip plugin we might want to force the tooltip to read the `title` attribute from the formatter result first instead of the cell itself,\n * make the cell as a 2nd read, in other words check the formatter prior to the cell which the AutoTooltip might have filled.\n * renderRegularTooltipAsHtml: defaults to false, regular \"title\" tooltip won't be rendered as html unless specified via this flag (also \"\\r\\n\" will be replaced by
)\n * tooltipTextMaxLength: defaults to 700 (characters), when defined the text will be truncated to the max length characters provided\n * usabilityOverride: callback method that user can override the default behavior of showing the tooltip. If it returns False, then the tooltip won't show\n *\n * @param options {Object} Custom Tooltip Options\n * @class Slick.Plugins.CustomTooltip\n * @constructor\n */\n\ntype CellType = 'slick-cell' | 'slick-header-column' | 'slick-headerrow-column';\n\n/**\n * CustomTooltip plugin to show/hide tooltips when columns are too narrow to fit content.\n * @constructor\n * @param {boolean} [options.className=\"slick-custom-tooltip\"] - custom tooltip class name\n * @param {boolean} [options.offsetTop=5] - tooltip offset from the top\n */\nexport class SlickCustomTooltip {\n // --\n // public API\n pluginName = 'CustomTooltip' as const;\n\n // --\n // protected props\n protected _cancellablePromise?: CancellablePromiseWrapper;\n protected _cellNodeElm?: HTMLDivElement;\n protected _dataView?: SlickDataView | null;\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _tooltipElm?: HTMLDivElement;\n protected _options!: CustomTooltipOption;\n protected _defaults: CustomTooltipOption = {\n className: 'slick-custom-tooltip',\n offsetLeft: 0,\n offsetRight: 0,\n offsetTopBottom: 4,\n hideArrow: false,\n tooltipTextMaxLength: 700,\n regularTooltipWhiteSpace: 'pre-line',\n whiteSpace: 'normal',\n };\n protected _eventHandler = new SlickEventHandler();\n protected _cellTooltipOptions!: CustomTooltipOption;\n\n constructor(protected readonly tooltipOptions: Partial) { }\n\n /**\n * Initialize plugin.\n */\n init(grid: SlickGrid) {\n this._grid = grid;\n const _data = grid?.getData() || [];\n this._dataView = Array.isArray(_data) ? null : _data as SlickDataView;\n this._gridOptions = (grid.getOptions() || {}) as GridOption;\n this._options = Utils.extend(true, {}, this._defaults, this._gridOptions.customTooltip, this.tooltipOptions);\n this._eventHandler\n .subscribe(grid.onMouseEnter, this.handleOnMouseEnter.bind(this))\n .subscribe(grid.onHeaderMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-header-column'))\n .subscribe(grid.onHeaderRowMouseEnter, (e, args) => this.handleOnHeaderMouseEnterByType(e, args, 'slick-headerrow-column'))\n .subscribe(grid.onMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderMouseLeave, () => this.hideTooltip())\n .subscribe(grid.onHeaderRowMouseLeave, () => this.hideTooltip());\n }\n\n /**\n * Destroy plugin.\n */\n destroy() {\n this.hideTooltip();\n this._eventHandler.unsubscribeAll();\n }\n\n /** depending on the selector type, execute the necessary handler code */\n protected handleOnHeaderMouseEnterByType(e: DOMEvent, args: any, selector: CellType) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n const cell = {\n row: -1, // negative row to avoid pulling any dataContext while rendering\n cell: this._grid.getColumns().findIndex((col) => args?.column?.id === col.id)\n };\n const columnDef = args.column;\n const item = {};\n const isHeaderRowType = selector === 'slick-headerrow-column';\n\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = isHeaderRowType ? 'header-row' : 'header';\n\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n if (columnDef && e.target) {\n this._cellNodeElm = (e.target as HTMLDivElement).closest(`.${selector}`) as HTMLDivElement;\n const formatter = isHeaderRowType ? this._cellTooltipOptions.headerRowFormatter : this._cellTooltipOptions.headerFormatter;\n\n if (this._cellTooltipOptions.useRegularTooltip || !formatter) {\n const formatterOrText = !isHeaderRowType ? columnDef.name : this._cellTooltipOptions.useRegularTooltip ? null : formatter;\n this.renderRegularTooltip(formatterOrText, cell, null, columnDef, item);\n } else if (this._cellNodeElm && typeof formatter === 'function') {\n this.renderTooltipFormatter(formatter, cell, null, columnDef, item);\n }\n }\n }\n\n /**\n * Handle mouse entering grid cell to show tooltip.\n * @param {jQuery.Event} e - The event\n */\n protected handleOnMouseEnter(e: DOMEvent, args: any) {\n // before doing anything, let's remove any previous tooltip before\n // and cancel any opened Promise/Observable when using async\n this.hideTooltip();\n\n if (this._grid && e) {\n // get cell only when it's possible (ie, Composite Editor will not be able to get cell and so it will never show any tooltip)\n const targetClassName = (event?.target as HTMLDivElement)?.closest('.slick-cell')?.className;\n const cell = (targetClassName && /l\\d+/.exec(targetClassName || '')) ? this._grid.getCellFromEvent(e) : null;\n\n if (cell) {\n const item = this._dataView ? this._dataView.getItem(cell.row) : this._grid.getDataItem(cell.row);\n const columnDef = this._grid.getColumns()[cell.cell];\n this._cellNodeElm = this._grid.getCellNode(cell.row, cell.cell) as HTMLDivElement;\n this._cellTooltipOptions = Utils.extend(true, {}, this._options, columnDef.customTooltip);\n\n if (item && columnDef) {\n // run the override function (when defined), if the result is false it won't go further\n args = args || {};\n args.cell = cell.cell;\n args.row = cell.row;\n args.columnDef = columnDef;\n args.dataContext = item;\n args.grid = this._grid;\n args.type = 'cell';\n if ((columnDef?.disableTooltip) || !this.runOverrideFunctionWhenExists(this._cellTooltipOptions.usabilityOverride, args)) {\n return;\n }\n\n const value = item.hasOwnProperty(columnDef.field) ? item[columnDef.field] : null;\n\n if (this._cellTooltipOptions.useRegularTooltip || !this._cellTooltipOptions.formatter) {\n this.renderRegularTooltip(columnDef.formatter, cell, value, columnDef, item);\n } else {\n if (typeof this._cellTooltipOptions.formatter === 'function') {\n this.renderTooltipFormatter(this._cellTooltipOptions.formatter, cell, value, columnDef, item);\n }\n if (typeof this._cellTooltipOptions.asyncProcess === 'function') {\n const asyncProcess = this._cellTooltipOptions.asyncProcess(cell.row, cell.cell, value, columnDef, item, this._grid);\n if (!this._cellTooltipOptions.asyncPostFormatter) {\n throw new Error('[SlickGrid] when using \"asyncProcess\", you must also provide an \"asyncPostFormatter\" formatter');\n }\n\n if (asyncProcess instanceof Promise) {\n // create a new cancellable promise which will resolve, unless it's cancelled, with the udpated `dataContext` object that includes the `this._this._params`\n this._cancellablePromise = this.cancellablePromise(asyncProcess);\n this._cancellablePromise.promise\n .then((asyncResult) => {\n this.asyncProcessCallback(asyncResult, cell, value, columnDef, item);\n })\n .catch(function (error) {\n // we will throw back any errors, unless it's a cancelled promise which in that case will be disregarded (thrown by the promise wrapper cancel() call)\n if (!(error.isPromiseCancelled)) {\n throw error;\n }\n });\n }\n }\n }\n }\n }\n }\n }\n\n protected findFirstElementAttribute(inputElm: Element | null | undefined, attributes: string[]): string | null {\n if (inputElm) {\n let outputAttrData: string | null = null;\n attributes.forEach((attribute) => {\n const attrData = inputElm.getAttribute(attribute);\n if (attrData) {\n outputAttrData = attrData;\n }\n });\n return outputAttrData;\n }\n return null;\n }\n\n /**\n * Parse the cell formatter and assume it might be html\n * then create a temporary html element to easily retrieve the first [title=\"\"] attribute text content\n * also clear the \"title\" attribute from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected renderRegularTooltip(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: any) {\n const tmpDiv = document.createElement('div');\n tmpDiv.innerHTML = this.parseFormatterAndSanitize(formatterOrText, cell, value, columnDef, item);\n let tooltipText = columnDef.toolTip || '';\n let tmpTitleElm;\n\n if (!tooltipText) {\n if ((this._cellNodeElm && (this._cellNodeElm.clientWidth < this._cellNodeElm.scrollWidth)) && !this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tooltipText = (this._cellNodeElm.textContent || '').trim() || '';\n if (this._cellTooltipOptions.tooltipTextMaxLength && (tooltipText.length > this._cellTooltipOptions.tooltipTextMaxLength)) {\n tooltipText = tooltipText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...';\n }\n tmpTitleElm = this._cellNodeElm;\n } else {\n if (this._cellTooltipOptions.useRegularTooltipFromFormatterOnly) {\n tmpTitleElm = tmpDiv.querySelector('[title], [data-slick-tooltip]');\n } else {\n tmpTitleElm = this.findFirstElementAttribute(this._cellNodeElm, ['title', 'data-slick-tooltip']) ? this._cellNodeElm : tmpDiv.querySelector('[title], [data-slick-tooltip]');\n if ((!tmpTitleElm || !this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip'])) && this._cellNodeElm) {\n tmpTitleElm = this._cellNodeElm.querySelector('[title], [data-slick-tooltip]');\n }\n }\n if (!tooltipText || (typeof formatterOrText === 'function' && this._cellTooltipOptions.useRegularTooltipFromFormatterOnly)) {\n tooltipText = this.findFirstElementAttribute(tmpTitleElm, ['title', 'data-slick-tooltip']) || '';\n }\n }\n }\n\n if (tooltipText !== '') {\n this.renderTooltipFormatter(formatterOrText, cell, value, columnDef, item, tooltipText);\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(tmpTitleElm, tooltipText);\n }\n\n /**\n * swap and copy the \"title\" attribute into a new custom attribute then clear the \"title\" attribute\n * from the grid div text content so that it won't show also as a 2nd browser tooltip\n */\n protected swapAndClearTitleAttribute(inputTitleElm?: Element | null, tooltipText?: string) {\n // the title attribute might be directly on the slick-cell container element (when formatter returns a result object)\n // OR in a child element (most commonly as a custom formatter)\n const titleElm = inputTitleElm || (this._cellNodeElm && ((this._cellNodeElm.hasAttribute('title') && this._cellNodeElm.getAttribute('title')) ? this._cellNodeElm : this._cellNodeElm.querySelector('[title]')));\n\n // flip tooltip text from `title` to `data-slick-tooltip`\n if (titleElm) {\n titleElm.setAttribute('data-slick-tooltip', tooltipText || '');\n if (titleElm.hasAttribute('title')) {\n titleElm.setAttribute('title', '');\n }\n }\n }\n\n protected asyncProcessCallback(asyncResult: any, cell: { row: number, cell: number }, value: any, columnDef: Column, dataContext: any) {\n this.hideTooltip();\n const itemWithAsyncData = Utils.extend(true, {}, dataContext, { [this._cellTooltipOptions.asyncParamsPropName || '__params']: asyncResult });\n this.renderTooltipFormatter(this._cellTooltipOptions.asyncPostFormatter, cell, value, columnDef, itemWithAsyncData);\n }\n\n protected cancellablePromise(inputPromise: Promise): CancellablePromiseWrapper {\n let hasCancelled = false;\n\n if (inputPromise instanceof Promise) {\n return {\n promise: inputPromise.then(function (result) {\n if (hasCancelled) {\n throw { isPromiseCancelled: true };\n }\n return result;\n }),\n cancel: () => hasCancelled = true\n };\n }\n return inputPromise;\n }\n\n protected getHtmlElementOffset(element?: HTMLElement | null) {\n if (!element) {\n return undefined;\n }\n const rect = element.getBoundingClientRect();\n let left = 0;\n let top = 0;\n let bottom = 0;\n let right = 0;\n\n if (rect.top !== undefined && rect.left !== undefined) {\n top = rect.top + window.pageYOffset;\n left = rect.left + window.pageXOffset;\n right = rect.right;\n bottom = rect.bottom;\n }\n return { top, left, bottom, right };\n }\n\n /**\n * hide (remove) tooltip from the DOM,\n * when using async process, it will also cancel any opened Promise/Observable that might still be opened/pending.\n */\n hideTooltip() {\n this._cancellablePromise?.cancel();\n const prevTooltip = document.body.querySelector(`.${this._cellTooltipOptions?.className ?? this._defaults.className}.${this._grid.getUID()}`);\n prevTooltip?.remove();\n }\n\n /**\n * Reposition the Tooltip to be top-left position over the cell.\n * By default we use an \"auto\" mode which will allow to position the Tooltip to the best logical position in the window, also when we mention position, we are talking about the relative position against the grid cell.\n * We can assume that in 80% of the time the default position is top-right, the default is \"auto\" but we can also override it and use a specific position.\n * Most of the time positioning of the tooltip will be to the \"top-right\" of the cell is ok but if our column is completely on the right side then we'll want to change the position to \"left\" align.\n * Same goes for the top/bottom position, Most of the time positioning the tooltip to the \"top\" but if we are hovering a cell at the top of the grid and there's no room to display it then we might need to reposition to \"bottom\" instead.\n */\n protected reposition(cell: { row: number; cell: number; }) {\n if (this._tooltipElm) {\n this._cellNodeElm = (this._cellNodeElm || this._grid.getCellNode(cell.row, cell.cell)) as HTMLDivElement;\n const cellPosition = this.getHtmlElementOffset(this._cellNodeElm);\n const cellContainerWidth = this._cellNodeElm.offsetWidth;\n const calculatedTooltipHeight = this._tooltipElm.getBoundingClientRect().height;\n const calculatedTooltipWidth = this._tooltipElm.getBoundingClientRect().width;\n const calculatedBodyWidth = document.body.offsetWidth || window.innerWidth;\n\n // first calculate the default (top/left) position\n let newPositionTop = (cellPosition?.top || 0) - this._tooltipElm.offsetHeight - (this._cellTooltipOptions.offsetTopBottom ?? 0);\n let newPositionLeft = (cellPosition?.left || 0) - (this._cellTooltipOptions.offsetRight ?? 0);\n\n // user could explicitely use a \"left-align\" arrow position, (when user knows his column is completely on the right in the grid)\n // or when using \"auto\" and we detect not enough available space then we'll position to the \"left\" of the cell\n const position = this._cellTooltipOptions.position || 'auto';\n if (position === 'center') {\n newPositionLeft += (cellContainerWidth / 2) - (calculatedTooltipWidth / 2) + (this._cellTooltipOptions.offsetRight || 0);\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-center-align');\n\n } else if (position === 'right-align' || ((position === 'auto' || position !== 'left-align') && (newPositionLeft + calculatedTooltipWidth) > calculatedBodyWidth)) {\n newPositionLeft -= (calculatedTooltipWidth - cellContainerWidth - (this._cellTooltipOptions.offsetLeft || 0));\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-left-align');\n this._tooltipElm.classList.add('arrow-right-align');\n } else {\n this._tooltipElm.classList.remove('arrow-center-align');\n this._tooltipElm.classList.remove('arrow-right-align');\n this._tooltipElm.classList.add('arrow-left-align');\n }\n\n // do the same calculation/reposition with top/bottom (default is top of the cell or in other word starting from the cell going down)\n if (position === 'bottom' || (position === 'auto' && calculatedTooltipHeight > Utils.calculateAvailableSpace(this._cellNodeElm).top)) {\n newPositionTop = (cellPosition?.top || 0) + (this._gridOptions.rowHeight || 0) + (this._cellTooltipOptions.offsetTopBottom || 0);\n this._tooltipElm.classList.remove('arrow-down');\n this._tooltipElm.classList.add('arrow-up');\n } else {\n this._tooltipElm.classList.add('arrow-down');\n this._tooltipElm.classList.remove('arrow-up');\n }\n\n // reposition the tooltip over the cell (90% of the time this will end up using a position on the \"right\" of the cell)\n this._tooltipElm.style.top = newPositionTop + 'px';\n this._tooltipElm.style.left = newPositionLeft + 'px';\n }\n }\n\n /**\n * Parse the Custom Formatter (when provided) or return directly the text when it is already a string.\n * We will also sanitize the text in both cases before returning it so that it can be used safely.\n */\n protected parseFormatterAndSanitize(formatterOrText: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown): string {\n if (typeof formatterOrText === 'function') {\n const tooltipResult = formatterOrText(cell.row, cell.cell, value, columnDef, item, this._grid);\n let formatterText = (Object.prototype.toString.call(tooltipResult) !== '[object Object]' ? tooltipResult : (tooltipResult as FormatterResultWithHtml).html || (tooltipResult as FormatterResultWithText).text);\n if (formatterText instanceof HTMLElement) {\n formatterText = formatterText.outerHTML;\n }\n return this._grid.sanitizeHtmlString(formatterText as string);\n } else if (typeof formatterOrText === 'string') {\n return this._grid.sanitizeHtmlString(formatterOrText);\n }\n return '';\n }\n\n\n protected renderTooltipFormatter(formatter: Formatter | string | undefined, cell: { row: number; cell: number; }, value: any, columnDef: Column, item: unknown, tooltipText?: string, inputTitleElm?: Element | null) {\n // create the tooltip DOM element with the text returned by the Formatter\n this._tooltipElm = document.createElement('div');\n this._tooltipElm.className = (this._cellTooltipOptions.className || this._defaults.className) as string;\n this._tooltipElm.classList.add(this._grid.getUID());\n this._tooltipElm.classList.add('l' + cell.cell);\n this._tooltipElm.classList.add('r' + cell.cell);\n let outputText = tooltipText || this.parseFormatterAndSanitize(formatter, cell, value, columnDef, item) || '';\n outputText = (this._cellTooltipOptions.tooltipTextMaxLength && outputText.length > this._cellTooltipOptions.tooltipTextMaxLength) ? outputText.substring(0, this._cellTooltipOptions.tooltipTextMaxLength - 3) + '...' : outputText;\n\n let finalOutputText = '';\n if (!tooltipText || (this._cellTooltipOptions?.renderRegularTooltipAsHtml)) {\n finalOutputText = this._grid.sanitizeHtmlString(outputText);\n this._tooltipElm.innerHTML = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.whiteSpace ?? this._defaults.whiteSpace as string;\n } else {\n finalOutputText = outputText || '';\n this._tooltipElm.textContent = finalOutputText;\n this._tooltipElm.style.whiteSpace = this._cellTooltipOptions?.regularTooltipWhiteSpace ?? this._defaults.regularTooltipWhiteSpace as string; // use `pre` so that sequences of white space are collapsed. Lines are broken at newline characters\n }\n\n // optional max height/width of the tooltip container\n if (this._cellTooltipOptions.maxHeight) {\n this._tooltipElm.style.maxHeight = this._cellTooltipOptions.maxHeight + 'px';\n }\n if (this._cellTooltipOptions.maxWidth) {\n this._tooltipElm.style.maxWidth = this._cellTooltipOptions.maxWidth + 'px';\n }\n\n // when do have text to show, then append the new tooltip to the html body & reposition the tooltip\n if (finalOutputText) {\n document.body.appendChild(this._tooltipElm);\n\n // reposition the tooltip on top of the cell that triggered the mouse over event\n this.reposition(cell);\n\n // user could optionally hide the tooltip arrow (we can simply update the CSS variables, that's the only way we have to update CSS pseudo)\n if (!this._cellTooltipOptions.hideArrow) {\n this._tooltipElm.classList.add('tooltip-arrow');\n }\n\n // also clear any \"title\" attribute to avoid showing a 2nd browser tooltip\n this.swapAndClearTitleAttribute(inputTitleElm, outputText);\n }\n }\n\n /**\n * Method that user can pass to override the default behavior.\n * In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.\n * @param overrideFn: override function callback\n * @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)\n */\n protected runOverrideFunctionWhenExists(overrideFn: ((args: any) => boolean) | undefined, args: T): boolean {\n if (typeof overrideFn === 'function') {\n return overrideFn.call(this, args);\n }\n return true;\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n CustomTooltip: SlickCustomTooltip\n }\n }\n });\n}\n\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/plugins/slick.rowdetailview.js.map b/dist/browser/plugins/slick.rowdetailview.js.map index d093ab0b7..e56502fa8 100644 --- a/dist/browser/plugins/slick.rowdetailview.js.map +++ b/dist/browser/plugins/slick.rowdetailview.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.rowdetailview.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, FormatterResultObject, GridOption, OnAfterRowDetailToggleArgs, OnBeforeRowDetailToggleArgs, OnRowBackToViewportRangeArgs, OnRowDetailAsyncEndUpdateArgs, OnRowDetailAsyncResponseArgs, OnRowOutOfViewportRangeArgs, RowDetailViewOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add row detail panel\n * Original StackOverflow question & article making this possible (thanks to violet313)\n * https://stackoverflow.com/questions/10535164/can-slickgrids-row-height-be-dynamically-altered#29399927\n * http://violet313.org/slickgrids/#intro\n *\n * USAGE:\n * Add the slick.rowDetailView.(js|css) files and register the plugin with the grid.\n *\n * AVAILABLE ROW DETAIL OPTIONS:\n * cssClass: A CSS class to be added to the row detail\n * expandedClass: Extra classes to be added to the expanded Toggle\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * collapsedClass: Extra classes to be added to the collapse Toggle\n * loadOnce: Defaults to false, when set to True it will load the data once and then reuse it.\n * preTemplate: Template that will be used before the async process (typically used to show a spinner/loading)\n * postTemplate: Template that will be loaded once the async function finishes\n * process: Async server function call\n * panelRows: Row count to use for the template panel\n * singleRowExpand: Defaults to false, limit expanded row to 1 at a time.\n * useRowClick: Boolean flag, when True will open the row detail on a row click (from any column), default to False\n * keyPrefix: Defaults to '_', prefix used for all the plugin metadata added to the item object (meta e.g.: padding, collapsed, parent)\n * collapseAllOnSort: Defaults to true, which will collapse all row detail views when user calls a sort. Unless user implements a sort to deal with padding\n * saveDetailViewOnScroll: Defaults to true, which will save the row detail view in a cache when it detects that it will become out of the viewport buffer\n * useSimpleViewportCalc: Defaults to false, which will use simplified calculation of out or back of viewport visibility\n *\n * AVAILABLE PUBLIC METHODS:\n * init: initiliaze the plugin\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * destroy: destroy the plugin and it's events\n * collapseAll: collapse all opened row detail panel\n * collapseDetailView: collapse a row by passing the item object (row detail)\n * expandDetailView: expand a row by passing the item object (row detail)\n * getColumnDefinition: get the column definitions\n * getExpandedRows: get all the expanded rows\n * getFilterItem: takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on\n * getOptions: get current plugin options\n * resizeDetailView: resize a row detail view, it will auto-calculate the number of rows it needs\n * saveDetailView: save a row detail view content by passing the row object\n * setOptions: set or change some of the plugin options\n *\n * THE PLUGIN EXPOSES THE FOLLOWING SLICK EVENTS:\n * onAsyncResponse: This event must be used with the \"notify\" by the end user once the Asynchronous Server call returns the item detail\n * Event args:\n * item: Item detail returned from the async server call\n * detailView: An explicit view to use instead of template (Optional)\n *\n * onAsyncEndUpdate: Fired when the async response finished\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onBeforeRowDetailToggle: Fired before the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onAfterRowDetailToggle: Fired after the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * expandedRows: Array of the Expanded Rows\n *\n * onRowOutOfViewportRange: Fired after a row becomes out of viewport range (user can't see the row anymore)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n *\n * onRowBackToViewportRange: Fired after a row is back to viewport range (user can visually see the row detail)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n */\nexport class SlickRowDetailView {\n // --\n // public API\n pluginName = 'RowDetailView' as const;\n onAsyncResponse = new SlickEvent();\n onAsyncEndUpdate = new SlickEvent();\n onAfterRowDetailToggle = new SlickEvent();\n onBeforeRowDetailToggle = new SlickEvent();\n onRowBackToViewportRange = new SlickEvent();\n onRowOutOfViewportRange = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _dataView!: SlickDataView;\n protected _dataViewIdProperty = 'id';\n protected _expandableOverride: UsabilityOverrideFn | null = null;\n protected _lastRange: { bottom: number; top: number; } | null = null;\n protected _expandedRows: any[] = [];\n protected _eventHandler: SlickEventHandler_;\n protected _outsideRange = 5;\n protected _visibleRenderedCellCount = 0;\n protected _options: RowDetailViewOption;\n protected _defaults = {\n columnId: '_detail_selector',\n cssClass: 'detailView-toggle',\n expandedClass: undefined,\n collapsedClass: undefined,\n keyPrefix: '_',\n loadOnce: false,\n collapseAllOnSort: true,\n saveDetailViewOnScroll: true,\n singleRowExpand: false,\n useSimpleViewportCalc: false,\n alwaysRenderColumn: true,\n toolTip: '',\n width: 30,\n maxRows: undefined\n } as RowDetailViewOption;\n protected _keyPrefix = this._defaults.keyPrefix;\n protected _gridRowBuffer = 0;\n protected _rowIdsOutOfViewport: Array = [];\n\n /** Constructor of the Row Detail View Plugin which accepts optional options */\n constructor(options: RowDetailViewOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options.expandableOverride === 'function') {\n this.expandableOverride(this._options.expandableOverride);\n }\n }\n\n /**\n * Initialize the plugin, which requires user to pass the SlickGrid Grid object\n * @param grid: SlickGrid Grid object\n */\n init(grid: SlickGrid) {\n if (!grid) {\n throw new Error('RowDetailView Plugin requires the Grid instance to be passed as argument to the \"init()\" method');\n }\n this._grid = grid;\n this._gridUid = grid.getUID();\n this._gridOptions = grid.getOptions() || {};\n this._dataView = this._grid.getData();\n this._keyPrefix = this._options?.keyPrefix ?? '_';\n\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._gridRowBuffer = this._gridOptions.minRowBuffer || 0;\n this._gridOptions.minRowBuffer = this._options.panelRows + 3;\n\n this._eventHandler\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this));\n\n // Sort will, by default, Collapse all of the open items (unless user implements his own onSort which deals with open row and padding)\n if (this._options.collapseAllOnSort) {\n this._eventHandler.subscribe(this._grid.onSort, this.collapseAll.bind(this));\n this._expandedRows = [];\n this._rowIdsOutOfViewport = [];\n }\n\n this._eventHandler.subscribe(this._dataView.onRowCountChanged, () => {\n this._grid.updateRowCount();\n this._grid.render();\n });\n\n this._eventHandler.subscribe(this._dataView.onRowsChanged, (_e, a) => {\n this._grid.invalidateRows(a.rows);\n this._grid.render();\n });\n\n // subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n this.subscribeToOnAsyncResponse();\n\n // after data is set, let's get the DataView Id Property name used (defaults to \"id\")\n this._eventHandler.subscribe(this._dataView.onSetItemsCalled, () => {\n this._dataViewIdProperty = this._dataView?.getIdPropertyName() ?? 'id';\n });\n\n // if we use the alternative & simpler calculation of the out of viewport range\n // we will need to know how many rows are rendered on the screen and we need to wait for grid to be rendered\n // unfortunately there is no triggered event for knowing when grid is finished, so we use 250ms delay and it's typically more than enough\n if (this._options.useSimpleViewportCalc) {\n this._eventHandler.subscribe(this._grid.onRendered, (_e, args) => {\n if (args?.endRow) {\n this._visibleRenderedCellCount = args.endRow - args.startRow;\n }\n });\n }\n }\n\n /** destroy the plugin and it's events */\n destroy() {\n this._eventHandler.unsubscribeAll();\n this.onAsyncResponse.unsubscribe();\n this.onAsyncEndUpdate.unsubscribe();\n this.onAfterRowDetailToggle.unsubscribe();\n this.onBeforeRowDetailToggle.unsubscribe();\n this.onRowOutOfViewportRange.unsubscribe();\n this.onRowBackToViewportRange.unsubscribe();\n }\n\n /** Get current plugin options */\n getOptions() {\n return this._options;\n }\n\n /** set or change some of the plugin options */\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n }\n\n /** Find a value in an array and return the index when (or -1 when not found) */\n protected arrayFindIndex(sourceArray: any[], value: any) {\n if (Array.isArray(sourceArray)) {\n for (let i = 0; i < sourceArray.length; i++) {\n if (sourceArray[i] === value) {\n return i;\n }\n }\n }\n return -1;\n }\n\n /** Handle mouse click event */\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n const dataContext = this._grid.getDataItem(args.row);\n if (!this.checkExpandableOverride(args.row, dataContext, this._grid)) {\n return;\n }\n\n // clicking on a row select checkbox\n if (this._options.useRowClick || this._grid.getColumns()[args.cell]['id'] === this._options.columnId && e.target.classList.contains(this._options.cssClass || '')) {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n // trigger an event before toggling\n // user could cancel the Row Detail opening when event is returning false\n if (this.onBeforeRowDetailToggle.notify({ grid: this._grid, item: dataContext }, e, this).getReturnValue() === false) {\n return;\n }\n\n this.toggleRowSelection(args.row, dataContext);\n\n // trigger an event after toggling\n this.onAfterRowDetailToggle.notify({\n grid: this._grid,\n item: dataContext,\n expandedRows: this._expandedRows,\n }, e, this);\n\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n /** If we scroll save detail views that go out of cache range */\n protected handleScroll() {\n if (this._options.useSimpleViewportCalc) {\n this.calculateOutOfRangeViewsSimplerVersion();\n } else {\n this.calculateOutOfRangeViews();\n }\n }\n\n /** Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViews() {\n let scrollDir = '';\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n // Only check if we have expanded rows\n if (this._expandedRows.length > 0) {\n // Assume scroll direction is down by default.\n scrollDir = 'DOWN';\n if (this._lastRange) {\n // Some scrolling isn't anything as the range is the same\n if (this._lastRange.top === renderedRange.top && this._lastRange.bottom === renderedRange.bottom) {\n return;\n }\n\n // If our new top is smaller we are scrolling up\n if (this._lastRange.top > renderedRange.top ||\n // Or we are at very top but our bottom is increasing\n (this._lastRange.top === 0 && renderedRange.top === 0) && this._lastRange.bottom > renderedRange.bottom) {\n scrollDir = 'UP';\n }\n }\n }\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView?.getRowById(row[this._dataViewIdProperty]) ?? 0;\n const rowPadding = row[`${this._keyPrefix}sizePadding`];\n const rowOutOfRange = this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0;\n\n if (scrollDir === 'UP') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the bottom item within buffer range is an expanded row save it.\n if (rowIndex >= renderedRange.bottom - this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If the row expanded area is within the buffer notify that it is back in range\n if (rowOutOfRange && rowIndex - this._outsideRange < renderedRange.top && rowIndex >= renderedRange.top) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n\n // if our first expanded row is about to go off the bottom\n else if (!rowOutOfRange && (rowIndex + rowPadding) > renderedRange.bottom) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n else if (scrollDir === 'DOWN') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the top item within buffer range is an expanded row save it.\n if (rowIndex <= renderedRange.top + this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If row index is i higher than bottom with some added value (To ignore top rows off view) and is with view and was our of range\n if (rowOutOfRange && (rowIndex + rowPadding + this._outsideRange) > renderedRange.bottom && rowIndex < rowIndex + rowPadding) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n // if our row is outside top of and the buffering zone but not in the array of outOfVisable range notify it\n else if (!rowOutOfRange && rowIndex < renderedRange.top) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n });\n this._lastRange = renderedRange;\n }\n }\n\n /** This is an alternative & more simpler version of the Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViewsSimplerVersion() {\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView.getRowById(row[this._dataViewIdProperty]) ?? -1;\n const isOutOfVisibility = this.checkIsRowOutOfViewportRange(rowIndex, renderedRange);\n if (!isOutOfVisibility && this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n } else if (isOutOfVisibility) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n });\n }\n }\n\n /**\n * Check if the row became out of visible range (when user can't see it anymore)\n * @param rowIndex\n * @param renderedRange from SlickGrid\n */\n protected checkIsRowOutOfViewportRange(rowIndex: number, renderedRange: any) {\n if (Math.abs(renderedRange.bottom - this._gridRowBuffer - rowIndex) > this._visibleRenderedCellCount * 2) {\n return true;\n }\n return false;\n }\n\n /** Send a notification, through \"onRowOutOfViewportRange\", that is out of the viewport range */\n protected notifyOutOfViewport(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n this.onRowOutOfViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, true)\n }, null, this);\n }\n\n /** Send a notification, through \"onRowBackToViewportRange\", that a row came back into the viewport visible range */\n protected notifyBackToViewportWhenDomExist(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n setTimeout(() => {\n // make sure View Row DOM Element really exist before notifying that it's a row that is visible again\n if (document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`)) {\n this.onRowBackToViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, false)\n }, null, this);\n }\n }, 100);\n }\n\n /**\n * This function will sync the \"out of viewport\" array whenever necessary.\n * The sync can add a detail row (when necessary, no need to add again if it already exist) or delete a row from the array.\n * @param rowId: number\n * @param isAdding: are we adding or removing a row?\n */\n protected syncOutOfViewportArray(rowId: number | string, isAdding: boolean) {\n const arrayRowIndex = this.arrayFindIndex(this._rowIdsOutOfViewport, rowId);\n\n if (isAdding && arrayRowIndex < 0) {\n this._rowIdsOutOfViewport.push(rowId);\n } else if (!isAdding && arrayRowIndex >= 0) {\n this._rowIdsOutOfViewport.splice(arrayRowIndex, 1);\n }\n return this._rowIdsOutOfViewport;\n }\n\n // Toggle between showing or hiding a row\n protected toggleRowSelection(rowNumber: number, dataContext: any) {\n if (!this.checkExpandableOverride(rowNumber, dataContext, this._grid)) {\n return;\n }\n\n this._dataView.beginUpdate();\n this.handleAccordionShowHide(dataContext);\n this._dataView.endUpdate();\n }\n\n /** Collapse all of the open detail rows */\n collapseAll() {\n this._dataView.beginUpdate();\n for (let i = this._expandedRows.length - 1; i >= 0; i--) {\n this.collapseDetailView(this._expandedRows[i], true);\n }\n this._dataView.endUpdate();\n }\n\n /** Collapse a detail row so that it is not longer open */\n collapseDetailView(item: any, isMultipleCollapsing = false) {\n if (!isMultipleCollapsing) {\n this._dataView.beginUpdate();\n }\n // Save the details on the collapse assuming onetime loading\n if (this._options.loadOnce) {\n this.saveDetailView(item);\n }\n\n item[`${this._keyPrefix}collapsed`] = true;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(item[this._dataViewIdProperty] + '.' + idx);\n }\n item[`${this._keyPrefix}sizePadding`] = 0;\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // Remove the item from the expandedRows\n this._expandedRows = this._expandedRows.filter((r) => {\n return r[this._dataViewIdProperty] !== item[this._dataViewIdProperty];\n });\n\n if (!isMultipleCollapsing) {\n this._dataView.endUpdate();\n }\n }\n\n /** Expand a detail row by providing the dataview item that is to be expanded */\n expandDetailView(item: any) {\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n\n item[`${this._keyPrefix}collapsed`] = false;\n this._expandedRows.push(item);\n\n // In the case something went wrong loading it the first time such a scroll of screen before loaded\n if (!item[`${this._keyPrefix}detailContent`]) {\n item[`${this._keyPrefix}detailViewLoaded`] = false;\n }\n // display pre-loading template\n if (!item[`${this._keyPrefix}detailViewLoaded`] || this._options.loadOnce !== true) {\n item[`${this._keyPrefix}detailContent`] = this._options?.preTemplate?.(item);\n } else {\n this.onAsyncResponse.notify({\n item,\n itemDetail: item,\n detailView: item[`${this._keyPrefix}detailContent`]\n }, undefined, this);\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n return;\n }\n\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // async server call\n this._options.process(item);\n }\n\n /** Saves the current state of the detail view */\n saveDetailView(item: any) {\n const view = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n if (view) {\n const html = view.innerHTML;\n if (html !== undefined) {\n item[`${this._keyPrefix}detailContent`] = html;\n }\n }\n }\n\n /**\n * subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n * the response has to be as \"args.item\" (or \"args.itemDetail\") with it's data back\n */\n protected subscribeToOnAsyncResponse() {\n this.onAsyncResponse.subscribe((e, args) => {\n if (!args || (!args.item && !args.itemDetail)) {\n throw 'Slick.RowDetailView plugin requires the onAsyncResponse() to supply \"args.item\" property.';\n }\n\n // we accept item/itemDetail, just get the one which has data\n const itemDetail = args.item || args.itemDetail;\n\n // If we just want to load in a view directly we can use detailView property to do so\n if (args.detailView) {\n itemDetail[`${this._keyPrefix}detailContent`] = args.detailView;\n } else {\n itemDetail[`${this._keyPrefix}detailContent`] = this._options?.postTemplate?.(itemDetail);\n }\n\n itemDetail[`${this._keyPrefix}detailViewLoaded`] = true;\n this._dataView.updateItem(itemDetail[this._dataViewIdProperty], itemDetail);\n\n // trigger an event once the post template is finished loading\n this.onAsyncEndUpdate.notify({\n grid: this._grid,\n item: itemDetail,\n itemDetail\n }, e, this);\n });\n }\n\n /** When row is getting toggled, we will handle the action of collapsing/expanding */\n protected handleAccordionShowHide(item: any) {\n if (item) {\n if (!item[`${this._keyPrefix}collapsed`]) {\n this.collapseDetailView(item);\n } else {\n this.expandDetailView(item);\n }\n }\n }\n\n //////////////////////////////////////////////////////////////\n //////////////////////////////////////////////////////////////\n\n /** Get the Row Detail padding (which are the rows dedicated to the detail panel) */\n protected getPaddingItem(parent: any, offset: any) {\n const item: any = {};\n\n for (const prop in this._dataView) {\n item[prop] = null;\n }\n item[this._dataViewIdProperty] = parent[this._dataViewIdProperty] + '.' + offset;\n\n // additional hidden padding metadata fields\n item[`${this._keyPrefix}collapsed`] = true;\n item[`${this._keyPrefix}isPadding`] = true;\n item[`${this._keyPrefix}parent`] = parent;\n item[`${this._keyPrefix}offset`] = offset;\n\n return item;\n };\n\n /** Create the detail ctr node. this belongs to the dev & can be custom-styled as per */\n protected applyTemplateNewLineHeight(item: any) {\n // the height is calculated by the template row count (how many line of items does the template view have)\n const rowCount = this._options.panelRows;\n\n // calculate padding requirements based on detail-content..\n // ie. worst-case: create an invisible dom node now & find it's height.\n const lineHeight = 13; // we know cuz we wrote the custom css init ;)\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / this._gridOptions.rowHeight!);\n item[`${this._keyPrefix}height`] = (item[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!);\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n }\n\n /** Get the Column Definition of the first column dedicated to toggling the Row Detail View */\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: '',\n toolTip: this._options.toolTip,\n field: 'sel',\n width: this._options.width,\n resizable: false,\n sortable: false,\n alwaysRenderColumn: this._options.alwaysRenderColumn,\n cssClass: this._options.cssClass,\n formatter: this.detailSelectionFormatter.bind(this)\n };\n }\n\n /** Return the currently expanded rows */\n getExpandedRows() {\n return this._expandedRows;\n }\n\n /** The cell Formatter that shows the icon that will be used to toggle the Row Detail */\n protected detailSelectionFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkExpandableOverride(row, dataContext, grid)) {\n return '';\n } else {\n if (dataContext[`${this._keyPrefix}collapsed`] === undefined) {\n dataContext[`${this._keyPrefix}collapsed`] = true;\n dataContext[`${this._keyPrefix}sizePadding`] = 0; //the required number of pading rows\n dataContext[`${this._keyPrefix}height`] = 0; //the actual height in pixels of the detail field\n dataContext[`${this._keyPrefix}isPadding`] = false;\n dataContext[`${this._keyPrefix}parent`] = undefined;\n dataContext[`${this._keyPrefix}offset`] = 0;\n }\n\n if (dataContext[`${this._keyPrefix}isPadding`]) {\n // render nothing\n }\n else if (dataContext[`${this._keyPrefix}collapsed`]) {\n let collapsedClasses = this._options.cssClass + ' expand ';\n if (this._options.collapsedClass) {\n collapsedClasses += this._options.collapsedClass;\n }\n return '
';\n }\n else {\n const html: string[] = [];\n const rowHeight = this._gridOptions.rowHeight;\n let outterHeight = dataContext[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!;\n\n if (this._options.maxRows !== undefined && dataContext[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n dataContext[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // V313HAX:\n // putting in an extra closing div after the closing toggle div and ommiting a\n // final closing div for the detail ctr div causes the slickgrid renderer to\n // insert our detail div as a new column ;) ~since it wraps whatever we provide\n // in a generic div column container. so our detail becomes a child directly of\n // the row not the cell. nice =) ~no need to apply a css change to the parent\n // slick-cell to escape the cell overflow clipping.\n\n // sneaky extra inserted here-----------------v\n let expandedClasses = this._options.cssClass + ' collapse ';\n if (this._options.expandedClass) {\n expandedClasses += this._options.expandedClass;\n }\n html.push('
');\n\n html.push(`
`); //shift detail below 1st row\n html.push(`
`); //sub ctr for custom styling\n html.push(`
${dataContext[`${this._keyPrefix}detailContent`]}
`);\n // omit a final closing detail container
that would come next\n\n return html.join('');\n }\n }\n return '';\n }\n\n /** Resize the Row Detail View */\n resizeDetailView(item: any) {\n if (!item) {\n return;\n }\n\n // Grad each of the DOM elements\n const mainContainer = document.querySelector(`.${this._gridUid} .detailViewContainer_${item[this._dataViewIdProperty]}`);\n const cellItem = document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`);\n const inner = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n\n if (!mainContainer || !cellItem || !inner) {\n return;\n }\n\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);\n }\n\n const rowHeight = this._gridOptions.rowHeight; // height of a row\n const lineHeight = 13; // we know cuz we wrote the custom css innit ;)\n\n // remove the height so we can calculate the height\n mainContainer.style.minHeight = '';\n\n // Get the scroll height for the main container so we know the actual size of the view\n const itemHeight = mainContainer.scrollHeight;\n\n // Now work out how many rows\n const rowCount = Math.ceil(itemHeight / rowHeight!);\n\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight!);\n item[`${this._keyPrefix}height`] = itemHeight;\n\n let outterHeight = (item[`${this._keyPrefix}sizePadding`] * rowHeight!);\n if (this._options.maxRows !== undefined && item[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n item[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // If the padding is now more than the original minRowBuff we need to increase it\n if (this._grid.getOptions().minRowBuffer! < item[`${this._keyPrefix}sizePadding`]) {\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._grid.getOptions().minRowBuffer = item[`${this._keyPrefix}sizePadding`] + 3;\n }\n\n mainContainer.setAttribute('style', 'min-height: ' + item[`${this._keyPrefix}height`] + 'px');\n if (cellItem) {\n cellItem.setAttribute('style', 'height: ' + outterHeight + 'px; top:' + rowHeight + 'px');\n }\n\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n\n // Lastly save the updated state\n this.saveDetailView(item);\n }\n\n /** Takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on */\n getFilterItem(item: any) {\n if (item[`${this._keyPrefix}isPadding`] && item[`${this._keyPrefix}parent`]) {\n item = item[`${this._keyPrefix}parent`];\n }\n return item;\n }\n\n protected checkExpandableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._expandableOverride === 'function') {\n return this._expandableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row an expandable row.\n * In order word, user can choose which rows to be an available row detail (or not) by providing his own logic.\n * @param overrideFn: override function callback\n */\n expandableOverride(overrideFn: UsabilityOverrideFn) {\n this._expandableOverride = overrideFn;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n RowDetailView: SlickRowDetailView\n }\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, FormatterResultWithHtml, FormatterResultWithText, GridOption, OnAfterRowDetailToggleArgs, OnBeforeRowDetailToggleArgs, OnRowBackToViewportRangeArgs, OnRowDetailAsyncEndUpdateArgs, OnRowDetailAsyncResponseArgs, OnRowOutOfViewportRangeArgs, RowDetailViewOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickDataView } from '../slick.dataview';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * A plugin to add row detail panel\n * Original StackOverflow question & article making this possible (thanks to violet313)\n * https://stackoverflow.com/questions/10535164/can-slickgrids-row-height-be-dynamically-altered#29399927\n * http://violet313.org/slickgrids/#intro\n *\n * USAGE:\n * Add the slick.rowDetailView.(js|css) files and register the plugin with the grid.\n *\n * AVAILABLE ROW DETAIL OPTIONS:\n * cssClass: A CSS class to be added to the row detail\n * expandedClass: Extra classes to be added to the expanded Toggle\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * collapsedClass: Extra classes to be added to the collapse Toggle\n * loadOnce: Defaults to false, when set to True it will load the data once and then reuse it.\n * preTemplate: Template that will be used before the async process (typically used to show a spinner/loading)\n * postTemplate: Template that will be loaded once the async function finishes\n * process: Async server function call\n * panelRows: Row count to use for the template panel\n * singleRowExpand: Defaults to false, limit expanded row to 1 at a time.\n * useRowClick: Boolean flag, when True will open the row detail on a row click (from any column), default to False\n * keyPrefix: Defaults to '_', prefix used for all the plugin metadata added to the item object (meta e.g.: padding, collapsed, parent)\n * collapseAllOnSort: Defaults to true, which will collapse all row detail views when user calls a sort. Unless user implements a sort to deal with padding\n * saveDetailViewOnScroll: Defaults to true, which will save the row detail view in a cache when it detects that it will become out of the viewport buffer\n * useSimpleViewportCalc: Defaults to false, which will use simplified calculation of out or back of viewport visibility\n *\n * AVAILABLE PUBLIC METHODS:\n * init: initiliaze the plugin\n * expandableOverride: callback method that user can override the default behavior of making every row an expandable row (the logic to show or not the expandable icon).\n * destroy: destroy the plugin and it's events\n * collapseAll: collapse all opened row detail panel\n * collapseDetailView: collapse a row by passing the item object (row detail)\n * expandDetailView: expand a row by passing the item object (row detail)\n * getColumnDefinition: get the column definitions\n * getExpandedRows: get all the expanded rows\n * getFilterItem: takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on\n * getOptions: get current plugin options\n * resizeDetailView: resize a row detail view, it will auto-calculate the number of rows it needs\n * saveDetailView: save a row detail view content by passing the row object\n * setOptions: set or change some of the plugin options\n *\n * THE PLUGIN EXPOSES THE FOLLOWING SLICK EVENTS:\n * onAsyncResponse: This event must be used with the \"notify\" by the end user once the Asynchronous Server call returns the item detail\n * Event args:\n * item: Item detail returned from the async server call\n * detailView: An explicit view to use instead of template (Optional)\n *\n * onAsyncEndUpdate: Fired when the async response finished\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onBeforeRowDetailToggle: Fired before the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n *\n * onAfterRowDetailToggle: Fired after the row detail gets toggled\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * expandedRows: Array of the Expanded Rows\n *\n * onRowOutOfViewportRange: Fired after a row becomes out of viewport range (user can't see the row anymore)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n *\n * onRowBackToViewportRange: Fired after a row is back to viewport range (user can visually see the row detail)\n * Event args:\n * grid: Reference to the grid.\n * item: Item data context\n * rowId: Id of the Row object (datacontext) in the Grid\n * rowIndex: Index of the Row in the Grid\n * expandedRows: Array of the Expanded Rows\n * rowIdsOutOfViewport: Array of the Out of viewport Range Rows\n */\nexport class SlickRowDetailView {\n // --\n // public API\n pluginName = 'RowDetailView' as const;\n onAsyncResponse = new SlickEvent();\n onAsyncEndUpdate = new SlickEvent();\n onAfterRowDetailToggle = new SlickEvent();\n onBeforeRowDetailToggle = new SlickEvent();\n onRowBackToViewportRange = new SlickEvent();\n onRowOutOfViewportRange = new SlickEvent();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _gridOptions!: GridOption;\n protected _gridUid = '';\n protected _dataView!: SlickDataView;\n protected _dataViewIdProperty = 'id';\n protected _expandableOverride: UsabilityOverrideFn | null = null;\n protected _lastRange: { bottom: number; top: number; } | null = null;\n protected _expandedRows: any[] = [];\n protected _eventHandler: SlickEventHandler_;\n protected _outsideRange = 5;\n protected _visibleRenderedCellCount = 0;\n protected _options: RowDetailViewOption;\n protected _defaults = {\n columnId: '_detail_selector',\n cssClass: 'detailView-toggle',\n expandedClass: undefined,\n collapsedClass: undefined,\n keyPrefix: '_',\n loadOnce: false,\n collapseAllOnSort: true,\n saveDetailViewOnScroll: true,\n singleRowExpand: false,\n useSimpleViewportCalc: false,\n alwaysRenderColumn: true,\n toolTip: '',\n width: 30,\n maxRows: undefined\n } as RowDetailViewOption;\n protected _keyPrefix = this._defaults.keyPrefix;\n protected _gridRowBuffer = 0;\n protected _rowIdsOutOfViewport: Array = [];\n\n /** Constructor of the Row Detail View Plugin which accepts optional options */\n constructor(options: RowDetailViewOption) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options.expandableOverride === 'function') {\n this.expandableOverride(this._options.expandableOverride);\n }\n }\n\n /**\n * Initialize the plugin, which requires user to pass the SlickGrid Grid object\n * @param grid: SlickGrid Grid object\n */\n init(grid: SlickGrid) {\n if (!grid) {\n throw new Error('RowDetailView Plugin requires the Grid instance to be passed as argument to the \"init()\" method');\n }\n this._grid = grid;\n this._gridUid = grid.getUID();\n this._gridOptions = grid.getOptions() || {};\n this._dataView = this._grid.getData();\n this._keyPrefix = this._options?.keyPrefix ?? '_';\n\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._gridRowBuffer = this._gridOptions.minRowBuffer || 0;\n this._gridOptions.minRowBuffer = this._options.panelRows + 3;\n\n this._eventHandler\n .subscribe(this._grid.onClick, this.handleClick.bind(this))\n .subscribe(this._grid.onScroll, this.handleScroll.bind(this));\n\n // Sort will, by default, Collapse all of the open items (unless user implements his own onSort which deals with open row and padding)\n if (this._options.collapseAllOnSort) {\n this._eventHandler.subscribe(this._grid.onSort, this.collapseAll.bind(this));\n this._expandedRows = [];\n this._rowIdsOutOfViewport = [];\n }\n\n this._eventHandler.subscribe(this._dataView.onRowCountChanged, () => {\n this._grid.updateRowCount();\n this._grid.render();\n });\n\n this._eventHandler.subscribe(this._dataView.onRowsChanged, (_e, a) => {\n this._grid.invalidateRows(a.rows);\n this._grid.render();\n });\n\n // subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n this.subscribeToOnAsyncResponse();\n\n // after data is set, let's get the DataView Id Property name used (defaults to \"id\")\n this._eventHandler.subscribe(this._dataView.onSetItemsCalled, () => {\n this._dataViewIdProperty = this._dataView?.getIdPropertyName() ?? 'id';\n });\n\n // if we use the alternative & simpler calculation of the out of viewport range\n // we will need to know how many rows are rendered on the screen and we need to wait for grid to be rendered\n // unfortunately there is no triggered event for knowing when grid is finished, so we use 250ms delay and it's typically more than enough\n if (this._options.useSimpleViewportCalc) {\n this._eventHandler.subscribe(this._grid.onRendered, (_e, args) => {\n if (args?.endRow) {\n this._visibleRenderedCellCount = args.endRow - args.startRow;\n }\n });\n }\n }\n\n /** destroy the plugin and it's events */\n destroy() {\n this._eventHandler.unsubscribeAll();\n this.onAsyncResponse.unsubscribe();\n this.onAsyncEndUpdate.unsubscribe();\n this.onAfterRowDetailToggle.unsubscribe();\n this.onBeforeRowDetailToggle.unsubscribe();\n this.onRowOutOfViewportRange.unsubscribe();\n this.onRowBackToViewportRange.unsubscribe();\n }\n\n /** Get current plugin options */\n getOptions() {\n return this._options;\n }\n\n /** set or change some of the plugin options */\n setOptions(options: Partial) {\n this._options = Utils.extend(true, {}, this._options, options);\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n }\n\n /** Find a value in an array and return the index when (or -1 when not found) */\n protected arrayFindIndex(sourceArray: any[], value: any) {\n if (Array.isArray(sourceArray)) {\n for (let i = 0; i < sourceArray.length; i++) {\n if (sourceArray[i] === value) {\n return i;\n }\n }\n }\n return -1;\n }\n\n /** Handle mouse click event */\n protected handleClick(e: DOMEvent, args: { row: number; cell: number; }) {\n const dataContext = this._grid.getDataItem(args.row);\n if (!this.checkExpandableOverride(args.row, dataContext, this._grid)) {\n return;\n }\n\n // clicking on a row select checkbox\n if (this._options.useRowClick || this._grid.getColumns()[args.cell]['id'] === this._options.columnId && e.target.classList.contains(this._options.cssClass || '')) {\n // if editing, try to commit\n if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {\n e.preventDefault();\n e.stopImmediatePropagation();\n return;\n }\n\n // trigger an event before toggling\n // user could cancel the Row Detail opening when event is returning false\n if (this.onBeforeRowDetailToggle.notify({ grid: this._grid, item: dataContext }, e, this).getReturnValue() === false) {\n return;\n }\n\n this.toggleRowSelection(args.row, dataContext);\n\n // trigger an event after toggling\n this.onAfterRowDetailToggle.notify({\n grid: this._grid,\n item: dataContext,\n expandedRows: this._expandedRows,\n }, e, this);\n\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n\n /** If we scroll save detail views that go out of cache range */\n protected handleScroll() {\n if (this._options.useSimpleViewportCalc) {\n this.calculateOutOfRangeViewsSimplerVersion();\n } else {\n this.calculateOutOfRangeViews();\n }\n }\n\n /** Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViews() {\n let scrollDir = '';\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n // Only check if we have expanded rows\n if (this._expandedRows.length > 0) {\n // Assume scroll direction is down by default.\n scrollDir = 'DOWN';\n if (this._lastRange) {\n // Some scrolling isn't anything as the range is the same\n if (this._lastRange.top === renderedRange.top && this._lastRange.bottom === renderedRange.bottom) {\n return;\n }\n\n // If our new top is smaller we are scrolling up\n if (this._lastRange.top > renderedRange.top ||\n // Or we are at very top but our bottom is increasing\n (this._lastRange.top === 0 && renderedRange.top === 0) && this._lastRange.bottom > renderedRange.bottom) {\n scrollDir = 'UP';\n }\n }\n }\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView?.getRowById(row[this._dataViewIdProperty]) ?? 0;\n const rowPadding = row[`${this._keyPrefix}sizePadding`];\n const rowOutOfRange = this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0;\n\n if (scrollDir === 'UP') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the bottom item within buffer range is an expanded row save it.\n if (rowIndex >= renderedRange.bottom - this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If the row expanded area is within the buffer notify that it is back in range\n if (rowOutOfRange && rowIndex - this._outsideRange < renderedRange.top && rowIndex >= renderedRange.top) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n\n // if our first expanded row is about to go off the bottom\n else if (!rowOutOfRange && (rowIndex + rowPadding) > renderedRange.bottom) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n else if (scrollDir === 'DOWN') {\n // save the view when asked\n if (this._options.saveDetailViewOnScroll) {\n // If the top item within buffer range is an expanded row save it.\n if (rowIndex <= renderedRange.top + this._gridRowBuffer) {\n this.saveDetailView(row);\n }\n }\n\n // If row index is i higher than bottom with some added value (To ignore top rows off view) and is with view and was our of range\n if (rowOutOfRange && (rowIndex + rowPadding + this._outsideRange) > renderedRange.bottom && rowIndex < rowIndex + rowPadding) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n }\n // if our row is outside top of and the buffering zone but not in the array of outOfVisable range notify it\n else if (!rowOutOfRange && rowIndex < renderedRange.top) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n }\n });\n this._lastRange = renderedRange;\n }\n }\n\n /** This is an alternative & more simpler version of the Calculate when expanded rows become out of view range */\n protected calculateOutOfRangeViewsSimplerVersion() {\n if (this._grid) {\n const renderedRange = this._grid.getRenderedRange();\n\n this._expandedRows.forEach((row) => {\n const rowIndex = this._dataView.getRowById(row[this._dataViewIdProperty]) ?? -1;\n const isOutOfVisibility = this.checkIsRowOutOfViewportRange(rowIndex, renderedRange);\n if (!isOutOfVisibility && this.arrayFindIndex(this._rowIdsOutOfViewport, row[this._dataViewIdProperty]) >= 0) {\n this.notifyBackToViewportWhenDomExist(row, row[this._dataViewIdProperty]);\n } else if (isOutOfVisibility) {\n this.notifyOutOfViewport(row, row[this._dataViewIdProperty]);\n }\n });\n }\n }\n\n /**\n * Check if the row became out of visible range (when user can't see it anymore)\n * @param rowIndex\n * @param renderedRange from SlickGrid\n */\n protected checkIsRowOutOfViewportRange(rowIndex: number, renderedRange: any) {\n if (Math.abs(renderedRange.bottom - this._gridRowBuffer - rowIndex) > this._visibleRenderedCellCount * 2) {\n return true;\n }\n return false;\n }\n\n /** Send a notification, through \"onRowOutOfViewportRange\", that is out of the viewport range */\n protected notifyOutOfViewport(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n this.onRowOutOfViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, true)\n }, null, this);\n }\n\n /** Send a notification, through \"onRowBackToViewportRange\", that a row came back into the viewport visible range */\n protected notifyBackToViewportWhenDomExist(item: any, rowId: number | string) {\n const rowIndex = (item.rowIndex || this._dataView.getRowById(item[this._dataViewIdProperty])) as number;\n\n setTimeout(() => {\n // make sure View Row DOM Element really exist before notifying that it's a row that is visible again\n if (document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`)) {\n this.onRowBackToViewportRange.notify({\n grid: this._grid,\n item,\n rowId,\n rowIndex,\n expandedRows: this._expandedRows,\n rowIdsOutOfViewport: this.syncOutOfViewportArray(rowId, false)\n }, null, this);\n }\n }, 100);\n }\n\n /**\n * This function will sync the \"out of viewport\" array whenever necessary.\n * The sync can add a detail row (when necessary, no need to add again if it already exist) or delete a row from the array.\n * @param rowId: number\n * @param isAdding: are we adding or removing a row?\n */\n protected syncOutOfViewportArray(rowId: number | string, isAdding: boolean) {\n const arrayRowIndex = this.arrayFindIndex(this._rowIdsOutOfViewport, rowId);\n\n if (isAdding && arrayRowIndex < 0) {\n this._rowIdsOutOfViewport.push(rowId);\n } else if (!isAdding && arrayRowIndex >= 0) {\n this._rowIdsOutOfViewport.splice(arrayRowIndex, 1);\n }\n return this._rowIdsOutOfViewport;\n }\n\n // Toggle between showing or hiding a row\n protected toggleRowSelection(rowNumber: number, dataContext: any) {\n if (!this.checkExpandableOverride(rowNumber, dataContext, this._grid)) {\n return;\n }\n\n this._dataView.beginUpdate();\n this.handleAccordionShowHide(dataContext);\n this._dataView.endUpdate();\n }\n\n /** Collapse all of the open detail rows */\n collapseAll() {\n this._dataView.beginUpdate();\n for (let i = this._expandedRows.length - 1; i >= 0; i--) {\n this.collapseDetailView(this._expandedRows[i], true);\n }\n this._dataView.endUpdate();\n }\n\n /** Collapse a detail row so that it is not longer open */\n collapseDetailView(item: any, isMultipleCollapsing = false) {\n if (!isMultipleCollapsing) {\n this._dataView.beginUpdate();\n }\n // Save the details on the collapse assuming onetime loading\n if (this._options.loadOnce) {\n this.saveDetailView(item);\n }\n\n item[`${this._keyPrefix}collapsed`] = true;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(item[this._dataViewIdProperty] + '.' + idx);\n }\n item[`${this._keyPrefix}sizePadding`] = 0;\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // Remove the item from the expandedRows\n this._expandedRows = this._expandedRows.filter((r) => {\n return r[this._dataViewIdProperty] !== item[this._dataViewIdProperty];\n });\n\n if (!isMultipleCollapsing) {\n this._dataView.endUpdate();\n }\n }\n\n /** Expand a detail row by providing the dataview item that is to be expanded */\n expandDetailView(item: any) {\n if (this._options?.singleRowExpand) {\n this.collapseAll();\n }\n\n item[`${this._keyPrefix}collapsed`] = false;\n this._expandedRows.push(item);\n\n // In the case something went wrong loading it the first time such a scroll of screen before loaded\n if (!item[`${this._keyPrefix}detailContent`]) {\n item[`${this._keyPrefix}detailViewLoaded`] = false;\n }\n // display pre-loading template\n if (!item[`${this._keyPrefix}detailViewLoaded`] || this._options.loadOnce !== true) {\n item[`${this._keyPrefix}detailContent`] = this._options?.preTemplate?.(item);\n } else {\n this.onAsyncResponse.notify({\n item,\n itemDetail: item,\n detailView: item[`${this._keyPrefix}detailContent`]\n }, undefined, this);\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n return;\n }\n\n this.applyTemplateNewLineHeight(item);\n this._dataView.updateItem(item[this._dataViewIdProperty], item);\n\n // async server call\n this._options.process(item);\n }\n\n /** Saves the current state of the detail view */\n saveDetailView(item: any) {\n const view = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n if (view) {\n const html = view.innerHTML;\n if (html !== undefined) {\n item[`${this._keyPrefix}detailContent`] = html;\n }\n }\n }\n\n /**\n * subscribe to the onAsyncResponse so that the plugin knows when the user server side calls finished\n * the response has to be as \"args.item\" (or \"args.itemDetail\") with it's data back\n */\n protected subscribeToOnAsyncResponse() {\n this.onAsyncResponse.subscribe((e, args) => {\n if (!args || (!args.item && !args.itemDetail)) {\n throw 'Slick.RowDetailView plugin requires the onAsyncResponse() to supply \"args.item\" property.';\n }\n\n // we accept item/itemDetail, just get the one which has data\n const itemDetail = args.item || args.itemDetail;\n\n // If we just want to load in a view directly we can use detailView property to do so\n if (args.detailView) {\n itemDetail[`${this._keyPrefix}detailContent`] = args.detailView;\n } else {\n itemDetail[`${this._keyPrefix}detailContent`] = this._options?.postTemplate?.(itemDetail);\n }\n\n itemDetail[`${this._keyPrefix}detailViewLoaded`] = true;\n this._dataView.updateItem(itemDetail[this._dataViewIdProperty], itemDetail);\n\n // trigger an event once the post template is finished loading\n this.onAsyncEndUpdate.notify({\n grid: this._grid,\n item: itemDetail,\n itemDetail\n }, e, this);\n });\n }\n\n /** When row is getting toggled, we will handle the action of collapsing/expanding */\n protected handleAccordionShowHide(item: any) {\n if (item) {\n if (!item[`${this._keyPrefix}collapsed`]) {\n this.collapseDetailView(item);\n } else {\n this.expandDetailView(item);\n }\n }\n }\n\n //////////////////////////////////////////////////////////////\n //////////////////////////////////////////////////////////////\n\n /** Get the Row Detail padding (which are the rows dedicated to the detail panel) */\n protected getPaddingItem(parent: any, offset: any) {\n const item: any = {};\n\n for (const prop in this._dataView) {\n item[prop] = null;\n }\n item[this._dataViewIdProperty] = parent[this._dataViewIdProperty] + '.' + offset;\n\n // additional hidden padding metadata fields\n item[`${this._keyPrefix}collapsed`] = true;\n item[`${this._keyPrefix}isPadding`] = true;\n item[`${this._keyPrefix}parent`] = parent;\n item[`${this._keyPrefix}offset`] = offset;\n\n return item;\n };\n\n /** Create the detail ctr node. this belongs to the dev & can be custom-styled as per */\n protected applyTemplateNewLineHeight(item: any) {\n // the height is calculated by the template row count (how many line of items does the template view have)\n const rowCount = this._options.panelRows;\n\n // calculate padding requirements based on detail-content..\n // ie. worst-case: create an invisible dom node now & find it's height.\n const lineHeight = 13; // we know cuz we wrote the custom css init ;)\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / this._gridOptions.rowHeight!);\n item[`${this._keyPrefix}height`] = (item[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!);\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n }\n\n /** Get the Column Definition of the first column dedicated to toggling the Row Detail View */\n getColumnDefinition() {\n return {\n id: this._options.columnId,\n name: '',\n toolTip: this._options.toolTip,\n field: 'sel',\n width: this._options.width,\n resizable: false,\n sortable: false,\n alwaysRenderColumn: this._options.alwaysRenderColumn,\n cssClass: this._options.cssClass,\n formatter: this.detailSelectionFormatter.bind(this)\n };\n }\n\n /** Return the currently expanded rows */\n getExpandedRows() {\n return this._expandedRows;\n }\n\n /** The cell Formatter that shows the icon that will be used to toggle the Row Detail */\n protected detailSelectionFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultWithHtml | FormatterResultWithText | string {\n if (!this.checkExpandableOverride(row, dataContext, grid)) {\n return '';\n } else {\n if (dataContext[`${this._keyPrefix}collapsed`] === undefined) {\n dataContext[`${this._keyPrefix}collapsed`] = true;\n dataContext[`${this._keyPrefix}sizePadding`] = 0; //the required number of pading rows\n dataContext[`${this._keyPrefix}height`] = 0; //the actual height in pixels of the detail field\n dataContext[`${this._keyPrefix}isPadding`] = false;\n dataContext[`${this._keyPrefix}parent`] = undefined;\n dataContext[`${this._keyPrefix}offset`] = 0;\n }\n\n if (dataContext[`${this._keyPrefix}isPadding`]) {\n // render nothing\n }\n else if (dataContext[`${this._keyPrefix}collapsed`]) {\n let collapsedClasses = this._options.cssClass + ' expand ';\n if (this._options.collapsedClass) {\n collapsedClasses += this._options.collapsedClass;\n }\n return '
';\n }\n else {\n const html: string[] = [];\n const rowHeight = this._gridOptions.rowHeight;\n let outterHeight = dataContext[`${this._keyPrefix}sizePadding`] * this._gridOptions.rowHeight!;\n\n if (this._options.maxRows !== undefined && dataContext[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n dataContext[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // V313HAX:\n // putting in an extra closing div after the closing toggle div and ommiting a\n // final closing div for the detail ctr div causes the slickgrid renderer to\n // insert our detail div as a new column ;) ~since it wraps whatever we provide\n // in a generic div column container. so our detail becomes a child directly of\n // the row not the cell. nice =) ~no need to apply a css change to the parent\n // slick-cell to escape the cell overflow clipping.\n\n // sneaky extra inserted here-----------------v\n let expandedClasses = this._options.cssClass + ' collapse ';\n if (this._options.expandedClass) {\n expandedClasses += this._options.expandedClass;\n }\n html.push('
');\n\n html.push(`
`); //shift detail below 1st row\n html.push(`
`); //sub ctr for custom styling\n html.push(`
${dataContext[`${this._keyPrefix}detailContent`]}
`);\n // omit a final closing detail container
that would come next\n\n return html.join('');\n }\n }\n return '';\n }\n\n /** Resize the Row Detail View */\n resizeDetailView(item: any) {\n if (!item) {\n return;\n }\n\n // Grad each of the DOM elements\n const mainContainer = document.querySelector(`.${this._gridUid} .detailViewContainer_${item[this._dataViewIdProperty]}`);\n const cellItem = document.querySelector(`.${this._gridUid} .cellDetailView_${item[this._dataViewIdProperty]}`);\n const inner = document.querySelector(`.${this._gridUid} .innerDetailView_${item[this._dataViewIdProperty]}`);\n\n if (!mainContainer || !cellItem || !inner) {\n return;\n }\n\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.deleteItem(`${item[this._dataViewIdProperty]}.${idx}`);\n }\n\n const rowHeight = this._gridOptions.rowHeight; // height of a row\n const lineHeight = 13; // we know cuz we wrote the custom css innit ;)\n\n // remove the height so we can calculate the height\n mainContainer.style.minHeight = '';\n\n // Get the scroll height for the main container so we know the actual size of the view\n const itemHeight = mainContainer.scrollHeight;\n\n // Now work out how many rows\n const rowCount = Math.ceil(itemHeight / rowHeight!);\n\n item[`${this._keyPrefix}sizePadding`] = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight!);\n item[`${this._keyPrefix}height`] = itemHeight;\n\n let outterHeight = (item[`${this._keyPrefix}sizePadding`] * rowHeight!);\n if (this._options.maxRows !== undefined && item[`${this._keyPrefix}sizePadding`] > this._options.maxRows) {\n outterHeight = this._options.maxRows * rowHeight!;\n item[`${this._keyPrefix}sizePadding`] = this._options.maxRows;\n }\n\n // If the padding is now more than the original minRowBuff we need to increase it\n if (this._grid.getOptions().minRowBuffer! < item[`${this._keyPrefix}sizePadding`]) {\n // Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3\n this._grid.getOptions().minRowBuffer = item[`${this._keyPrefix}sizePadding`] + 3;\n }\n\n mainContainer.setAttribute('style', 'min-height: ' + item[`${this._keyPrefix}height`] + 'px');\n if (cellItem) {\n cellItem.setAttribute('style', 'height: ' + outterHeight + 'px; top:' + rowHeight + 'px');\n }\n\n const idxParent = this._dataView.getIdxById(item[this._dataViewIdProperty]) ?? 0;\n for (let idx = 1; idx <= item[`${this._keyPrefix}sizePadding`]; idx++) {\n this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));\n }\n\n // Lastly save the updated state\n this.saveDetailView(item);\n }\n\n /** Takes in the item we are filtering and if it is an expanded row returns it's parents row to filter on */\n getFilterItem(item: any) {\n if (item[`${this._keyPrefix}isPadding`] && item[`${this._keyPrefix}parent`]) {\n item = item[`${this._keyPrefix}parent`];\n }\n return item;\n }\n\n protected checkExpandableOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._expandableOverride === 'function') {\n return this._expandableOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row an expandable row.\n * In order word, user can choose which rows to be an available row detail (or not) by providing his own logic.\n * @param overrideFn: override function callback\n */\n expandableOverride(overrideFn: UsabilityOverrideFn) {\n this._expandableOverride = overrideFn;\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n Plugins: {\n RowDetailView: SlickRowDetailView\n }\n }\n });\n}\n\n"], + "mappings": "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", "names": ["_a", "_b"] } diff --git a/dist/browser/plugins/slick.rowmovemanager.js b/dist/browser/plugins/slick.rowmovemanager.js index 162415ec3..40a66a90a 100644 --- a/dist/browser/plugins/slick.rowmovemanager.js +++ b/dist/browser/plugins/slick.rowmovemanager.js @@ -113,7 +113,14 @@ }; } moveIconFormatter(row, _cell, _val, _column, dataContext, grid) { - return this.checkUsabilityOverride(row, dataContext, grid) ? { addClasses: `cell-reorder dnd ${this._options.cssClass || ""}`.trim(), text: "" } : ""; + if (this.checkUsabilityOverride(row, dataContext, grid)) { + let iconElm = document.createElement("div"); + return iconElm.className = this._options.cssClass || "", { + addClasses: `cell-reorder dnd ${this._options.containerCssClass || ""}`, + html: iconElm + }; + } else + return ""; } checkUsabilityOverride(row, dataContext, grid) { return typeof this._usabilityOverride == "function" ? this._usabilityOverride(row, dataContext, grid) : !0; diff --git a/dist/browser/plugins/slick.rowmovemanager.js.map b/dist/browser/plugins/slick.rowmovemanager.js.map index 50d71dcca..c0c665d19 100644 --- a/dist/browser/plugins/slick.rowmovemanager.js.map +++ b/dist/browser/plugins/slick.rowmovemanager.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../src/plugins/slick.rowmovemanager.ts"], - "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultObject, RowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * cssClass: A CSS class to be added to the div of the cell formatter.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\n\nexport class SlickRowMoveManager {\n // --\n // public API\n pluginName = 'RowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n onMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _eventHandler: SlickEventHandler_;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _options: RowMoveManagerOption;\n protected _defaults: RowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const slickRowElm = this._grid.getCellNode(cell.row, cell.cell)?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._canvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._canvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._canvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._canvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent)?.touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._canvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._grid.getOptions().rowHeight!), this._grid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._grid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._grid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._grid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n resizable: false,\n selectable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultObject | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n return { addClasses: `cell-reorder dnd ${this._options.cssClass || ''}`.trim(), text: '' };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowMoveManager: SlickRowMoveManager\n }\n });\n}\n\n"], - "mappings": "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", + "sourcesContent": ["import { SlickEvent as SlickEvent_, SlickEventData as SlickEventData_, SlickEventHandler as SlickEventHandler_, Utils as Utils_ } from '../slick.core';\nimport type { Column, DOMEvent, DragRowMove, FormatterResultWithHtml, RowMoveManagerOption, UsabilityOverrideFn } from '../models/index';\nimport type { SlickGrid } from '../slick.grid';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventHandler = IIFE_ONLY ? Slick.EventHandler : SlickEventHandler_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/**\n * Row Move Manager options:\n * containerCssClass: A CSS class to be added to the cell container.\n * cssClass: A CSS class to be added to the div of the cell formatter.\n * columnId: Column definition id (defaults to \"_move\")\n * cancelEditOnDrag: Do we want to cancel any Editing while dragging a row (defaults to false)\n * disableRowSelection: Do we want to disable the row selection? (defaults to false)\n * hideRowMoveShadow: Do we want to hide the row move shadow clone? (defaults to true)\n * rowMoveShadowMarginTop: When row move shadow is shown, optional margin-top (defaults to 0)\n * rowMoveShadowMarginLeft: When row move shadow is shown, optional margin-left (defaults to 0)\n * rowMoveShadowOpacity: When row move shadow is shown, what is its opacity? (defaults to 0.95)\n * rowMoveShadowScale: When row move shadow is shown, what is its size scale? (default to 0.75)\n * singleRowMove: Do we want a single row move? Setting this to false means that it's a multple row move (defaults to false)\n * width: Width of the column\n * usabilityOverride: Callback method that user can override the default behavior of the row being moveable or not\n *\n */\n\nexport class SlickRowMoveManager {\n // --\n // public API\n pluginName = 'RowMoveManager' as const;\n onBeforeMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n onMoveRows = new SlickEvent<{ grid: SlickGrid; rows: number[]; insertBefore: number; }>();\n\n // --\n // protected props\n protected _grid!: SlickGrid;\n protected _canvas!: HTMLElement;\n protected _dragging = false;\n protected _eventHandler: SlickEventHandler_;\n protected _usabilityOverride?: UsabilityOverrideFn;\n protected _options: RowMoveManagerOption;\n protected _defaults: RowMoveManagerOption = {\n columnId: '_move',\n cssClass: undefined,\n cancelEditOnDrag: false,\n disableRowSelection: false,\n hideRowMoveShadow: true,\n rowMoveShadowMarginTop: 0,\n rowMoveShadowMarginLeft: 0,\n rowMoveShadowOpacity: 0.95,\n rowMoveShadowScale: 0.75,\n singleRowMove: false,\n width: 40,\n };\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this._defaults, options);\n this._eventHandler = new SlickEventHandler();\n }\n\n\n init(grid: SlickGrid) {\n this._grid = grid;\n this._canvas = this._grid.getCanvasNode();\n\n // user could override the expandable icon logic from within the options or after instantiating the plugin\n if (typeof this._options?.usabilityOverride === 'function') {\n this.usabilityOverride(this._options.usabilityOverride);\n }\n\n this._eventHandler\n .subscribe(this._grid.onDragInit, this.handleDragInit.bind(this))\n .subscribe(this._grid.onDragStart, this.handleDragStart.bind(this))\n .subscribe(this._grid.onDrag, this.handleDrag.bind(this))\n .subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));\n }\n\n destroy() {\n this._eventHandler.unsubscribeAll();\n }\n\n setOptions(newOptions: Partial) {\n this._options = Utils.extend({}, this._options, newOptions);\n }\n\n protected handleDragInit(e: SlickEventData_) {\n // prevent the grid from cancelling drag'n'drop by default\n e.stopImmediatePropagation();\n }\n\n protected handleDragStart(e: DOMEvent, dd: DragRowMove): boolean | void {\n const cell = this._grid.getCellFromEvent(e) || { cell: -1, row: -1 };\n const currentRow = cell?.row;\n const dataContext = this._grid.getDataItem(currentRow);\n\n if (!this.checkUsabilityOverride(currentRow, dataContext, this._grid)) {\n return;\n }\n\n if (this._options.cancelEditOnDrag && this._grid.getEditorLock().isActive()) {\n this._grid.getEditorLock().cancelCurrentEdit();\n }\n\n if (this._grid.getEditorLock().isActive() || !this.isHandlerColumn(cell.cell)) {\n return false;\n }\n\n this._dragging = true;\n e.stopImmediatePropagation();\n\n // optionally create a shadow element of the row so that we can see all the time which row exactly we're dragging\n if (!this._options.hideRowMoveShadow) {\n const slickRowElm = this._grid.getCellNode(cell.row, cell.cell)?.closest('.slick-row');\n if (slickRowElm) {\n dd.clonedSlickRow = slickRowElm.cloneNode(true) as HTMLDivElement;\n dd.clonedSlickRow.classList.add('slick-reorder-shadow-row');\n dd.clonedSlickRow.style.display = 'none';\n dd.clonedSlickRow.style.marginLeft = Number(this._options.rowMoveShadowMarginLeft || 0) + 'px';\n dd.clonedSlickRow.style.marginTop = Number(this._options.rowMoveShadowMarginTop || 0) + 'px';\n dd.clonedSlickRow.style.opacity = `${this._options.rowMoveShadowOpacity || 0.95}`;\n dd.clonedSlickRow.style.transform = `scale(${this._options.rowMoveShadowScale || 0.75})`;\n this._canvas.appendChild(dd.clonedSlickRow);\n }\n }\n\n let selectedRows = this._options.singleRowMove ? [cell.row] : this._grid.getSelectedRows();\n if (selectedRows.length === 0 || !selectedRows.some(selectedRow => selectedRow === cell.row)) {\n selectedRows = [cell.row];\n if (!this._options.disableRowSelection) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n const rowHeight = this._grid.getOptions().rowHeight;\n\n dd.selectedRows = selectedRows;\n\n dd.selectionProxy = document.createElement('div');\n dd.selectionProxy.className = 'slick-reorder-proxy';\n dd.selectionProxy.style.display = 'none';\n dd.selectionProxy.style.position = 'absolute';\n dd.selectionProxy.style.zIndex = '99999';\n dd.selectionProxy.style.width = `${this._canvas.clientWidth}px`;\n dd.selectionProxy.style.height = `${rowHeight! * selectedRows.length}px`;\n this._canvas.appendChild(dd.selectionProxy);\n\n dd.guide = document.createElement('div');\n dd.guide.className = 'slick-reorder-guide';\n dd.guide.style.position = 'absolute';\n dd.guide.style.zIndex = '99999';\n dd.guide.style.width = `${this._canvas.clientWidth}px`;\n dd.guide.style.top = `-1000px`;\n this._canvas.appendChild(dd.guide);\n\n dd.insertBefore = -1;\n }\n\n protected handleDrag(evt: SlickEventData_, dd: DragRowMove): boolean | void {\n if (!this._dragging) {\n return;\n }\n\n evt.stopImmediatePropagation();\n const e = evt.getNativeEvent();\n\n const targetEvent = (e as TouchEvent)?.touches?.[0] ?? e;\n const top = targetEvent.pageY - (Utils.offset(this._canvas)?.top ?? 0);\n dd.selectionProxy.style.top = `${top - 5}px`;\n dd.selectionProxy.style.display = 'block';\n\n // if the row move shadow is enabled, we'll also make it follow the mouse cursor\n if (dd.clonedSlickRow) {\n dd.clonedSlickRow.style.top = `${top - 6}px`;\n dd.clonedSlickRow.style.display = 'block';\n }\n\n const insertBefore = Math.max(0, Math.min(Math.round(top / this._grid.getOptions().rowHeight!), this._grid.getDataLength()));\n if (insertBefore !== dd.insertBefore) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore\n };\n\n if (this.onBeforeMoveRows.notify(eventData).getReturnValue() === false) {\n dd.canMove = false;\n } else {\n dd.canMove = true;\n }\n\n // if there's a UsabilityOverride defined, we also need to verify that the condition is valid\n if (this._usabilityOverride && dd.canMove) {\n const insertBeforeDataContext = this._grid.getDataItem(insertBefore);\n dd.canMove = this.checkUsabilityOverride(insertBefore, insertBeforeDataContext, this._grid);\n }\n\n // if the new target is possible we'll display the dark blue bar (representin the acceptability) at the target position\n // else it won't show up (it will be off the screen)\n if (!dd.canMove) {\n dd.guide.style.top = '-1000px';\n } else {\n dd.guide.style.top = `${insertBefore * (this._grid.getOptions().rowHeight || 0)}px`;\n }\n\n dd.insertBefore = insertBefore;\n }\n }\n\n protected handleDragEnd(e: SlickEventData_, dd: DragRowMove) {\n if (!this._dragging) {\n return;\n }\n this._dragging = false;\n e.stopImmediatePropagation();\n\n dd.guide?.remove();\n dd.selectionProxy?.remove();\n dd.clonedSlickRow?.remove();\n\n if (dd.canMove) {\n const eventData = {\n grid: this._grid,\n rows: dd.selectedRows,\n insertBefore: dd.insertBefore\n };\n // TODO: this._grid.remapCellCssClasses ?\n this.onMoveRows.notify(eventData);\n }\n }\n\n getColumnDefinition(): Column {\n const columnId = String(this._options?.columnId ?? this._defaults.columnId);\n\n return {\n id: columnId,\n name: '',\n field: 'move',\n behavior: 'selectAndMove',\n excludeFromColumnPicker: true,\n excludeFromGridMenu: true,\n excludeFromHeaderMenu: true,\n resizable: false,\n selectable: false,\n width: this._options.width || 40,\n formatter: this.moveIconFormatter.bind(this)\n };\n }\n\n protected moveIconFormatter(row: number, _cell: number, _val: any, _column: Column, dataContext: any, grid: SlickGrid): FormatterResultWithHtml | string {\n if (!this.checkUsabilityOverride(row, dataContext, grid)) {\n return '';\n } else {\n const iconElm = document.createElement('div');\n iconElm.className = this._options.cssClass || '';\n return {\n addClasses: `cell-reorder dnd ${this._options.containerCssClass || ''}`,\n html: iconElm\n };\n }\n }\n\n protected checkUsabilityOverride(row: number, dataContext: any, grid: SlickGrid) {\n if (typeof this._usabilityOverride === 'function') {\n return this._usabilityOverride(row, dataContext, grid);\n }\n return true;\n }\n\n /**\n * Method that user can pass to override the default behavior or making every row moveable.\n * In order word, user can choose which rows to be an available as moveable (or not) by providing his own logic show/hide icon and usability.\n * @param overrideFn: override function callback\n */\n usabilityOverride(overrideFn: UsabilityOverrideFn) {\n this._usabilityOverride = overrideFn;\n }\n\n isHandlerColumn(columnIndex: number | string) {\n return /move|selectAndMove/.test(this._grid.getColumns()[+columnIndex].behavior || '');\n }\n}\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(true, window, {\n Slick: {\n RowMoveManager: SlickRowMoveManager\n }\n });\n}\n\n"], + "mappings": ";;;;;;;AAKA,MAAM,aAAyB,MAAM,OAC/B,oBAAgC,MAAM,cACtC,QAAoB,MAAM,OAoBnB,sBAAN,MAA0B;AAAA,IA6B/B,YAAY,SAAwC;AA1BpD;AAAA;AAAA,wCAAa;AACb,8CAAmB,IAAI,WAAuE;AAC9F,wCAAa,IAAI,WAAuE;AAIxF;AAAA;AAAA,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAY;AACtB,0BAAU;AACV,0BAAU;AACV,0BAAU;AACV,0BAAU,aAAkC;AAAA,QAC1C,UAAU;AAAA,QACV,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,QACrB,mBAAmB;AAAA,QACnB,wBAAwB;AAAA,QACxB,yBAAyB;AAAA,QACzB,sBAAsB;AAAA,QACtB,oBAAoB;AAAA,QACpB,eAAe;AAAA,QACf,OAAO;AAAA,MACT;AAGE,WAAK,WAAW,MAAM,OAAO,IAAM,CAAC,GAAG,KAAK,WAAW,OAAO,GAC9D,KAAK,gBAAgB,IAAI,kBAAkB;AAAA,IAC7C;AAAA,IAGA,KAAK,MAAiB;AA9DxB;AA+DI,WAAK,QAAQ,MACb,KAAK,UAAU,KAAK,MAAM,cAAc,GAGpC,SAAO,UAAK,aAAL,mBAAe,sBAAsB,cAC9C,KAAK,kBAAkB,KAAK,SAAS,iBAAiB,GAGxD,KAAK,cACF,UAAU,KAAK,MAAM,YAAY,KAAK,eAAe,KAAK,IAAI,CAAC,EAC/D,UAAU,KAAK,MAAM,aAAa,KAAK,gBAAgB,KAAK,IAAI,CAAC,EACjE,UAAU,KAAK,MAAM,QAAQ,KAAK,WAAW,KAAK,IAAI,CAAC,EACvD,UAAU,KAAK,MAAM,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IAClE;AAAA,IAEA,UAAU;AACR,WAAK,cAAc,eAAe;AAAA,IACpC;AAAA,IAEA,WAAW,YAA2C;AACpD,WAAK,WAAW,MAAM,OAAO,CAAC,GAAG,KAAK,UAAU,UAAU;AAAA,IAC5D;AAAA,IAEU,eAAe,GAAoB;AAE3C,QAAE,yBAAyB;AAAA,IAC7B;AAAA,IAEU,gBAAgB,GAA6B,IAAiC;AA3F1F;AA4FI,UAAM,OAAO,KAAK,MAAM,iBAAiB,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,GAAG,GAC7D,aAAa,6BAAM,KACnB,cAAc,KAAK,MAAM,YAAY,UAAU;AAErD,UAAI,CAAC,KAAK,uBAAuB,YAAY,aAAa,KAAK,KAAK;AAClE;AAOF,UAJI,KAAK,SAAS,oBAAoB,KAAK,MAAM,cAAc,EAAE,SAAS,KACxE,KAAK,MAAM,cAAc,EAAE,kBAAkB,GAG3C,KAAK,MAAM,cAAc,EAAE,SAAS,KAAK,CAAC,KAAK,gBAAgB,KAAK,IAAI;AAC1E,eAAO;AAOT,UAJA,KAAK,YAAY,IACjB,EAAE,yBAAyB,GAGvB,CAAC,KAAK,SAAS,mBAAmB;AACpC,YAAM,eAAc,UAAK,MAAM,YAAY,KAAK,KAAK,KAAK,IAAI,MAA1C,mBAA6C,QAAwB;AACzF,QAAI,gBACF,GAAG,iBAAiB,YAAY,UAAU,EAAI,GAC9C,GAAG,eAAe,UAAU,IAAI,0BAA0B,GAC1D,GAAG,eAAe,MAAM,UAAU,QAClC,GAAG,eAAe,MAAM,aAAa,OAAO,KAAK,SAAS,2BAA2B,CAAC,IAAI,MAC1F,GAAG,eAAe,MAAM,YAAY,OAAO,KAAK,SAAS,0BAA0B,CAAC,IAAI,MACxF,GAAG,eAAe,MAAM,UAAU,GAAG,KAAK,SAAS,wBAAwB,IAAI,IAC/E,GAAG,eAAe,MAAM,YAAY,SAAS,KAAK,SAAS,sBAAsB,IAAI,KACrF,KAAK,QAAQ,YAAY,GAAG,cAAc;AAAA,MAE9C;AAEA,UAAI,eAAe,KAAK,SAAS,gBAAgB,CAAC,KAAK,GAAG,IAAI,KAAK,MAAM,gBAAgB;AACzF,OAAI,aAAa,WAAW,KAAK,CAAC,aAAa,KAAK,iBAAe,gBAAgB,KAAK,GAAG,OACzF,eAAe,CAAC,KAAK,GAAG,GACnB,KAAK,SAAS,uBACjB,KAAK,MAAM,gBAAgB,YAAY;AAI3C,UAAM,YAAY,KAAK,MAAM,WAAW,EAAE;AAE1C,SAAG,eAAe,cAElB,GAAG,iBAAiB,SAAS,cAAc,KAAK,GAChD,GAAG,eAAe,YAAY,uBAC9B,GAAG,eAAe,MAAM,UAAU,QAClC,GAAG,eAAe,MAAM,WAAW,YACnC,GAAG,eAAe,MAAM,SAAS,SACjC,GAAG,eAAe,MAAM,QAAQ,GAAG,KAAK,QAAQ,WAAW,MAC3D,GAAG,eAAe,MAAM,SAAS,GAAG,YAAa,aAAa,MAAM,MACpE,KAAK,QAAQ,YAAY,GAAG,cAAc,GAE1C,GAAG,QAAQ,SAAS,cAAc,KAAK,GACvC,GAAG,MAAM,YAAY,uBACrB,GAAG,MAAM,MAAM,WAAW,YAC1B,GAAG,MAAM,MAAM,SAAS,SACxB,GAAG,MAAM,MAAM,QAAQ,GAAG,KAAK,QAAQ,WAAW,MAClD,GAAG,MAAM,MAAM,MAAM,WACrB,KAAK,QAAQ,YAAY,GAAG,KAAK,GAEjC,GAAG,eAAe;AAAA,IACpB;AAAA,IAEU,WAAW,KAAsB,IAAiC;AA9J9E;AA+JI,UAAI,CAAC,KAAK;AACR;AAGF,UAAI,yBAAyB;AAC7B,UAAM,IAAI,IAAI,eAAwC,GAGhD,QADe,kCAAkB,YAAlB,mBAA4B,OAA5B,YAAkC,GAC/B,UAAS,iBAAM,OAAO,KAAK,OAAO,MAAzB,mBAA4B,QAA5B,YAAmC;AACpE,SAAG,eAAe,MAAM,MAAM,GAAG,MAAM,CAAC,MACxC,GAAG,eAAe,MAAM,UAAU,SAG9B,GAAG,mBACL,GAAG,eAAe,MAAM,MAAM,GAAG,MAAM,CAAC,MACxC,GAAG,eAAe,MAAM,UAAU;AAGpC,UAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,MAAM,KAAK,MAAM,WAAW,EAAE,SAAU,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC;AAC3H,UAAI,iBAAiB,GAAG,cAAc;AACpC,YAAM,YAAY;AAAA,UAChB,MAAM,KAAK;AAAA,UACX,MAAM,GAAG;AAAA,UACT;AAAA,QACF;AASA,YAPI,KAAK,iBAAiB,OAAO,SAAS,EAAE,eAAe,MAAM,KAC/D,GAAG,UAAU,KAEb,GAAG,UAAU,IAIX,KAAK,sBAAsB,GAAG,SAAS;AACzC,cAAM,0BAA0B,KAAK,MAAM,YAAY,YAAY;AACnE,aAAG,UAAU,KAAK,uBAAuB,cAAc,yBAAyB,KAAK,KAAK;AAAA,QAC5F;AAIA,QAAK,GAAG,UAGN,GAAG,MAAM,MAAM,MAAM,GAAG,gBAAgB,KAAK,MAAM,WAAW,EAAE,aAAa,EAAE,OAF/E,GAAG,MAAM,MAAM,MAAM,WAKvB,GAAG,eAAe;AAAA,MACpB;AAAA,IACF;AAAA,IAEU,cAAc,GAAoB,IAAiB;AAjN/D;AAkNI,UAAK,KAAK,cAGV,KAAK,YAAY,IACjB,EAAE,yBAAyB,IAE3B,QAAG,UAAH,WAAU,WACV,QAAG,mBAAH,WAAmB,WACnB,QAAG,mBAAH,WAAmB,UAEf,GAAG,UAAS;AACd,YAAM,YAAY;AAAA,UAChB,MAAM,KAAK;AAAA,UACX,MAAM,GAAG;AAAA,UACT,cAAc,GAAG;AAAA,QACnB;AAEA,aAAK,WAAW,OAAO,SAAS;AAAA,MAClC;AAAA,IACF;AAAA,IAEA,sBAA8B;AAvOhC;AA0OI,aAAO;AAAA,QACL,IAHe,QAAO,gBAAK,aAAL,mBAAe,aAAf,YAA2B,KAAK,UAAU,QAAQ;AAAA,QAIxE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,yBAAyB;AAAA,QACzB,qBAAqB;AAAA,QACrB,uBAAuB;AAAA,QACvB,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO,KAAK,SAAS,SAAS;AAAA,QAC9B,WAAW,KAAK,kBAAkB,KAAK,IAAI;AAAA,MAC7C;AAAA,IACF;AAAA,IAEU,kBAAkB,KAAa,OAAe,MAAW,SAAiB,aAAkB,MAAmD;AACvJ,UAAK,KAAK,uBAAuB,KAAK,aAAa,IAAI,GAEhD;AACL,YAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,uBAAQ,YAAY,KAAK,SAAS,YAAY,IACvC;AAAA,UACL,YAAY,oBAAoB,KAAK,SAAS,qBAAqB,EAAE;AAAA,UACrE,MAAM;AAAA,QACR;AAAA,MACF;AARE,eAAO;AAAA,IASX;AAAA,IAEU,uBAAuB,KAAa,aAAkB,MAAiB;AAC/E,aAAI,OAAO,KAAK,sBAAuB,aAC9B,KAAK,mBAAmB,KAAK,aAAa,IAAI,IAEhD;AAAA,IACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,kBAAkB,YAAiC;AACjD,WAAK,qBAAqB;AAAA,IAC5B;AAAA,IAEA,gBAAgB,aAA8B;AAC5C,aAAO,qBAAqB,KAAK,KAAK,MAAM,WAAW,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE;AAAA,IACvF;AAAA,EACF;AAGA,EAAiB,OAAO,SACtB,MAAM,OAAO,IAAM,QAAQ;AAAA,IACzB,OAAO;AAAA,MACL,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC;", "names": [] } diff --git a/dist/browser/slick.dataview.js b/dist/browser/slick.dataview.js index ea11509d0..61ccd3cc9 100644 --- a/dist/browser/slick.dataview.js +++ b/dist/browser/slick.dataview.js @@ -9,7 +9,8 @@ constructor(options) { __publicField(this, "defaults", { groupItemMetadataProvider: null, - inlineFilters: !1 + inlineFilters: !1, + useCSPSafeFilter: !1 }); // private __publicField(this, "idProperty", "id"); @@ -24,6 +25,8 @@ // rows by id; lazy-calculated __publicField(this, "filter", null); // filter function + __publicField(this, "filterCSPSafe", null); + // filter function __publicField(this, "updated", null); // updated item ids __publicField(this, "suspend", !1); @@ -41,7 +44,9 @@ __publicField(this, "filterArgs"); __publicField(this, "filteredItems", []); __publicField(this, "compiledFilter"); + __publicField(this, "compiledFilterCSPSafe"); __publicField(this, "compiledFilterWithCaching"); + __publicField(this, "compiledFilterWithCachingCSPSafe"); __publicField(this, "filterCache", []); __publicField(this, "_grid"); // grid object will be defined only after using "syncGridSelection()" method" @@ -96,7 +101,7 @@ this.isBulkSuspend = !1, this.suspend = !1, wasBulkSuspend && (this.processBulkDelete(), this.ensureIdUniqueness()), this.refresh(); } destroy() { - this.items = [], this.idxById = null, this.rowsById = null, this.filter = null, this.updated = null, this.sortComparer = null, this.filterCache = [], this.filteredItems = [], this.compiledFilter = null, this.compiledFilterWithCaching = null, this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged && (this._grid.onSelectedRowsChanged.unsubscribe(), this._grid.onCellCssStylesChanged.unsubscribe()), this.onRowsOrCountChanged && this.onRowsOrCountChanged.unsubscribe(); + this.items = [], this.idxById = null, this.rowsById = null, this.filter = null, this.filterCSPSafe = null, this.updated = null, this.sortComparer = null, this.filterCache = [], this.filteredItems = [], this.compiledFilter = null, this.compiledFilterCSPSafe = null, this.compiledFilterWithCaching = null, this.compiledFilterWithCachingCSPSafe = null, this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged && (this._grid.onSelectedRowsChanged.unsubscribe(), this._grid.onCellCssStylesChanged.unsubscribe()), this.onRowsOrCountChanged && this.onRowsOrCountChanged.unsubscribe(); } setRefreshHints(hints) { this.refreshHints = hints; @@ -193,14 +198,14 @@ } /** Get current Filter used by the DataView */ getFilter() { - return this.filter; + return this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter; } /** * Set a Filter that will be used by the DataView * @param {Function} fn - filter callback function */ setFilter(filterFn) { - this.filter = filterFn, this._options.inlineFilters && (this.compiledFilter = this.compileFilter(), this.compiledFilterWithCaching = this.compileFilterWithCaching()), this.refresh(); + this.filterCSPSafe = filterFn, this.filter = filterFn, this._options.inlineFilters && (this.compiledFilterCSPSafe = this.compileFilterCSPSafe, this.compiledFilterWithCachingCSPSafe = this.compileFilterWithCachingCSPSafe, this.compiledFilter = this.compileFilter(this._options.useCSPSafeFilter), this.compiledFilterWithCaching = this.compileFilterWithCaching(this._options.useCSPSafeFilter)), this.refresh(); } /** Get current Grouping info */ getGrouping() { @@ -555,7 +560,17 @@ return function() { }; } - compileFilter() { + compileFilterCSPSafe(_items, _args) { + if (typeof this.filterCSPSafe != "function") + return []; + let _retval = [], _il = _items.length; + for (let _i = 0; _i < _il; _i++) + this.filterCSPSafe(_items[_i], _args) && _retval.push(_items[_i]); + return _retval; + } + compileFilter(stopRunningIfCSPSafeIsActive = !1) { + if (stopRunningIfCSPSafeIsActive) + return null; let filterInfo = this.getFunctionInfo(this.filter), filterPath1 = "{ continue _coreloop; }$1", filterPath2 = "{ _retval[_idx++] = $item$; continue _coreloop; }$1", filterBody = filterInfo.body.replace(/return false\s*([;}]|\}|$)/gi, filterPath1).replace(/return!1([;}]|\}|$)/gi, filterPath1).replace(/return true\s*([;}]|\}|$)/gi, filterPath2).replace(/return!0([;}]|\}|$)/gi, filterPath2).replace( /return ([^;}]+?)\s*([;}]|$)/gi, "{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2" @@ -575,7 +590,9 @@ let fn = new Function("_items,_args", tpl), fnName = "compiledFilter"; return fn.displayName = fnName, fn.name = this.setFunctionName(fn, fnName), fn; } - compileFilterWithCaching() { + compileFilterWithCaching(stopRunningIfCSPSafeIsActive = !1) { + if (stopRunningIfCSPSafeIsActive) + return null; let filterInfo = this.getFunctionInfo(this.filter), filterPath1 = "{ continue _coreloop; }$1", filterPath2 = "{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1", filterBody = filterInfo.body.replace(/return false\s*([;}]|\}|$)/gi, filterPath1).replace(/return!1([;}]|\}|$)/gi, filterPath1).replace(/return true\s*([;}]|\}|$)/gi, filterPath2).replace(/return!0([;}]|\}|$)/gi, filterPath2).replace( /return ([^;}]+?)\s*([;}]|$)/gi, "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2" @@ -599,6 +616,14 @@ let fn = new Function("_items,_args,_cache", tpl), fnName = "compiledFilterWithCaching"; return fn.displayName = fnName, fn.name = this.setFunctionName(fn, fnName), fn; } + compileFilterWithCachingCSPSafe(_items, _args, filterCache) { + if (typeof this.filterCSPSafe != "function") + return []; + let _retval = [], _il = _items.length; + for (let _i = 0; _i < _il; _i++) + (filterCache[_i] || this.filterCSPSafe(_items[_i], _args)) && _retval.push(_items[_i]); + return _retval; + } /** * 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 * We can use Object.defineProperty and set it the property to writable, see MDN for reference @@ -631,9 +656,9 @@ return retval; } getFilteredAndPagedItems(items) { - if (this.filter) { - let batchFilter = this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter, batchFilterWithCaching = this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching; - this.refreshHints.isFilterNarrowing ? this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs) : this.refreshHints.isFilterExpanding ? this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache) : this.refreshHints.isFilterUnchanged || (this.filteredItems = batchFilter.call(this, items, this.filterArgs)); + if (this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter) { + let batchFilter, batchFilterWithCaching; + this._options.useCSPSafeFilter ? (batchFilter = this._options.inlineFilters ? this.compiledFilterCSPSafe : this.uncompiledFilter, batchFilterWithCaching = this._options.inlineFilters ? this.compiledFilterWithCachingCSPSafe : this.uncompiledFilterWithCaching) : (batchFilter = this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter, batchFilterWithCaching = this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching), this.refreshHints.isFilterNarrowing ? this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs) : this.refreshHints.isFilterExpanding ? this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache) : this.refreshHints.isFilterUnchanged || (this.filteredItems = batchFilter.call(this, items, this.filterArgs)); } else this.filteredItems = this.pagesize ? items : items.concat(); let paged; diff --git a/dist/browser/slick.dataview.js.map b/dist/browser/slick.dataview.js.map index 697190333..a0f984c2e 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 {\n Aggregator,\n CssStyleHash,\n CustomDataView,\n Grouping,\n GroupingFormatterItem,\n ItemMetadata,\n OnGroupCollapsedEventArgs,\n OnGroupExpandedEventArgs,\n OnRowCountChangedEventArgs,\n OnRowsChangedEventArgs,\n OnRowsOrCountChangedEventArgs,\n OnSelectedRowIdsChangedEventArgs,\n OnSetItemsCalledEventArgs,\n PagingInfo,\n} from './models/index';\nimport {\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickGroup as SlickGroup_,\n SlickGroupTotals as SlickGroupTotals_,\n Utils as Utils_,\n SlickNonDataItem,\n} from './slick.core';\nimport type { SlickGrid } from './slick.grid';\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\n\nexport interface DataViewOption {\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\n inlineFilters: boolean;\n}\nexport type FilterFn = (item: T, args: any) => boolean;\nexport type DataIdType = number | string;\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\n\n/**\n * A sample Model implementation.\n * Provides a filtered view of the underlying data.\n *\n * Relies on the data item having an \"id\" property uniquely identifying it.\n */\nexport class SlickDataView implements CustomDataView {\n protected defaults: DataViewOption = {\n groupItemMetadataProvider: null,\n inlineFilters: false\n };\n\n // private\n protected idProperty = 'id'; // property holding a unique row id\n protected items: TData[] = []; // data by index\n protected rows: TData[] = []; // data by row\n protected idxById = new Map(); // indexes by id\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\n protected filter: FilterFn | null = null; // filter function\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\n protected suspend = false; // suspends the recalculation\n protected isBulkSuspend = false; // delays protectedious operations like the\n // index update and delete to efficient\n // versions at endUpdate\n protected bulkDeleteIds = new Map();\n protected sortAsc: boolean | undefined = true;\n protected fastSortField?: string | null | (() => string);\n protected sortComparer!: ((a: TData, b: TData) => number);\n protected refreshHints: any = {};\n protected prevRefreshHints: any = {};\n protected filterArgs: any;\n protected filteredItems: TData[] = [];\n protected compiledFilter?: FilterFn | null;\n protected compiledFilterWithCaching?: FilterFn | null;\n protected filterCache: any[] = [];\n protected _grid?: SlickGrid; // grid object will be defined only after using \"syncGridSelection()\" method\"\n\n // grouping\n protected groupingInfoDefaults: Grouping = {\n getter: undefined,\n formatter: undefined,\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\n predefinedValues: [],\n aggregators: [],\n aggregateEmpty: false,\n aggregateCollapsed: false,\n aggregateChildGroups: false,\n collapsed: false,\n displayTotalsRow: true,\n lazyTotalsCalculation: false\n };\n protected groupingInfos: Array = [];\n protected groups: SlickGroup_[] = [];\n protected toggledGroupsByLevel: any[] = [];\n protected groupingDelimiter = ':|:';\n protected selectedRowIds: DataIdType[] = [];\n protected preSelectedRowIdsChangeFn?: Function;\n\n protected pagesize = 0;\n protected pagenum = 0;\n protected totalRows = 0;\n protected _options: DataViewOption;\n\n // public events\n onBeforePagingInfoChanged = new SlickEvent();\n onGroupExpanded = new SlickEvent();\n onGroupCollapsed = new SlickEvent();\n onPagingInfoChanged = new SlickEvent();\n onRowCountChanged = new SlickEvent();\n onRowsChanged = new SlickEvent();\n onRowsOrCountChanged = new SlickEvent();\n onSelectedRowIdsChanged = new SlickEvent();\n onSetItemsCalled = new SlickEvent();\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this.defaults, options);\n }\n\n /**\n * Begins a bached update of the items in the data view.\n * including deletes and the related events are postponed to the endUpdate call.\n * As certain operations are postponed during this update, some methods might not\n * deliver fully consistent information.\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\n */\n beginUpdate(bulkUpdate?: boolean) {\n this.suspend = true;\n this.isBulkSuspend = bulkUpdate === true;\n }\n\n endUpdate() {\n const wasBulkSuspend = this.isBulkSuspend;\n this.isBulkSuspend = false;\n this.suspend = false;\n if (wasBulkSuspend) {\n this.processBulkDelete();\n this.ensureIdUniqueness();\n }\n this.refresh();\n }\n\n destroy() {\n this.items = [];\n this.idxById = null as any;\n this.rowsById = null as any;\n this.filter = null as any;\n this.updated = null as any;\n this.sortComparer = null as any;\n this.filterCache = [];\n this.filteredItems = [];\n this.compiledFilter = null;\n this.compiledFilterWithCaching = null;\n\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\n this._grid.onSelectedRowsChanged.unsubscribe();\n this._grid.onCellCssStylesChanged.unsubscribe();\n }\n if (this.onRowsOrCountChanged) {\n this.onRowsOrCountChanged.unsubscribe();\n }\n }\n\n setRefreshHints(hints: any) {\n this.refreshHints = hints;\n }\n\n setFilterArgs(args: any) {\n this.filterArgs = args;\n }\n\n /**\n * Processes all delete requests placed during bulk update\n * by recomputing the items and idxById members.\n */\n protected processBulkDelete() {\n if (!this.idxById) { return; }\n\n // the bulk update is processed by\n // recomputing the whole items array and the index lookup in one go.\n // this is done by placing the not-deleted items\n // from left to right into the array and shrink the array the the new\n // size afterwards.\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\n\n let id: DataIdType, item, newIdx = 0;\n for (let i = 0, l = this.items.length; i < l; i++) {\n item = this.items[i];\n id = item[this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n\n // if items have been marked as deleted we skip them for the new final items array\n // and we remove them from the lookup table.\n if (this.bulkDeleteIds.has(id)) {\n this.idxById.delete(id);\n } else {\n // for items which are not deleted, we add them to the\n // next free position in the array and register the index in the lookup.\n this.items[newIdx] = item;\n this.idxById.set(id, newIdx);\n ++newIdx;\n }\n }\n\n // here we shrink down the full item array to the ones actually\n // inserted in the cleanup loop above.\n this.items.length = newIdx;\n // and finally cleanup the deleted ids to start cleanly on the next update.\n this.bulkDeleteIds = new Map();\n }\n\n protected updateIdxById(startingIndex?: number) {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n startingIndex = startingIndex || 0;\n let id: DataIdType;\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n this.idxById.set(id, i);\n }\n }\n\n protected ensureIdUniqueness() {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n let id: DataIdType;\n for (let i = 0, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined || this.idxById.get(id) !== i) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n }\n }\n\n /** Get all DataView Items */\n getItems() {\n return this.items;\n }\n\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\n getIdPropertyName() {\n return this.idProperty;\n }\n\n /**\n * Set the Items with a new Dataset and optionally pass a different Id property name\n * @param {Array<*>} data - array of data\n * @param {String} [objectIdProperty] - optional id property to use as primary id\n */\n setItems(data: TData[], objectIdProperty?: string) {\n if (objectIdProperty !== undefined) {\n this.idProperty = objectIdProperty;\n }\n this.items = this.filteredItems = data;\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\n this.idxById = new Map();\n this.updateIdxById();\n this.ensureIdUniqueness();\n this.refresh();\n }\n\n /** Set Paging Options */\n setPagingOptions(args: Partial) {\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\n if (Utils.isDefined(args.pageSize)) {\n this.pagesize = args.pageSize;\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\n }\n\n if (Utils.isDefined(args.pageNum)) {\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\n }\n\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n\n this.refresh();\n }\n }\n\n /** Get Paging Options */\n getPagingInfo(): PagingInfo {\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages, dataView: this as SlickDataView };\n }\n\n /** Sort Method to use by the DataView */\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\n this.sortAsc = ascending;\n this.sortComparer = comparer;\n this.fastSortField = null;\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort(comparer);\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /**\n * Provides a workaround for the extremely slow sorting in IE.\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n * to return the value of that field and then doing a native Array.sort().\n */\n fastSort(field: string | (() => string), ascending?: boolean) {\n this.sortAsc = ascending;\n this.fastSortField = field;\n this.sortComparer = null as any;\n const oldToString = Object.prototype.toString;\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\n // @ts-ignore\n return this[field];\n };\n // an extra reversal for descending sort keeps the sort stable\n // (assuming a stable native sort implementation, which isn't true in some cases)\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort();\n Object.prototype.toString = oldToString;\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /** Re-Sort the dataset */\n reSort() {\n if (this.sortComparer) {\n this.sort(this.sortComparer, this.sortAsc);\n } else if (this.fastSortField) {\n this.fastSort(this.fastSortField, this.sortAsc);\n }\n }\n\n /** Get only the DataView filtered items */\n getFilteredItems() {\n return this.filteredItems as T[];\n }\n\n /** Get the array length (count) of only the DataView filtered items */\n getFilteredItemCount() {\n return this.filteredItems.length;\n }\n\n /** Get current Filter used by the DataView */\n getFilter() {\n return this.filter;\n }\n\n /**\n * Set a Filter that will be used by the DataView\n * @param {Function} fn - filter callback function\n */\n setFilter(filterFn: FilterFn) {\n this.filter = filterFn;\n if (this._options.inlineFilters) {\n this.compiledFilter = this.compileFilter();\n this.compiledFilterWithCaching = this.compileFilterWithCaching();\n }\n this.refresh();\n }\n\n /** Get current Grouping info */\n getGrouping(): Grouping[] {\n return this.groupingInfos;\n }\n\n /** Set some Grouping */\n setGrouping(groupingInfo: Grouping | Grouping[]) {\n if (!this._options.groupItemMetadataProvider) {\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\n }\n\n this.groups = [];\n this.toggledGroupsByLevel = [];\n groupingInfo = groupingInfo || [];\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\n\n for (let i = 0; i < this.groupingInfos.length; i++) {\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\n gi.getterIsAFn = typeof gi.getter === 'function';\n\n // pre-compile accumulator loops\n gi.compiledAccumulators = [];\n let idx = gi.aggregators.length;\n while (idx--) {\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoop(gi.aggregators[idx]);\n }\n\n this.toggledGroupsByLevel[i] = {};\n }\n\n this.refresh();\n }\n\n /** Get an item in the DataView by its row index */\n getItemByIdx(i: number) {\n return this.items[i] as T;\n }\n\n /** Get row index in the DataView by its Id */\n getIdxById(id: DataIdType) {\n return this.idxById?.get(id);\n }\n\n protected ensureRowsByIdCache() {\n if (!this.rowsById) {\n this.rowsById = {};\n for (let i = 0, l = this.rows.length; i < l; i++) {\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\n }\n }\n }\n\n /** Get row number in the grid by its item object */\n getRowByItem(item: TData) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\n }\n\n /** Get row number in the grid by its Id */\n getRowById(id: DataIdType) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[id];\n }\n\n /** Get an item in the DataView by its Id */\n getItemById(id: DataIdType) {\n return this.items[(this.idxById.get(id) as number)] as T;\n }\n\n /** From the items array provided, return the mapped rows */\n mapItemsToRows(itemArray: TData[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = itemArray.length; i < l; i++) {\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the Ids array provided, return the mapped rows */\n mapIdsToRows(idArray: DataIdType[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = idArray.length; i < l; i++) {\n const row = this.rowsById?.[idArray[i]];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the rows array provided, return the mapped Ids */\n mapRowsToIds(rowArray: number[]) {\n const ids: DataIdType[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (rowArray[i] < this.rows.length) {\n const rowItem = this.rows[rowArray[i]];\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\n }\n }\n return ids;\n }\n\n /**\n * Performs the update operations of a single item by id without\n * triggering any events or refresh operations.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateSingleItem(id: DataIdType, item: TData) {\n if (!this.idxById) { return; }\n\n // see also https://github.com/mleibman/SlickGrid/issues/1082\n if (!this.idxById.has(id)) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n\n // What if the specified item also has an updated idProperty?\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\n if (id !== item[this.idProperty as keyof TData]) {\n // make sure the new id is unique:\n const newId = item[this.idProperty as keyof TData] as DataIdType;\n if (!Utils.isDefined(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\n }\n if (this.idxById.has(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\n }\n this.idxById.set(newId, this.idxById.get(id) as number);\n this.idxById.delete(id);\n\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\n if (this.updated?.[id]) {\n delete this.updated[id];\n }\n\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\n\n id = newId;\n }\n this.items[this.idxById.get(id) as number] = item;\n\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\n\n if (!this.updated) {\n this.updated = {};\n }\n this.updated[id] = true;\n }\n\n /**\n * Updates a single item in the data view given the id and new value.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateItem(id: DataIdType, item: T) {\n this.updateSingleItem(id, item);\n this.refresh();\n }\n\n /**\n * Updates multiple items in the data view given the new ids and new values.\n * @param id {Array} The array of new ids which is in the same order as the items.\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\n */\n updateItems(ids: DataIdType[], newItems: T[]) {\n if (ids.length !== newItems.length) {\n throw new Error(\"[SlickGrid DataView] Mismatch on the length of ids and items provided to update\");\n }\n for (let i = 0, l = newItems.length; i < l; i++) {\n this.updateSingleItem(ids[i], newItems[i]);\n }\n this.refresh();\n }\n\n /**\n * Inserts a single item into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\n * @param item The item to insert.\n */\n insertItem(insertBefore: number, item: TData) {\n this.items.splice(insertBefore, 0, item);\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Inserts multiple items into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\n * @param newItems {Array} The items to insert.\n */\n insertItems(insertBefore: number, newItems: TData[]) {\n // @ts-ignore\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Adds a single item at the end of the data view.\n * @param item The item to add at the end.\n */\n addItem(item: TData) {\n this.items.push(item);\n this.updateIdxById(this.items.length - 1);\n this.refresh();\n }\n\n /**\n * Adds multiple items at the end of the data view.\n * @param {Array} newItems The items to add at the end.\n */\n addItems(newItems: TData[]) {\n this.items = this.items.concat(newItems);\n this.updateIdxById(this.items.length - newItems.length);\n this.refresh();\n }\n\n /**\n * Deletes a single item identified by the given id from the data view.\n * @param {String|Number} id The id identifying the object to delete.\n */\n deleteItem(id: DataIdType) {\n if (!this.idxById) { return; }\n if (this.isBulkSuspend) {\n this.bulkDeleteIds.set(id, true);\n } else {\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n this.items.splice(idx, 1);\n this.updateIdxById(idx);\n this.refresh();\n }\n }\n\n /**\n * Deletes multiple item identified by the given ids from the data view.\n * @param {Array} ids The ids of the items to delete.\n */\n deleteItems(ids: DataIdType[]) {\n if (ids.length === 0 || !this.idxById) {\n return;\n }\n\n if (this.isBulkSuspend) {\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.bulkDeleteIds.set(id, true);\n }\n } else {\n // collect all indexes\n const indexesToDelete: number[] = [];\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n indexesToDelete.push(idx);\n }\n\n // Remove from back to front\n indexesToDelete.sort();\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\n this.items.splice(indexesToDelete[i], 1);\n }\n\n // update lookup from front to back\n this.updateIdxById(indexesToDelete[0]);\n this.refresh();\n }\n }\n\n /** Add an item in a sorted dataset (a Sort function must be defined) */\n sortedAddItem(item: TData) {\n if (!this.sortComparer) {\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\n }\n this.insertItem(this.sortedIndex(item), item);\n }\n\n /** Update an item in a sorted dataset (a Sort function must be defined) */\n sortedUpdateItem(id: string | number, item: TData) {\n if (!this.idxById) { return; }\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\n }\n if (!this.sortComparer) {\n throw new Error(\"[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()\");\n }\n const oldItem = this.getItemById(id);\n if (this.sortComparer(oldItem, item) !== 0) {\n // item affects sorting -> must use sorted add\n this.deleteItem(id);\n this.sortedAddItem(item);\n } else { // update does not affect sorting -> regular update works fine\n this.updateItem(id, item);\n }\n }\n\n protected sortedIndex(searchItem: TData) {\n let low = 0;\n let high = this.items.length;\n\n while (low < high) {\n const mid = low + high >>> 1;\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n }\n\n /** Get item count, that is the full dataset lenght of the DataView */\n getItemCount() {\n return this.items.length;\n }\n\n /** Get row count (rows displayed in current page) */\n getLength() {\n return this.rows.length;\n }\n\n /** Retrieve an item from the DataView at specific index */\n getItem(i: number) {\n const item = this.rows[i] as T;\n\n // if this is a group row, make sure totals are calculated and update the title\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\n const gi = this.groupingInfos[(item as SlickGroup_).level];\n if (!gi.displayTotalsRow) {\n this.calculateTotals((item as SlickGroup_).totals);\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\n }\n }\n // if this is a totals row, make sure it's calculated\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\n this.calculateTotals(item as SlickGroupTotals_);\n }\n\n return item;\n }\n\n getItemMetadata(i: number): ItemMetadata | null {\n const item = this.rows[i];\n if (item === undefined) {\n return null;\n }\n\n // overrides for grouping rows\n if ((item as SlickGroup_).__group) {\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\n }\n\n // overrides for totals rows\n if ((item as SlickGroupTotals_).__groupTotals) {\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\n }\n\n return null;\n }\n\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\n if (!Utils.isDefined(level)) {\n for (let i = 0; i < this.groupingInfos.length; i++) {\n this.toggledGroupsByLevel[i] = {};\n this.groupingInfos[i].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\n }\n }\n } else {\n this.toggledGroupsByLevel[level] = {};\n this.groupingInfos[level].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level, groupingKey: null });\n }\n }\n this.refresh();\n }\n\n /**\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\n */\n collapseAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, true);\n }\n\n /**\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\n */\n expandAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, false);\n }\n\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\n // @ts-ignore\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\n this.refresh();\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n * the 'high' group.\n */\n collapseGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n groupingKey = arg0;\n level = arg0.split(this.groupingDelimiter).length - 1;\n } else {\n groupingKey = args.join(this.groupingDelimiter);\n level = args.length - 1;\n }\n\n this.expandCollapseGroup(level, groupingKey, true);\n this.onGroupCollapsed.notify({ level, groupingKey });\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n * the 'high' group.\n */\n expandGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n level = arg0.split(this.groupingDelimiter).length - 1;\n groupingKey = arg0;\n } else {\n level = args.length - 1;\n groupingKey = args.join(this.groupingDelimiter);\n }\n\n this.expandCollapseGroup(level, groupingKey, false);\n this.onGroupExpanded.notify({ level, groupingKey });\n }\n\n getGroups() {\n return this.groups;\n }\n\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\n let group;\n let val;\n const groups: SlickGroup_[] = [];\n const groupsByVal: any = {};\n let r;\n const level = parentGroup ? parentGroup.level + 1 : 0;\n const gi = this.groupingInfos[level];\n\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\n val = gi.predefinedValues?.[i];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n }\n\n for (let i = 0, l = rows.length; i < l; i++) {\n r = rows[i];\n val = gi.getterIsAFn ? (gi.getter as Function)(r) : r[gi.getter as keyof TData];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n\n group.rows[group.count++] = r;\n }\n\n if (level < this.groupingInfos.length - 1) {\n for (let i = 0; i < groups.length; i++) {\n group = groups[i];\n group.groups = this.extractGroups(group.rows, group);\n }\n }\n\n if (groups.length) {\n this.addTotals(groups, level);\n }\n\n groups.sort(this.groupingInfos[level].comparer);\n\n return groups;\n }\n\n protected calculateTotals(totals: SlickGroupTotals_) {\n const group = totals.group;\n const gi = this.groupingInfos[group.level ?? 0];\n const isLeafLevel = (group.level === this.groupingInfos.length);\n let agg: Aggregator, idx = gi.aggregators.length;\n\n if (!isLeafLevel && gi.aggregateChildGroups) {\n // make sure all the subgroups are calculated\n let i = group.groups?.length ?? 0;\n while (i--) {\n if (!group.groups[i].totals.initialized) {\n this.calculateTotals(group.groups[i].totals);\n }\n }\n }\n\n while (idx--) {\n agg = gi.aggregators[idx];\n agg.init();\n if (!isLeafLevel && gi.aggregateChildGroups) {\n gi.compiledAccumulators[idx].call(agg, group.groups);\n } else {\n gi.compiledAccumulators[idx].call(agg, group.rows);\n }\n agg.storeResult(totals);\n }\n totals.initialized = true;\n }\n\n protected addGroupTotals(group: SlickGroup_) {\n const gi = this.groupingInfos[group.level];\n const totals = new SlickGroupTotals();\n totals.group = group;\n group.totals = totals;\n if (!gi.lazyTotalsCalculation) {\n this.calculateTotals(totals);\n }\n }\n\n protected addTotals(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupCollapsed = gi.collapsed;\n const toggledGroups = this.toggledGroupsByLevel[level];\n let idx = groups.length, g;\n while (idx--) {\n g = groups[idx];\n\n if (g.collapsed && !gi.aggregateCollapsed) {\n continue;\n }\n\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n if (g.groups) {\n this.addTotals(g.groups, level + 1);\n }\n\n if (gi.aggregators?.length && (\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\n this.addGroupTotals(g);\n }\n\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\n g.title = gi.formatter ? gi.formatter(g) : g.value;\n }\n }\n\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupedRows: any[] = [];\n let rows: any[], gl = 0, g;\n for (let i = 0, l = groups.length; i < l; i++) {\n g = groups[i];\n groupedRows[gl++] = g;\n\n if (!g.collapsed) {\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\n for (let j = 0, jj = rows.length; j < jj; j++) {\n groupedRows[gl++] = rows[j];\n }\n }\n\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n groupedRows[gl++] = g.totals;\n }\n }\n return groupedRows;\n }\n\n protected getFunctionInfo(fn: Function) {\n const fnStr = fn.toString();\n const usingEs5 = fnStr.indexOf('function') >= 0; // with ES6, the word function is not present\n const fnRegex = usingEs5 ? /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/ : /^[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n const matches = fn.toString().match(fnRegex) || [];\n return {\n params: matches[1].split(\",\"),\n body: matches[2]\n };\n }\n\n protected compileAccumulatorLoop(aggregator: Aggregator) {\n if (aggregator.accumulate) {\n const accumulatorInfo = this.getFunctionInfo(aggregator.accumulate);\n const fn: any = new Function(\n \"_items\",\n \"for (var \" + accumulatorInfo.params[0] + \", _i=0, _il=_items.length; _i<_il; _i++) {\" +\n accumulatorInfo.params[0] + \" = _items[_i]; \" +\n accumulatorInfo.body +\n \"}\"\n );\n const fnName = \"compiledAccumulatorLoop\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n } else {\n return function noAccumulator() { };\n }\n }\n\n protected compileFilter(): FilterFn {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args\", tpl);\n const fnName = \"compiledFilter\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n protected compileFilterWithCaching() {\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args, _cache) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"if (_cache[_i]) { \",\n \"_retval[_idx++] = $item$; \",\n \"continue _coreloop; \",\n \"} \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args,_cache\", tpl);\n const fnName = \"compiledFilterWithCaching\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n /**\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\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n * @param {*} fn\n * @param {string} fnName\n */\n protected setFunctionName(fn: any, fnName: string) {\n try {\n Object.defineProperty(fn, 'name', {\n writable: true,\n value: fnName\n });\n } catch (err) {\n fn.name = fnName;\n }\n }\n\n protected uncompiledFilter(items: TData[], args: any) {\n const retval: any[] = [];\n let idx = 0;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n if (this.filter?.(items[i], args)) {\n retval[idx++] = items[i];\n }\n }\n\n return retval;\n }\n\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\n const retval: any[] = [];\n let idx = 0,\n item: TData;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n item = items[i];\n if (cache[i]) {\n retval[idx++] = item;\n } else if (this.filter?.(item, args)) {\n retval[idx++] = item;\n cache[i] = true;\n }\n }\n\n return retval;\n }\n\n protected getFilteredAndPagedItems(items: TData[]) {\n if (this.filter) {\n const batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function;\n const batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function;\n\n if (this.refreshHints.isFilterNarrowing) {\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\n } else if (this.refreshHints.isFilterExpanding) {\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\n } else if (!this.refreshHints.isFilterUnchanged) {\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\n }\n } else {\n // special case: if not filtering and not paging, the resulting\n // rows collection needs to be a copy so that changes due to sort\n // can be caught\n this.filteredItems = this.pagesize ? items : items.concat();\n }\n\n // get the current page\n let paged: TData[];\n if (this.pagesize) {\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\n if (this.filteredItems.length === 0) {\n this.pagenum = 0;\n } else {\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\n }\n }\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\n } else {\n paged = this.filteredItems;\n }\n return { totalRows: this.filteredItems.length, rows: paged };\n }\n\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\n let item: any, r, eitherIsNonData;\n const diff: number[] = [];\n let from = 0, to = Math.max(newRows.length, rows.length);\n\n if (this.refreshHints?.ignoreDiffsBefore) {\n from = Math.max(0,\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\n }\n\n if (this.refreshHints?.ignoreDiffsAfter) {\n to = Math.min(newRows.length,\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\n }\n\n for (let i = from, rl = rows.length; i < to; i++) {\n if (i >= rl) {\n diff[diff.length] = i;\n } else {\n item = newRows[i];\n r = rows[i];\n\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\n || (eitherIsNonData &&\n // no good way to compare totals since they are arbitrary DTOs\n // deep object comparison is pretty expensive\n // always considering them 'dirty' seems easier for the time being\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\n || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData]\n || (this.updated?.[item[this.idProperty as keyof TData]])\n ) {\n diff[diff.length] = i;\n }\n }\n }\n return diff;\n }\n\n protected recalc(_items: TData[]) {\n this.rowsById = undefined;\n\n if (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing ||\n this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) {\n this.filterCache = [];\n }\n\n const filteredItems = this.getFilteredAndPagedItems(_items);\n this.totalRows = filteredItems.totalRows;\n let newRows: TData[] = filteredItems.rows;\n\n this.groups = [];\n if (this.groupingInfos.length) {\n this.groups = this.extractGroups(newRows);\n if (this.groups.length) {\n newRows = this.flattenGroupedRows(this.groups);\n }\n }\n\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\n\n this.rows = newRows as TData[];\n\n return diff;\n }\n\n refresh() {\n if (this.suspend) {\n return;\n }\n\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\n\n const countBefore = this.rows.length;\n const totalRowsBefore = this.totalRows;\n\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\n\n // if the current page is no longer valid, go to last page and recalc\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\n diff = this.recalc(this.items);\n }\n\n this.updated = null;\n this.prevRefreshHints = this.refreshHints;\n this.refreshHints = {};\n\n if (totalRowsBefore !== this.totalRows) {\n // use the previously saved paging info\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n }\n }\n if (countBefore !== this.rows.length) {\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\n }\n if (diff.length > 0) {\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\n }\n if (countBefore !== this.rows.length || diff.length > 0) {\n this.onRowsOrCountChanged.notify({\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\n }, null, this);\n }\n }\n\n /**\n * Wires the grid and the DataView together to keep row selection tied to item ids.\n * This is useful since, without it, the grid only knows about rows, so if the items\n * move around, the same rows stay selected instead of the selection moving along\n * with the items.\n *\n * NOTE: This doesn't work with cell selection model.\n *\n * @param {SlickGrid} grid - The grid to sync selection with.\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\n * view due to them getting filtered out.\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\n * that are currently out of the view (see preserveHidden) as selected when selection\n * changes.\n * @return {Event} An event that notifies when an internal list of selected row ids\n * changes. This is useful since, in combination with the above two options, it allows\n * access to the full list selected row ids, and not just the ones visible to the grid.\n * @method syncGridSelection\n */\n syncGridSelection(grid: SlickGrid, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\n this._grid = grid;\n let inHandler: boolean;\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\n\n /** @param {Array} rowIds */\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\n if (rowIds === false) {\n this.selectedRowIds = [];\n } else {\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\n this.selectedRowIds = rowIds;\n }\n }\n };\n\n const update = () => {\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\n inHandler = true;\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\n if (!preserveHidden) {\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: this.mapRowsToIds(selectedRows),\n rows: selectedRows,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n grid.setSelectedRows(selectedRows);\n inHandler = false;\n }\n };\n\n grid.onSelectedRowsChanged.subscribe((_e: Event, args: { rows: number[]; }) => {\n if (!inHandler) {\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: newSelectedRowIds,\n rows: args.rows,\n added: true,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n });\n\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\n if (!inHandler) {\n inHandler = true;\n const overwrite = (typeof args.added === typeof undefined);\n\n if (overwrite) {\n setSelectedRowIds(args.ids);\n } else {\n let rowIds: DataIdType[];\n if (args.added) {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // find the ones that are hidden\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\n // add the newly selected ones\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\n } else {\n rowIds = args.ids;\n }\n } else {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // remove rows whose id is on the list\n rowIds = this.selectedRowIds!.filter((id) => args.ids.indexOf(id) === -1);\n } else {\n rowIds = [];\n }\n }\n setSelectedRowIds(rowIds);\n }\n inHandler = false;\n }\n };\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n\n return this.onSelectedRowIdsChanged;\n }\n\n /**\n * Get all selected IDs\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedIds() {\n return this.selectedRowIds;\n }\n\n /**\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredIds() {\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\n }\n\n /**\n * Set current row selected IDs array (regardless of Pagination)\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\n * \"grid.setSelectedRows(rows)\"\n * @param {Array} selectedIds - list of IDs which have been selected for this action\n * @param {Object} options\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\n */\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\n let isRowBeingAdded = options?.isRowBeingAdded;\n const shouldTriggerEvent = options?.shouldTriggerEvent;\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\n\n if (isRowBeingAdded !== false) {\n isRowBeingAdded = true;\n }\n const selectedRows = this.mapIdsToRows(selectedIds);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: selectedIds,\n rows: selectedRows,\n added: isRowBeingAdded,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\n\n if (shouldTriggerEvent !== false) {\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n\n // should we also apply the row selection in to the grid (UI) as well?\n if (applyRowSelectionToGrid !== false && this._grid) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n /**\n * Get all selected dataContext items\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedItems() {\n const selectedData: TData[] = [];\n const selectedIds = this.getAllSelectedIds();\n selectedIds!.forEach((id) => {\n selectedData.push(this.getItemById(id));\n });\n return selectedData as T[];\n }\n\n /**\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredItems() {\n if (!Array.isArray(this.selectedRowIds)) {\n return [];\n }\n\n const intersection = this.filteredItems.filter((a) => this.selectedRowIds!.some((b) => a[this.idProperty as keyof TData] === b));\n return (intersection || []) as T[];\n }\n\n syncGridCellCssStyles(grid: SlickGrid, key: string) {\n let hashById: any;\n let inHandler: boolean;\n\n const storeCellCssStyles = (hash: CssStyleHash) => {\n hashById = {};\n for (const row in hash) {\n const id = this.rows[row as any][this.idProperty as keyof TData];\n hashById[id] = hash[row];\n }\n };\n\n // since this method can be called after the cell styles have been set,\n // get the existing ones right away\n storeCellCssStyles(grid.getCellCssStyles(key));\n\n const update = () => {\n if (hashById) {\n inHandler = true;\n this.ensureRowsByIdCache();\n const newHash: CssStyleHash = {};\n for (const id in hashById) {\n const row = this.rowsById?.[id];\n if (Utils.isDefined(row)) {\n newHash[row] = hashById[id];\n }\n }\n grid.setCellCssStyles(key, newHash);\n inHandler = false;\n }\n };\n\n grid.onCellCssStylesChanged.subscribe((_e, args) => {\n if (inHandler) { return; }\n if (key !== args.key) { return; }\n if (args.hash) {\n storeCellCssStyles(args.hash);\n } else {\n grid.onCellCssStylesChanged.unsubscribe();\n this.onRowsOrCountChanged.unsubscribe(update);\n }\n });\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n }\n}\n\nexport class AvgAggregator implements Aggregator {\n private _nonNullCount = 0;\n private _sum = 0;\n private _field: number | string;\n private _type = 'avg' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._nonNullCount = 0;\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._nonNullCount++;\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n (groupTotals as any)[this._type] = {};\n }\n if (this._nonNullCount !== 0) {\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\n }\n }\n}\n\nexport class MinAggregator implements Aggregator {\n private _min: number | null = null;\n private _field: number | string;\n private _type = 'min' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._min = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._min === null || val < this._min) {\n this._min = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._min;\n }\n}\n\nexport class MaxAggregator implements Aggregator {\n private _max: number | null = null;\n private _field: number | string;\n private _type = 'max' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._max = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._max === null || val > this._max) {\n this._max = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._max;\n }\n}\n\nexport class SumAggregator implements Aggregator {\n private _sum = 0;\n private _field: number | string;\n private _type = 'sum' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._sum;\n }\n}\n\nexport class CountAggregator implements Aggregator {\n private _field: number | string;\n private _type = 'count' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\n }\n}\n\n// TODO: add more built-in aggregators\n// TODO: merge common aggregators in one to prevent needless iterating\n\nexport const Aggregators = {\n Avg: AvgAggregator,\n Min: MinAggregator,\n Max: MaxAggregator,\n Sum: SumAggregator,\n Count: CountAggregator\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Data = window.Slick.Data || {};\n window.Slick.Data.DataView = SlickDataView;\n window.Slick.Data.Aggregators = Aggregators;\n}"], - "mappings": "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", + "sourcesContent": ["import type {\n Aggregator,\n CssStyleHash,\n CustomDataView,\n Grouping,\n GroupingFormatterItem,\n ItemMetadata,\n OnGroupCollapsedEventArgs,\n OnGroupExpandedEventArgs,\n OnRowCountChangedEventArgs,\n OnRowsChangedEventArgs,\n OnRowsOrCountChangedEventArgs,\n OnSelectedRowIdsChangedEventArgs,\n OnSetItemsCalledEventArgs,\n PagingInfo,\n} from './models/index';\nimport {\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickGroup as SlickGroup_,\n SlickGroupTotals as SlickGroupTotals_,\n Utils as Utils_,\n SlickNonDataItem,\n} from './slick.core';\nimport type { SlickGrid } from './slick.grid';\nimport { SlickGroupItemMetadataProvider as SlickGroupItemMetadataProvider_ } from './slick.groupitemmetadataprovider';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst SlickGroup = IIFE_ONLY ? Slick.Group : SlickGroup_;\nconst SlickGroupTotals = IIFE_ONLY ? Slick.GroupTotals : SlickGroupTotals_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst SlickGroupItemMetadataProvider = IIFE_ONLY ? Slick.Data?.GroupItemMetadataProvider ?? {} : SlickGroupItemMetadataProvider_;\n\nexport interface DataViewOption {\n groupItemMetadataProvider: SlickGroupItemMetadataProvider_ | null;\n inlineFilters: boolean;\n useCSPSafeFilter: boolean;\n}\nexport type FilterFn = (item: T, args: any) => boolean;\nexport type DataIdType = number | string;\nexport type SlickDataItem = SlickNonDataItem | SlickGroup_ | SlickGroupTotals_ | any;\n\n/**\n * A sample Model implementation.\n * Provides a filtered view of the underlying data.\n *\n * Relies on the data item having an \"id\" property uniquely identifying it.\n */\nexport class SlickDataView implements CustomDataView {\n protected defaults: DataViewOption = {\n groupItemMetadataProvider: null,\n inlineFilters: false,\n useCSPSafeFilter: false,\n };\n\n // private\n protected idProperty = 'id'; // property holding a unique row id\n protected items: TData[] = []; // data by index\n protected rows: TData[] = []; // data by row\n protected idxById = new Map(); // indexes by id\n protected rowsById: { [id: DataIdType]: number } | undefined = undefined; // rows by id; lazy-calculated\n protected filter: FilterFn | null = null; // filter function\n protected filterCSPSafe: Function | null = null; // filter function\n protected updated: ({ [id: DataIdType]: boolean }) | null = null; // updated item ids\n protected suspend = false; // suspends the recalculation\n protected isBulkSuspend = false; // delays protectedious operations like the\n // index update and delete to efficient\n // versions at endUpdate\n protected bulkDeleteIds = new Map();\n protected sortAsc: boolean | undefined = true;\n protected fastSortField?: string | null | (() => string);\n protected sortComparer!: ((a: TData, b: TData) => number);\n protected refreshHints: any = {};\n protected prevRefreshHints: any = {};\n protected filterArgs: any;\n protected filteredItems: TData[] = [];\n protected compiledFilter?: FilterFn | null;\n protected compiledFilterCSPSafe?: Function | null;\n protected compiledFilterWithCaching?: FilterFn | null;\n protected compiledFilterWithCachingCSPSafe?: Function | null;\n protected filterCache: any[] = [];\n protected _grid?: SlickGrid; // grid object will be defined only after using \"syncGridSelection()\" method\"\n\n // grouping\n protected groupingInfoDefaults: Grouping = {\n getter: undefined,\n formatter: undefined,\n comparer: (a: { value: any; }, b: { value: any; }) => (a.value === b.value ? 0 : (a.value > b.value ? 1 : -1)),\n predefinedValues: [],\n aggregators: [],\n aggregateEmpty: false,\n aggregateCollapsed: false,\n aggregateChildGroups: false,\n collapsed: false,\n displayTotalsRow: true,\n lazyTotalsCalculation: false\n };\n protected groupingInfos: Array = [];\n protected groups: SlickGroup_[] = [];\n protected toggledGroupsByLevel: any[] = [];\n protected groupingDelimiter = ':|:';\n protected selectedRowIds: DataIdType[] = [];\n protected preSelectedRowIdsChangeFn?: Function;\n\n protected pagesize = 0;\n protected pagenum = 0;\n protected totalRows = 0;\n protected _options: DataViewOption;\n\n // public events\n onBeforePagingInfoChanged = new SlickEvent();\n onGroupExpanded = new SlickEvent();\n onGroupCollapsed = new SlickEvent();\n onPagingInfoChanged = new SlickEvent();\n onRowCountChanged = new SlickEvent();\n onRowsChanged = new SlickEvent();\n onRowsOrCountChanged = new SlickEvent();\n onSelectedRowIdsChanged = new SlickEvent();\n onSetItemsCalled = new SlickEvent();\n\n constructor(options: Partial) {\n this._options = Utils.extend(true, {}, this.defaults, options);\n }\n\n /**\n * Begins a bached update of the items in the data view.\n * including deletes and the related events are postponed to the endUpdate call.\n * As certain operations are postponed during this update, some methods might not\n * deliver fully consistent information.\n * @param {Boolean} [bulkUpdate] - if set to true, most data view modifications\n */\n beginUpdate(bulkUpdate?: boolean) {\n this.suspend = true;\n this.isBulkSuspend = bulkUpdate === true;\n }\n\n endUpdate() {\n const wasBulkSuspend = this.isBulkSuspend;\n this.isBulkSuspend = false;\n this.suspend = false;\n if (wasBulkSuspend) {\n this.processBulkDelete();\n this.ensureIdUniqueness();\n }\n this.refresh();\n }\n\n destroy() {\n this.items = [];\n this.idxById = null as any;\n this.rowsById = null as any;\n this.filter = null as any;\n this.filterCSPSafe = null as any;\n this.updated = null as any;\n this.sortComparer = null as any;\n this.filterCache = [];\n this.filteredItems = [];\n this.compiledFilter = null;\n this.compiledFilterCSPSafe = null;\n this.compiledFilterWithCaching = null;\n this.compiledFilterWithCachingCSPSafe = null;\n\n if (this._grid && this._grid.onSelectedRowsChanged && this._grid.onCellCssStylesChanged) {\n this._grid.onSelectedRowsChanged.unsubscribe();\n this._grid.onCellCssStylesChanged.unsubscribe();\n }\n if (this.onRowsOrCountChanged) {\n this.onRowsOrCountChanged.unsubscribe();\n }\n }\n\n setRefreshHints(hints: any) {\n this.refreshHints = hints;\n }\n\n setFilterArgs(args: any) {\n this.filterArgs = args;\n }\n\n /**\n * Processes all delete requests placed during bulk update\n * by recomputing the items and idxById members.\n */\n protected processBulkDelete() {\n if (!this.idxById) { return; }\n\n // the bulk update is processed by\n // recomputing the whole items array and the index lookup in one go.\n // this is done by placing the not-deleted items\n // from left to right into the array and shrink the array the the new\n // size afterwards.\n // see https://github.com/6pac/SlickGrid/issues/571 for further details.\n\n let id: DataIdType, item, newIdx = 0;\n for (let i = 0, l = this.items.length; i < l; i++) {\n item = this.items[i];\n id = item[this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n\n // if items have been marked as deleted we skip them for the new final items array\n // and we remove them from the lookup table.\n if (this.bulkDeleteIds.has(id)) {\n this.idxById.delete(id);\n } else {\n // for items which are not deleted, we add them to the\n // next free position in the array and register the index in the lookup.\n this.items[newIdx] = item;\n this.idxById.set(id, newIdx);\n ++newIdx;\n }\n }\n\n // here we shrink down the full item array to the ones actually\n // inserted in the cleanup loop above.\n this.items.length = newIdx;\n // and finally cleanup the deleted ids to start cleanly on the next update.\n this.bulkDeleteIds = new Map();\n }\n\n protected updateIdxById(startingIndex?: number) {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n startingIndex = startingIndex || 0;\n let id: DataIdType;\n for (let i = startingIndex, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n this.idxById.set(id, i);\n }\n }\n\n protected ensureIdUniqueness() {\n if (this.isBulkSuspend || !this.idxById) { // during bulk update we do not reorganize\n return;\n }\n let id: DataIdType;\n for (let i = 0, l = this.items.length; i < l; i++) {\n id = this.items[i][this.idProperty as keyof TData] as DataIdType;\n if (id === undefined || this.idxById.get(id) !== i) {\n throw new Error(\"[SlickGrid DataView] Each data element must implement a unique 'id' property\");\n }\n }\n }\n\n /** Get all DataView Items */\n getItems() {\n return this.items;\n }\n\n /** Get the DataView Id property name to use (defaults to \"Id\" but could be customized to something else when instantiating the DataView) */\n getIdPropertyName() {\n return this.idProperty;\n }\n\n /**\n * Set the Items with a new Dataset and optionally pass a different Id property name\n * @param {Array<*>} data - array of data\n * @param {String} [objectIdProperty] - optional id property to use as primary id\n */\n setItems(data: TData[], objectIdProperty?: string) {\n if (objectIdProperty !== undefined) {\n this.idProperty = objectIdProperty;\n }\n this.items = this.filteredItems = data;\n this.onSetItemsCalled.notify({ idProperty: this.idProperty, itemCount: this.items.length }, null, this);\n this.idxById = new Map();\n this.updateIdxById();\n this.ensureIdUniqueness();\n this.refresh();\n }\n\n /** Set Paging Options */\n setPagingOptions(args: Partial) {\n if (this.onBeforePagingInfoChanged.notify(this.getPagingInfo(), null, this).getReturnValue() !== false) {\n if (Utils.isDefined(args.pageSize)) {\n this.pagesize = args.pageSize;\n this.pagenum = this.pagesize ? Math.min(this.pagenum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1)) : 0;\n }\n\n if (Utils.isDefined(args.pageNum)) {\n this.pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1));\n }\n\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n\n this.refresh();\n }\n }\n\n /** Get Paging Options */\n getPagingInfo(): PagingInfo {\n const totalPages = this.pagesize ? Math.max(1, Math.ceil(this.totalRows / this.pagesize)) : 1;\n return { pageSize: this.pagesize, pageNum: this.pagenum, totalRows: this.totalRows, totalPages, dataView: this as SlickDataView };\n }\n\n /** Sort Method to use by the DataView */\n sort(comparer: (a: TData, b: TData) => number, ascending?: boolean) {\n this.sortAsc = ascending;\n this.sortComparer = comparer;\n this.fastSortField = null;\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort(comparer);\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /**\n * Provides a workaround for the extremely slow sorting in IE.\n * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString\n * to return the value of that field and then doing a native Array.sort().\n */\n fastSort(field: string | (() => string), ascending?: boolean) {\n this.sortAsc = ascending;\n this.fastSortField = field;\n this.sortComparer = null as any;\n const oldToString = Object.prototype.toString;\n Object.prototype.toString = (typeof field === 'function') ? field : function () {\n // @ts-ignore\n return this[field];\n };\n // an extra reversal for descending sort keeps the sort stable\n // (assuming a stable native sort implementation, which isn't true in some cases)\n if (ascending === false) {\n this.items.reverse();\n }\n this.items.sort();\n Object.prototype.toString = oldToString;\n if (ascending === false) {\n this.items.reverse();\n }\n this.idxById = new Map();\n this.updateIdxById();\n this.refresh();\n }\n\n /** Re-Sort the dataset */\n reSort() {\n if (this.sortComparer) {\n this.sort(this.sortComparer, this.sortAsc);\n } else if (this.fastSortField) {\n this.fastSort(this.fastSortField, this.sortAsc);\n }\n }\n\n /** Get only the DataView filtered items */\n getFilteredItems() {\n return this.filteredItems as T[];\n }\n\n /** Get the array length (count) of only the DataView filtered items */\n getFilteredItemCount() {\n return this.filteredItems.length;\n }\n\n /** Get current Filter used by the DataView */\n getFilter() {\n return this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter;\n }\n\n /**\n * Set a Filter that will be used by the DataView\n * @param {Function} fn - filter callback function\n */\n setFilter(filterFn: FilterFn) {\n this.filterCSPSafe = filterFn;\n this.filter = filterFn;\n if (this._options.inlineFilters) {\n this.compiledFilterCSPSafe = this.compileFilterCSPSafe;\n this.compiledFilterWithCachingCSPSafe = this.compileFilterWithCachingCSPSafe;\n this.compiledFilter = this.compileFilter(this._options.useCSPSafeFilter);\n this.compiledFilterWithCaching = this.compileFilterWithCaching(this._options.useCSPSafeFilter);\n }\n this.refresh();\n }\n\n /** Get current Grouping info */\n getGrouping(): Grouping[] {\n return this.groupingInfos;\n }\n\n /** Set some Grouping */\n setGrouping(groupingInfo: Grouping | Grouping[]) {\n if (!this._options.groupItemMetadataProvider) {\n this._options.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();\n }\n\n this.groups = [];\n this.toggledGroupsByLevel = [];\n groupingInfo = groupingInfo || [];\n this.groupingInfos = ((groupingInfo instanceof Array) ? groupingInfo : [groupingInfo]) as any;\n\n for (let i = 0; i < this.groupingInfos.length; i++) {\n const gi = this.groupingInfos[i] = Utils.extend(true, {}, this.groupingInfoDefaults, this.groupingInfos[i]);\n gi.getterIsAFn = typeof gi.getter === 'function';\n\n // pre-compile accumulator loops\n gi.compiledAccumulators = [];\n let idx = gi.aggregators.length;\n while (idx--) {\n gi.compiledAccumulators[idx] = this.compileAccumulatorLoop(gi.aggregators[idx]);\n }\n\n this.toggledGroupsByLevel[i] = {};\n }\n\n this.refresh();\n }\n\n /** Get an item in the DataView by its row index */\n getItemByIdx(i: number) {\n return this.items[i] as T;\n }\n\n /** Get row index in the DataView by its Id */\n getIdxById(id: DataIdType) {\n return this.idxById?.get(id);\n }\n\n protected ensureRowsByIdCache() {\n if (!this.rowsById) {\n this.rowsById = {};\n for (let i = 0, l = this.rows.length; i < l; i++) {\n this.rowsById[this.rows[i][this.idProperty as keyof TData] as DataIdType] = i;\n }\n }\n }\n\n /** Get row number in the grid by its item object */\n getRowByItem(item: TData) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[item[this.idProperty as keyof TData] as DataIdType];\n }\n\n /** Get row number in the grid by its Id */\n getRowById(id: DataIdType) {\n this.ensureRowsByIdCache();\n return this.rowsById?.[id];\n }\n\n /** Get an item in the DataView by its Id */\n getItemById(id: DataIdType) {\n return this.items[(this.idxById.get(id) as number)] as T;\n }\n\n /** From the items array provided, return the mapped rows */\n mapItemsToRows(itemArray: TData[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = itemArray.length; i < l; i++) {\n const row = this.rowsById?.[itemArray[i][this.idProperty as keyof TData] as DataIdType];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the Ids array provided, return the mapped rows */\n mapIdsToRows(idArray: DataIdType[]) {\n const rows: number[] = [];\n this.ensureRowsByIdCache();\n for (let i = 0, l = idArray.length; i < l; i++) {\n const row = this.rowsById?.[idArray[i]];\n if (Utils.isDefined(row)) {\n rows[rows.length] = row;\n }\n }\n return rows;\n }\n\n /** From the rows array provided, return the mapped Ids */\n mapRowsToIds(rowArray: number[]) {\n const ids: DataIdType[] = [];\n for (let i = 0, l = rowArray.length; i < l; i++) {\n if (rowArray[i] < this.rows.length) {\n const rowItem = this.rows[rowArray[i]];\n ids[ids.length] = rowItem![this.idProperty as keyof TData] as DataIdType;\n }\n }\n return ids;\n }\n\n /**\n * Performs the update operations of a single item by id without\n * triggering any events or refresh operations.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateSingleItem(id: DataIdType, item: TData) {\n if (!this.idxById) { return; }\n\n // see also https://github.com/mleibman/SlickGrid/issues/1082\n if (!this.idxById.has(id)) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n\n // What if the specified item also has an updated idProperty?\n // Then we'll have to update the index as well, and possibly the `updated` cache too.\n if (id !== item[this.idProperty as keyof TData]) {\n // make sure the new id is unique:\n const newId = item[this.idProperty as keyof TData] as DataIdType;\n if (!Utils.isDefined(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a null id');\n }\n if (this.idxById.has(newId)) {\n throw new Error('[SlickGrid DataView] Cannot update item to associate with a non-unique id');\n }\n this.idxById.set(newId, this.idxById.get(id) as number);\n this.idxById.delete(id);\n\n // Also update the `updated` hashtable/markercache? Yes, `recalc()` inside `refresh()` needs that one!\n if (this.updated?.[id]) {\n delete this.updated[id];\n }\n\n // Also update the row indexes? no need since the `refresh()`, further down, blows away the `rowsById[]` cache!\n\n id = newId;\n }\n this.items[this.idxById.get(id) as number] = item;\n\n // Also update the rows? no need since the `refresh()`, further down, blows away the `rows[]` cache and recalculates it via `recalc()`!\n\n if (!this.updated) {\n this.updated = {};\n }\n this.updated[id] = true;\n }\n\n /**\n * Updates a single item in the data view given the id and new value.\n * @param id The new id of the item.\n * @param item The item which should be the new value for the given id.\n */\n updateItem(id: DataIdType, item: T) {\n this.updateSingleItem(id, item);\n this.refresh();\n }\n\n /**\n * Updates multiple items in the data view given the new ids and new values.\n * @param id {Array} The array of new ids which is in the same order as the items.\n * @param newItems {Array} The new items that should be set in the data view for the given ids.\n */\n updateItems(ids: DataIdType[], newItems: T[]) {\n if (ids.length !== newItems.length) {\n throw new Error(\"[SlickGrid DataView] Mismatch on the length of ids and items provided to update\");\n }\n for (let i = 0, l = newItems.length; i < l; i++) {\n this.updateSingleItem(ids[i], newItems[i]);\n }\n this.refresh();\n }\n\n /**\n * Inserts a single item into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the item should be inserted.\n * @param item The item to insert.\n */\n insertItem(insertBefore: number, item: TData) {\n this.items.splice(insertBefore, 0, item);\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Inserts multiple items into the data view at the given position.\n * @param insertBefore {Number} The 0-based index before which the items should be inserted.\n * @param newItems {Array} The items to insert.\n */\n insertItems(insertBefore: number, newItems: TData[]) {\n // @ts-ignore\n Array.prototype.splice.apply(this.items, [insertBefore, 0].concat(newItems));\n this.updateIdxById(insertBefore);\n this.refresh();\n }\n\n /**\n * Adds a single item at the end of the data view.\n * @param item The item to add at the end.\n */\n addItem(item: TData) {\n this.items.push(item);\n this.updateIdxById(this.items.length - 1);\n this.refresh();\n }\n\n /**\n * Adds multiple items at the end of the data view.\n * @param {Array} newItems The items to add at the end.\n */\n addItems(newItems: TData[]) {\n this.items = this.items.concat(newItems);\n this.updateIdxById(this.items.length - newItems.length);\n this.refresh();\n }\n\n /**\n * Deletes a single item identified by the given id from the data view.\n * @param {String|Number} id The id identifying the object to delete.\n */\n deleteItem(id: DataIdType) {\n if (!this.idxById) { return; }\n if (this.isBulkSuspend) {\n this.bulkDeleteIds.set(id, true);\n } else {\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n this.items.splice(idx, 1);\n this.updateIdxById(idx);\n this.refresh();\n }\n }\n\n /**\n * Deletes multiple item identified by the given ids from the data view.\n * @param {Array} ids The ids of the items to delete.\n */\n deleteItems(ids: DataIdType[]) {\n if (ids.length === 0 || !this.idxById) {\n return;\n }\n\n if (this.isBulkSuspend) {\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.bulkDeleteIds.set(id, true);\n }\n } else {\n // collect all indexes\n const indexesToDelete: number[] = [];\n for (let i = 0, l = ids.length; i < l; i++) {\n const id = ids[i];\n const idx = this.idxById.get(id);\n if (idx === undefined) {\n throw new Error('[SlickGrid DataView] Invalid id');\n }\n this.idxById.delete(id);\n indexesToDelete.push(idx);\n }\n\n // Remove from back to front\n indexesToDelete.sort();\n for (let i = indexesToDelete.length - 1; i >= 0; --i) {\n this.items.splice(indexesToDelete[i], 1);\n }\n\n // update lookup from front to back\n this.updateIdxById(indexesToDelete[0]);\n this.refresh();\n }\n }\n\n /** Add an item in a sorted dataset (a Sort function must be defined) */\n sortedAddItem(item: TData) {\n if (!this.sortComparer) {\n throw new Error('[SlickGrid DataView] sortedAddItem() requires a sort comparer, use sort()');\n }\n this.insertItem(this.sortedIndex(item), item);\n }\n\n /** Update an item in a sorted dataset (a Sort function must be defined) */\n sortedUpdateItem(id: string | number, item: TData) {\n if (!this.idxById) { return; }\n if (!this.idxById.has(id) || id !== item[this.idProperty as keyof TData]) {\n throw new Error('[SlickGrid DataView] Invalid or non-matching id ' + this.idxById.get(id));\n }\n if (!this.sortComparer) {\n throw new Error(\"[SlickGrid DataView] sortedUpdateItem() requires a sort comparer, use sort()\");\n }\n const oldItem = this.getItemById(id);\n if (this.sortComparer(oldItem, item) !== 0) {\n // item affects sorting -> must use sorted add\n this.deleteItem(id);\n this.sortedAddItem(item);\n } else { // update does not affect sorting -> regular update works fine\n this.updateItem(id, item);\n }\n }\n\n protected sortedIndex(searchItem: TData) {\n let low = 0;\n let high = this.items.length;\n\n while (low < high) {\n const mid = low + high >>> 1;\n if (this.sortComparer(this.items[mid], searchItem) === -1) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return low;\n }\n\n /** Get item count, that is the full dataset lenght of the DataView */\n getItemCount() {\n return this.items.length;\n }\n\n /** Get row count (rows displayed in current page) */\n getLength() {\n return this.rows.length;\n }\n\n /** Retrieve an item from the DataView at specific index */\n getItem(i: number) {\n const item = this.rows[i] as T;\n\n // if this is a group row, make sure totals are calculated and update the title\n if ((item as SlickGroup_)?.__group && (item as SlickGroup_).totals && !(item as SlickGroup_).totals?.initialized) {\n const gi = this.groupingInfos[(item as SlickGroup_).level];\n if (!gi.displayTotalsRow) {\n this.calculateTotals((item as SlickGroup_).totals);\n (item as SlickGroup_).title = gi.formatter ? gi.formatter((item as SlickGroup_)) : (item as SlickGroup_).value;\n }\n }\n // if this is a totals row, make sure it's calculated\n else if ((item as SlickGroupTotals_)?.__groupTotals && !(item as SlickGroupTotals_).initialized) {\n this.calculateTotals(item as SlickGroupTotals_);\n }\n\n return item;\n }\n\n getItemMetadata(i: number): ItemMetadata | null {\n const item = this.rows[i];\n if (item === undefined) {\n return null;\n }\n\n // overrides for grouping rows\n if ((item as SlickGroup_).__group) {\n return this._options.groupItemMetadataProvider!.getGroupRowMetadata(item as GroupingFormatterItem);\n }\n\n // overrides for totals rows\n if ((item as SlickGroupTotals_).__groupTotals) {\n return this._options.groupItemMetadataProvider!.getTotalsRowMetadata(item as { group: GroupingFormatterItem });\n }\n\n return null;\n }\n\n protected expandCollapseAllGroups(level?: number, collapse?: boolean) {\n if (!Utils.isDefined(level)) {\n for (let i = 0; i < this.groupingInfos.length; i++) {\n this.toggledGroupsByLevel[i] = {};\n this.groupingInfos[i].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level: i, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level: i, groupingKey: null });\n }\n }\n } else {\n this.toggledGroupsByLevel[level] = {};\n this.groupingInfos[level].collapsed = collapse;\n\n if (collapse === true) {\n this.onGroupCollapsed.notify({ level, groupingKey: null });\n } else {\n this.onGroupExpanded.notify({ level, groupingKey: null });\n }\n }\n this.refresh();\n }\n\n /**\n * @param {Number} [level] Optional level to collapse. If not specified, applies to all levels.\n */\n collapseAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, true);\n }\n\n /**\n * @param {Number} [level] Optional level to expand. If not specified, applies to all levels.\n */\n expandAllGroups(level?: number) {\n this.expandCollapseAllGroups(level, false);\n }\n\n expandCollapseGroup(level: number, groupingKey: string, collapse?: boolean) {\n // @ts-ignore\n this.toggledGroupsByLevel[level][groupingKey] = this.groupingInfos[level].collapsed ^ collapse;\n this.refresh();\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of\n * the 'high' group.\n */\n collapseGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n groupingKey = arg0;\n level = arg0.split(this.groupingDelimiter).length - 1;\n } else {\n groupingKey = args.join(this.groupingDelimiter);\n level = args.length - 1;\n }\n\n this.expandCollapseGroup(level, groupingKey, true);\n this.onGroupCollapsed.notify({ level, groupingKey });\n }\n\n /**\n * @param varArgs Either a Slick.Group's \"groupingKey\" property, or a\n * variable argument list of grouping values denoting a unique path to the row. For\n * example, calling expandGroup('high', '10%') will expand the '10%' subgroup of\n * the 'high' group.\n */\n expandGroup(...args: any) {\n const calledArgs = Array.prototype.slice.call(args);\n const arg0 = calledArgs[0];\n let groupingKey;\n let level;\n\n if (args.length === 1 && arg0.indexOf(this.groupingDelimiter) !== -1) {\n level = arg0.split(this.groupingDelimiter).length - 1;\n groupingKey = arg0;\n } else {\n level = args.length - 1;\n groupingKey = args.join(this.groupingDelimiter);\n }\n\n this.expandCollapseGroup(level, groupingKey, false);\n this.onGroupExpanded.notify({ level, groupingKey });\n }\n\n getGroups() {\n return this.groups;\n }\n\n protected extractGroups(rows: any[], parentGroup?: SlickGroup_) {\n let group;\n let val;\n const groups: SlickGroup_[] = [];\n const groupsByVal: any = {};\n let r;\n const level = parentGroup ? parentGroup.level + 1 : 0;\n const gi = this.groupingInfos[level];\n\n for (let i = 0, l = gi.predefinedValues?.length ?? 0; i < l; i++) {\n val = gi.predefinedValues?.[i];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n }\n\n for (let i = 0, l = rows.length; i < l; i++) {\n r = rows[i];\n val = gi.getterIsAFn ? (gi.getter as Function)(r) : r[gi.getter as keyof TData];\n group = groupsByVal[val];\n if (!group) {\n group = new SlickGroup();\n group.value = val;\n group.level = level;\n group.groupingKey = (parentGroup ? parentGroup.groupingKey + this.groupingDelimiter : '') + val;\n groups[groups.length] = group;\n groupsByVal[val] = group;\n }\n\n group.rows[group.count++] = r;\n }\n\n if (level < this.groupingInfos.length - 1) {\n for (let i = 0; i < groups.length; i++) {\n group = groups[i];\n group.groups = this.extractGroups(group.rows, group);\n }\n }\n\n if (groups.length) {\n this.addTotals(groups, level);\n }\n\n groups.sort(this.groupingInfos[level].comparer);\n\n return groups;\n }\n\n protected calculateTotals(totals: SlickGroupTotals_) {\n const group = totals.group;\n const gi = this.groupingInfos[group.level ?? 0];\n const isLeafLevel = (group.level === this.groupingInfos.length);\n let agg: Aggregator, idx = gi.aggregators.length;\n\n if (!isLeafLevel && gi.aggregateChildGroups) {\n // make sure all the subgroups are calculated\n let i = group.groups?.length ?? 0;\n while (i--) {\n if (!group.groups[i].totals.initialized) {\n this.calculateTotals(group.groups[i].totals);\n }\n }\n }\n\n while (idx--) {\n agg = gi.aggregators[idx];\n agg.init();\n if (!isLeafLevel && gi.aggregateChildGroups) {\n gi.compiledAccumulators[idx].call(agg, group.groups);\n } else {\n gi.compiledAccumulators[idx].call(agg, group.rows);\n }\n agg.storeResult(totals);\n }\n totals.initialized = true;\n }\n\n protected addGroupTotals(group: SlickGroup_) {\n const gi = this.groupingInfos[group.level];\n const totals = new SlickGroupTotals();\n totals.group = group;\n group.totals = totals;\n if (!gi.lazyTotalsCalculation) {\n this.calculateTotals(totals);\n }\n }\n\n protected addTotals(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupCollapsed = gi.collapsed;\n const toggledGroups = this.toggledGroupsByLevel[level];\n let idx = groups.length, g;\n while (idx--) {\n g = groups[idx];\n\n if (g.collapsed && !gi.aggregateCollapsed) {\n continue;\n }\n\n // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.\n if (g.groups) {\n this.addTotals(g.groups, level + 1);\n }\n\n if (gi.aggregators?.length && (\n gi.aggregateEmpty || g.rows.length || g.groups?.length)) {\n this.addGroupTotals(g);\n }\n\n g.collapsed = (groupCollapsed as any) ^ toggledGroups[g.groupingKey];\n g.title = gi.formatter ? gi.formatter(g) : g.value;\n }\n }\n\n protected flattenGroupedRows(groups: SlickGroup_[], level?: number) {\n level = level || 0;\n const gi = this.groupingInfos[level];\n const groupedRows: any[] = [];\n let rows: any[], gl = 0, g;\n for (let i = 0, l = groups.length; i < l; i++) {\n g = groups[i];\n groupedRows[gl++] = g;\n\n if (!g.collapsed) {\n rows = g.groups ? this.flattenGroupedRows(g.groups, level + 1) : g.rows;\n for (let j = 0, jj = rows.length; j < jj; j++) {\n groupedRows[gl++] = rows[j];\n }\n }\n\n if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {\n groupedRows[gl++] = g.totals;\n }\n }\n return groupedRows;\n }\n\n protected getFunctionInfo(fn: Function) {\n const fnStr = fn.toString();\n const usingEs5 = fnStr.indexOf('function') >= 0; // with ES6, the word function is not present\n const fnRegex = usingEs5 ? /^function[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/ : /^[^(]*\\(([^)]*)\\)\\s*{([\\s\\S]*)}$/;\n const matches = fn.toString().match(fnRegex) || [];\n return {\n params: matches[1].split(\",\"),\n body: matches[2]\n };\n }\n\n protected compileAccumulatorLoop(aggregator: Aggregator) {\n if (aggregator.accumulate) {\n const accumulatorInfo = this.getFunctionInfo(aggregator.accumulate);\n const fn: any = new Function(\n \"_items\",\n \"for (var \" + accumulatorInfo.params[0] + \", _i=0, _il=_items.length; _i<_il; _i++) {\" +\n accumulatorInfo.params[0] + \" = _items[_i]; \" +\n accumulatorInfo.body +\n \"}\"\n );\n const fnName = \"compiledAccumulatorLoop\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n } else {\n return function noAccumulator() { };\n }\n }\n\n protected compileFilterCSPSafe(_items: TData[], _args: any): TData[] {\n if (typeof this.filterCSPSafe !== 'function') {\n return [];\n }\n const _retval: TData[] = [];\n const _il = _items.length;\n\n for (let _i = 0; _i < _il; _i++) {\n if (this.filterCSPSafe(_items[_i], _args)) {\n _retval.push(_items[_i]);\n }\n }\n\n return _retval;\n }\n protected compileFilter(stopRunningIfCSPSafeIsActive: boolean = false): FilterFn {\n if(stopRunningIfCSPSafeIsActive) {\n return null as any;\n }\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n const fn: any = new Function(\"_items,_args\", tpl);\n const fnName = \"compiledFilter\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n protected compileFilterWithCaching(stopRunningIfCSPSafeIsActive: boolean = false) {\n if(stopRunningIfCSPSafeIsActive) {\n return null as any;\n }\n\n const filterInfo = this.getFunctionInfo(this.filter as Function);\n\n const filterPath1 = \"{ continue _coreloop; }$1\";\n const filterPath2 = \"{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1\";\n // make some allowances for minification - there's only so far we can go with RegEx\n const filterBody = filterInfo.body\n .replace(/return false\\s*([;}]|\\}|$)/gi, filterPath1)\n .replace(/return!1([;}]|\\}|$)/gi, filterPath1)\n .replace(/return true\\s*([;}]|\\}|$)/gi, filterPath2)\n .replace(/return!0([;}]|\\}|$)/gi, filterPath2)\n .replace(/return ([^;}]+?)\\s*([;}]|$)/gi,\n \"{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2\");\n\n // This preserves the function template code after JS compression,\n // so that replace() commands still work as expected.\n let tpl = [\n //\"function(_items, _args, _cache) { \",\n \"var _retval = [], _idx = 0; \",\n \"var $item$, $args$ = _args; \",\n \"_coreloop: \",\n \"for (var _i = 0, _il = _items.length; _i < _il; _i++) { \",\n \"$item$ = _items[_i]; \",\n \"if (_cache[_i]) { \",\n \"_retval[_idx++] = $item$; \",\n \"continue _coreloop; \",\n \"} \",\n \"$filter$; \",\n \"} \",\n \"return _retval; \"\n //\"}\"\n ].join(\"\");\n tpl = tpl.replace(/\\$filter\\$/gi, filterBody);\n tpl = tpl.replace(/\\$item\\$/gi, filterInfo.params[0]);\n tpl = tpl.replace(/\\$args\\$/gi, filterInfo.params[1]);\n\n const fn: any = new Function(\"_items,_args,_cache\", tpl);\n const fnName = \"compiledFilterWithCaching\";\n fn.displayName = fnName;\n fn.name = this.setFunctionName(fn, fnName);\n return fn;\n }\n\n protected compileFilterWithCachingCSPSafe(_items: TData[], _args: any, filterCache: any[]): TData[] {\n if (typeof this.filterCSPSafe !== 'function') {\n return [];\n }\n \n const _retval: TData[] = [];\n const _il = _items.length;\n \n for (let _i = 0; _i < _il; _i++) {\n if (filterCache[_i] || this.filterCSPSafe(_items[_i], _args)) {\n _retval.push(_items[_i]);\n }\n }\n \n return _retval;\n }\n\n /**\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\n * We can use Object.defineProperty and set it the property to writable, see MDN for reference\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty\n * @param {*} fn\n * @param {string} fnName\n */\n protected setFunctionName(fn: any, fnName: string) {\n try {\n Object.defineProperty(fn, 'name', {\n writable: true,\n value: fnName\n });\n } catch (err) {\n fn.name = fnName;\n }\n }\n\n protected uncompiledFilter(items: TData[], args: any) {\n const retval: any[] = [];\n let idx = 0;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n if (this.filter?.(items[i], args)) {\n retval[idx++] = items[i];\n }\n }\n\n return retval;\n }\n\n protected uncompiledFilterWithCaching(items: TData[], args: any, cache: any) {\n const retval: any[] = [];\n let idx = 0,\n item: TData;\n\n for (let i = 0, ii = items.length; i < ii; i++) {\n item = items[i];\n if (cache[i]) {\n retval[idx++] = item;\n } else if (this.filter?.(item, args)) {\n retval[idx++] = item;\n cache[i] = true;\n }\n }\n\n return retval;\n }\n\n protected getFilteredAndPagedItems(items: TData[]) {\n if (this._options.useCSPSafeFilter ? this.filterCSPSafe : this.filter) {\n let batchFilter: Function;\n let batchFilterWithCaching: Function;\n if (this._options.useCSPSafeFilter) {\n batchFilter = (this._options.inlineFilters ? this.compiledFilterCSPSafe : this.uncompiledFilter) as Function;\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCachingCSPSafe : this.uncompiledFilterWithCaching) as Function;\n } else {\n batchFilter = (this._options.inlineFilters ? this.compiledFilter : this.uncompiledFilter) as Function;\n batchFilterWithCaching = (this._options.inlineFilters ? this.compiledFilterWithCaching : this.uncompiledFilterWithCaching) as Function;\n }\n if (this.refreshHints.isFilterNarrowing) {\n this.filteredItems = batchFilter.call(this, this.filteredItems, this.filterArgs);\n } else if (this.refreshHints.isFilterExpanding) {\n this.filteredItems = batchFilterWithCaching.call(this, items, this.filterArgs, this.filterCache);\n } else if (!this.refreshHints.isFilterUnchanged) {\n this.filteredItems = batchFilter.call(this, items, this.filterArgs);\n }\n } else {\n // special case: if not filtering and not paging, the resulting\n // rows collection needs to be a copy so that changes due to sort\n // can be caught\n this.filteredItems = this.pagesize ? items : items.concat();\n }\n\n // get the current page\n let paged: TData[];\n if (this.pagesize) {\n if (this.filteredItems.length <= this.pagenum * this.pagesize) {\n if (this.filteredItems.length === 0) {\n this.pagenum = 0;\n } else {\n this.pagenum = Math.floor((this.filteredItems.length - 1) / this.pagesize);\n }\n }\n paged = this.filteredItems.slice(this.pagesize * this.pagenum, this.pagesize * this.pagenum + this.pagesize);\n } else {\n paged = this.filteredItems;\n }\n return { totalRows: this.filteredItems.length, rows: paged };\n }\n\n protected getRowDiffs(rows: TData[], newRows: TData[]) {\n let item: any, r, eitherIsNonData;\n const diff: number[] = [];\n let from = 0, to = Math.max(newRows.length, rows.length);\n\n if (this.refreshHints?.ignoreDiffsBefore) {\n from = Math.max(0,\n Math.min(newRows.length, this.refreshHints.ignoreDiffsBefore));\n }\n\n if (this.refreshHints?.ignoreDiffsAfter) {\n to = Math.min(newRows.length,\n Math.max(0, this.refreshHints.ignoreDiffsAfter));\n }\n\n for (let i = from, rl = rows.length; i < to; i++) {\n if (i >= rl) {\n diff[diff.length] = i;\n } else {\n item = newRows[i];\n r = rows[i];\n\n if (!item || (this.groupingInfos.length && (eitherIsNonData = ((item as SlickNonDataItem).__nonDataRow) || ((r as SlickNonDataItem).__nonDataRow)) &&\n (item as SlickGroup_).__group !== (r as SlickGroup_).__group ||\n (item as SlickGroup_).__group && !(item as SlickGroup_).equals(r as SlickGroup_))\n || (eitherIsNonData &&\n // no good way to compare totals since they are arbitrary DTOs\n // deep object comparison is pretty expensive\n // always considering them 'dirty' seems easier for the time being\n ((item as SlickGroupTotals_).__groupTotals || (r as SlickGroupTotals_).__groupTotals))\n || item[this.idProperty as keyof TData] !== r[this.idProperty as keyof TData]\n || (this.updated?.[item[this.idProperty as keyof TData]])\n ) {\n diff[diff.length] = i;\n }\n }\n }\n return diff;\n }\n\n protected recalc(_items: TData[]) {\n this.rowsById = undefined;\n\n if (this.refreshHints.isFilterNarrowing !== this.prevRefreshHints.isFilterNarrowing ||\n this.refreshHints.isFilterExpanding !== this.prevRefreshHints.isFilterExpanding) {\n this.filterCache = [];\n }\n\n const filteredItems = this.getFilteredAndPagedItems(_items);\n this.totalRows = filteredItems.totalRows;\n let newRows: TData[] = filteredItems.rows;\n\n this.groups = [];\n if (this.groupingInfos.length) {\n this.groups = this.extractGroups(newRows);\n if (this.groups.length) {\n newRows = this.flattenGroupedRows(this.groups);\n }\n }\n\n const diff = this.getRowDiffs(this.rows, newRows as TData[]);\n\n this.rows = newRows as TData[];\n\n return diff;\n }\n\n refresh() {\n if (this.suspend) {\n return;\n }\n\n const previousPagingInfo = Utils.extend(true, {}, this.getPagingInfo());\n\n const countBefore = this.rows.length;\n const totalRowsBefore = this.totalRows;\n\n let diff = this.recalc(this.items); // pass as direct refs to avoid closure perf hit\n\n // if the current page is no longer valid, go to last page and recalc\n // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized\n if (this.pagesize && this.totalRows < this.pagenum * this.pagesize) {\n this.pagenum = Math.max(0, Math.ceil(this.totalRows / this.pagesize) - 1);\n diff = this.recalc(this.items);\n }\n\n this.updated = null;\n this.prevRefreshHints = this.refreshHints;\n this.refreshHints = {};\n\n if (totalRowsBefore !== this.totalRows) {\n // use the previously saved paging info\n if (this.onBeforePagingInfoChanged.notify(previousPagingInfo, null, this).getReturnValue() !== false) {\n this.onPagingInfoChanged.notify(this.getPagingInfo(), null, this);\n }\n }\n if (countBefore !== this.rows.length) {\n this.onRowCountChanged.notify({ previous: countBefore, current: this.rows.length, itemCount: this.items.length, dataView: this, callingOnRowsChanged: (diff.length > 0) }, null, this);\n }\n if (diff.length > 0) {\n this.onRowsChanged.notify({ rows: diff, itemCount: this.items.length, dataView: this, calledOnRowCountChanged: (countBefore !== this.rows.length) }, null, this);\n }\n if (countBefore !== this.rows.length || diff.length > 0) {\n this.onRowsOrCountChanged.notify({\n rowsDiff: diff, previousRowCount: countBefore, currentRowCount: this.rows.length, itemCount: this.items.length,\n rowCountChanged: countBefore !== this.rows.length, rowsChanged: diff.length > 0, dataView: this\n }, null, this);\n }\n }\n\n /**\n * Wires the grid and the DataView together to keep row selection tied to item ids.\n * This is useful since, without it, the grid only knows about rows, so if the items\n * move around, the same rows stay selected instead of the selection moving along\n * with the items.\n *\n * NOTE: This doesn't work with cell selection model.\n *\n * @param {SlickGrid} grid - The grid to sync selection with.\n * @param {Boolean} preserveHidden - Whether to keep selected items that go out of the\n * view due to them getting filtered out.\n * @param {Boolean} [preserveHiddenOnSelectionChange] - Whether to keep selected items\n * that are currently out of the view (see preserveHidden) as selected when selection\n * changes.\n * @return {Event} An event that notifies when an internal list of selected row ids\n * changes. This is useful since, in combination with the above two options, it allows\n * access to the full list selected row ids, and not just the ones visible to the grid.\n * @method syncGridSelection\n */\n syncGridSelection(grid: SlickGrid, preserveHidden: boolean, preserveHiddenOnSelectionChange?: boolean) {\n this._grid = grid;\n let inHandler: boolean;\n this.selectedRowIds = this.mapRowsToIds(grid.getSelectedRows());\n\n /** @param {Array} rowIds */\n const setSelectedRowIds = (rowIds: DataIdType[] | false) => {\n if (rowIds === false) {\n this.selectedRowIds = [];\n } else {\n if (this.selectedRowIds!.sort().join(',') !== rowIds.sort().join(',')) {\n this.selectedRowIds = rowIds;\n }\n }\n };\n\n const update = () => {\n if ((this.selectedRowIds || []).length > 0 && !inHandler) {\n inHandler = true;\n const selectedRows = this.mapIdsToRows(this.selectedRowIds || []);\n if (!preserveHidden) {\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: this.mapRowsToIds(selectedRows),\n rows: selectedRows,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n grid.setSelectedRows(selectedRows);\n inHandler = false;\n }\n };\n\n grid.onSelectedRowsChanged.subscribe((_e: Event, args: { rows: number[]; }) => {\n if (!inHandler) {\n const newSelectedRowIds = this.mapRowsToIds(args.rows);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: newSelectedRowIds,\n rows: args.rows,\n added: true,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn!(selectedRowsChangedArgs);\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n });\n\n this.preSelectedRowIdsChangeFn = (args: { ids: DataIdType[]; added?: boolean; }) => {\n if (!inHandler) {\n inHandler = true;\n const overwrite = (typeof args.added === typeof undefined);\n\n if (overwrite) {\n setSelectedRowIds(args.ids);\n } else {\n let rowIds: DataIdType[];\n if (args.added) {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // find the ones that are hidden\n const hiddenSelectedRowIds = this.selectedRowIds?.filter((id) => this.getRowById(id) === undefined);\n // add the newly selected ones\n rowIds = hiddenSelectedRowIds!.concat(args.ids);\n } else {\n rowIds = args.ids;\n }\n } else {\n if (preserveHiddenOnSelectionChange && grid.getOptions().multiSelect) {\n // remove rows whose id is on the list\n rowIds = this.selectedRowIds!.filter((id) => args.ids.indexOf(id) === -1);\n } else {\n rowIds = [];\n }\n }\n setSelectedRowIds(rowIds);\n }\n inHandler = false;\n }\n };\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n\n return this.onSelectedRowIdsChanged;\n }\n\n /**\n * Get all selected IDs\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedIds() {\n return this.selectedRowIds;\n }\n\n /**\n * Get all selected filtered IDs (similar to \"getAllSelectedIds\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredIds() {\n return this.getAllSelectedFilteredItems().map((item) => item[this.idProperty as keyof TData]);\n }\n\n /**\n * Set current row selected IDs array (regardless of Pagination)\n * NOTE: This will NOT change the selection in the grid, if you need to do that then you still need to call\n * \"grid.setSelectedRows(rows)\"\n * @param {Array} selectedIds - list of IDs which have been selected for this action\n * @param {Object} options\n * - `isRowBeingAdded`: defaults to true, are the new selected IDs being added (or removed) as new row selections\n * - `shouldTriggerEvent`: defaults to true, should we trigger `onSelectedRowIdsChanged` event\n * - `applyRowSelectionToGrid`: defaults to true, should we apply the row selections to the grid in the UI\n */\n setSelectedIds(selectedIds: Array, options?: Partial<{ isRowBeingAdded: boolean; shouldTriggerEvent: boolean; applyRowSelectionToGrid: boolean; }>) {\n let isRowBeingAdded = options?.isRowBeingAdded;\n const shouldTriggerEvent = options?.shouldTriggerEvent;\n const applyRowSelectionToGrid = options?.applyRowSelectionToGrid;\n\n if (isRowBeingAdded !== false) {\n isRowBeingAdded = true;\n }\n const selectedRows = this.mapIdsToRows(selectedIds);\n const selectedRowsChangedArgs = {\n grid: this._grid,\n ids: selectedIds,\n rows: selectedRows,\n added: isRowBeingAdded,\n dataView: this\n };\n this.preSelectedRowIdsChangeFn?.(selectedRowsChangedArgs);\n\n if (shouldTriggerEvent !== false) {\n this.onSelectedRowIdsChanged.notify(Object.assign(selectedRowsChangedArgs, {\n selectedRowIds: this.selectedRowIds,\n filteredIds: this.getAllSelectedFilteredIds() as DataIdType[],\n }), new SlickEventData(), this);\n }\n\n // should we also apply the row selection in to the grid (UI) as well?\n if (applyRowSelectionToGrid !== false && this._grid) {\n this._grid.setSelectedRows(selectedRows);\n }\n }\n\n /**\n * Get all selected dataContext items\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedItems() {\n const selectedData: TData[] = [];\n const selectedIds = this.getAllSelectedIds();\n selectedIds!.forEach((id) => {\n selectedData.push(this.getItemById(id));\n });\n return selectedData as T[];\n }\n\n /**\n * Get all selected filtered dataContext items (similar to \"getAllSelectedItems\" but only return filtered data)\n * Note: when using Pagination it will also include hidden selections assuming `preserveHiddenOnSelectionChange` is set to true.\n */\n getAllSelectedFilteredItems() {\n if (!Array.isArray(this.selectedRowIds)) {\n return [];\n }\n\n const intersection = this.filteredItems.filter((a) => this.selectedRowIds!.some((b) => a[this.idProperty as keyof TData] === b));\n return (intersection || []) as T[];\n }\n\n syncGridCellCssStyles(grid: SlickGrid, key: string) {\n let hashById: any;\n let inHandler: boolean;\n\n const storeCellCssStyles = (hash: CssStyleHash) => {\n hashById = {};\n for (const row in hash) {\n const id = this.rows[row as any][this.idProperty as keyof TData];\n hashById[id] = hash[row];\n }\n };\n\n // since this method can be called after the cell styles have been set,\n // get the existing ones right away\n storeCellCssStyles(grid.getCellCssStyles(key));\n\n const update = () => {\n if (hashById) {\n inHandler = true;\n this.ensureRowsByIdCache();\n const newHash: CssStyleHash = {};\n for (const id in hashById) {\n const row = this.rowsById?.[id];\n if (Utils.isDefined(row)) {\n newHash[row] = hashById[id];\n }\n }\n grid.setCellCssStyles(key, newHash);\n inHandler = false;\n }\n };\n\n grid.onCellCssStylesChanged.subscribe((_e, args) => {\n if (inHandler) { return; }\n if (key !== args.key) { return; }\n if (args.hash) {\n storeCellCssStyles(args.hash);\n } else {\n grid.onCellCssStylesChanged.unsubscribe();\n this.onRowsOrCountChanged.unsubscribe(update);\n }\n });\n\n this.onRowsOrCountChanged.subscribe(update.bind(this));\n }\n}\n\nexport class AvgAggregator implements Aggregator {\n private _nonNullCount = 0;\n private _sum = 0;\n private _field: number | string;\n private _type = 'avg' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._nonNullCount = 0;\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._nonNullCount++;\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { avg: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n (groupTotals as any)[this._type] = {};\n }\n if (this._nonNullCount !== 0) {\n groupTotals[this._type][this._field] = this._sum / this._nonNullCount;\n }\n }\n}\n\nexport class MinAggregator implements Aggregator {\n private _min: number | null = null;\n private _field: number | string;\n private _type = 'min' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._min = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._min === null || val < this._min) {\n this._min = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { min: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._min;\n }\n}\n\nexport class MaxAggregator implements Aggregator {\n private _max: number | null = null;\n private _field: number | string;\n private _type = 'max' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n this._max = null;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n if (this._max === null || val > this._max) {\n this._max = parseFloat(val);\n }\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { max: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._max;\n }\n}\n\nexport class SumAggregator implements Aggregator {\n private _sum = 0;\n private _field: number | string;\n private _type = 'sum' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init() {\n this._sum = 0;\n }\n\n accumulate(item: T) {\n const val: any = (item?.hasOwnProperty(this._field)) ? item[this._field as keyof T] : null;\n if (val !== null && val !== '' && !isNaN(val)) {\n this._sum += parseFloat(val);\n }\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { sum: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = this._sum;\n }\n}\n\nexport class CountAggregator implements Aggregator {\n private _field: number | string;\n private _type = 'count' as const;\n\n constructor(field: number | string) {\n this._field = field;\n }\n\n get field(): number | string {\n return this._field;\n }\n\n get type(): string {\n return this._type;\n }\n\n init(): void {\n }\n\n storeResult(groupTotals: SlickGroupTotals_ & { count: Record; }) {\n if (!groupTotals || groupTotals[this._type] === undefined) {\n groupTotals[this._type] = {};\n }\n groupTotals[this._type][this._field] = groupTotals.group.rows.length;\n }\n}\n\n// TODO: add more built-in aggregators\n// TODO: merge common aggregators in one to prevent needless iterating\n\nexport const Aggregators = {\n Avg: AvgAggregator,\n Min: MinAggregator,\n Max: MaxAggregator,\n Sum: SumAggregator,\n Count: CountAggregator\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n window.Slick.Data = window.Slick.Data || {};\n window.Slick.Data.DataView = SlickDataView;\n window.Slick.Data.Aggregators = Aggregators;\n}"], + "mappings": "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", "names": ["_a", "_b"] } diff --git a/dist/browser/slick.grid.js b/dist/browser/slick.grid.js index 90a7a8076..80b806650 100644 --- a/dist/browser/slick.grid.js +++ b/dist/browser/slick.grid.js @@ -23,7 +23,7 @@ this.options = options; ////////////////////////////////////////////////////////////////////////////////////////////// // Public API - __publicField(this, "slickGridVersion", "5.4.2"); + __publicField(this, "slickGridVersion", "5.5.0"); /** optional grid state clientId */ __publicField(this, "cid", ""); // Events @@ -94,6 +94,7 @@ explicitInitialization: !1, rowHeight: 25, defaultColumnWidth: 80, + enableHtmlRendering: !0, enableAddRow: !1, leaveSpaceForNewRows: !1, editable: !1, @@ -111,6 +112,7 @@ enableAsyncPostRenderCleanup: !1, asyncPostRenderCleanupDelay: 40, auto: !1, + nonce: "", editorLock: GlobalEditorLock, showColumnHeader: !0, showHeaderRow: !1, @@ -374,6 +376,17 @@ init() { this.finishInitialization(); } + /** + * Apply HTML code by 3 different ways depending on what is provided as input and what options are enabled. + * 1. value is an HTMLElement, then simply append the HTML to the target element. + * 2. value is string and `enableHtmlRendering` is enabled, then use `target.innerHTML = value;` + * 3. value is string and `enableHtmlRendering` is disabled, then use `target.textContent = value;` + * @param target - target element to apply to + * @param val - input value can be either a string or an HTMLElement + */ + applyHtmlCode(target, val) { + val instanceof HTMLElement ? target.appendChild(val) : this._options.enableHtmlRendering ? target.innerHTML = this.sanitizeHtmlString(val) : target.textContent = this.sanitizeHtmlString(val); + } initialize() { if (typeof this.container == "string" ? this._container = document.querySelector(this.container) : this._container = this.container, !this._container) throw new Error(`SlickGrid requires a valid container, ${this.container} does not exist in the DOM.`); @@ -647,7 +660,7 @@ node: header, column: columnDef, grid: this - }), header.setAttribute("title", toolTip || ""), title !== void 0 && (header.children[0].innerHTML = this.sanitizeHtmlString(title)), this.trigger(this.onHeaderCellRendered, { + }), header.setAttribute("title", toolTip || ""), title !== void 0 && this.applyHtmlCode(header.children[0], title), this.trigger(this.onHeaderCellRendered, { node: header, column: columnDef, grid: this @@ -774,7 +787,7 @@ }), Utils.emptyElement(this._footerRowR))); for (let i = 0; i < this.columns.length; i++) { let m = this.columns[i], headerTarget = this.hasFrozenColumns() ? i <= this._options.frozenColumn ? this._headerL : this._headerR : this._headerL, headerRowTarget = this.hasFrozenColumns() ? i <= this._options.frozenColumn ? this._headerRowL : this._headerRowR : this._headerRowL, header = Utils.createDomElement("div", { id: `${this.uid + m.id}`, dataset: { id: String(m.id) }, className: "ui-state-default slick-state-default slick-header-column", title: m.toolTip || "" }, headerTarget), colNameElm = Utils.createDomElement("span", { className: "slick-column-name" }, header); - colNameElm.innerHTML = this.sanitizeHtmlString(m.name), Utils.width(header, m.width - this.headerColumnWidthDiff); + this.applyHtmlCode(colNameElm, m.name), Utils.width(header, m.width - this.headerColumnWidthDiff); let classname = m.headerCssClass || null; if (classname && header.classList.add(...classname.split(" ")), classname = this.hasFrozenColumns() && i <= this._options.frozenColumn ? "frozen" : null, classname && header.classList.add(classname), this._bindingEventService.bind(header, "mouseenter", this.handleHeaderMouseEnter.bind(this)), this._bindingEventService.bind(header, "mouseleave", this.handleHeaderMouseLeave.bind(this)), Utils.storage.put(header, "column", m), (this._options.enableColumnReorder || m.sortable) && (this._bindingEventService.bind(header, "mouseenter", this.handleHeaderMouseHoverOn.bind(this)), this._bindingEventService.bind(header, "mouseleave", this.handleHeaderMouseHoverOff.bind(this))), m.hasOwnProperty("headerCellAttrs") && m.headerCellAttrs instanceof Object) for (let key in m.headerCellAttrs) @@ -1020,7 +1033,7 @@ el = Utils.createDomElement("div", { className: "slick-cell", id: "", style: { visibility: "hidden" }, textContent: "-" }, r), style = getComputedStyle(el), style.boxSizing !== "border-box" && (h.forEach((val) => this.cellWidthDiff += Utils.toFloat(style[val])), v.forEach((val) => this.cellHeightDiff += Utils.toFloat(style[val]))), r.remove(), this.absoluteColumnMinWidth = Math.max(this.headerColumnWidthDiff, this.cellWidthDiff); } createCssRules() { - this._style = document.createElement("style"), this._style.nonce = "random-string", (this._options.shadowRoot || document.head).appendChild(this._style); + this._style = document.createElement("style"), this._style.nonce = this._options.nonce || "", (this._options.shadowRoot || document.head).appendChild(this._style); let rowHeight = this._options.rowHeight - this.cellHeightDiff, rules = [ `.${this.uid} .slick-group-header-column { left: 1000px; }`, `.${this.uid} .slick-header-column { left: 1000px; }`, @@ -1274,7 +1287,7 @@ let header = this.getHeader(columnDef); headerColEl = Utils.createDomElement("div", { id: dummyHeaderColElId, className: "ui-state-default slick-state-default slick-header-column" }, header); let colNameElm = Utils.createDomElement("span", { className: "slick-column-name" }, headerColEl); - colNameElm.innerHTML = this.sanitizeHtmlString(String(columnDef.name)), clone.style.cssText = "position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;", columnDef.headerCssClass && headerColEl.classList.add(...(columnDef.headerCssClass || "").split(" ")), width = headerColEl.offsetWidth, header.removeChild(headerColEl); + this.applyHtmlCode(colNameElm, columnDef.name), clone.style.cssText = "position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;", columnDef.headerCssClass && headerColEl.classList.add(...(columnDef.headerCssClass || "").split(" ")), width = headerColEl.offsetWidth, header.removeChild(headerColEl); } return width; } @@ -1660,14 +1673,14 @@ getDataItemValueForColumn(item, columnDef) { return this._options.dataItemColumnValueExtractor ? this._options.dataItemColumnValueExtractor(item, columnDef) : item[columnDef.field]; } - appendRowHtml(stringArrayL, stringArrayR, row, range, dataLength) { + appendRowHtml(divArrayL, divArrayR, row, range, dataLength) { var _a, _b; let d = this.getDataItem(row), dataLoading = row < dataLength && !d, rowCss = "slick-row" + (this.hasFrozenRows && row <= this._options.frozenRow ? " frozen" : "") + (dataLoading ? " loading" : "") + (row === this.activeRow && this._options.showCellSelection ? " active" : "") + (row % 2 === 1 ? " odd" : " even"); d || (rowCss += " " + this._options.addNewRowCssClass); let metadata = (_b = (_a = this.data) == null ? void 0 : _a.getItemMetadata) == null ? void 0 : _b.call(_a, row); metadata != null && metadata.cssClasses && (rowCss += " " + metadata.cssClasses); - let frozenRowOffset = this.getFrozenRowOffset(row), rowHtml = `
`; - stringArrayL.push(rowHtml), this.hasFrozenColumns() && stringArrayR.push(rowHtml); + let frozenRowOffset = this.getFrozenRowOffset(row), rowDiv = document.createElement("div"), rowDivR; + rowDiv.className = "ui-widget-content " + rowCss, rowDiv.style.top = `${this.getRowTop(row) - frozenRowOffset}px`, divArrayL.push(rowDiv), this.hasFrozenColumns() && (rowDivR = rowDiv.cloneNode(!0), divArrayR.push(rowDivR)); let colspan, m; for (let i = 0, ii = this.columns.length; i < ii; i++) if (m = this.columns[i], !(!m || m.hidden)) { @@ -1678,14 +1691,13 @@ if (this.columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx) { if (!m.alwaysRenderColumn && this.columnPosLeft[i] > range.rightPx) break; - this.hasFrozenColumns() && i > this._options.frozenColumn ? this.appendCellHtml(stringArrayR, row, i, colspan, d) : this.appendCellHtml(stringArrayL, row, i, colspan, d); + this.hasFrozenColumns() && i > this._options.frozenColumn ? this.appendCellHtml(rowDivR, row, i, colspan, d) : this.appendCellHtml(rowDiv, row, i, colspan, d); } else - (m.alwaysRenderColumn || this.hasFrozenColumns() && i <= this._options.frozenColumn) && this.appendCellHtml(stringArrayL, row, i, colspan, d); + (m.alwaysRenderColumn || this.hasFrozenColumns() && i <= this._options.frozenColumn) && this.appendCellHtml(rowDiv, row, i, colspan, d); colspan > 1 && (i += colspan - 1); } - stringArrayL.push("
"), this.hasFrozenColumns() && stringArrayR.push(""); } - appendCellHtml(stringArray, row, cell, colspan, item) { + appendCellHtml(divRow, row, cell, colspan, item) { var _a; let m = this.columns[cell], cellCss = "slick-cell l" + cell + " r" + Math.min(this.columns.length - 1, cell + colspan - 1) + (m.cssClass ? " " + m.cssClass : ""); this.hasFrozenColumns() && cell <= this._options.frozenColumn && (cellCss += " frozen"), row === this.activeRow && cell === this.activeCell && this._options.showCellSelection && (cellCss += " active"); @@ -1695,11 +1707,15 @@ item && (value = this.getDataItemValueForColumn(item, m), formatterResult = this.getFormatter(row, m)(row, cell, value, m, item, this), formatterResult == null && (formatterResult = "")); let appendCellResult = this.trigger(this.onBeforeAppendCell, { row, cell, value, dataContext: item }).getReturnValue(), addlCssClasses = typeof appendCellResult == "string" ? appendCellResult : ""; formatterResult != null && formatterResult.addClasses && (addlCssClasses += (addlCssClasses ? " " : "") + formatterResult.addClasses); - let toolTip = formatterResult != null && formatterResult.toolTip ? `title="${formatterResult.toolTip}"` : "", customAttrStr = ""; - if (m.hasOwnProperty("cellAttrs") && m.cellAttrs instanceof Object) + let toolTipText = formatterResult != null && formatterResult.toolTip ? `${formatterResult.toolTip}` : "", cellDiv = document.createElement("div"); + if (cellDiv.className = cellCss + (addlCssClasses ? " " + addlCssClasses : ""), cellDiv.setAttribute("title", toolTipText), m.hasOwnProperty("cellAttrs") && m.cellAttrs instanceof Object) for (let key in m.cellAttrs) - m.cellAttrs.hasOwnProperty(key) && (customAttrStr += ` ${key}="${m.cellAttrs[key]}" `); - stringArray.push(`
`), item && stringArray.push(Object.prototype.toString.call(formatterResult) !== "[object Object]" ? formatterResult : formatterResult.text), stringArray.push("
"), this.rowsCache[row].cellRenderQueue.push(cell), this.rowsCache[row].cellColSpans[cell] = colspan; + m.cellAttrs.hasOwnProperty(key) && cellDiv.setAttribute(key, m.cellAttrs[key]); + if (item) { + let cellResult = Object.prototype.toString.call(formatterResult) !== "[object Object]" ? formatterResult : formatterResult.html || formatterResult.text; + cellResult instanceof HTMLElement ? cellDiv.appendChild(cellResult) : cellDiv.innerHTML = this.sanitizeHtmlString(cellResult); + } + divRow.appendChild(cellDiv), this.rowsCache[row].cellRenderQueue.push(cell), this.rowsCache[row].cellColSpans[cell] = colspan; } cleanupRows(rangeToKeep) { for (let rowId in this.rowsCache) @@ -1777,10 +1793,11 @@ /** Apply a Formatter Result to a Cell DOM Node */ applyFormatResultToCellNode(formatterResult, cellNode, suppressRemove) { if (formatterResult == null && (formatterResult = ""), Object.prototype.toString.call(formatterResult) !== "[object Object]") { - cellNode.innerHTML = this.sanitizeHtmlString(formatterResult); + this.applyHtmlCode(cellNode, formatterResult); return; } - cellNode.innerHTML = this.sanitizeHtmlString(formatterResult.text), formatterResult.removeClasses && !suppressRemove && formatterResult.removeClasses.split(" ").forEach((c) => cellNode.classList.remove(c)), formatterResult.addClasses && formatterResult.addClasses.split(" ").forEach((c) => cellNode.classList.add(c)), formatterResult.toolTip && cellNode.setAttribute("title", formatterResult.toolTip); + let formatterVal = formatterResult.html || formatterResult.text; + this.applyHtmlCode(cellNode, formatterVal), formatterResult.removeClasses && !suppressRemove && formatterResult.removeClasses.split(" ").forEach((c) => cellNode.classList.remove(c)), formatterResult.addClasses && formatterResult.addClasses.split(" ").forEach((c) => cellNode.classList.add(c)), formatterResult.toolTip && cellNode.setAttribute("title", formatterResult.toolTip); } /** * Update a specific cell by its row and column index @@ -1931,7 +1948,7 @@ } cleanUpAndRenderCells(range) { var _a, _b, _c, _d; - let cacheEntry, stringArray = [], processedRows = [], cellsAdded, totalCellsAdded = 0, colspan; + let cacheEntry, divRow = document.createElement("div"), processedRows = [], cellsAdded, totalCellsAdded = 0, colspan; for (let row = range.top, btm = range.bottom; row <= btm; row++) { if (cacheEntry = this.rowsCache[row], !cacheEntry) continue; @@ -1939,37 +1956,39 @@ let metadata = (_c = (_b = (_a = this.data) == null ? void 0 : _a.getItemMetadata) == null ? void 0 : _b.call(_a, row)) != null ? _c : {}; metadata = metadata == null ? void 0 : metadata.columns; let d = this.getDataItem(row); - for (let i = 0, ii = this.columns.length; i < ii; i++) - if (!(!this.columns[i] || this.columns[i].hidden)) { - if (this.columnPosLeft[i] > range.rightPx) - break; - if (Utils.isDefined(colspan = cacheEntry.cellColSpans[i])) { - i += colspan > 1 ? colspan - 1 : 0; - continue; - } - if (colspan = 1, metadata) { - let columnData = metadata[this.columns[i].id] || metadata[i]; - colspan = (_d = columnData == null ? void 0 : columnData.colspan) != null ? _d : 1, colspan === "*" && (colspan = ii - i); - } - this.columnPosRight[Math.min(ii - 1, i + colspan - 1)] > range.leftPx && (this.appendCellHtml(stringArray, row, i, colspan, d), cellsAdded++), i += colspan > 1 ? colspan - 1 : 0; + for (let i = 0, ii = this.columns.length; i < ii; i++) { + if (!this.columns[i] || this.columns[i].hidden) + continue; + if (this.columnPosLeft[i] > range.rightPx) + break; + if (Utils.isDefined(colspan = cacheEntry.cellColSpans[i])) { + i += colspan > 1 ? colspan - 1 : 0; + continue; } + if (colspan = 1, metadata) { + let columnData = metadata[this.columns[i].id] || metadata[i]; + colspan = (_d = columnData == null ? void 0 : columnData.colspan) != null ? _d : 1, colspan === "*" && (colspan = ii - i); + } + let colspanNb = colspan; + this.columnPosRight[Math.min(ii - 1, i + colspanNb - 1)] > range.leftPx && (this.appendCellHtml(divRow, row, i, colspanNb, d), cellsAdded++), i += colspanNb > 1 ? colspanNb - 1 : 0; + } cellsAdded && (totalCellsAdded += cellsAdded, processedRows.push(row)); } - if (!stringArray.length) + if (!divRow.children.length) return; let x = document.createElement("div"); - x.innerHTML = this.sanitizeHtmlString(stringArray.join("")); + x.innerHTML = this.sanitizeHtmlString(divRow.outerHTML); let processedRow, node; for (; Utils.isDefined(processedRow = processedRows.pop()); ) { cacheEntry = this.rowsCache[processedRow]; let columnIdx; for (; Utils.isDefined(columnIdx = cacheEntry.cellRenderQueue.pop()); ) - node = x.lastChild, this.hasFrozenColumns() && columnIdx > this._options.frozenColumn ? cacheEntry.rowNode[1].appendChild(node) : cacheEntry.rowNode[0].appendChild(node), cacheEntry.cellNodesByColumnIdx[columnIdx] = node; + node = x.lastChild, node && (this.hasFrozenColumns() && columnIdx > this._options.frozenColumn ? cacheEntry.rowNode[1].appendChild(node) : cacheEntry.rowNode[0].appendChild(node), cacheEntry.cellNodesByColumnIdx[columnIdx] = node); } } renderRows(range) { var _a, _b, _c, _d; - let stringArrayL = [], stringArrayR = [], rows = [], needToReselectCell = !1, dataLength = this.getDataLength(); + let divArrayL = [], divArrayR = [], rows = [], needToReselectCell = !1, dataLength = this.getDataLength(); for (let i = range.top, ii = range.bottom; i <= ii; i++) this.rowsCache[i] || this.hasFrozenRows && this._options.frozenBottom && i === this.getDataLength() || (this.renderedRows++, rows.push(i), this.rowsCache[i] = { rowNode: null, @@ -1982,11 +2001,15 @@ // cellNodesByColumnIdx. These are in the same order as cell nodes added at the // end of the row. cellRenderQueue: [] - }, this.appendRowHtml(stringArrayL, stringArrayR, i, range, dataLength), this.activeCellNode && this.activeRow === i && (needToReselectCell = !0), this.counter_rows_rendered++); + }, this.appendRowHtml(divArrayL, divArrayR, i, range, dataLength), this.activeCellNode && this.activeRow === i && (needToReselectCell = !0), this.counter_rows_rendered++); if (!rows.length) return; let x = document.createElement("div"), xRight = document.createElement("div"); - x.innerHTML = this.sanitizeHtmlString(stringArrayL.join("")), xRight.innerHTML = this.sanitizeHtmlString(stringArrayR.join("")); + divArrayL.forEach((elm) => { + x.appendChild(elm); + }), divArrayR.forEach((elm) => { + xRight.appendChild(elm); + }); for (let i = 0, ii = rows.length; i < ii; i++) this.hasFrozenRows && rows[i] >= this.actualFrozenRow ? this.hasFrozenColumns() ? (_a = this.rowsCache) != null && _a.hasOwnProperty(rows[i]) && x.firstChild && xRight.firstChild && (this.rowsCache[rows[i]].rowNode = [x.firstChild, xRight.firstChild], this._canvasBottomL.appendChild(x.firstChild), this._canvasBottomR.appendChild(xRight.firstChild)) : (_b = this.rowsCache) != null && _b.hasOwnProperty(rows[i]) && x.firstChild && (this.rowsCache[rows[i]].rowNode = [x.firstChild], this._canvasBottomL.appendChild(x.firstChild)) : this.hasFrozenColumns() ? (_c = this.rowsCache) != null && _c.hasOwnProperty(rows[i]) && x.firstChild && xRight.firstChild && (this.rowsCache[rows[i]].rowNode = [x.firstChild, xRight.firstChild], this._canvasTopL.appendChild(x.firstChild), this._canvasTopR.appendChild(xRight.firstChild)) : (_d = this.rowsCache) != null && _d.hasOwnProperty(rows[i]) && x.firstChild && (this.rowsCache[rows[i]].rowNode = [x.firstChild], this._canvasTopL.appendChild(x.firstChild)); needToReselectCell && (this.activeCellNode = this.getCellNode(this.activeRow, this.activeCell)); @@ -3028,7 +3051,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v5.4.2 + * SlickGrid v5.5.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 3c6140494..1de7cc171 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\nimport type SortableInstance from 'sortablejs';\n\nimport type {\n AutoSize,\n CellViewportRange,\n Column,\n ColumnSort,\n CssStyleHash,\n CSSStyleDeclarationWritable,\n CustomDataView,\n DOMEvent,\n DOMMouseOrTouchEvent,\n DragPosition,\n DragRowMove,\n Editor,\n EditController,\n Formatter,\n FormatterOverrideCallback,\n FormatterResultObject,\n GridOption as BaseGridOption,\n InteractionBase,\n ItemMetadata,\n MultiColumnSort,\n OnActiveCellChangedEventArgs,\n OnAddNewRowEventArgs,\n OnAutosizeColumnsEventArgs,\n OnBeforeUpdateColumnsEventArgs,\n OnBeforeAppendCellEventArgs,\n OnBeforeCellEditorDestroyEventArgs,\n OnBeforeColumnsResizeEventArgs,\n OnBeforeEditCellEventArgs,\n OnBeforeHeaderCellDestroyEventArgs,\n OnBeforeHeaderRowCellDestroyEventArgs,\n OnBeforeFooterRowCellDestroyEventArgs,\n OnBeforeSetColumnsEventArgs,\n OnCellChangeEventArgs,\n OnCellCssStylesChangedEventArgs,\n OnColumnsDragEventArgs,\n OnColumnsReorderedEventArgs,\n OnColumnsResizedEventArgs,\n OnColumnsResizeDblClickEventArgs,\n OnCompositeEditorChangeEventArgs,\n OnClickEventArgs,\n OnDblClickEventArgs,\n OnFooterContextMenuEventArgs,\n OnFooterRowCellRenderedEventArgs,\n OnHeaderCellRenderedEventArgs,\n OnFooterClickEventArgs,\n OnHeaderClickEventArgs,\n OnHeaderContextMenuEventArgs,\n OnHeaderMouseEventArgs,\n OnHeaderRowCellRenderedEventArgs,\n OnKeyDownEventArgs,\n OnValidationErrorEventArgs,\n OnRenderedEventArgs,\n OnSelectedRowsChangedEventArgs,\n OnSetOptionsEventArgs,\n OnActivateChangedOptionsEventArgs,\n OnScrollEventArgs,\n PagingInfo,\n RowInfo,\n SelectionModel,\n SingleColumnSort,\n SlickGridEventData,\n SlickGridModel,\n SlickPlugin,\n} from './models/index';\nimport {\n BindingEventService as BindingEventService_,\n ColAutosizeMode as ColAutosizeMode_,\n GlobalEditorLock as GlobalEditorLock_,\n GridAutosizeColsMode as GridAutosizeColsMode_,\n keyCode as keyCode_,\n preClickClassName as preClickClassName_,\n RowSelectionMode as RowSelectionMode_,\n type SlickEditorLock,\n SlickEvent as SlickEvent_,\n SlickEventData as SlickEventData_,\n SlickRange as SlickRange_,\n Utils as Utils_,\n ValueFilterMode as ValueFilterMode_,\n WidthEvalMode as WidthEvalMode_,\n} from './slick.core';\nimport { Draggable as Draggable_, MouseWheel as MouseWheel_, Resizable as Resizable_ } from './slick.interactions';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\nconst ColAutosizeMode = IIFE_ONLY ? Slick.ColAutosizeMode : ColAutosizeMode_;\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\nconst GlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : GlobalEditorLock_;\nconst GridAutosizeColsMode = IIFE_ONLY ? Slick.GridAutosizeColsMode : GridAutosizeColsMode_;\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst preClickClassName = IIFE_ONLY ? Slick.preClickClassName : preClickClassName_;\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\nconst RowSelectionMode = IIFE_ONLY ? Slick.RowSelectionMode : RowSelectionMode_;\nconst ValueFilterMode = IIFE_ONLY ? Slick.ValueFilterMode : ValueFilterMode_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\nconst WidthEvalMode = IIFE_ONLY ? Slick.WidthEvalMode : WidthEvalMode_;\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\nconst MouseWheel = IIFE_ONLY ? Slick.MouseWheel : MouseWheel_;\nconst Resizable = IIFE_ONLY ? Slick.Resizable : Resizable_;\n\n/**\n * @license\n * (c) 2009-present Michael Leibman\n * michael{dot}leibman{at}gmail{dot}com\n * http://github.com/mleibman/slickgrid\n *\n * Distributed under MIT license.\n * All rights reserved.\n *\n * SlickGrid v5.4.2\n *\n * NOTES:\n * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods.\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\n * and do proper cleanup.\n */\n\n//////////////////////////////////////////////////////////////////////////////////////////////\n// SlickGrid class implementation (available as SlickGrid)\n\ninterface RowCaching {\n rowNode: HTMLElement[] | null,\n cellColSpans: Array;\n cellNodesByColumnIdx: HTMLElement[];\n cellRenderQueue: any[];\n}\n\nexport class SlickGrid = Column, O extends BaseGridOption = BaseGridOption> {\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Public API\n slickGridVersion = '5.4.2';\n\n /** optional grid state clientId */\n cid = '';\n\n // Events\n onActiveCellChanged = new SlickEvent();\n onActiveCellPositionChanged = new SlickEvent();\n onAddNewRow = new SlickEvent();\n onAutosizeColumns = new SlickEvent();\n onBeforeAppendCell = new SlickEvent();\n onBeforeCellEditorDestroy = new SlickEvent();\n onBeforeColumnsResize = new SlickEvent();\n onBeforeDestroy = new SlickEvent();\n onBeforeEditCell = new SlickEvent();\n onBeforeFooterRowCellDestroy = new SlickEvent();\n onBeforeHeaderCellDestroy = new SlickEvent();\n onBeforeHeaderRowCellDestroy = new SlickEvent();\n onBeforeSetColumns = new SlickEvent();\n onBeforeSort = new SlickEvent();\n onBeforeUpdateColumns = new SlickEvent();\n onCellChange = new SlickEvent();\n onCellCssStylesChanged = new SlickEvent();\n onClick = new SlickEvent();\n onColumnsReordered = new SlickEvent();\n onColumnsDrag = new SlickEvent();\n onColumnsResized = new SlickEvent();\n onColumnsResizeDblClick = new SlickEvent();\n onCompositeEditorChange = new SlickEvent();\n onContextMenu = new SlickEvent();\n onDrag = new SlickEvent();\n onDblClick = new SlickEvent();\n onDragInit = new SlickEvent();\n onDragStart = new SlickEvent();\n onDragEnd = new SlickEvent();\n onFooterClick = new SlickEvent();\n onFooterContextMenu = new SlickEvent();\n onFooterRowCellRendered = new SlickEvent();\n onHeaderCellRendered = new SlickEvent();\n onHeaderClick = new SlickEvent();\n onHeaderContextMenu = new SlickEvent();\n onHeaderMouseEnter = new SlickEvent();\n onHeaderMouseLeave = new SlickEvent();\n onHeaderRowCellRendered = new SlickEvent();\n onHeaderRowMouseEnter = new SlickEvent();\n onHeaderRowMouseLeave = new SlickEvent();\n onKeyDown = new SlickEvent();\n onMouseEnter = new SlickEvent();\n onMouseLeave = new SlickEvent();\n onRendered = new SlickEvent();\n onScroll = new SlickEvent();\n onSelectedRowsChanged = new SlickEvent();\n onSetOptions = new SlickEvent();\n onActivateChangedOptions = new SlickEvent();\n onSort = new SlickEvent();\n onValidationError = new SlickEvent();\n onViewportChanged = new SlickEvent();\n\n // ---\n // protected variables\n\n // shared across all grids on the page\n protected scrollbarDimensions?: { height: number; width: number; };\n protected maxSupportedCssHeight!: number; // browser's breaking point\n\n protected canvas: HTMLCanvasElement | null = null;\n protected canvas_context: CanvasRenderingContext2D | null = null;\n\n // settings\n protected _options!: O;\n protected _defaults: BaseGridOption = {\n alwaysShowVerticalScroll: false,\n alwaysAllowHorizontalScroll: false,\n explicitInitialization: false,\n rowHeight: 25,\n defaultColumnWidth: 80,\n enableAddRow: false,\n leaveSpaceForNewRows: false,\n editable: false,\n autoEdit: true,\n autoEditNewRow: true,\n autoCommitEdit: false,\n suppressActiveCellChangeOnEdit: false,\n enableCellNavigation: true,\n enableColumnReorder: true,\n asyncEditorLoading: false,\n asyncEditorLoadDelay: 100,\n forceFitColumns: false,\n enableAsyncPostRender: false,\n asyncPostRenderDelay: 50,\n enableAsyncPostRenderCleanup: false,\n asyncPostRenderCleanupDelay: 40,\n auto: false,\n editorLock: GlobalEditorLock,\n showColumnHeader: true,\n showHeaderRow: false,\n headerRowHeight: 25,\n createFooterRow: false,\n showFooterRow: false,\n footerRowHeight: 25,\n createPreHeaderPanel: false,\n showPreHeaderPanel: false,\n preHeaderPanelHeight: 25,\n showTopPanel: false,\n topPanelHeight: 25,\n formatterFactory: null,\n editorFactory: null,\n cellFlashingCssClass: 'flashing',\n selectedCellCssClass: 'selected',\n multiSelect: true,\n enableTextSelectionOnCells: false,\n dataItemColumnValueExtractor: null,\n frozenBottom: false,\n frozenColumn: -1,\n frozenRow: -1,\n frozenRightViewportMinWidth: 100,\n throwWhenFrozenNotAllViewable: false,\n fullWidthRows: false,\n multiColumnSort: false,\n numberedMultiColumnSort: false,\n tristateMultiColumnSort: false,\n sortColNumberInSeparateSpan: false,\n defaultFormatter: this.defaultFormatter,\n forceSyncScrolling: false,\n addNewRowCssClass: 'new-row',\n preserveCopiedSelectionOnPaste: false,\n showCellSelection: true,\n viewportClass: undefined,\n minRowBuffer: 3,\n emulatePagingWhenScrolling: true, // when scrolling off bottom of viewport, place new row at top of viewport\n editorCellNavOnLRKeys: false,\n enableMouseWheelScrollHandler: true,\n doPaging: true,\n autosizeColsMode: GridAutosizeColsMode.LegacyOff,\n autosizeColPaddingPx: 4,\n scrollRenderThrottling: 50,\n autosizeTextAvgToMWidthRatio: 0.75,\n viewportSwitchToScrollModeWidthPercent: undefined,\n viewportMinWidthPx: undefined,\n viewportMaxWidthPx: undefined,\n suppressCssChangesOnHiddenInit: false,\n ffMaxSupportedCssHeight: 6000000,\n maxSupportedCssHeight: 1000000000,\n sanitizer: undefined, // sanitize function, built in basic sanitizer is: Slick.RegexSanitizer(dirtyHtml)\n logSanitizedHtml: false, // log to console when sanitised - recommend true for testing of dev and production\n mixinDefaults: true,\n shadowRoot: undefined\n };\n\n protected _columnDefaults = {\n name: '',\n resizable: true,\n sortable: false,\n minWidth: 30,\n maxWidth: undefined,\n rerenderOnResize: false,\n headerCssClass: null,\n defaultSortAsc: true,\n focusable: true,\n selectable: true,\n hidden: false\n } as Partial;\n\n protected _columnAutosizeDefaults: AutoSize = {\n ignoreHeaderText: false,\n colValueArray: undefined,\n allowAddlPercent: undefined,\n formatterOverride: undefined,\n autosizeMode: ColAutosizeMode.ContentIntelligent,\n rowSelectionModeOnInit: undefined,\n rowSelectionMode: RowSelectionMode.FirstNRows,\n rowSelectionCount: 100,\n valueFilterMode: ValueFilterMode.None,\n widthEvalMode: WidthEvalMode.Auto,\n sizeToRemaining: undefined,\n widthPx: undefined,\n contentSizePx: 0,\n headerWidthPx: 0,\n colDataTypeOf: undefined\n };\n\n // scroller\n protected th!: number; // virtual height\n protected h!: number; // real scrollable height\n protected ph!: number; // page height\n protected n!: number; // number of pages\n protected cj!: number; // \"jumpiness\" coefficient\n\n protected page = 0; // current page\n protected offset = 0; // current page offset\n protected vScrollDir = 1;\n protected _bindingEventService = new BindingEventService();\n protected initialized = false;\n protected _container!: HTMLElement;\n protected uid = `slickgrid_${Math.round(1000000 * Math.random())}`;\n protected _focusSink!: HTMLDivElement;\n protected _focusSink2!: HTMLDivElement;\n protected _groupHeaders: HTMLDivElement[] = [];\n protected _headerScroller: HTMLDivElement[] = [];\n protected _headers: HTMLDivElement[] = [];\n protected _headerRows!: HTMLDivElement[];\n protected _headerRowScroller!: HTMLDivElement[];\n protected _headerRowSpacerL!: HTMLDivElement;\n protected _headerRowSpacerR!: HTMLDivElement;\n protected _footerRow!: HTMLDivElement[];\n protected _footerRowScroller!: HTMLDivElement[];\n protected _footerRowSpacerL!: HTMLDivElement;\n protected _footerRowSpacerR!: HTMLDivElement;\n protected _preHeaderPanel!: HTMLDivElement;\n protected _preHeaderPanelScroller!: HTMLDivElement;\n protected _preHeaderPanelSpacer!: HTMLDivElement;\n protected _preHeaderPanelR!: HTMLDivElement;\n protected _preHeaderPanelScrollerR!: HTMLDivElement;\n protected _preHeaderPanelSpacerR!: HTMLDivElement;\n protected _topPanelScrollers!: HTMLDivElement[];\n protected _topPanels!: HTMLDivElement[];\n protected _viewport!: HTMLDivElement[];\n protected _canvas!: HTMLDivElement[];\n protected _style?: HTMLStyleElement;\n protected _boundAncestors: HTMLElement[] = [];\n protected stylesheet?: { cssRules: Array<{ selectorText: string; }>; rules: Array<{ selectorText: string; }>; } | null;\n protected columnCssRulesL?: Array<{ selectorText: string; }>;\n protected columnCssRulesR?: Array<{ selectorText: string; }>;\n protected viewportH = 0;\n protected viewportW = 0;\n protected canvasWidth = 0;\n protected canvasWidthL = 0;\n protected canvasWidthR = 0;\n protected headersWidth = 0;\n protected headersWidthL = 0;\n protected headersWidthR = 0;\n protected viewportHasHScroll = false;\n protected viewportHasVScroll = false;\n protected headerColumnWidthDiff = 0;\n protected headerColumnHeightDiff = 0; // border+padding\n protected cellWidthDiff = 0;\n protected cellHeightDiff = 0;\n protected absoluteColumnMinWidth!: number;\n protected hasFrozenRows = false;\n protected frozenRowsHeight = 0;\n protected actualFrozenRow = -1;\n protected paneTopH = 0;\n protected paneBottomH = 0;\n protected viewportTopH = 0;\n protected viewportBottomH = 0;\n protected topPanelH = 0;\n protected headerRowH = 0;\n protected footerRowH = 0;\n\n protected tabbingDirection = 1;\n protected _activeCanvasNode!: HTMLDivElement;\n protected _activeViewportNode!: HTMLDivElement;\n protected activePosX!: number;\n protected activeRow!: number;\n protected activeCell!: number;\n protected activeCellNode: HTMLDivElement | null = null;\n protected currentEditor: Editor | null = null;\n protected serializedEditorValue: any;\n protected editController?: EditController;\n\n protected rowsCache: Array = {} as any;\n protected renderedRows = 0;\n protected numVisibleRows = 0;\n protected prevScrollTop = 0;\n protected scrollTop = 0;\n protected lastRenderedScrollTop = 0;\n protected lastRenderedScrollLeft = 0;\n protected prevScrollLeft = 0;\n protected scrollLeft = 0;\n\n protected selectionModel?: SelectionModel;\n protected selectedRows: number[] = [];\n\n protected plugins: SlickPlugin[] = [];\n protected cellCssClasses: CssStyleHash = {};\n\n protected columnsById: Record = {};\n protected sortColumns: ColumnSort[] = [];\n protected columnPosLeft: number[] = [];\n protected columnPosRight: number[] = [];\n\n protected pagingActive = false;\n protected pagingIsLastPage = false;\n\n protected scrollThrottle!: { enqueue: () => void; dequeue: () => void; };\n\n // async call handles\n protected h_editorLoader: any = null;\n protected h_render = null;\n protected h_postrender: any = null;\n protected h_postrenderCleanup: any = null;\n protected postProcessedRows: any = {};\n protected postProcessToRow: number = null as any;\n protected postProcessFromRow: number = null as any;\n protected postProcessedCleanupQueue: Array<{\n actionType: string;\n groupId: number;\n node: HTMLElement | HTMLElement[];\n columnIdx?: number;\n rowIdx?: number;\n }> = [];\n protected postProcessgroupId = 0;\n\n // perf counters\n protected counter_rows_rendered = 0;\n protected counter_rows_removed = 0;\n\n protected _paneHeaderL!: HTMLDivElement;\n protected _paneHeaderR!: HTMLDivElement;\n protected _paneTopL!: HTMLDivElement;\n protected _paneTopR!: HTMLDivElement;\n protected _paneBottomL!: HTMLDivElement;\n protected _paneBottomR!: HTMLDivElement;\n protected _headerScrollerL!: HTMLDivElement;\n protected _headerScrollerR!: HTMLDivElement;\n protected _headerL!: HTMLDivElement;\n protected _headerR!: HTMLDivElement;\n protected _groupHeadersL!: HTMLDivElement;\n protected _groupHeadersR!: HTMLDivElement;\n protected _headerRowScrollerL!: HTMLDivElement;\n protected _headerRowScrollerR!: HTMLDivElement;\n protected _footerRowScrollerL!: HTMLDivElement;\n protected _footerRowScrollerR!: HTMLDivElement;\n protected _headerRowL!: HTMLDivElement;\n protected _headerRowR!: HTMLDivElement;\n protected _footerRowL!: HTMLDivElement;\n protected _footerRowR!: HTMLDivElement;\n protected _topPanelScrollerL!: HTMLDivElement;\n protected _topPanelScrollerR!: HTMLDivElement;\n protected _topPanelL!: HTMLDivElement;\n protected _topPanelR!: HTMLDivElement;\n protected _viewportTopL!: HTMLDivElement;\n protected _viewportTopR!: HTMLDivElement;\n protected _viewportBottomL!: HTMLDivElement;\n protected _viewportBottomR!: HTMLDivElement;\n protected _canvasTopL!: HTMLDivElement;\n protected _canvasTopR!: HTMLDivElement;\n protected _canvasBottomL!: HTMLDivElement;\n protected _canvasBottomR!: HTMLDivElement;\n protected _viewportScrollContainerX!: HTMLDivElement;\n protected _viewportScrollContainerY!: HTMLDivElement;\n protected _headerScrollContainer!: HTMLDivElement;\n protected _headerRowScrollContainer!: HTMLDivElement;\n protected _footerRowScrollContainer!: HTMLDivElement;\n\n // store css attributes if display:none is active in container or parent\n protected cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\n protected _hiddenParents: HTMLElement[] = [];\n protected oldProps: Array> = [];\n protected enforceFrozenRowHeightRecalc = false;\n protected columnResizeDragging = false;\n protected slickDraggableInstance: InteractionBase | null = null;\n protected slickMouseWheelInstances: Array = [];\n protected slickResizableInstances: Array = [];\n protected sortableSideLeftInstance?: SortableInstance;\n protected sortableSideRightInstance?: SortableInstance;\n protected logMessageCount = 0;\n protected logMessageMaxCount = 30;\n\n /**\n * Creates a new instance of the grid.\n * @class SlickGrid\n * @constructor\n * @param {Node} container - Container node to create the grid in.\n * @param {Array|Object} data - An array of objects for databinding.\n * @param {Array} columns - An array of column definitions.\n * @param {Object} [options] - Grid this._options.\n **/\n constructor(protected container: HTMLElement | string, protected data: CustomDataView | TData[], protected columns: C[], protected options: Partial) {\n this.initialize();\n }\n\n //////////////////////////////////////////////////////////////////////////////////////////////\n // Initialization\n\n /** Initializes the grid. */\n init() {\n this.finishInitialization();\n }\n\n protected initialize() {\n if (typeof this.container === 'string') {\n this._container = document.querySelector(this.container) as HTMLDivElement;\n } else {\n this._container = this.container;\n }\n\n if (!this._container) {\n throw new Error(`SlickGrid requires a valid container, ${this.container} does not exist in the DOM.`);\n }\n\n // calculate these only once and share between grid instances\n if (this.options.mixinDefaults) {\n if (!this.options) { this.options = {}; }\n Utils.applyDefaults(this.options, this._defaults);\n } else {\n this._options = Utils.extend(true, {}, this._defaults, this.options);\n }\n this.scrollThrottle = this.actionThrottle(this.render.bind(this), this._options.scrollRenderThrottling as number);\n this.maxSupportedCssHeight = this.maxSupportedCssHeight || this.getMaxSupportedCssHeight();\n this.validateAndEnforceOptions();\n this._columnDefaults.width = this._options.defaultColumnWidth;\n\n if (!this._options.suppressCssChangesOnHiddenInit) {\n this.cacheCssForHiddenInit();\n }\n\n this.updateColumnProps();\n\n // validate loaded JavaScript modules against requested options\n if (this._options.enableColumnReorder && (!Sortable || !Sortable.create)) {\n throw new Error('SlickGrid requires Sortable.js module to be loaded');\n }\n\n this.editController = {\n commitCurrentEdit: this.commitCurrentEdit.bind(this),\n cancelCurrentEdit: this.cancelCurrentEdit.bind(this),\n };\n\n Utils.emptyElement(this._container);\n this._container.style.overflow = 'hidden';\n this._container.style.outline = String(0);\n this._container.classList.add(this.uid);\n this._container.classList.add('ui-widget');\n\n const containerStyles = window.getComputedStyle(this._container);\n if (!(/relative|absolute|fixed/).test(containerStyles.position)) {\n this._container.style.position = 'relative';\n }\n\n this._focusSink = Utils.createDomElement('div', { tabIndex: 0, style: { position: 'fixed', width: '0px', height: '0px', top: '0px', left: '0px', outline: '0px' } }, this._container);\n\n // Containers used for scrolling frozen columns and rows\n this._paneHeaderL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-left', tabIndex: 0 }, this._container);\n this._paneHeaderR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-right', tabIndex: 0 }, this._container);\n this._paneTopL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-left', tabIndex: 0 }, this._container);\n this._paneTopR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-right', tabIndex: 0 }, this._container);\n this._paneBottomL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-left', tabIndex: 0 }, this._container);\n this._paneBottomR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-right', tabIndex: 0 }, this._container);\n\n if (this._options.createPreHeaderPanel) {\n this._preHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);\n this._preHeaderPanelScroller.appendChild(document.createElement('div'));\n this._preHeaderPanel = Utils.createDomElement('div', null, this._preHeaderPanelScroller);\n this._preHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScroller);\n\n this._preHeaderPanelScrollerR = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);\n this._preHeaderPanelR = Utils.createDomElement('div', null, this._preHeaderPanelScrollerR);\n this._preHeaderPanelSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScrollerR);\n\n if (!this._options.showPreHeaderPanel) {\n Utils.hide(this._preHeaderPanelScroller);\n Utils.hide(this._preHeaderPanelScrollerR);\n }\n }\n\n // Append the header scroller containers\n this._headerScrollerL = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-left' }, this._paneHeaderL);\n this._headerScrollerR = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-right' }, this._paneHeaderR);\n\n // Cache the header scroller containers\n this._headerScroller.push(this._headerScrollerL);\n this._headerScroller.push(this._headerScrollerR);\n\n // Append the columnn containers to the headers\n this._headerL = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-left', style: { left: '-1000px' } }, this._headerScrollerL);\n this._headerR = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-right', style: { left: '-1000px' } }, this._headerScrollerR);\n\n // Cache the header columns\n this._headers = [this._headerL, this._headerR];\n\n this._headerRowScrollerL = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopL);\n this._headerRowScrollerR = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopR);\n\n this._headerRowScroller = [this._headerRowScrollerL, this._headerRowScrollerR];\n\n this._headerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerL);\n this._headerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerR);\n\n this._headerRowL = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-left' }, this._headerRowScrollerL);\n this._headerRowR = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-right' }, this._headerRowScrollerR);\n\n this._headerRows = [this._headerRowL, this._headerRowR];\n\n // Append the top panel scroller\n this._topPanelScrollerL = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopL);\n this._topPanelScrollerR = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopR);\n\n this._topPanelScrollers = [this._topPanelScrollerL, this._topPanelScrollerR];\n\n // Append the top panel\n this._topPanelL = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerL);\n this._topPanelR = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerR);\n\n this._topPanels = [this._topPanelL, this._topPanelR];\n\n if (!this._options.showColumnHeader) {\n this._headerScroller.forEach((el) => {\n Utils.hide(el);\n });\n }\n\n if (!this._options.showTopPanel) {\n this._topPanelScrollers.forEach((scroller) => {\n Utils.hide(scroller);\n });\n }\n\n if (!this._options.showHeaderRow) {\n this._headerRowScroller.forEach((scroller) => {\n Utils.hide(scroller);\n });\n }\n\n // Append the viewport containers\n this._viewportTopL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-left', tabIndex: 0 }, this._paneTopL);\n this._viewportTopR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-right', tabIndex: 0 }, this._paneTopR);\n this._viewportBottomL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-left', tabIndex: 0 }, this._paneBottomL);\n this._viewportBottomR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-right', tabIndex: 0 }, this._paneBottomR);\n\n // Cache the viewports\n this._viewport = [this._viewportTopL, this._viewportTopR, this._viewportBottomL, this._viewportBottomR];\n if (this._options.viewportClass) {\n this._viewport.forEach((view) => {\n view.classList.add(...(this._options.viewportClass || '').split(' '));\n });\n }\n\n // Default the active viewport to the top left\n this._activeViewportNode = this._viewportTopL;\n\n // Append the canvas containers\n this._canvasTopL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-left', tabIndex: 0 }, this._viewportTopL);\n this._canvasTopR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-right', tabIndex: 0 }, this._viewportTopR);\n this._canvasBottomL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-left', tabIndex: 0 }, this._viewportBottomL);\n this._canvasBottomR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-right', tabIndex: 0 }, this._viewportBottomR);\n\n // Cache the canvases\n this._canvas = [this._canvasTopL, this._canvasTopR, this._canvasBottomL, this._canvasBottomR];\n\n this.scrollbarDimensions = this.scrollbarDimensions || this.measureScrollbar();\n\n // Default the active canvas to the top left\n this._activeCanvasNode = this._canvasTopL;\n\n // pre-header\n if (this._preHeaderPanelSpacer) {\n Utils.width(this._preHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\n }\n\n this._headers.forEach((el) => {\n Utils.width(el, this.getHeadersWidth());\n });\n\n Utils.width(this._headerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\n Utils.width(this._headerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\n\n // footer Row\n if (this._options.createFooterRow) {\n this._footerRowScrollerR = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopR);\n this._footerRowScrollerL = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopL);\n\n this._footerRowScroller = [this._footerRowScrollerL, this._footerRowScrollerR];\n\n this._footerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerL);\n Utils.width(this._footerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\n this._footerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerR);\n Utils.width(this._footerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\n\n this._footerRowL = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-left' }, this._footerRowScrollerL);\n this._footerRowR = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-right' }, this._footerRowScrollerR);\n\n this._footerRow = [this._footerRowL, this._footerRowR];\n\n if (!this._options.showFooterRow) {\n this._footerRowScroller.forEach((scroller) => {\n Utils.hide(scroller);\n });\n }\n }\n\n this._focusSink2 = this._focusSink.cloneNode(true) as HTMLDivElement;\n this._container.appendChild(this._focusSink2);\n\n if (!this._options.explicitInitialization) {\n this.finishInitialization();\n }\n }\n\n protected finishInitialization() {\n if (!this.initialized) {\n this.initialized = true;\n\n this.getViewportWidth();\n this.getViewportHeight();\n\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\n // calculate the diff so we can set consistent sizes\n this.measureCellPaddingAndBorder();\n\n // for usability reasons, all text selection in SlickGrid is disabled\n // with the exception of input and textarea elements (selection must\n // be enabled there so that editors work as expected); note that\n // selection in grid cells (grid body) is already unavailable in\n // all browsers except IE\n this.disableSelection(this._headers); // disable all text selection in header (including input and textarea)\n\n if (!this._options.enableTextSelectionOnCells) {\n // disable text selection in grid cells except in input and textarea elements\n // (this is IE-specific, because selectstart event will only fire in IE)\n this._viewport.forEach((view) => {\n this._bindingEventService.bind(view, 'selectstart', (event) => {\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\n return;\n }\n });\n });\n }\n\n this.setFrozenOptions();\n this.setPaneVisibility();\n this.setScroller();\n this.setOverflow();\n\n this.updateColumnCaches();\n this.createColumnHeaders();\n this.createColumnFooter();\n this.setupColumnSort();\n this.createCssRules();\n this.resizeCanvas();\n this.bindAncestorScrollEvents();\n\n this._bindingEventService.bind(this._container, 'resize', this.resizeCanvas.bind(this));\n this._viewport.forEach((view) => {\n this._bindingEventService.bind(view, 'scroll', this.handleScroll.bind(this));\n });\n\n if (this._options.enableMouseWheelScrollHandler) {\n this._viewport.forEach((view) => {\n this.slickMouseWheelInstances.push(MouseWheel({\n element: view,\n onMouseWheel: this.handleMouseWheel.bind(this)\n }));\n });\n }\n\n this._headerScroller.forEach((el) => {\n this._bindingEventService.bind(el, 'contextmenu', this.handleHeaderContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(el, 'click', this.handleHeaderClick.bind(this) as EventListener);\n });\n\n this._headerRowScroller.forEach((scroller) => {\n this._bindingEventService.bind(scroller, 'scroll', this.handleHeaderRowScroll.bind(this) as EventListener);\n });\n\n if (this._options.createFooterRow) {\n this._footerRow.forEach((footer) => {\n this._bindingEventService.bind(footer, 'contextmenu', this.handleFooterContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(footer, 'click', this.handleFooterClick.bind(this) as EventListener);\n });\n\n this._footerRowScroller.forEach((scroller) => {\n this._bindingEventService.bind(scroller, 'scroll', this.handleFooterRowScroll.bind(this) as EventListener);\n });\n }\n\n if (this._options.createPreHeaderPanel) {\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'scroll', this.handlePreHeaderPanelScroll.bind(this) as EventListener);\n }\n\n this._bindingEventService.bind(this._focusSink, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n this._bindingEventService.bind(this._focusSink2, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n\n this._canvas.forEach((element) => {\n this._bindingEventService.bind(element, 'keydown', this.handleKeyDown.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'click', this.handleClick.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'dblclick', this.handleDblClick.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'contextmenu', this.handleContextMenu.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'mouseover', this.handleCellMouseOver.bind(this) as EventListener);\n this._bindingEventService.bind(element, 'mouseout', this.handleCellMouseOut.bind(this) as EventListener);\n });\n\n if (Draggable) {\n this.slickDraggableInstance = Draggable({\n containerElement: this._container,\n allowDragFrom: 'div.slick-cell',\n allowDragFromClosest: 'div.slick-cell',\n onDragInit: this.handleDragInit.bind(this),\n onDragStart: this.handleDragStart.bind(this),\n onDrag: this.handleDrag.bind(this),\n onDragEnd: this.handleDragEnd.bind(this)\n });\n }\n\n if (!this._options.suppressCssChangesOnHiddenInit) {\n this.restoreCssFromHiddenInit();\n }\n }\n }\n\n /** handles \"display:none\" on container or container parents, related to issue: https://github.com/6pac/SlickGrid/issues/568 */\n cacheCssForHiddenInit() {\n this._hiddenParents = Utils.parents(this._container, ':hidden') as HTMLElement[];\n for (const el of this._hiddenParents) {\n const old: Partial = {};\n for (const name in this.cssShow) {\n if (this.cssShow) {\n old[name as any] = el.style[name as 'position' | 'visibility' | 'display'];\n el.style[name as any] = this.cssShow[name as 'position' | 'visibility' | 'display'];\n }\n }\n this.oldProps.push(old);\n }\n }\n\n restoreCssFromHiddenInit() {\n // finish handle display:none on container or container parents\n // - put values back the way they were\n let i = 0;\n for (const el of this._hiddenParents) {\n const old = this.oldProps[i++];\n for (const name in this.cssShow) {\n if (this.cssShow) {\n el.style[name as CSSStyleDeclarationWritable] = (old as any)[name];\n }\n }\n }\n }\n\n protected hasFrozenColumns() {\n return this._options.frozenColumn! > -1;\n }\n\n /** Register an external Plugin */\n registerPlugin(plugin: T) {\n this.plugins.unshift(plugin);\n plugin.init(this as unknown as SlickGridModel);\n }\n\n /** Unregister (destroy) an external Plugin */\n unregisterPlugin(plugin: SlickPlugin) {\n for (let i = this.plugins.length; i >= 0; i--) {\n if (this.plugins[i] === plugin) {\n this.plugins[i]?.destroy();\n this.plugins.splice(i, 1);\n break;\n }\n }\n }\n\n /** Get a Plugin (addon) by its name */\n getPluginByName

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