diff --git a/CHANGELOG.md b/CHANGELOG.md index 51313ba1..88c601ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [5.12.0](https://github.com/6pac/SlickGrid/compare/5.11.0...5.12.0) (2024-08-23) + +### Bug Fixes + +* increase virtual scroll render throttling to 10ms ([64bf6ff](https://github.com/6pac/SlickGrid/commit/64bf6ff1c526da3686559092cfe4292db7b6ddf9)) + +### Features + +* add `params.editorOptions` to change Flatpickr Editor date format ([#1048](https://github.com/6pac/SlickGrid/issues/1048)) ([8b46763](https://github.com/6pac/SlickGrid/commit/8b46763ac4aeb38a0098c38cad0b078852b3b399)) + +### Performance Improvements + +* add new `rowTopOffsetRenderType` grid option to use "transform" ([#1050](https://github.com/6pac/SlickGrid/issues/1050)) ([7b7ff83](https://github.com/6pac/SlickGrid/commit/7b7ff831fdb7984633e77d832cc33ceaea3e4253)) +* decrease virtual scroll render throttling to 5ms ([#1049](https://github.com/6pac/SlickGrid/issues/1049)) ([b0e7706](https://github.com/6pac/SlickGrid/commit/b0e7706ee4b011f34b382bbb38826ee711b5889f)) + # [5.11.0](https://github.com/6pac/SlickGrid/compare/5.10.1...5.11.0) (2024-07-27) ### Bug Fixes diff --git a/dist/browser/slick.compositeeditor.js.map b/dist/browser/slick.compositeeditor.js.map index 653d8e05..bd1726dd 100644 --- a/dist/browser/slick.compositeeditor.js.map +++ b/dist/browser/slick.compositeeditor.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.compositeeditor.ts"], - "sourcesContent": ["import type { Column, CompositeEditorOption, Editor, EditorArguments, HtmlElementPosition } from './models/index';\r\nimport { Utils as Utils_ } from './slick.core';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\n\r\n/**\r\n * A composite SlickGrid editor factory.\r\n * Generates an editor that is composed of multiple editors for given columns.\r\n * Individual editors are provided given containers instead of the original cell.\r\n * Validation will be performed on all editors individually and the results will be aggregated into one\r\n * validation result.\r\n *\r\n *\r\n * The returned editor will have its prototype set to CompositeEditor, so you can use the \"instanceof\" check.\r\n *\r\n * NOTE: This doesn't work for detached editors since they will be created and positioned relative to the\r\n * active cell and not the provided container.\r\n *\r\n * @namespace Slick\r\n * @class CompositeEditor\r\n * @constructor\r\n * @param columns {Array} Column definitions from which editors will be pulled.\r\n * @param containers {Array} Container HTMLElements in which editors will be placed.\r\n * @param options {Object} Options hash:\r\n * validationFailedMsg - A generic failed validation message set on the aggregated validation resuls.\r\n * validationMsgPrefix - Add an optional prefix to each validation message (only the ones shown in the modal form, not the ones in the \"errors\")\r\n * modalType - Defaults to \"edit\", modal type can 1 of these 3: (create, edit, mass, mass-selection)\r\n * hide - A function to be called when the grid asks the editor to hide itself.\r\n * show - A function to be called when the grid asks the editor to show itself.\r\n * position - A function to be called when the grid asks the editor to reposition itself.\r\n * destroy - A function to be called when the editor is destroyed.\r\n */\r\nexport function SlickCompositeEditor(columns: Column[], containers: Array, options: CompositeEditorOption) {\r\n const defaultOptions = {\r\n modalType: 'edit', // available type (create, edit, mass)\r\n validationFailedMsg: 'Some of the fields have failed validation',\r\n validationMsgPrefix: null,\r\n show: null,\r\n hide: null,\r\n position: null,\r\n destroy: null,\r\n formValues: {},\r\n editors: {}\r\n };\r\n\r\n const noop = function () { };\r\n\r\n let firstInvalidEditor: Editor | null = null;\r\n\r\n options = Slick.Utils.extend({}, defaultOptions, options);\r\n\r\n function getContainerBox(i: number) {\r\n const c = containers[i];\r\n const offset = Slick.Utils.offset(c);\r\n const w = Slick.Utils.width(c);\r\n const h = Slick.Utils.height(c);\r\n\r\n return {\r\n top: (offset?.top ?? 0),\r\n left: (offset?.left ?? 0),\r\n bottom: (offset?.top ?? 0) + (h || 0),\r\n right: (offset?.left ?? 0) + (w || 0),\r\n width: w,\r\n height: h,\r\n visible: true\r\n };\r\n }\r\n\r\n function editor(args: any[]) {\r\n // @ts-ignore\r\n const context: any = this;\r\n let editors: Array = [];\r\n\r\n function init() {\r\n let newArgs: any = {};\r\n let idx = 0;\r\n while (idx < columns.length) {\r\n if (columns[idx].editor) {\r\n const column = columns[idx];\r\n newArgs = Slick.Utils.extend(false, {}, args);\r\n newArgs.container = containers[idx];\r\n newArgs.column = column;\r\n newArgs.position = getContainerBox(idx);\r\n newArgs.commitChanges = noop;\r\n newArgs.cancelChanges = noop;\r\n newArgs.compositeEditorOptions = options;\r\n newArgs.formValues = {};\r\n\r\n const currentEditor = new (column.editor as any)(newArgs) as Editor & { args: EditorArguments };\r\n options.editors[column.id] = currentEditor; // add every Editor instance refs\r\n editors.push(currentEditor);\r\n }\r\n idx++;\r\n }\r\n\r\n // focus on first input\r\n setTimeout(function () {\r\n if (Array.isArray(editors) && editors.length > 0 && typeof editors[0].focus === 'function') {\r\n editors[0].focus();\r\n }\r\n }, 0);\r\n }\r\n\r\n context.destroy = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx].destroy();\r\n idx++;\r\n }\r\n\r\n options.destroy?.();\r\n editors = [];\r\n };\r\n\r\n\r\n context.focus = () => {\r\n // if validation has failed, set the focus to the first invalid editor\r\n (firstInvalidEditor || editors[0]).focus();\r\n };\r\n\r\n context.isValueChanged = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n if (editors[idx].isValueChanged()) {\r\n return true;\r\n }\r\n idx++;\r\n }\r\n return false;\r\n };\r\n\r\n context.serializeValue = () => {\r\n const serializedValue: any[] = [];\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n serializedValue[idx] = editors[idx].serializeValue();\r\n idx++;\r\n }\r\n return serializedValue;\r\n };\r\n\r\n context.applyValue = (item: any, state: any) => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx].applyValue(item, state[idx]);\r\n idx++;\r\n }\r\n };\r\n\r\n context.loadValue = (item: any) => {\r\n let idx = 0;\r\n\r\n while (idx < editors.length) {\r\n editors[idx].loadValue(item);\r\n idx++;\r\n }\r\n };\r\n\r\n context.validate = (target: HTMLElement | null) => {\r\n let validationResults;\r\n const errors: any[] = [];\r\n let targetElm = target ? target : null;\r\n\r\n firstInvalidEditor = null;\r\n\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n const columnDef = editors[idx].args?.column ?? {};\r\n if (columnDef) {\r\n let validationElm = document.querySelector(`.item-details-validation.editor-${columnDef.id}`);\r\n let labelElm = document.querySelector(`.item-details-label.editor-${columnDef.id}`);\r\n let editorElm = document.querySelector(`[data-editorid=${columnDef.id}]`);\r\n const validationMsgPrefix = options?.validationMsgPrefix || '';\r\n\r\n if (!targetElm || Slick.Utils.contains(editorElm as HTMLElement, targetElm)) {\r\n validationResults = editors[idx].validate();\r\n\r\n if (!validationResults.valid) {\r\n firstInvalidEditor = editors[idx];\r\n errors.push({\r\n index: idx,\r\n editor: editors[idx],\r\n container: containers[idx],\r\n msg: validationResults.msg\r\n });\r\n\r\n if (validationElm) {\r\n validationElm.textContent = validationMsgPrefix + validationResults.msg;\r\n labelElm?.classList.add('invalid');\r\n editorElm?.classList.add('invalid');\r\n }\r\n } else if (validationElm) {\r\n validationElm.textContent = '';\r\n editorElm?.classList.remove('invalid');\r\n labelElm?.classList.remove('invalid');\r\n }\r\n }\r\n validationElm = null;\r\n labelElm = null;\r\n editorElm = null;\r\n }\r\n idx++;\r\n }\r\n targetElm = null;\r\n\r\n if (errors.length) {\r\n return {\r\n valid: false,\r\n msg: options.validationFailedMsg,\r\n errors\r\n };\r\n } else {\r\n return {\r\n valid: true,\r\n msg: ''\r\n };\r\n }\r\n };\r\n\r\n context.hide = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx]?.hide?.();\r\n idx++;\r\n }\r\n options?.hide?.();\r\n };\r\n\r\n context.show = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx]?.show?.();\r\n idx++;\r\n }\r\n options?.show?.();\r\n };\r\n\r\n context.position = (box: HtmlElementPosition) => {\r\n options?.position?.(box);\r\n };\r\n\r\n init();\r\n }\r\n\r\n // so we can do \"editor instanceof Slick.CompositeEditor\r\n // @ts-ignore\r\n editor.prototype = this;\r\n return editor;\r\n}\r\n\r\n// extend Slick namespace on window object when building as iife\r\nif (IIFE_ONLY && window.Slick) {\r\n Utils.extend(Slick, {\r\n CompositeEditor: SlickCompositeEditor\r\n });\r\n}\r\n"], - "mappings": "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", + "sourcesContent": ["import type { Column, CompositeEditorOption, Editor, EditorArguments, HtmlElementPosition } from './models/index';\r\nimport { Utils as Utils_ } from './slick.core';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\n\r\n/**\r\n * A composite SlickGrid editor factory.\r\n * Generates an editor that is composed of multiple editors for given columns.\r\n * Individual editors are provided given containers instead of the original cell.\r\n * Validation will be performed on all editors individually and the results will be aggregated into one\r\n * validation result.\r\n *\r\n *\r\n * The returned editor will have its prototype set to CompositeEditor, so you can use the \"instanceof\" check.\r\n *\r\n * NOTE: This doesn't work for detached editors since they will be created and positioned relative to the\r\n * active cell and not the provided container.\r\n *\r\n * @namespace Slick\r\n * @class CompositeEditor\r\n * @constructor\r\n * @param columns {Array} Column definitions from which editors will be pulled.\r\n * @param containers {Array} Container HTMLElements in which editors will be placed.\r\n * @param options {Object} Options hash:\r\n * validationFailedMsg - A generic failed validation message set on the aggregated validation resuls.\r\n * validationMsgPrefix - Add an optional prefix to each validation message (only the ones shown in the modal form, not the ones in the \"errors\")\r\n * modalType - Defaults to \"edit\", modal type can 1 of these 3: (create, edit, mass, mass-selection)\r\n * hide - A function to be called when the grid asks the editor to hide itself.\r\n * show - A function to be called when the grid asks the editor to show itself.\r\n * position - A function to be called when the grid asks the editor to reposition itself.\r\n * destroy - A function to be called when the editor is destroyed.\r\n */\r\nexport function SlickCompositeEditor(columns: Column[], containers: Array, options: CompositeEditorOption) {\r\n const defaultOptions = {\r\n modalType: 'edit', // available type (create, edit, mass)\r\n validationFailedMsg: 'Some of the fields have failed validation',\r\n validationMsgPrefix: null,\r\n show: null,\r\n hide: null,\r\n position: null,\r\n destroy: null,\r\n formValues: {},\r\n editors: {}\r\n };\r\n\r\n const noop = function () { };\r\n\r\n let firstInvalidEditor: Editor | null = null;\r\n\r\n options = Slick.Utils.extend({}, defaultOptions, options);\r\n\r\n function getContainerBox(i: number) {\r\n const c = containers[i];\r\n const offset = Slick.Utils.offset(c);\r\n const w = Slick.Utils.width(c);\r\n const h = Slick.Utils.height(c);\r\n\r\n return {\r\n top: (offset?.top ?? 0),\r\n left: (offset?.left ?? 0),\r\n bottom: (offset?.top ?? 0) + (h || 0),\r\n right: (offset?.left ?? 0) + (w || 0),\r\n width: w,\r\n height: h,\r\n visible: true\r\n };\r\n }\r\n\r\n function editor(args: any[]) {\r\n // @ts-ignore\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const context: any = this;\r\n let editors: Array = [];\r\n\r\n function init() {\r\n let newArgs: any = {};\r\n let idx = 0;\r\n while (idx < columns.length) {\r\n if (columns[idx].editor) {\r\n const column = columns[idx];\r\n newArgs = Slick.Utils.extend(false, {}, args);\r\n newArgs.container = containers[idx];\r\n newArgs.column = column;\r\n newArgs.position = getContainerBox(idx);\r\n newArgs.commitChanges = noop;\r\n newArgs.cancelChanges = noop;\r\n newArgs.compositeEditorOptions = options;\r\n newArgs.formValues = {};\r\n\r\n const currentEditor = new (column.editor as any)(newArgs) as Editor & { args: EditorArguments };\r\n options.editors[column.id] = currentEditor; // add every Editor instance refs\r\n editors.push(currentEditor);\r\n }\r\n idx++;\r\n }\r\n\r\n // focus on first input\r\n setTimeout(function () {\r\n if (Array.isArray(editors) && editors.length > 0 && typeof editors[0].focus === 'function') {\r\n editors[0].focus();\r\n }\r\n }, 0);\r\n }\r\n\r\n context.destroy = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx].destroy();\r\n idx++;\r\n }\r\n\r\n options.destroy?.();\r\n editors = [];\r\n };\r\n\r\n\r\n context.focus = () => {\r\n // if validation has failed, set the focus to the first invalid editor\r\n (firstInvalidEditor || editors[0]).focus();\r\n };\r\n\r\n context.isValueChanged = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n if (editors[idx].isValueChanged()) {\r\n return true;\r\n }\r\n idx++;\r\n }\r\n return false;\r\n };\r\n\r\n context.serializeValue = () => {\r\n const serializedValue: any[] = [];\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n serializedValue[idx] = editors[idx].serializeValue();\r\n idx++;\r\n }\r\n return serializedValue;\r\n };\r\n\r\n context.applyValue = (item: any, state: any) => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx].applyValue(item, state[idx]);\r\n idx++;\r\n }\r\n };\r\n\r\n context.loadValue = (item: any) => {\r\n let idx = 0;\r\n\r\n while (idx < editors.length) {\r\n editors[idx].loadValue(item);\r\n idx++;\r\n }\r\n };\r\n\r\n context.validate = (target: HTMLElement | null) => {\r\n let validationResults;\r\n const errors: any[] = [];\r\n let targetElm = target ? target : null;\r\n\r\n firstInvalidEditor = null;\r\n\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n const columnDef = editors[idx].args?.column ?? {};\r\n if (columnDef) {\r\n let validationElm = document.querySelector(`.item-details-validation.editor-${columnDef.id}`);\r\n let labelElm = document.querySelector(`.item-details-label.editor-${columnDef.id}`);\r\n let editorElm = document.querySelector(`[data-editorid=${columnDef.id}]`);\r\n const validationMsgPrefix = options?.validationMsgPrefix || '';\r\n\r\n if (!targetElm || Slick.Utils.contains(editorElm as HTMLElement, targetElm)) {\r\n validationResults = editors[idx].validate();\r\n\r\n if (!validationResults.valid) {\r\n firstInvalidEditor = editors[idx];\r\n errors.push({\r\n index: idx,\r\n editor: editors[idx],\r\n container: containers[idx],\r\n msg: validationResults.msg\r\n });\r\n\r\n if (validationElm) {\r\n validationElm.textContent = validationMsgPrefix + validationResults.msg;\r\n labelElm?.classList.add('invalid');\r\n editorElm?.classList.add('invalid');\r\n }\r\n } else if (validationElm) {\r\n validationElm.textContent = '';\r\n editorElm?.classList.remove('invalid');\r\n labelElm?.classList.remove('invalid');\r\n }\r\n }\r\n validationElm = null;\r\n labelElm = null;\r\n editorElm = null;\r\n }\r\n idx++;\r\n }\r\n targetElm = null;\r\n\r\n if (errors.length) {\r\n return {\r\n valid: false,\r\n msg: options.validationFailedMsg,\r\n errors\r\n };\r\n } else {\r\n return {\r\n valid: true,\r\n msg: ''\r\n };\r\n }\r\n };\r\n\r\n context.hide = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx]?.hide?.();\r\n idx++;\r\n }\r\n options?.hide?.();\r\n };\r\n\r\n context.show = () => {\r\n let idx = 0;\r\n while (idx < editors.length) {\r\n editors[idx]?.show?.();\r\n idx++;\r\n }\r\n options?.show?.();\r\n };\r\n\r\n context.position = (box: HtmlElementPosition) => {\r\n options?.position?.(box);\r\n };\r\n\r\n init();\r\n }\r\n\r\n // so we can do \"editor instanceof Slick.CompositeEditor\r\n // @ts-ignore\r\n editor.prototype = this;\r\n return editor;\r\n}\r\n\r\n// extend Slick namespace on window object when building as iife\r\nif (IIFE_ONLY && window.Slick) {\r\n Utils.extend(Slick, {\r\n CompositeEditor: SlickCompositeEditor\r\n });\r\n}\r\n"], + "mappings": "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", "names": [] } diff --git a/dist/browser/slick.core.js.map b/dist/browser/slick.core.js.map index 1adb37c6..c01d7e71 100644 --- a/dist/browser/slick.core.js.map +++ b/dist/browser/slick.core.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.core.ts"], - "sourcesContent": ["/**\r\n * Contains core SlickGrid classes.\r\n * @module Core\r\n * @namespace Slick\r\n */\r\n\r\nimport type {\r\n AnyFunction,\r\n CSSStyleDeclarationWritable,\r\n EditController,\r\n ElementEventListener,\r\n Handler,\r\n InferDOMType,\r\n MergeTypes\r\n} from './models/index';\r\n\r\nexport interface BasePubSub {\r\n publish(_eventName: string | any, _data?: ArgType): any;\r\n subscribe(_eventName: string | Function, _callback: (data: ArgType) => void): any;\r\n}\r\n\r\n/**\r\n * An event object for passing data to event handlers and letting them control propagation.\r\n *

This is pretty much identical to how W3C and jQuery implement events.

\r\n * @class EventData\r\n * @constructor\r\n */\r\nexport class SlickEventData {\r\n protected _isPropagationStopped = false;\r\n protected _isImmediatePropagationStopped = false;\r\n protected _isDefaultPrevented = false;\r\n protected returnValues: string[] = [];\r\n protected returnValue: any = undefined;\r\n protected _eventTarget?: EventTarget | null;\r\n protected nativeEvent?: Event | null;\r\n protected arguments_?: ArgType;\r\n\r\n // public props that can be optionally pulled from the provided Event in constructor\r\n // they are all optional props because it really depends on the type of Event provided (KeyboardEvent, MouseEvent, ...)\r\n readonly altKey?: boolean;\r\n readonly ctrlKey?: boolean;\r\n readonly metaKey?: boolean;\r\n readonly shiftKey?: boolean;\r\n readonly key?: string;\r\n readonly keyCode?: number;\r\n readonly clientX?: number;\r\n readonly clientY?: number;\r\n readonly offsetX?: number;\r\n readonly offsetY?: number;\r\n readonly pageX?: number;\r\n readonly pageY?: number;\r\n readonly bubbles?: boolean;\r\n readonly target?: HTMLElement;\r\n readonly type?: string;\r\n readonly which?: number;\r\n readonly x?: number;\r\n readonly y?: number;\r\n\r\n get defaultPrevented() {\r\n return this._isDefaultPrevented;\r\n }\r\n\r\n constructor(protected event?: Event | null, protected args?: ArgType) {\r\n this.nativeEvent = event;\r\n this.arguments_ = args;\r\n\r\n // when we already have an event, we want to keep some of the event properties\r\n // looping through some props is the only way to keep and sync these properties to the returned EventData\r\n if (event) {\r\n [\r\n 'altKey', 'ctrlKey', 'metaKey', 'shiftKey', 'key', 'keyCode',\r\n 'clientX', 'clientY', 'offsetX', 'offsetY', 'pageX', 'pageY',\r\n 'bubbles', 'target', 'type', 'which', 'x', 'y'\r\n ].forEach(key => (this as any)[key] = event[key as keyof Event]);\r\n }\r\n this._eventTarget = this.nativeEvent ? this.nativeEvent.target : undefined;\r\n }\r\n\r\n /**\r\n * Stops event from propagating up the DOM tree.\r\n * @method stopPropagation\r\n */\r\n stopPropagation() {\r\n this._isPropagationStopped = true;\r\n this.nativeEvent?.stopPropagation();\r\n }\r\n\r\n /**\r\n * Returns whether stopPropagation was called on this event object.\r\n * @method isPropagationStopped\r\n * @return {Boolean}\r\n */\r\n isPropagationStopped() {\r\n return this._isPropagationStopped;\r\n }\r\n\r\n /**\r\n * Prevents the rest of the handlers from being executed.\r\n * @method stopImmediatePropagation\r\n */\r\n stopImmediatePropagation() {\r\n this._isImmediatePropagationStopped = true;\r\n if (this.nativeEvent) {\r\n this.nativeEvent.stopImmediatePropagation();\r\n }\r\n };\r\n\r\n /**\r\n * Returns whether stopImmediatePropagation was called on this event object.\\\r\n * @method isImmediatePropagationStopped\r\n * @return {Boolean}\r\n */\r\n isImmediatePropagationStopped() {\r\n return this._isImmediatePropagationStopped;\r\n };\r\n\r\n getNativeEvent() {\r\n return this.nativeEvent as E;\r\n }\r\n\r\n preventDefault() {\r\n if (this.nativeEvent) {\r\n this.nativeEvent.preventDefault();\r\n }\r\n this._isDefaultPrevented = true;\r\n }\r\n\r\n isDefaultPrevented() {\r\n if (this.nativeEvent) {\r\n return this.nativeEvent.defaultPrevented;\r\n }\r\n return this._isDefaultPrevented;\r\n }\r\n\r\n addReturnValue(value: any) {\r\n this.returnValues.push(value);\r\n if (this.returnValue === undefined && value !== undefined) {\r\n this.returnValue = value;\r\n }\r\n }\r\n\r\n getReturnValue() {\r\n return this.returnValue;\r\n }\r\n\r\n getArguments() {\r\n return this.arguments_;\r\n }\r\n}\r\n\r\n/**\r\n * A simple publisher-subscriber implementation.\r\n * @class Event\r\n * @constructor\r\n */\r\nexport class SlickEvent {\r\n protected _handlers: Handler[] = [];\r\n protected _pubSubService?: BasePubSub;\r\n\r\n get subscriberCount() {\r\n return this._handlers.length;\r\n }\r\n\r\n /**\r\n * Constructor\r\n * @param {String} [eventName] - event name that could be used for dispatching CustomEvent (when enabled)\r\n * @param {BasePubSub} [pubSubService] - event name that could be used for dispatching CustomEvent (when enabled)\r\n */\r\n constructor(protected readonly eventName?: string, protected readonly pubSub?: BasePubSub) {\r\n this._pubSubService = pubSub;\r\n }\r\n\r\n /**\r\n * Adds an event handler to be called when the event is fired.\r\n *

Event handler will receive two arguments - an EventData and the data\r\n * object the event was fired with.

\r\n * @method subscribe\r\n * @param {Function} fn - Event handler.\r\n */\r\n subscribe(fn: Handler) {\r\n this._handlers.push(fn);\r\n }\r\n\r\n /**\r\n * Removes an event handler added with subscribe(fn).\r\n * @method unsubscribe\r\n * @param {Function} [fn] - Event handler to be removed.\r\n */\r\n unsubscribe(fn?: Handler) {\r\n for (let i = this._handlers.length - 1; i >= 0; i--) {\r\n if (this._handlers[i] === fn) {\r\n this._handlers.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Fires an event notifying all subscribers.\r\n * @method notify\r\n * @param {Object} args Additional data object to be passed to all handlers.\r\n * @param {EventData} [event] - An EventData object to be passed to all handlers.\r\n * For DOM events, an existing W3C event object can be passed in.\r\n * @param {Object} [scope] - The scope (\"this\") within which the handler will be executed.\r\n * If not specified, the scope will be set to the Event instance.\r\n */\r\n notify(args: ArgType, evt?: SlickEventData | Event | MergeTypes, Event> | null, scope?: any) {\r\n const sed: SlickEventData = evt instanceof SlickEventData\r\n ? evt\r\n : new SlickEventData(evt, args);\r\n scope = scope || this;\r\n\r\n for (let i = 0; i < this._handlers.length && !(sed.isPropagationStopped() || sed.isImmediatePropagationStopped()); i++) {\r\n const returnValue = this._handlers[i].call(scope, sed, args);\r\n sed.addReturnValue(returnValue);\r\n }\r\n\r\n // user can optionally add a global PubSub Service which makes it easy to publish/subscribe to events\r\n if (typeof this._pubSubService?.publish === 'function' && this.eventName) {\r\n const ret = this._pubSubService.publish<{ args: ArgType; eventData?: SlickEventData; nativeEvent?: Event; }>(this.eventName, { args, eventData: sed });\r\n sed.addReturnValue(ret);\r\n }\r\n return sed;\r\n }\r\n\r\n setPubSubService(pubSub: BasePubSub) {\r\n this._pubSubService = pubSub;\r\n }\r\n}\r\n\r\nexport class SlickEventHandler {\r\n protected handlers: Array<{ event: SlickEvent; handler: Handler; }> = [];\r\n\r\n subscribe(event: SlickEvent, handler: Handler) {\r\n this.handlers.push({ event, handler });\r\n event.subscribe(handler);\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n\r\n unsubscribe(event: SlickEvent, handler: Handler) {\r\n let i = this.handlers.length;\r\n while (i--) {\r\n if (this.handlers[i].event === event &&\r\n this.handlers[i].handler === handler) {\r\n this.handlers.splice(i, 1);\r\n event.unsubscribe(handler);\r\n return;\r\n }\r\n }\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n\r\n unsubscribeAll() {\r\n let i = this.handlers.length;\r\n while (i--) {\r\n this.handlers[i].event.unsubscribe(this.handlers[i].handler);\r\n }\r\n this.handlers = [];\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n}\r\n\r\n/**\r\n * A structure containing a range of cells.\r\n * @class Range\r\n * @constructor\r\n * @param fromRow {Integer} Starting row.\r\n * @param fromCell {Integer} Starting cell.\r\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\r\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\r\n */\r\nexport class SlickRange {\r\n fromRow: number;\r\n fromCell: number;\r\n toCell: number;\r\n toRow: number;\r\n\r\n constructor(fromRow: number, fromCell: number, toRow?: number, toCell?: number) {\r\n if (toRow === undefined && toCell === undefined) {\r\n toRow = fromRow;\r\n toCell = fromCell;\r\n }\r\n\r\n /**\r\n * @property fromRow\r\n * @type {Integer}\r\n */\r\n this.fromRow = Math.min(fromRow, toRow as number);\r\n\r\n /**\r\n * @property fromCell\r\n * @type {Integer}\r\n */\r\n this.fromCell = Math.min(fromCell, toCell as number);\r\n\r\n /**\r\n * @property toCell\r\n * @type {Integer}\r\n */\r\n this.toCell = Math.max(fromCell, toCell as number);\r\n\r\n /**\r\n * @property toRow\r\n * @type {Integer}\r\n */\r\n this.toRow = Math.max(fromRow, toRow as number);\r\n }\r\n\r\n\r\n /**\r\n * Returns whether a range represents a single row.\r\n * @method isSingleRow\r\n * @return {Boolean}\r\n */\r\n isSingleRow() {\r\n return this.fromRow === this.toRow;\r\n }\r\n\r\n /**\r\n * Returns whether a range represents a single cell.\r\n * @method isSingleCell\r\n * @return {Boolean}\r\n */\r\n isSingleCell() {\r\n return this.fromRow === this.toRow && this.fromCell === this.toCell;\r\n }\r\n\r\n /**\r\n * Returns whether a range contains a given cell.\r\n * @method contains\r\n * @param row {Integer}\r\n * @param cell {Integer}\r\n * @return {Boolean}\r\n */\r\n contains(row: number, cell: number) {\r\n return row >= this.fromRow && row <= this.toRow &&\r\n cell >= this.fromCell && cell <= this.toCell;\r\n }\r\n\r\n /**\r\n * Returns a readable representation of a range.\r\n * @method toString\r\n * @return {String}\r\n */\r\n toString() {\r\n if (this.isSingleCell()) {\r\n return `(${this.fromRow}:${this.fromCell})`;\r\n }\r\n else {\r\n return `(${this.fromRow}:${this.fromCell} - ${this.toRow}:${this.toCell})`;\r\n }\r\n };\r\n}\r\n\r\n\r\n/**\r\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\r\n * @class NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickNonDataItem {\r\n __nonDataRow = true;\r\n}\r\n\r\n\r\n/**\r\n * Information about a group of rows.\r\n * @class Group\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickGroup extends SlickNonDataItem {\r\n __group = true;\r\n\r\n /**\r\n * Grouping level, starting with 0.\r\n * @property level\r\n * @type {Number}\r\n */\r\n level = 0;\r\n\r\n /**\r\n * Number of rows in the group.\r\n * @property count\r\n * @type {Integer}\r\n */\r\n count = 0;\r\n\r\n /**\r\n * Grouping value.\r\n * @property value\r\n * @type {Object}\r\n */\r\n value = null;\r\n\r\n /**\r\n * Formatted display value of the group.\r\n * @property title\r\n * @type {String}\r\n */\r\n title: string | null = null;\r\n\r\n /**\r\n * Whether a group is collapsed.\r\n * @property collapsed\r\n * @type {Boolean}\r\n */\r\n collapsed: boolean | number = false;\r\n\r\n /**\r\n * Whether a group selection checkbox is checked.\r\n * @property selectChecked\r\n * @type {Boolean}\r\n */\r\n selectChecked = false;\r\n\r\n /**\r\n * GroupTotals, if any.\r\n * @property totals\r\n * @type {GroupTotals}\r\n */\r\n totals: SlickGroupTotals = null as any;\r\n\r\n /**\r\n * Rows that are part of the group.\r\n * @property rows\r\n * @type {Array}\r\n */\r\n rows: number[] = [];\r\n\r\n /**\r\n * Sub-groups that are part of the group.\r\n * @property groups\r\n * @type {Array}\r\n */\r\n groups: any[] = null as any;\r\n\r\n /**\r\n * A unique key used to identify the group. This key can be used in calls to DataView\r\n * collapseGroup() or expandGroup().\r\n * @property groupingKey\r\n * @type {Object}\r\n */\r\n groupingKey: any = null;\r\n\r\n constructor() {\r\n super();\r\n }\r\n /**\r\n * Compares two Group instances.\r\n * @method equals\r\n * @return {Boolean}\r\n * @param group {Group} Group instance to compare to.\r\n */\r\n equals(group: SlickGroup): boolean {\r\n return this.value === group.value &&\r\n this.count === group.count &&\r\n this.collapsed === group.collapsed &&\r\n this.title === group.title;\r\n };\r\n}\r\n\r\n/**\r\n * Information about group totals.\r\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\r\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\r\n * formatters during the display.\r\n * @class GroupTotals\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickGroupTotals extends SlickNonDataItem {\r\n __groupTotals = true;\r\n\r\n /**\r\n * Parent Group.\r\n * @param group\r\n * @type {Group}\r\n */\r\n group: SlickGroup = null as any;\r\n\r\n /**\r\n * Whether the totals have been fully initialized / calculated.\r\n * Will be set to false for lazy-calculated group totals.\r\n * @param initialized\r\n * @type {Boolean}\r\n */\r\n initialized = false;\r\n\r\n constructor() {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * A locking helper to track the active edit controller and ensure that only a single controller\r\n * can be active at a time. This prevents a whole class of state and validation synchronization\r\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\r\n * and attempt a commit or cancel before proceeding.\r\n * @class EditorLock\r\n * @constructor\r\n */\r\nexport class SlickEditorLock {\r\n activeEditController: any = null;\r\n\r\n /**\r\n * Returns true if a specified edit controller is active (has the edit lock).\r\n * If the parameter is not specified, returns true if any edit controller is active.\r\n * @method isActive\r\n * @param editController {EditController}\r\n * @return {Boolean}\r\n */\r\n isActive(editController?: EditController): boolean {\r\n return (editController ? this.activeEditController === editController : this.activeEditController !== null);\r\n };\r\n\r\n /**\r\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\r\n * If another edit controller is already active, and exception will be throw new Error(.\r\n * @method activate\r\n * @param editController {EditController} edit controller acquiring the lock\r\n */\r\n activate(editController: EditController) {\r\n if (editController === this.activeEditController) { // already activated?\r\n return;\r\n }\r\n if (this.activeEditController !== null) {\r\n throw new Error(`Slick.EditorLock.activate: an editController is still active, can't activate another editController`);\r\n }\r\n if (!editController.commitCurrentEdit) {\r\n throw new Error('Slick.EditorLock.activate: editController must implement .commitCurrentEdit()');\r\n }\r\n if (!editController.cancelCurrentEdit) {\r\n throw new Error('Slick.EditorLock.activate: editController must implement .cancelCurrentEdit()');\r\n }\r\n this.activeEditController = editController;\r\n };\r\n\r\n /**\r\n * Unsets the specified edit controller as the active edit controller (release edit lock).\r\n * If the specified edit controller is not the active one, an exception will be throw new Error(.\r\n * @method deactivate\r\n * @param editController {EditController} edit controller releasing the lock\r\n */\r\n deactivate(editController: EditController) {\r\n if (!this.activeEditController) {\r\n return;\r\n }\r\n if (this.activeEditController !== editController) {\r\n throw new Error('Slick.EditorLock.deactivate: specified editController is not the currently active one');\r\n }\r\n this.activeEditController = null;\r\n };\r\n\r\n /**\r\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\r\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\r\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\r\n * and false otherwise. If no edit controller is active, returns true.\r\n * @method commitCurrentEdit\r\n * @return {Boolean}\r\n */\r\n commitCurrentEdit(): boolean {\r\n return (this.activeEditController ? this.activeEditController.commitCurrentEdit() : true);\r\n };\r\n\r\n /**\r\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\r\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\r\n * active, returns true.\r\n * @method cancelCurrentEdit\r\n * @return {Boolean}\r\n */\r\n cancelCurrentEdit(): boolean {\r\n return (this.activeEditController ? this.activeEditController.cancelCurrentEdit() : true);\r\n };\r\n}\r\n\r\nfunction regexSanitizer(dirtyHtml: string) {\r\n return dirtyHtml.replace(/(\\b)(on[a-z]+)(\\s*)=|javascript:([^>]*)[^>]*|(<\\s*)(\\/*)script([<>]*).*(<\\s*)(\\/*)script(>*)|(<)(\\/*)(script|script defer)(.*)(>|>\">)/gi, '');\r\n}\r\n\r\n/**\r\n * A simple binding event service to keep track of all JavaScript events with callback listeners,\r\n * it allows us to unbind event(s) and their listener(s) by calling a simple unbind method call.\r\n * Unbinding is a necessary step to make sure that all event listeners are removed to avoid memory leaks when destroing the grid\r\n */\r\nexport class BindingEventService {\r\n protected _boundedEvents: ElementEventListener[] = [];\r\n\r\n getBoundedEvents() {\r\n return this._boundedEvents;\r\n }\r\n\r\n destroy() {\r\n this.unbindAll();\r\n }\r\n\r\n /** Bind an event listener to any element */\r\n bind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions, groupName = '') {\r\n if (element) {\r\n element.addEventListener(eventName, listener, options);\r\n this._boundedEvents.push({ element, eventName, listener, groupName });\r\n }\r\n }\r\n\r\n /** Unbind all will remove every every event handlers that were bounded earlier */\r\n unbind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject) {\r\n if (element?.removeEventListener) {\r\n element.removeEventListener(eventName, listener);\r\n }\r\n }\r\n\r\n unbindByEventName(element: Element | Window, eventName: string) {\r\n const boundedEvent = this._boundedEvents.find(e => e.element === element && e.eventName === eventName);\r\n if (boundedEvent) {\r\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\r\n }\r\n }\r\n\r\n /**\r\n * Unbind all event listeners that were bounded, optionally provide a group name to unbind all listeners assigned to that specific group only.\r\n */\r\n unbindAll(groupName?: string | string[]) {\r\n if (groupName) {\r\n const groupNames = Array.isArray(groupName) ? groupName : [groupName];\r\n\r\n // unbind only the bounded event with a specific group\r\n // Note: we need to loop in reverse order to avoid array reindexing (causing index offset) after a splice is called\r\n for (let i = this._boundedEvents.length - 1; i >= 0; --i) {\r\n const boundedEvent = this._boundedEvents[i];\r\n if (groupNames.some(g => g === boundedEvent.groupName)) {\r\n const { element, eventName, listener } = boundedEvent;\r\n this.unbind(element, eventName, listener);\r\n this._boundedEvents.splice(i, 1);\r\n }\r\n }\r\n } else {\r\n // unbind everything\r\n while (this._boundedEvents.length > 0) {\r\n const boundedEvent = this._boundedEvents.pop() as ElementEventListener;\r\n const { element, eventName, listener } = boundedEvent;\r\n this.unbind(element, eventName, listener);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport class Utils {\r\n // jQuery's extend\r\n private static getProto = Object.getPrototypeOf;\r\n private static class2type: any = {};\r\n private static toString = Utils.class2type.toString;\r\n private static hasOwn = Utils.class2type.hasOwnProperty;\r\n private static fnToString = Utils.hasOwn.toString;\r\n private static ObjectFunctionString = Utils.fnToString.call(Object);\r\n public static storage = {\r\n // https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati\r\n _storage: new WeakMap(),\r\n // eslint-disable-next-line object-shorthand\r\n put: function (element: any, key: string, obj: any) {\r\n if (!this._storage.has(element)) {\r\n this._storage.set(element, new Map());\r\n }\r\n this._storage.get(element).set(key, obj);\r\n },\r\n // eslint-disable-next-line object-shorthand\r\n get: function (element: any, key: string) {\r\n const el = this._storage.get(element);\r\n if (el) {\r\n return el.get(key);\r\n }\r\n return null;\r\n },\r\n // eslint-disable-next-line object-shorthand\r\n remove: function (element: any, key: string) {\r\n const ret = this._storage.get(element).delete(key);\r\n if (!(this._storage.get(element).size === 0)) {\r\n this._storage.delete(element);\r\n }\r\n return ret;\r\n }\r\n };\r\n\r\n public static isFunction(obj: any) {\r\n return typeof obj === 'function' && typeof obj.nodeType !== 'number' && typeof obj.item !== 'function';\r\n }\r\n\r\n public static isPlainObject(obj: any) {\r\n if (!obj || Utils.toString.call(obj) !== '[object Object]') {\r\n return false;\r\n }\r\n\r\n const proto = Utils.getProto(obj);\r\n if (!proto) {\r\n return true;\r\n }\r\n const Ctor = Utils.hasOwn.call(proto, 'constructor') && proto.constructor;\r\n return typeof Ctor === 'function' && Utils.fnToString.call(Ctor) === Utils.ObjectFunctionString;\r\n }\r\n\r\n public static calculateAvailableSpace(element: HTMLElement) {\r\n let bottom = 0, top = 0, left = 0, right = 0;\r\n\r\n const windowHeight = window.innerHeight || 0;\r\n const windowWidth = window.innerWidth || 0;\r\n const scrollPosition = Utils.windowScrollPosition();\r\n const pageScrollTop = scrollPosition.top;\r\n const pageScrollLeft = scrollPosition.left;\r\n const elmOffset = Utils.offset(element);\r\n\r\n if (elmOffset) {\r\n const elementOffsetTop = elmOffset.top || 0;\r\n const elementOffsetLeft = elmOffset.left || 0;\r\n top = elementOffsetTop - pageScrollTop;\r\n bottom = windowHeight - (elementOffsetTop - pageScrollTop);\r\n left = elementOffsetLeft - pageScrollLeft;\r\n right = windowWidth - (elementOffsetLeft - pageScrollLeft);\r\n }\r\n\r\n return { top, bottom, left, right };\r\n }\r\n\r\n public static extend(...args: any[]): T {\r\n let options, name, src, copy, copyIsArray, clone,\r\n target = args[0],\r\n i = 1,\r\n deep = false;\r\n const length = args.length;\r\n\r\n if (typeof target === 'boolean') {\r\n deep = target;\r\n target = args[i] || {};\r\n i++;\r\n } else {\r\n target = target || {};\r\n }\r\n if (typeof target !== 'object' && !Utils.isFunction(target)) {\r\n target = {};\r\n }\r\n if (i === length) {\r\n // @ts-ignore\r\n target = this;\r\n i--;\r\n }\r\n for (; i < length; i++) {\r\n if (Utils.isDefined(options = args[i])) {\r\n for (name in options) {\r\n copy = options[name];\r\n if (name === '__proto__' || target === copy) {\r\n continue;\r\n }\r\n if (deep && copy && (Utils.isPlainObject(copy) ||\r\n (copyIsArray = Array.isArray(copy)))) {\r\n src = target[name];\r\n if (copyIsArray && !Array.isArray(src)) {\r\n clone = [];\r\n } else if (!copyIsArray && !Utils.isPlainObject(src)) {\r\n clone = {};\r\n } else {\r\n clone = src;\r\n }\r\n copyIsArray = false;\r\n target[name] = Utils.extend(deep, clone, copy);\r\n } else if (copy !== undefined) {\r\n target[name] = copy;\r\n }\r\n }\r\n }\r\n }\r\n return target as T;\r\n }\r\n\r\n /**\r\n * Create a DOM Element with any optional attributes or properties.\r\n * It will only accept valid DOM element properties that `createElement` would accept.\r\n * For example: `createDomElement('div', { className: 'my-css-class' })`,\r\n * for style or dataset you need to use nested object `{ style: { display: 'none' }}\r\n * The last argument is to optionally append the created element to a parent container element.\r\n * @param {String} tagName - html tag\r\n * @param {Object} options - element properties\r\n * @param {[HTMLElement]} appendToParent - parent element to append to\r\n */\r\n public static createDomElement(\r\n tagName: T,\r\n elementOptions?: null | { [P in K]: InferDOMType },\r\n appendToParent?: Element\r\n ): HTMLElementTagNameMap[T] {\r\n const elm = document.createElement(tagName);\r\n\r\n if (elementOptions) {\r\n Object.keys(elementOptions).forEach((elmOptionKey) => {\r\n if (elmOptionKey === 'innerHTML') {\r\n console.warn(`[SlickGrid] For better CSP (Content Security Policy) support, do not use \"innerHTML\" directly in \"createDomElement('${tagName}', { innerHTML: 'some html'})\"` +\r\n `, it is better as separate assignment: \"const elm = createDomElement('span'); elm.innerHTML = 'some html';\"`);\r\n }\r\n\r\n const elmValue = elementOptions[elmOptionKey as keyof typeof elementOptions];\r\n if (typeof elmValue === 'object') {\r\n Object.assign(elm[elmOptionKey as K] as object, elmValue);\r\n } else {\r\n elm[elmOptionKey as K] = (elementOptions as any)[elmOptionKey as keyof typeof elementOptions];\r\n }\r\n });\r\n }\r\n if (appendToParent?.appendChild) {\r\n appendToParent.appendChild(elm);\r\n }\r\n return elm;\r\n }\r\n\r\n /**\r\n * From any input provided, return the HTML string (when a string is provided, it will be returned \"as is\" but when it's a number it will be converted to string)\r\n * When detecting HTMLElement/DocumentFragment, we can also specify which HTML type to retrieve innerHTML or outerHTML.\r\n * We can get the HTML by looping through all fragment `childNodes`\r\n * @param {DocumentFragment | HTMLElement | string | number} input\r\n * @param {'innerHTML' | 'outerHTML'} [type] - when the input is a DocumentFragment or HTMLElement, which type of HTML do you want to return? 'innerHTML' or 'outerHTML'\r\n * @returns {String}\r\n */\r\n public static getHtmlStringOutput(input: DocumentFragment | HTMLElement | string | number, type: 'innerHTML' | 'outerHTML' = 'innerHTML'): string {\r\n if (input instanceof DocumentFragment) {\r\n // a DocumentFragment doesn't have innerHTML/outerHTML, but we can loop through all children and concatenate them all to an HTML string\r\n return [].map.call(input.childNodes, (x: HTMLElement) => x[type]).join('') || input.textContent || '';\r\n } else if (input instanceof HTMLElement) {\r\n return input[type];\r\n }\r\n return String(input); // reaching this line means it's already a string (or number) so just return it as string\r\n }\r\n\r\n public static emptyElement(element?: T | null): T | undefined | null {\r\n while (element?.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n return element;\r\n }\r\n\r\n /**\r\n * Accepts string containing the class or space-separated list of classes, and\r\n * returns list of individual classes.\r\n * Method properly takes into account extra whitespaces in the `className`\r\n * e.g.: \" class1 class2 \" => will result in `['class1', 'class2']`.\r\n * @param {String} className - space separated list of class names\r\n */\r\n public static classNameToList(className = ''): string[] {\r\n return className.split(' ').filter(cls => cls);\r\n }\r\n\r\n public static innerSize(elm: HTMLElement, type: 'height' | 'width') {\r\n let size = 0;\r\n\r\n if (elm) {\r\n const clientSize = type === 'height' ? 'clientHeight' : 'clientWidth';\r\n const sides = type === 'height' ? ['top', 'bottom'] : ['left', 'right'];\r\n size = elm[clientSize];\r\n for (const side of sides) {\r\n const sideSize = (parseFloat(Utils.getElementProp(elm, `padding-${side}`) || '') || 0);\r\n size -= sideSize;\r\n }\r\n }\r\n return size;\r\n }\r\n\r\n public static isDefined(value: T | undefined | null): value is T {\r\n return value !== undefined && value !== null && value !== '';\r\n }\r\n\r\n public static getElementProp(elm: HTMLElement & { getComputedStyle?: () => CSSStyleDeclaration }, property: string) {\r\n if (elm?.getComputedStyle) {\r\n return window.getComputedStyle(elm, null).getPropertyValue(property);\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the function details (param & body) of a function.\r\n * It supports regular function and also ES6 arrow functions\r\n * @param {Function} fn - function to analyze\r\n * @param {Boolean} [addReturn] - when using ES6 function as single liner, we could add the missing `return ...`\r\n * @returns\r\n */\r\n public static getFunctionDetails(fn: AnyFunction, addReturn = true) {\r\n let isAsyncFn = false;\r\n\r\n const getFunctionBody = (func: AnyFunction) => {\r\n const fnStr = func.toString();\r\n isAsyncFn = fnStr.includes('async ');\r\n\r\n // when fn is one liner arrow fn returning an object in brackets e.g. `() => ({ hello: 'world' })`\r\n if ((fnStr.replaceAll(' ', '').includes('=>({'))) {\r\n const matches = fnStr.match(/(({.*}))/g) || [];\r\n return matches.length >= 1 ? `return ${matches[0]!.trimStart()}` : fnStr;\r\n }\r\n const isOneLinerArrowFn = (!fnStr.includes('{') && fnStr.includes('=>'));\r\n const body = fnStr.substring(\r\n (fnStr.indexOf('{') + 1) || (fnStr.indexOf('=>') + 2),\r\n fnStr.includes('}') ? fnStr.lastIndexOf('}') : fnStr.length\r\n );\r\n if (addReturn && isOneLinerArrowFn && !body.startsWith('return')) {\r\n return 'return ' + body.trimStart(); // add the `return ...` to the body for ES6 arrow fn\r\n }\r\n return body;\r\n };\r\n\r\n const getFunctionParams = (func: AnyFunction): string[] => {\r\n const STRIP_COMMENTS = /(\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/)|(\\s*=[^,)]*(('(?:\\\\'|[^'\\r\\n])*')|(\"(?:\\\\\"|[^\"\\r\\n])*\"))|(\\s*=[^,)]*))/mg;\r\n const ARG_NAMES = /([^\\s,]+)/g;\r\n const fnStr = func.toString().replace(STRIP_COMMENTS, '');\r\n return fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARG_NAMES) ?? [];\r\n };\r\n\r\n return {\r\n params: getFunctionParams(fn),\r\n body: getFunctionBody(fn),\r\n isAsync: isAsyncFn,\r\n };\r\n }\r\n\r\n public static insertAfterElement(referenceNode: HTMLElement, newNode: HTMLElement) {\r\n referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling);\r\n }\r\n\r\n public static isEmptyObject(obj: any) {\r\n if (obj === null || obj === undefined) {\r\n return true;\r\n }\r\n return Object.entries(obj).length === 0;\r\n }\r\n\r\n public static noop() { }\r\n\r\n public static offset(el: HTMLElement | null) {\r\n if (!el || !el.getBoundingClientRect) {\r\n return undefined;\r\n }\r\n const box = el.getBoundingClientRect();\r\n const docElem = document.documentElement;\r\n\r\n return {\r\n top: box.top + window.pageYOffset - docElem.clientTop,\r\n left: box.left + window.pageXOffset - docElem.clientLeft\r\n };\r\n }\r\n\r\n public static windowScrollPosition() {\r\n return {\r\n left: window.pageXOffset || document.documentElement.scrollLeft || 0,\r\n top: window.pageYOffset || document.documentElement.scrollTop || 0,\r\n };\r\n }\r\n\r\n public static width(el: HTMLElement, value?: number | string): number | void {\r\n if (!el || !el.getBoundingClientRect) { return; }\r\n if (value === undefined) {\r\n return el.getBoundingClientRect().width;\r\n }\r\n Utils.setStyleSize(el, 'width', value);\r\n }\r\n\r\n public static height(el: HTMLElement, value?: number | string): number | void {\r\n if (!el) { return; }\r\n if (value === undefined) {\r\n return el.getBoundingClientRect().height;\r\n }\r\n Utils.setStyleSize(el, 'height', value);\r\n }\r\n\r\n public static setStyleSize(el: HTMLElement, style: string, val?: number | string | Function) {\r\n if (typeof val === 'function') {\r\n val = val();\r\n } else if (typeof val === 'string') {\r\n el.style[style as CSSStyleDeclarationWritable] = val;\r\n } else {\r\n el.style[style as CSSStyleDeclarationWritable] = val + 'px';\r\n }\r\n }\r\n\r\n public static contains(parent: HTMLElement, child: HTMLElement) {\r\n if (!parent || !child) {\r\n return false;\r\n }\r\n\r\n const parentList = Utils.parents(child);\r\n return !parentList.every((p) => {\r\n if (parent === p) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n public static isHidden(el: HTMLElement) {\r\n return el.offsetWidth === 0 && el.offsetHeight === 0;\r\n }\r\n\r\n public static parents(el: HTMLElement | ParentNode, selector?: string) {\r\n const parents: Array = [];\r\n const visible = selector === ':visible';\r\n const hidden = selector === ':hidden';\r\n\r\n while ((el = el.parentNode as ParentNode) && el !== document) {\r\n if (!el || !el.parentNode) {\r\n break;\r\n }\r\n if (hidden) {\r\n if (Utils.isHidden(el as HTMLElement)) {\r\n parents.push(el);\r\n }\r\n } else if (visible) {\r\n if (!Utils.isHidden(el as HTMLElement)) {\r\n parents.push(el);\r\n }\r\n } else if (!selector || (el as any).matches(selector)) {\r\n parents.push(el);\r\n }\r\n }\r\n return parents;\r\n }\r\n\r\n public static toFloat(value: string | number) {\r\n const x = parseFloat(value as string);\r\n if (isNaN(x)) {\r\n return 0;\r\n }\r\n return x;\r\n }\r\n\r\n public static show(el: HTMLElement | HTMLElement[], type = '') {\r\n if (Array.isArray(el)) {\r\n el.forEach((e) => e.style.display = type);\r\n } else {\r\n el.style.display = type;\r\n }\r\n }\r\n\r\n public static hide(el: HTMLElement | HTMLElement[]) {\r\n if (Array.isArray(el)) {\r\n el.forEach((e) => e.style.display = 'none');\r\n } else {\r\n el.style.display = 'none';\r\n }\r\n }\r\n\r\n public static slideUp(el: HTMLElement | HTMLElement[], callback: Function) {\r\n return Utils.slideAnimation(el, 'slideUp', callback);\r\n }\r\n\r\n public static slideDown(el: HTMLElement | HTMLElement[], callback: Function) {\r\n return Utils.slideAnimation(el, 'slideDown', callback);\r\n }\r\n\r\n public static slideAnimation(el: HTMLElement | HTMLElement[], slideDirection: 'slideDown' | 'slideUp', callback: Function) {\r\n if ((window as any).jQuery !== undefined) {\r\n (window as any).jQuery(el)[slideDirection]('fast', callback);\r\n return;\r\n }\r\n (slideDirection === 'slideUp') ? Utils.hide(el) : Utils.show(el);\r\n callback();\r\n }\r\n\r\n public static applyDefaults(targetObj: any, srcObj: any) {\r\n if (typeof srcObj === 'object') {\r\n Object.keys(srcObj).forEach(key => {\r\n if (srcObj.hasOwnProperty(key) && !targetObj.hasOwnProperty(key)) {\r\n targetObj[key] = srcObj[key];\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * User could optionally add PubSub Service to SlickEvent\r\n * When it is defined then a SlickEvent `notify()` call will also dispatch it by using the PubSub publish() method\r\n * @param {BasePubSub} [pubSubService]\r\n * @param {*} scope\r\n */\r\n public static addSlickEventPubSubWhenDefined(pubSub?: BasePubSub, scope?: T) {\r\n if (pubSub) {\r\n for (const prop in scope) {\r\n if (scope[prop] instanceof SlickEvent && typeof (scope[prop] as SlickEvent).setPubSubService === 'function') {\r\n (scope[prop] as SlickEvent).setPubSubService(pubSub);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport const SlickGlobalEditorLock = new SlickEditorLock();\r\n\r\n// export Slick namespace on both global & window objects\r\nconst SlickCore = {\r\n Event: SlickEvent,\r\n EventData: SlickEventData,\r\n EventHandler: SlickEventHandler,\r\n Range: SlickRange,\r\n NonDataRow: SlickNonDataItem,\r\n Group: SlickGroup,\r\n GroupTotals: SlickGroupTotals,\r\n EditorLock: SlickEditorLock,\r\n RegexSanitizer: regexSanitizer,\r\n\r\n /**\r\n * A global singleton editor lock.\r\n * @class GlobalEditorLock\r\n * @static\r\n * @constructor\r\n */\r\n GlobalEditorLock: SlickGlobalEditorLock,\r\n\r\n keyCode: {\r\n SPACE: 8,\r\n BACKSPACE: 8,\r\n DELETE: 46,\r\n DOWN: 40,\r\n END: 35,\r\n ENTER: 13,\r\n ESCAPE: 27,\r\n HOME: 36,\r\n INSERT: 45,\r\n LEFT: 37,\r\n PAGE_DOWN: 34,\r\n PAGE_UP: 33,\r\n RIGHT: 39,\r\n TAB: 9,\r\n UP: 38,\r\n A: 65\r\n },\r\n preClickClassName: 'slick-edit-preclick',\r\n\r\n GridAutosizeColsMode: {\r\n None: 'NOA',\r\n LegacyOff: 'LOF',\r\n LegacyForceFit: 'LFF',\r\n IgnoreViewport: 'IGV',\r\n FitColsToViewport: 'FCV',\r\n FitViewportToCols: 'FVC'\r\n },\r\n\r\n 'ColAutosizeMode': {\r\n Locked: 'LCK',\r\n Guide: 'GUI',\r\n Content: 'CON',\r\n ContentExpandOnly: 'CXO',\r\n ContentIntelligent: 'CTI'\r\n },\r\n\r\n 'RowSelectionMode': {\r\n FirstRow: 'FS1',\r\n FirstNRows: 'FSN',\r\n AllRows: 'ALL',\r\n LastRow: 'LS1'\r\n },\r\n\r\n 'ValueFilterMode': {\r\n None: 'NONE',\r\n DeDuplicate: 'DEDP',\r\n GetGreatestAndSub: 'GR8T',\r\n GetLongestTextAndSub: 'LNSB',\r\n GetLongestText: 'LNSC'\r\n },\r\n\r\n WidthEvalMode: {\r\n Auto: 'AUTO',\r\n TextOnly: 'CANV',\r\n HTML: 'HTML'\r\n }\r\n};\r\n\r\nexport const {\r\n EditorLock, Event, EventData, EventHandler, Group, GroupTotals, NonDataRow, Range,\r\n RegexSanitizer, GlobalEditorLock, keyCode, preClickClassName, GridAutosizeColsMode, ColAutosizeMode,\r\n RowSelectionMode, ValueFilterMode, WidthEvalMode\r\n} = SlickCore;\r\n\r\n// also add to global object when exist\r\nif (IIFE_ONLY && typeof global !== 'undefined' && window.Slick) {\r\n global.Slick = window.Slick;\r\n}\r\n"], + "sourcesContent": ["/**\r\n * Contains core SlickGrid classes.\r\n * @module Core\r\n * @namespace Slick\r\n */\r\n\r\nimport type {\r\n AnyFunction,\r\n CSSStyleDeclarationWritable,\r\n EditController,\r\n ElementEventListener,\r\n Handler,\r\n InferDOMType,\r\n MergeTypes\r\n} from './models/index';\r\n\r\nexport interface BasePubSub {\r\n publish(_eventName: string | any, _data?: ArgType): any;\r\n subscribe(_eventName: string | Function, _callback: (data: ArgType) => void): any;\r\n}\r\n\r\n/**\r\n * An event object for passing data to event handlers and letting them control propagation.\r\n *

This is pretty much identical to how W3C and jQuery implement events.

\r\n * @class EventData\r\n * @constructor\r\n */\r\nexport class SlickEventData {\r\n protected _isPropagationStopped = false;\r\n protected _isImmediatePropagationStopped = false;\r\n protected _isDefaultPrevented = false;\r\n protected returnValues: string[] = [];\r\n protected returnValue: any = undefined;\r\n protected _eventTarget?: EventTarget | null;\r\n protected nativeEvent?: Event | null;\r\n protected arguments_?: ArgType;\r\n\r\n // public props that can be optionally pulled from the provided Event in constructor\r\n // they are all optional props because it really depends on the type of Event provided (KeyboardEvent, MouseEvent, ...)\r\n readonly altKey?: boolean;\r\n readonly ctrlKey?: boolean;\r\n readonly metaKey?: boolean;\r\n readonly shiftKey?: boolean;\r\n readonly key?: string;\r\n readonly keyCode?: number;\r\n readonly clientX?: number;\r\n readonly clientY?: number;\r\n readonly offsetX?: number;\r\n readonly offsetY?: number;\r\n readonly pageX?: number;\r\n readonly pageY?: number;\r\n readonly bubbles?: boolean;\r\n readonly target?: HTMLElement;\r\n readonly type?: string;\r\n readonly which?: number;\r\n readonly x?: number;\r\n readonly y?: number;\r\n\r\n get defaultPrevented() {\r\n return this._isDefaultPrevented;\r\n }\r\n\r\n constructor(protected event?: Event | null, protected args?: ArgType) {\r\n this.nativeEvent = event;\r\n this.arguments_ = args;\r\n\r\n // when we already have an event, we want to keep some of the event properties\r\n // looping through some props is the only way to keep and sync these properties to the returned EventData\r\n if (event) {\r\n [\r\n 'altKey', 'ctrlKey', 'metaKey', 'shiftKey', 'key', 'keyCode',\r\n 'clientX', 'clientY', 'offsetX', 'offsetY', 'pageX', 'pageY',\r\n 'bubbles', 'target', 'type', 'which', 'x', 'y'\r\n ].forEach(key => (this as any)[key] = event[key as keyof Event]);\r\n }\r\n this._eventTarget = this.nativeEvent ? this.nativeEvent.target : undefined;\r\n }\r\n\r\n /**\r\n * Stops event from propagating up the DOM tree.\r\n * @method stopPropagation\r\n */\r\n stopPropagation() {\r\n this._isPropagationStopped = true;\r\n this.nativeEvent?.stopPropagation();\r\n }\r\n\r\n /**\r\n * Returns whether stopPropagation was called on this event object.\r\n * @method isPropagationStopped\r\n * @return {Boolean}\r\n */\r\n isPropagationStopped() {\r\n return this._isPropagationStopped;\r\n }\r\n\r\n /**\r\n * Prevents the rest of the handlers from being executed.\r\n * @method stopImmediatePropagation\r\n */\r\n stopImmediatePropagation() {\r\n this._isImmediatePropagationStopped = true;\r\n if (this.nativeEvent) {\r\n this.nativeEvent.stopImmediatePropagation();\r\n }\r\n };\r\n\r\n /**\r\n * Returns whether stopImmediatePropagation was called on this event object.\\\r\n * @method isImmediatePropagationStopped\r\n * @return {Boolean}\r\n */\r\n isImmediatePropagationStopped() {\r\n return this._isImmediatePropagationStopped;\r\n };\r\n\r\n getNativeEvent() {\r\n return this.nativeEvent as E;\r\n }\r\n\r\n preventDefault() {\r\n if (this.nativeEvent) {\r\n this.nativeEvent.preventDefault();\r\n }\r\n this._isDefaultPrevented = true;\r\n }\r\n\r\n isDefaultPrevented() {\r\n if (this.nativeEvent) {\r\n return this.nativeEvent.defaultPrevented;\r\n }\r\n return this._isDefaultPrevented;\r\n }\r\n\r\n addReturnValue(value: any) {\r\n this.returnValues.push(value);\r\n if (this.returnValue === undefined && value !== undefined) {\r\n this.returnValue = value;\r\n }\r\n }\r\n\r\n getReturnValue() {\r\n return this.returnValue;\r\n }\r\n\r\n getArguments() {\r\n return this.arguments_;\r\n }\r\n}\r\n\r\n/**\r\n * A simple publisher-subscriber implementation.\r\n * @class Event\r\n * @constructor\r\n */\r\nexport class SlickEvent {\r\n protected _handlers: Handler[] = [];\r\n protected _pubSubService?: BasePubSub;\r\n\r\n get subscriberCount() {\r\n return this._handlers.length;\r\n }\r\n\r\n /**\r\n * Constructor\r\n * @param {String} [eventName] - event name that could be used for dispatching CustomEvent (when enabled)\r\n * @param {BasePubSub} [pubSubService] - event name that could be used for dispatching CustomEvent (when enabled)\r\n */\r\n constructor(protected readonly eventName?: string, protected readonly pubSub?: BasePubSub) {\r\n this._pubSubService = pubSub;\r\n }\r\n\r\n /**\r\n * Adds an event handler to be called when the event is fired.\r\n *

Event handler will receive two arguments - an EventData and the data\r\n * object the event was fired with.

\r\n * @method subscribe\r\n * @param {Function} fn - Event handler.\r\n */\r\n subscribe(fn: Handler) {\r\n this._handlers.push(fn);\r\n }\r\n\r\n /**\r\n * Removes an event handler added with subscribe(fn).\r\n * @method unsubscribe\r\n * @param {Function} [fn] - Event handler to be removed.\r\n */\r\n unsubscribe(fn?: Handler) {\r\n for (let i = this._handlers.length - 1; i >= 0; i--) {\r\n if (this._handlers[i] === fn) {\r\n this._handlers.splice(i, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Fires an event notifying all subscribers.\r\n * @method notify\r\n * @param {Object} args Additional data object to be passed to all handlers.\r\n * @param {EventData} [event] - An EventData object to be passed to all handlers.\r\n * For DOM events, an existing W3C event object can be passed in.\r\n * @param {Object} [scope] - The scope (\"this\") within which the handler will be executed.\r\n * If not specified, the scope will be set to the Event instance.\r\n */\r\n notify(args: ArgType, evt?: SlickEventData | Event | MergeTypes, Event> | null, scope?: any) {\r\n const sed: SlickEventData = evt instanceof SlickEventData\r\n ? evt\r\n : new SlickEventData(evt, args);\r\n scope = scope || this;\r\n\r\n for (let i = 0; i < this._handlers.length && !(sed.isPropagationStopped() || sed.isImmediatePropagationStopped()); i++) {\r\n const returnValue = this._handlers[i].call(scope, sed, args);\r\n sed.addReturnValue(returnValue);\r\n }\r\n\r\n // user can optionally add a global PubSub Service which makes it easy to publish/subscribe to events\r\n if (typeof this._pubSubService?.publish === 'function' && this.eventName) {\r\n const ret = this._pubSubService.publish<{ args: ArgType; eventData?: SlickEventData; nativeEvent?: Event; }>(this.eventName, { args, eventData: sed });\r\n sed.addReturnValue(ret);\r\n }\r\n return sed;\r\n }\r\n\r\n setPubSubService(pubSub: BasePubSub) {\r\n this._pubSubService = pubSub;\r\n }\r\n}\r\n\r\nexport class SlickEventHandler {\r\n protected handlers: Array<{ event: SlickEvent; handler: Handler; }> = [];\r\n\r\n subscribe(event: SlickEvent, handler: Handler) {\r\n this.handlers.push({ event, handler });\r\n event.subscribe(handler);\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n\r\n unsubscribe(event: SlickEvent, handler: Handler) {\r\n let i = this.handlers.length;\r\n while (i--) {\r\n if (this.handlers[i].event === event &&\r\n this.handlers[i].handler === handler) {\r\n this.handlers.splice(i, 1);\r\n event.unsubscribe(handler);\r\n return;\r\n }\r\n }\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n\r\n unsubscribeAll() {\r\n let i = this.handlers.length;\r\n while (i--) {\r\n this.handlers[i].event.unsubscribe(this.handlers[i].handler);\r\n }\r\n this.handlers = [];\r\n\r\n return this as SlickEventHandler; // allow chaining\r\n }\r\n}\r\n\r\n/**\r\n * A structure containing a range of cells.\r\n * @class Range\r\n * @constructor\r\n * @param fromRow {Integer} Starting row.\r\n * @param fromCell {Integer} Starting cell.\r\n * @param toRow {Integer} Optional. Ending row. Defaults to fromRow.\r\n * @param toCell {Integer} Optional. Ending cell. Defaults to fromCell.\r\n */\r\nexport class SlickRange {\r\n fromRow: number;\r\n fromCell: number;\r\n toCell: number;\r\n toRow: number;\r\n\r\n constructor(fromRow: number, fromCell: number, toRow?: number, toCell?: number) {\r\n if (toRow === undefined && toCell === undefined) {\r\n toRow = fromRow;\r\n toCell = fromCell;\r\n }\r\n\r\n /**\r\n * @property fromRow\r\n * @type {Integer}\r\n */\r\n this.fromRow = Math.min(fromRow, toRow as number);\r\n\r\n /**\r\n * @property fromCell\r\n * @type {Integer}\r\n */\r\n this.fromCell = Math.min(fromCell, toCell as number);\r\n\r\n /**\r\n * @property toCell\r\n * @type {Integer}\r\n */\r\n this.toCell = Math.max(fromCell, toCell as number);\r\n\r\n /**\r\n * @property toRow\r\n * @type {Integer}\r\n */\r\n this.toRow = Math.max(fromRow, toRow as number);\r\n }\r\n\r\n\r\n /**\r\n * Returns whether a range represents a single row.\r\n * @method isSingleRow\r\n * @return {Boolean}\r\n */\r\n isSingleRow() {\r\n return this.fromRow === this.toRow;\r\n }\r\n\r\n /**\r\n * Returns whether a range represents a single cell.\r\n * @method isSingleCell\r\n * @return {Boolean}\r\n */\r\n isSingleCell() {\r\n return this.fromRow === this.toRow && this.fromCell === this.toCell;\r\n }\r\n\r\n /**\r\n * Returns whether a range contains a given cell.\r\n * @method contains\r\n * @param row {Integer}\r\n * @param cell {Integer}\r\n * @return {Boolean}\r\n */\r\n contains(row: number, cell: number) {\r\n return row >= this.fromRow && row <= this.toRow &&\r\n cell >= this.fromCell && cell <= this.toCell;\r\n }\r\n\r\n /**\r\n * Returns a readable representation of a range.\r\n * @method toString\r\n * @return {String}\r\n */\r\n toString() {\r\n if (this.isSingleCell()) {\r\n return `(${this.fromRow}:${this.fromCell})`;\r\n }\r\n else {\r\n return `(${this.fromRow}:${this.fromCell} - ${this.toRow}:${this.toCell})`;\r\n }\r\n };\r\n}\r\n\r\n\r\n/**\r\n * A base class that all special / non-data rows (like Group and GroupTotals) derive from.\r\n * @class NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickNonDataItem {\r\n __nonDataRow = true;\r\n}\r\n\r\n\r\n/**\r\n * Information about a group of rows.\r\n * @class Group\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickGroup extends SlickNonDataItem {\r\n __group = true;\r\n\r\n /**\r\n * Grouping level, starting with 0.\r\n * @property level\r\n * @type {Number}\r\n */\r\n level = 0;\r\n\r\n /**\r\n * Number of rows in the group.\r\n * @property count\r\n * @type {Integer}\r\n */\r\n count = 0;\r\n\r\n /**\r\n * Grouping value.\r\n * @property value\r\n * @type {Object}\r\n */\r\n value = null;\r\n\r\n /**\r\n * Formatted display value of the group.\r\n * @property title\r\n * @type {String}\r\n */\r\n title: string | null = null;\r\n\r\n /**\r\n * Whether a group is collapsed.\r\n * @property collapsed\r\n * @type {Boolean}\r\n */\r\n collapsed: boolean | number = false;\r\n\r\n /**\r\n * Whether a group selection checkbox is checked.\r\n * @property selectChecked\r\n * @type {Boolean}\r\n */\r\n selectChecked = false;\r\n\r\n /**\r\n * GroupTotals, if any.\r\n * @property totals\r\n * @type {GroupTotals}\r\n */\r\n totals: SlickGroupTotals = null as any;\r\n\r\n /**\r\n * Rows that are part of the group.\r\n * @property rows\r\n * @type {Array}\r\n */\r\n rows: number[] = [];\r\n\r\n /**\r\n * Sub-groups that are part of the group.\r\n * @property groups\r\n * @type {Array}\r\n */\r\n groups: any[] = null as any;\r\n\r\n /**\r\n * A unique key used to identify the group. This key can be used in calls to DataView\r\n * collapseGroup() or expandGroup().\r\n * @property groupingKey\r\n * @type {Object}\r\n */\r\n groupingKey: any = null;\r\n\r\n constructor() {\r\n super();\r\n }\r\n /**\r\n * Compares two Group instances.\r\n * @method equals\r\n * @return {Boolean}\r\n * @param group {Group} Group instance to compare to.\r\n */\r\n equals(group: SlickGroup): boolean {\r\n return this.value === group.value &&\r\n this.count === group.count &&\r\n this.collapsed === group.collapsed &&\r\n this.title === group.title;\r\n };\r\n}\r\n\r\n/**\r\n * Information about group totals.\r\n * An instance of GroupTotals will be created for each totals row and passed to the aggregators\r\n * so that they can store arbitrary data in it. That data can later be accessed by group totals\r\n * formatters during the display.\r\n * @class GroupTotals\r\n * @extends Slick.NonDataItem\r\n * @constructor\r\n */\r\nexport class SlickGroupTotals extends SlickNonDataItem {\r\n __groupTotals = true;\r\n\r\n /**\r\n * Parent Group.\r\n * @param group\r\n * @type {Group}\r\n */\r\n group: SlickGroup = null as any;\r\n\r\n /**\r\n * Whether the totals have been fully initialized / calculated.\r\n * Will be set to false for lazy-calculated group totals.\r\n * @param initialized\r\n * @type {Boolean}\r\n */\r\n initialized = false;\r\n\r\n constructor() {\r\n super();\r\n }\r\n}\r\n\r\n/**\r\n * A locking helper to track the active edit controller and ensure that only a single controller\r\n * can be active at a time. This prevents a whole class of state and validation synchronization\r\n * issues. An edit controller (such as SlickGrid) can query if an active edit is in progress\r\n * and attempt a commit or cancel before proceeding.\r\n * @class EditorLock\r\n * @constructor\r\n */\r\nexport class SlickEditorLock {\r\n activeEditController: any = null;\r\n\r\n /**\r\n * Returns true if a specified edit controller is active (has the edit lock).\r\n * If the parameter is not specified, returns true if any edit controller is active.\r\n * @method isActive\r\n * @param editController {EditController}\r\n * @return {Boolean}\r\n */\r\n isActive(editController?: EditController): boolean {\r\n return (editController ? this.activeEditController === editController : this.activeEditController !== null);\r\n };\r\n\r\n /**\r\n * Sets the specified edit controller as the active edit controller (acquire edit lock).\r\n * If another edit controller is already active, and exception will be throw new Error(.\r\n * @method activate\r\n * @param editController {EditController} edit controller acquiring the lock\r\n */\r\n activate(editController: EditController) {\r\n if (editController === this.activeEditController) { // already activated?\r\n return;\r\n }\r\n if (this.activeEditController !== null) {\r\n throw new Error(`Slick.EditorLock.activate: an editController is still active, can't activate another editController`);\r\n }\r\n if (!editController.commitCurrentEdit) {\r\n throw new Error('Slick.EditorLock.activate: editController must implement .commitCurrentEdit()');\r\n }\r\n if (!editController.cancelCurrentEdit) {\r\n throw new Error('Slick.EditorLock.activate: editController must implement .cancelCurrentEdit()');\r\n }\r\n this.activeEditController = editController;\r\n };\r\n\r\n /**\r\n * Unsets the specified edit controller as the active edit controller (release edit lock).\r\n * If the specified edit controller is not the active one, an exception will be throw new Error(.\r\n * @method deactivate\r\n * @param editController {EditController} edit controller releasing the lock\r\n */\r\n deactivate(editController: EditController) {\r\n if (!this.activeEditController) {\r\n return;\r\n }\r\n if (this.activeEditController !== editController) {\r\n throw new Error('Slick.EditorLock.deactivate: specified editController is not the currently active one');\r\n }\r\n this.activeEditController = null;\r\n };\r\n\r\n /**\r\n * Attempts to commit the current edit by calling \"commitCurrentEdit\" method on the active edit\r\n * controller and returns whether the commit attempt was successful (commit may fail due to validation\r\n * errors, etc.). Edit controller's \"commitCurrentEdit\" must return true if the commit has succeeded\r\n * and false otherwise. If no edit controller is active, returns true.\r\n * @method commitCurrentEdit\r\n * @return {Boolean}\r\n */\r\n commitCurrentEdit(): boolean {\r\n return (this.activeEditController ? this.activeEditController.commitCurrentEdit() : true);\r\n };\r\n\r\n /**\r\n * Attempts to cancel the current edit by calling \"cancelCurrentEdit\" method on the active edit\r\n * controller and returns whether the edit was successfully cancelled. If no edit controller is\r\n * active, returns true.\r\n * @method cancelCurrentEdit\r\n * @return {Boolean}\r\n */\r\n cancelCurrentEdit(): boolean {\r\n return (this.activeEditController ? this.activeEditController.cancelCurrentEdit() : true);\r\n };\r\n}\r\n\r\nfunction regexSanitizer(dirtyHtml: string) {\r\n return dirtyHtml.replace(/(\\b)(on[a-z]+)(\\s*)=|javascript:([^>]*)[^>]*|(<\\s*)(\\/*)script([<>]*).*(<\\s*)(\\/*)script(>*)|(<)(\\/*)(script|script defer)(.*)(>|>\">)/gi, '');\r\n}\r\n\r\n/**\r\n * A simple binding event service to keep track of all JavaScript events with callback listeners,\r\n * it allows us to unbind event(s) and their listener(s) by calling a simple unbind method call.\r\n * Unbinding is a necessary step to make sure that all event listeners are removed to avoid memory leaks when destroing the grid\r\n */\r\nexport class BindingEventService {\r\n protected _boundedEvents: ElementEventListener[] = [];\r\n\r\n getBoundedEvents() {\r\n return this._boundedEvents;\r\n }\r\n\r\n destroy() {\r\n this.unbindAll();\r\n }\r\n\r\n /** Bind an event listener to any element */\r\n bind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions, groupName = '') {\r\n if (element) {\r\n element.addEventListener(eventName, listener, options);\r\n this._boundedEvents.push({ element, eventName, listener, groupName });\r\n }\r\n }\r\n\r\n /** Unbind all will remove every every event handlers that were bounded earlier */\r\n unbind(element: Element | Window, eventName: string, listener: EventListenerOrEventListenerObject) {\r\n if (element?.removeEventListener) {\r\n element.removeEventListener(eventName, listener);\r\n }\r\n }\r\n\r\n unbindByEventName(element: Element | Window, eventName: string) {\r\n const boundedEvent = this._boundedEvents.find(e => e.element === element && e.eventName === eventName);\r\n if (boundedEvent) {\r\n this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);\r\n }\r\n }\r\n\r\n /**\r\n * Unbind all event listeners that were bounded, optionally provide a group name to unbind all listeners assigned to that specific group only.\r\n */\r\n unbindAll(groupName?: string | string[]) {\r\n if (groupName) {\r\n const groupNames = Array.isArray(groupName) ? groupName : [groupName];\r\n\r\n // unbind only the bounded event with a specific group\r\n // Note: we need to loop in reverse order to avoid array reindexing (causing index offset) after a splice is called\r\n for (let i = this._boundedEvents.length - 1; i >= 0; --i) {\r\n const boundedEvent = this._boundedEvents[i];\r\n if (groupNames.some(g => g === boundedEvent.groupName)) {\r\n const { element, eventName, listener } = boundedEvent;\r\n this.unbind(element, eventName, listener);\r\n this._boundedEvents.splice(i, 1);\r\n }\r\n }\r\n } else {\r\n // unbind everything\r\n while (this._boundedEvents.length > 0) {\r\n const boundedEvent = this._boundedEvents.pop() as ElementEventListener;\r\n const { element, eventName, listener } = boundedEvent;\r\n this.unbind(element, eventName, listener);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport class Utils {\r\n // jQuery's extend\r\n private static getProto = Object.getPrototypeOf;\r\n private static class2type: any = {};\r\n private static toString = Utils.class2type.toString;\r\n private static hasOwn = Utils.class2type.hasOwnProperty;\r\n private static fnToString = Utils.hasOwn.toString;\r\n private static ObjectFunctionString = Utils.fnToString.call(Object);\r\n public static storage = {\r\n // https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati\r\n _storage: new WeakMap(),\r\n // eslint-disable-next-line object-shorthand\r\n put: function (element: any, key: string, obj: any) {\r\n if (!this._storage.has(element)) {\r\n this._storage.set(element, new Map());\r\n }\r\n this._storage.get(element).set(key, obj);\r\n },\r\n // eslint-disable-next-line object-shorthand\r\n get: function (element: any, key: string) {\r\n const el = this._storage.get(element);\r\n if (el) {\r\n return el.get(key);\r\n }\r\n return null;\r\n },\r\n // eslint-disable-next-line object-shorthand\r\n remove: function (element: any, key: string) {\r\n const ret = this._storage.get(element).delete(key);\r\n if (!(this._storage.get(element).size === 0)) {\r\n this._storage.delete(element);\r\n }\r\n return ret;\r\n }\r\n };\r\n\r\n public static isFunction(obj: any) {\r\n return typeof obj === 'function' && typeof obj.nodeType !== 'number' && typeof obj.item !== 'function';\r\n }\r\n\r\n public static isPlainObject(obj: any) {\r\n if (!obj || Utils.toString.call(obj) !== '[object Object]') {\r\n return false;\r\n }\r\n\r\n const proto = Utils.getProto(obj);\r\n if (!proto) {\r\n return true;\r\n }\r\n const Ctor = Utils.hasOwn.call(proto, 'constructor') && proto.constructor;\r\n return typeof Ctor === 'function' && Utils.fnToString.call(Ctor) === Utils.ObjectFunctionString;\r\n }\r\n\r\n public static calculateAvailableSpace(element: HTMLElement) {\r\n let bottom = 0, top = 0, left = 0, right = 0;\r\n\r\n const windowHeight = window.innerHeight || 0;\r\n const windowWidth = window.innerWidth || 0;\r\n const scrollPosition = Utils.windowScrollPosition();\r\n const pageScrollTop = scrollPosition.top;\r\n const pageScrollLeft = scrollPosition.left;\r\n const elmOffset = Utils.offset(element);\r\n\r\n if (elmOffset) {\r\n const elementOffsetTop = elmOffset.top || 0;\r\n const elementOffsetLeft = elmOffset.left || 0;\r\n top = elementOffsetTop - pageScrollTop;\r\n bottom = windowHeight - (elementOffsetTop - pageScrollTop);\r\n left = elementOffsetLeft - pageScrollLeft;\r\n right = windowWidth - (elementOffsetLeft - pageScrollLeft);\r\n }\r\n\r\n return { top, bottom, left, right };\r\n }\r\n\r\n public static extend(...args: any[]): T {\r\n let options, name, src, copy, copyIsArray, clone,\r\n target = args[0],\r\n i = 1,\r\n deep = false;\r\n const length = args.length;\r\n\r\n if (typeof target === 'boolean') {\r\n deep = target;\r\n target = args[i] || {};\r\n i++;\r\n } else {\r\n target = target || {};\r\n }\r\n if (typeof target !== 'object' && !Utils.isFunction(target)) {\r\n target = {};\r\n }\r\n if (i === length) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n target = this;\r\n i--;\r\n }\r\n for (; i < length; i++) {\r\n if (Utils.isDefined(options = args[i])) {\r\n for (name in options) {\r\n copy = options[name];\r\n if (name === '__proto__' || target === copy) {\r\n continue;\r\n }\r\n if (deep && copy && (Utils.isPlainObject(copy) ||\r\n (copyIsArray = Array.isArray(copy)))) {\r\n src = target[name];\r\n if (copyIsArray && !Array.isArray(src)) {\r\n clone = [];\r\n } else if (!copyIsArray && !Utils.isPlainObject(src)) {\r\n clone = {};\r\n } else {\r\n clone = src;\r\n }\r\n copyIsArray = false;\r\n target[name] = Utils.extend(deep, clone, copy);\r\n } else if (copy !== undefined) {\r\n target[name] = copy;\r\n }\r\n }\r\n }\r\n }\r\n return target as T;\r\n }\r\n\r\n /**\r\n * Create a DOM Element with any optional attributes or properties.\r\n * It will only accept valid DOM element properties that `createElement` would accept.\r\n * For example: `createDomElement('div', { className: 'my-css-class' })`,\r\n * for style or dataset you need to use nested object `{ style: { display: 'none' }}\r\n * The last argument is to optionally append the created element to a parent container element.\r\n * @param {String} tagName - html tag\r\n * @param {Object} options - element properties\r\n * @param {[HTMLElement]} appendToParent - parent element to append to\r\n */\r\n public static createDomElement(\r\n tagName: T,\r\n elementOptions?: null | { [P in K]: InferDOMType },\r\n appendToParent?: Element\r\n ): HTMLElementTagNameMap[T] {\r\n const elm = document.createElement(tagName);\r\n\r\n if (elementOptions) {\r\n Object.keys(elementOptions).forEach((elmOptionKey) => {\r\n if (elmOptionKey === 'innerHTML') {\r\n console.warn(`[SlickGrid] For better CSP (Content Security Policy) support, do not use \"innerHTML\" directly in \"createDomElement('${tagName}', { innerHTML: 'some html'})\"` +\r\n `, it is better as separate assignment: \"const elm = createDomElement('span'); elm.innerHTML = 'some html';\"`);\r\n }\r\n\r\n const elmValue = elementOptions[elmOptionKey as keyof typeof elementOptions];\r\n if (typeof elmValue === 'object') {\r\n Object.assign(elm[elmOptionKey as K] as object, elmValue);\r\n } else {\r\n elm[elmOptionKey as K] = (elementOptions as any)[elmOptionKey as keyof typeof elementOptions];\r\n }\r\n });\r\n }\r\n if (appendToParent?.appendChild) {\r\n appendToParent.appendChild(elm);\r\n }\r\n return elm;\r\n }\r\n\r\n /**\r\n * From any input provided, return the HTML string (when a string is provided, it will be returned \"as is\" but when it's a number it will be converted to string)\r\n * When detecting HTMLElement/DocumentFragment, we can also specify which HTML type to retrieve innerHTML or outerHTML.\r\n * We can get the HTML by looping through all fragment `childNodes`\r\n * @param {DocumentFragment | HTMLElement | string | number} input\r\n * @param {'innerHTML' | 'outerHTML'} [type] - when the input is a DocumentFragment or HTMLElement, which type of HTML do you want to return? 'innerHTML' or 'outerHTML'\r\n * @returns {String}\r\n */\r\n public static getHtmlStringOutput(input: DocumentFragment | HTMLElement | string | number, type: 'innerHTML' | 'outerHTML' = 'innerHTML'): string {\r\n if (input instanceof DocumentFragment) {\r\n // a DocumentFragment doesn't have innerHTML/outerHTML, but we can loop through all children and concatenate them all to an HTML string\r\n return [].map.call(input.childNodes, (x: HTMLElement) => x[type]).join('') || input.textContent || '';\r\n } else if (input instanceof HTMLElement) {\r\n return input[type];\r\n }\r\n return String(input); // reaching this line means it's already a string (or number) so just return it as string\r\n }\r\n\r\n public static emptyElement(element?: T | null): T | undefined | null {\r\n while (element?.firstChild) {\r\n element.removeChild(element.firstChild);\r\n }\r\n return element;\r\n }\r\n\r\n /**\r\n * Accepts string containing the class or space-separated list of classes, and\r\n * returns list of individual classes.\r\n * Method properly takes into account extra whitespaces in the `className`\r\n * e.g.: \" class1 class2 \" => will result in `['class1', 'class2']`.\r\n * @param {String} className - space separated list of class names\r\n */\r\n public static classNameToList(className = ''): string[] {\r\n return className.split(' ').filter(cls => cls);\r\n }\r\n\r\n public static innerSize(elm: HTMLElement, type: 'height' | 'width') {\r\n let size = 0;\r\n\r\n if (elm) {\r\n const clientSize = type === 'height' ? 'clientHeight' : 'clientWidth';\r\n const sides = type === 'height' ? ['top', 'bottom'] : ['left', 'right'];\r\n size = elm[clientSize];\r\n for (const side of sides) {\r\n const sideSize = (parseFloat(Utils.getElementProp(elm, `padding-${side}`) || '') || 0);\r\n size -= sideSize;\r\n }\r\n }\r\n return size;\r\n }\r\n\r\n public static isDefined(value: T | undefined | null): value is T {\r\n return value !== undefined && value !== null && value !== '';\r\n }\r\n\r\n public static getElementProp(elm: HTMLElement & { getComputedStyle?: () => CSSStyleDeclaration }, property: string) {\r\n if (elm?.getComputedStyle) {\r\n return window.getComputedStyle(elm, null).getPropertyValue(property);\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the function details (param & body) of a function.\r\n * It supports regular function and also ES6 arrow functions\r\n * @param {Function} fn - function to analyze\r\n * @param {Boolean} [addReturn] - when using ES6 function as single liner, we could add the missing `return ...`\r\n * @returns\r\n */\r\n public static getFunctionDetails(fn: AnyFunction, addReturn = true) {\r\n let isAsyncFn = false;\r\n\r\n const getFunctionBody = (func: AnyFunction) => {\r\n const fnStr = func.toString();\r\n isAsyncFn = fnStr.includes('async ');\r\n\r\n // when fn is one liner arrow fn returning an object in brackets e.g. `() => ({ hello: 'world' })`\r\n if ((fnStr.replaceAll(' ', '').includes('=>({'))) {\r\n const matches = fnStr.match(/(({.*}))/g) || [];\r\n return matches.length >= 1 ? `return ${matches[0]!.trimStart()}` : fnStr;\r\n }\r\n const isOneLinerArrowFn = (!fnStr.includes('{') && fnStr.includes('=>'));\r\n const body = fnStr.substring(\r\n (fnStr.indexOf('{') + 1) || (fnStr.indexOf('=>') + 2),\r\n fnStr.includes('}') ? fnStr.lastIndexOf('}') : fnStr.length\r\n );\r\n if (addReturn && isOneLinerArrowFn && !body.startsWith('return')) {\r\n return 'return ' + body.trimStart(); // add the `return ...` to the body for ES6 arrow fn\r\n }\r\n return body;\r\n };\r\n\r\n const getFunctionParams = (func: AnyFunction): string[] => {\r\n const STRIP_COMMENTS = /(\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/)|(\\s*=[^,)]*(('(?:\\\\'|[^'\\r\\n])*')|(\"(?:\\\\\"|[^\"\\r\\n])*\"))|(\\s*=[^,)]*))/mg;\r\n const ARG_NAMES = /([^\\s,]+)/g;\r\n const fnStr = func.toString().replace(STRIP_COMMENTS, '');\r\n return fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARG_NAMES) ?? [];\r\n };\r\n\r\n return {\r\n params: getFunctionParams(fn),\r\n body: getFunctionBody(fn),\r\n isAsync: isAsyncFn,\r\n };\r\n }\r\n\r\n public static insertAfterElement(referenceNode: HTMLElement, newNode: HTMLElement) {\r\n referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling);\r\n }\r\n\r\n public static isEmptyObject(obj: any) {\r\n if (obj === null || obj === undefined) {\r\n return true;\r\n }\r\n return Object.entries(obj).length === 0;\r\n }\r\n\r\n public static noop() { }\r\n\r\n public static offset(el: HTMLElement | null) {\r\n if (!el || !el.getBoundingClientRect) {\r\n return undefined;\r\n }\r\n const box = el.getBoundingClientRect();\r\n const docElem = document.documentElement;\r\n\r\n return {\r\n top: box.top + window.pageYOffset - docElem.clientTop,\r\n left: box.left + window.pageXOffset - docElem.clientLeft\r\n };\r\n }\r\n\r\n public static windowScrollPosition() {\r\n return {\r\n left: window.pageXOffset || document.documentElement.scrollLeft || 0,\r\n top: window.pageYOffset || document.documentElement.scrollTop || 0,\r\n };\r\n }\r\n\r\n public static width(el: HTMLElement, value?: number | string): number | void {\r\n if (!el || !el.getBoundingClientRect) { return; }\r\n if (value === undefined) {\r\n return el.getBoundingClientRect().width;\r\n }\r\n Utils.setStyleSize(el, 'width', value);\r\n }\r\n\r\n public static height(el: HTMLElement, value?: number | string): number | void {\r\n if (!el) { return; }\r\n if (value === undefined) {\r\n return el.getBoundingClientRect().height;\r\n }\r\n Utils.setStyleSize(el, 'height', value);\r\n }\r\n\r\n public static setStyleSize(el: HTMLElement, style: string, val?: number | string | Function) {\r\n if (typeof val === 'function') {\r\n val = val();\r\n } else if (typeof val === 'string') {\r\n el.style[style as CSSStyleDeclarationWritable] = val;\r\n } else {\r\n el.style[style as CSSStyleDeclarationWritable] = val + 'px';\r\n }\r\n }\r\n\r\n public static contains(parent: HTMLElement, child: HTMLElement) {\r\n if (!parent || !child) {\r\n return false;\r\n }\r\n\r\n const parentList = Utils.parents(child);\r\n return !parentList.every((p) => {\r\n if (parent === p) {\r\n return false;\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n public static isHidden(el: HTMLElement) {\r\n return el.offsetWidth === 0 && el.offsetHeight === 0;\r\n }\r\n\r\n public static parents(el: HTMLElement | ParentNode, selector?: string) {\r\n const parents: Array = [];\r\n const visible = selector === ':visible';\r\n const hidden = selector === ':hidden';\r\n\r\n while ((el = el.parentNode as ParentNode) && el !== document) {\r\n if (!el || !el.parentNode) {\r\n break;\r\n }\r\n if (hidden) {\r\n if (Utils.isHidden(el as HTMLElement)) {\r\n parents.push(el);\r\n }\r\n } else if (visible) {\r\n if (!Utils.isHidden(el as HTMLElement)) {\r\n parents.push(el);\r\n }\r\n } else if (!selector || (el as any).matches(selector)) {\r\n parents.push(el);\r\n }\r\n }\r\n return parents;\r\n }\r\n\r\n public static toFloat(value: string | number) {\r\n const x = parseFloat(value as string);\r\n if (isNaN(x)) {\r\n return 0;\r\n }\r\n return x;\r\n }\r\n\r\n public static show(el: HTMLElement | HTMLElement[], type = '') {\r\n if (Array.isArray(el)) {\r\n el.forEach((e) => e.style.display = type);\r\n } else {\r\n el.style.display = type;\r\n }\r\n }\r\n\r\n public static hide(el: HTMLElement | HTMLElement[]) {\r\n if (Array.isArray(el)) {\r\n el.forEach((e) => e.style.display = 'none');\r\n } else {\r\n el.style.display = 'none';\r\n }\r\n }\r\n\r\n public static slideUp(el: HTMLElement | HTMLElement[], callback: Function) {\r\n return Utils.slideAnimation(el, 'slideUp', callback);\r\n }\r\n\r\n public static slideDown(el: HTMLElement | HTMLElement[], callback: Function) {\r\n return Utils.slideAnimation(el, 'slideDown', callback);\r\n }\r\n\r\n public static slideAnimation(el: HTMLElement | HTMLElement[], slideDirection: 'slideDown' | 'slideUp', callback: Function) {\r\n if ((window as any).jQuery !== undefined) {\r\n (window as any).jQuery(el)[slideDirection]('fast', callback);\r\n return;\r\n }\r\n (slideDirection === 'slideUp') ? Utils.hide(el) : Utils.show(el);\r\n callback();\r\n }\r\n\r\n public static applyDefaults(targetObj: any, srcObj: any) {\r\n if (typeof srcObj === 'object') {\r\n Object.keys(srcObj).forEach(key => {\r\n if (srcObj.hasOwnProperty(key) && !targetObj.hasOwnProperty(key)) {\r\n targetObj[key] = srcObj[key];\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * User could optionally add PubSub Service to SlickEvent\r\n * When it is defined then a SlickEvent `notify()` call will also dispatch it by using the PubSub publish() method\r\n * @param {BasePubSub} [pubSubService]\r\n * @param {*} scope\r\n */\r\n public static addSlickEventPubSubWhenDefined(pubSub?: BasePubSub, scope?: T) {\r\n if (pubSub) {\r\n for (const prop in scope) {\r\n if (scope[prop] instanceof SlickEvent && typeof (scope[prop] as SlickEvent).setPubSubService === 'function') {\r\n (scope[prop] as SlickEvent).setPubSubService(pubSub);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport const SlickGlobalEditorLock = new SlickEditorLock();\r\n\r\n// export Slick namespace on both global & window objects\r\nconst SlickCore = {\r\n Event: SlickEvent,\r\n EventData: SlickEventData,\r\n EventHandler: SlickEventHandler,\r\n Range: SlickRange,\r\n NonDataRow: SlickNonDataItem,\r\n Group: SlickGroup,\r\n GroupTotals: SlickGroupTotals,\r\n EditorLock: SlickEditorLock,\r\n RegexSanitizer: regexSanitizer,\r\n\r\n /**\r\n * A global singleton editor lock.\r\n * @class GlobalEditorLock\r\n * @static\r\n * @constructor\r\n */\r\n GlobalEditorLock: SlickGlobalEditorLock,\r\n\r\n keyCode: {\r\n SPACE: 8,\r\n BACKSPACE: 8,\r\n DELETE: 46,\r\n DOWN: 40,\r\n END: 35,\r\n ENTER: 13,\r\n ESCAPE: 27,\r\n HOME: 36,\r\n INSERT: 45,\r\n LEFT: 37,\r\n PAGE_DOWN: 34,\r\n PAGE_UP: 33,\r\n RIGHT: 39,\r\n TAB: 9,\r\n UP: 38,\r\n A: 65\r\n },\r\n preClickClassName: 'slick-edit-preclick',\r\n\r\n GridAutosizeColsMode: {\r\n None: 'NOA',\r\n LegacyOff: 'LOF',\r\n LegacyForceFit: 'LFF',\r\n IgnoreViewport: 'IGV',\r\n FitColsToViewport: 'FCV',\r\n FitViewportToCols: 'FVC'\r\n },\r\n\r\n 'ColAutosizeMode': {\r\n Locked: 'LCK',\r\n Guide: 'GUI',\r\n Content: 'CON',\r\n ContentExpandOnly: 'CXO',\r\n ContentIntelligent: 'CTI'\r\n },\r\n\r\n 'RowSelectionMode': {\r\n FirstRow: 'FS1',\r\n FirstNRows: 'FSN',\r\n AllRows: 'ALL',\r\n LastRow: 'LS1'\r\n },\r\n\r\n 'ValueFilterMode': {\r\n None: 'NONE',\r\n DeDuplicate: 'DEDP',\r\n GetGreatestAndSub: 'GR8T',\r\n GetLongestTextAndSub: 'LNSB',\r\n GetLongestText: 'LNSC'\r\n },\r\n\r\n WidthEvalMode: {\r\n Auto: 'AUTO',\r\n TextOnly: 'CANV',\r\n HTML: 'HTML'\r\n }\r\n};\r\n\r\nexport const {\r\n EditorLock, Event, EventData, EventHandler, Group, GroupTotals, NonDataRow, Range,\r\n RegexSanitizer, GlobalEditorLock, keyCode, preClickClassName, GridAutosizeColsMode, ColAutosizeMode,\r\n RowSelectionMode, ValueFilterMode, WidthEvalMode\r\n} = SlickCore;\r\n\r\n// also add to global object when exist\r\nif (IIFE_ONLY && typeof global !== 'undefined' && window.Slick) {\r\n global.Slick = window.Slick;\r\n}\r\n"], "mappings": "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", "names": [] } diff --git a/dist/browser/slick.editors.js b/dist/browser/slick.editors.js index 023792b5..f4780d4b 100644 --- a/dist/browser/slick.editors.js +++ b/dist/browser/slick.editors.js @@ -206,19 +206,22 @@ throw new Error("Flatpickr not loaded but required in SlickGrid.Editors, refer to Flatpickr documentation: https://flatpickr.js.org/getting-started/"); } init() { - this.input = Utils.createDomElement("input", { type: "text", className: "editor-text" }, this.args.container), this.input.focus(), this.input.select(), this.flatpickrInstance = flatpickr(this.input, { + var _a, _b, _c; + this.input = Utils.createDomElement("input", { type: "text", className: "editor-text" }, this.args.container), this.input.focus(), this.input.select(); + let editorOptions = (_a = this.args.column.params) == null ? void 0 : _a.editorOptions; + this.flatpickrInstance = flatpickr(this.input, { closeOnSelect: !0, allowInput: !0, altInput: !0, - altFormat: "m/d/Y", - dateFormat: "m/d/Y", + altFormat: (_b = editorOptions == null ? void 0 : editorOptions.altFormat) != null ? _b : "m/d/Y", + dateFormat: (_c = editorOptions == null ? void 0 : editorOptions.dateFormat) != null ? _c : "m/d/Y", onChange: () => { - var _a, _b; + var _a2, _b2; if (this.args.compositeEditorOptions) { let activeCell = this.args.grid.getActiveCell(); this.validate().valid && this.applyValue(this.args.item, this.serializeValue()), this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue()), this.args.grid.onCompositeEditorChange.notify({ - row: (_a = activeCell == null ? void 0 : activeCell.row) != null ? _a : 0, - cell: (_b = activeCell == null ? void 0 : activeCell.cell) != null ? _b : 0, + row: (_a2 = activeCell == null ? void 0 : activeCell.row) != null ? _a2 : 0, + cell: (_b2 = activeCell == null ? void 0 : activeCell.cell) != null ? _b2 : 0, item: this.args.item, column: this.args.column, formValues: this.args.compositeEditorOptions.formValues, diff --git a/dist/browser/slick.editors.js.map b/dist/browser/slick.editors.js.map index e549f732..6476a817 100644 --- a/dist/browser/slick.editors.js.map +++ b/dist/browser/slick.editors.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.editors.ts"], - "sourcesContent": ["import type { Column, Editor, EditorArguments, EditorValidationResult, ElementPosition, GridOption, OnCompositeEditorChangeEventArgs } from './models/index';\nimport { keyCode as keyCode_, Utils as Utils_ } from './slick.core';\n\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\n\n/***\n * Contains basic SlickGrid editors.\n * @module Editors\n * @namespace Slick\n */\n\nexport class TextEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number | string;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // don't show Save/Cancel when it's a Composite Editor and also trigger a onCompositeEditorChange event when input changes\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n getValue() {\n return this.input.value;\n }\n\n setValue(val: string) {\n this.input.value = val;\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field] || '';\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class IntegerEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n }\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid integer'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FloatEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected navOnLR?: boolean;\n\n /** Default number of decimal places to use with FloatEditor */\n static DefaultDecimalPlaces?: number = undefined;\n\n /** Should we allow empty value when using FloatEditor */\n static AllowEmptyValue = false;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.focus();\n this.input.select();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n };\n\n destroy() {\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n }\n\n getDecimalPlaces() {\n // returns the number of fixed decimal places or null\n let rtn: number | undefined = this.args.column.editorFixedDecimalPlaces;\n if (!Utils.isDefined(rtn)) {\n rtn = FloatEditor.DefaultDecimalPlaces;\n }\n return (!rtn && rtn !== 0 ? null : rtn);\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (this.defaultValue || this.defaultValue === 0)\n && (this.defaultValue as number)?.toFixed) {\n this.defaultValue = (this.defaultValue as number).toFixed(decPlaces);\n }\n\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n }\n\n serializeValue() {\n let rtn: number | undefined = parseFloat(this.input.value);\n if (FloatEditor.AllowEmptyValue) {\n if (!rtn && rtn !== 0) {\n rtn = undefined;\n }\n } else {\n rtn = rtn || 0;\n }\n\n const decPlaces = this.getDecimalPlaces();\n if (decPlaces !== null\n && (rtn || rtn === 0)\n && rtn.toFixed) {\n rtn = parseFloat(rtn.toFixed(decPlaces));\n }\n\n return rtn as number;\n }\n\n applyValue(item: any, state: number | string) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (isNaN(this.input.value as unknown as number)) {\n return {\n valid: false,\n msg: 'Please enter a valid number'\n };\n }\n\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class FlatpickrEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: string | number;\n protected flatpickrInstance: any;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n if (typeof flatpickr === 'undefined') {\n throw new Error('Flatpickr not loaded but required in SlickGrid.Editors, refer to Flatpickr documentation: https://flatpickr.js.org/getting-started/');\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\n this.input.focus();\n this.input.select();\n this.flatpickrInstance = flatpickr(this.input, {\n closeOnSelect: true,\n allowInput: true,\n altInput: true,\n altFormat: 'm/d/Y',\n dateFormat: 'm/d/Y',\n onChange: () => {\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n }\n },\n });\n\n if (!this.args.compositeEditorOptions) {\n setTimeout(() => {\n this.show();\n this.focus();\n }, 50);\n }\n\n Utils.width(this.input, (Utils.width(this.input) as number) - (!this.args.compositeEditorOptions ? 18 : 28));\n }\n\n destroy() {\n this.hide();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.destroy();\n }\n this.input.remove();\n }\n\n show() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.open();\n }\n }\n\n hide() {\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\n this.flatpickrInstance.close();\n }\n }\n\n focus() {\n this.input.focus();\n }\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.input.value = String(this.defaultValue ?? '');\n this.input.defaultValue = String(this.defaultValue ?? '');\n this.input.select();\n if (this.flatpickrInstance) {\n this.flatpickrInstance.setDate(this.defaultValue);\n }\n }\n\n serializeValue() {\n return this.input.value;\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n }\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class YesNoSelectEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected select!: HTMLSelectElement;\n protected defaultValue?: string | number;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.select = Utils.createDomElement('select', { tabIndex: 0, className: 'editor-yesno' }, this.args.container);\n Utils.createDomElement('option', { value: 'yes', textContent: 'Yes' }, this.select);\n Utils.createDomElement('option', { value: 'no', textContent: 'No' }, this.select);\n\n this.select.focus();\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.select.addEventListener('change', this.onChange.bind(this));\n }\n }\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n }\n\n destroy() {\n this.select.removeEventListener('change', this.onChange.bind(this));\n this.select.remove();\n }\n\n focus() {\n this.select.focus();\n }\n\n loadValue(item: any) {\n this.select.value = ((this.defaultValue = item[this.args.column.field]) ? 'yes' : 'no');\n }\n\n serializeValue() {\n return this.select.value === 'yes';\n }\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return this.select.value !== this.defaultValue;\n }\n\n validate() {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class CheckboxEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: boolean;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-checkbox', type: 'checkbox', value: 'true' }, this.args.container);\n this.input.focus();\n\n // trigger onCompositeEditorChange event when input checkbox changes and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n }\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n };\n\n destroy() {\n this.input.removeEventListener('change', this.onChange.bind(this));\n this.input.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = !!(item[this.args.column.field]);\n if (this.defaultValue) {\n this.input.checked = true;\n } else {\n this.input.checked = false;\n }\n };\n\n serializeValue() {\n return this.input.checked;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n }\n\n isValueChanged() {\n return (this.serializeValue() !== this.defaultValue);\n }\n\n validate(): EditorValidationResult {\n return {\n valid: true,\n msg: null\n };\n }\n}\n\nexport class PercentCompleteEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLInputElement;\n protected defaultValue?: number;\n protected picker!: HTMLDivElement;\n protected slider!: HTMLInputElement | null;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n sliderInputHandler(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = e.target.value;\n }\n\n sliderChangeHandler() {\n // trigger onCompositeEditorChange event when slider stops and it's a Composite Editor\n if (this.args.compositeEditorOptions) {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n }\n }\n\n init() {\n this.input = Utils.createDomElement('input', { className: 'editor-percentcomplete', type: 'text' }, this.args.container);\n Utils.width(this.input, this.args.container.clientWidth - 25);\n\n this.picker = Utils.createDomElement('div', { className: 'editor-percentcomplete-picker' }, this.args.container);\n Utils.createDomElement('span', { className: 'editor-percentcomplete-picker-icon' }, this.picker);\n const containerHelper = Utils.createDomElement('div', { className: 'editor-percentcomplete-helper' }, this.picker);\n const containerWrapper = Utils.createDomElement('div', { className: 'editor-percentcomplete-wrapper' }, containerHelper);\n Utils.createDomElement('div', { className: 'editor-percentcomplete-slider' }, containerWrapper);\n this.slider = Utils.createDomElement('input', { className: 'editor-percentcomplete-slider', type: 'range', value: String(this.defaultValue ?? '') }, containerWrapper);\n const containerButtons = Utils.createDomElement('div', { className: 'editor-percentcomplete-buttons' }, containerWrapper);\n Utils.createDomElement('button', { value: '0', className: 'slick-btn slick-btn-default', textContent: 'Not started' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '50', className: 'slick-btn slick-btn-default', textContent: 'In Progress' }, containerButtons);\n containerButtons.appendChild(document.createElement('br'));\n Utils.createDomElement('button', { value: '100', className: 'slick-btn slick-btn-default', textContent: 'Complete' }, containerButtons);\n\n this.input.focus();\n this.input.select();\n\n this.slider.addEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider.addEventListener('change', this.sliderChangeHandler.bind(this));\n\n const buttons = this.picker.querySelectorAll('.editor-percentcomplete-buttons button');\n [].forEach.call(buttons, (button: HTMLButtonElement) => {\n button.addEventListener('click', this.onClick.bind(this) as EventListener);\n });\n };\n\n onClick(e: MouseEvent & { target: HTMLButtonElement }) {\n this.input.value = String(e.target.value ?? '');\n this.slider!.value = String(e.target.value ?? '');\n };\n\n destroy() {\n this.slider?.removeEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\n this.slider?.removeEventListener('change', this.sliderChangeHandler.bind(this));\n this.picker.querySelectorAll('.editor-percentcomplete-buttons button')\n .forEach(button => button.removeEventListener('click', this.onClick.bind(this) as EventListener));\n this.input.remove();\n this.picker.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.defaultValue = item[this.args.column.field];\n this.slider!.value = String(this.defaultValue ?? '');\n this.input.value = String(this.defaultValue);\n this.input.select();\n };\n\n serializeValue() {\n return parseInt(this.input.value, 10) || 0;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && ((parseInt(this.input.value as any, 10) || 0) !== this.defaultValue);\n };\n\n validate(): EditorValidationResult {\n if (isNaN(parseInt(this.input.value, 10))) {\n return {\n valid: false,\n msg: 'Please enter a valid positive number'\n };\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * An example of a 'detached' editor.\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\n */\nexport class LongTextEditor = Column, O extends GridOption = GridOption> implements Editor {\n protected input!: HTMLTextAreaElement;\n protected wrapper!: HTMLDivElement;\n protected defaultValue?: string;\n protected selectionStart = 0;\n\n constructor(protected readonly args: EditorArguments) {\n this.init();\n }\n\n init() {\n const compositeEditorOptions = this.args.compositeEditorOptions;\n this.args.grid.getOptions().editorCellNavOnLRKeys;\n const container = compositeEditorOptions ? this.args.container : document.body;\n\n this.wrapper = Utils.createDomElement('div', { className: 'slick-large-editor-text' }, container);\n if (compositeEditorOptions) {\n this.wrapper.style.position = 'relative';\n Utils.setStyleSize(this.wrapper, 'padding', 0);\n Utils.setStyleSize(this.wrapper, 'border', 0);\n } else {\n this.wrapper.style.position = 'absolute';\n }\n\n this.input = Utils.createDomElement('textarea', { rows: 5, style: { background: 'white', width: '250px', height: '80px', border: '0', outline: '0' } }, this.wrapper);\n\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\n if (compositeEditorOptions) {\n this.input.addEventListener('change', this.onChange.bind(this));\n } else {\n const btnContainer = Utils.createDomElement('div', { style: 'text-align:right' }, this.wrapper);\n Utils.createDomElement('button', { id: 'save', className: 'slick-btn slick-btn-primary', textContent: 'Save' }, btnContainer);\n Utils.createDomElement('button', { id: 'cancel', className: 'slick-btn slick-btn-default', textContent: 'Cancel' }, btnContainer);\n\n this.wrapper.querySelector('#save')!.addEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.addEventListener('click', this.cancel.bind(this));\n this.input.addEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n this.position(this.args.position as ElementPosition);\n }\n\n this.input.focus();\n this.input.select();\n };\n\n onChange() {\n const activeCell = this.args.grid.getActiveCell();\n\n // when valid, we'll also apply the new value to the dataContext item object\n if (this.validate().valid) {\n this.applyValue(this.args.item, this.serializeValue());\n }\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\n this.args.grid.onCompositeEditorChange.notify({\n row: activeCell?.row ?? 0,\n cell: activeCell?.cell ?? 0,\n item: this.args.item,\n column: this.args.column,\n formValues: this.args.compositeEditorOptions.formValues,\n grid: this.args.grid,\n editors: this.args.compositeEditorOptions.editors\n } as unknown as OnCompositeEditorChangeEventArgs);\n };\n\n handleKeyDown(e: KeyboardEvent & { target: HTMLInputElement }) {\n if (e.which === keyCode.ENTER && e.ctrlKey) {\n this.save();\n } else if (e.which === keyCode.ESCAPE) {\n e.preventDefault();\n this.cancel();\n } else if (e.which === keyCode.TAB && e.shiftKey) {\n e.preventDefault();\n this.args.grid.navigatePrev();\n } else if (e.which === keyCode.TAB) {\n e.preventDefault();\n this.args.grid.navigateNext();\n } else if (e.which === keyCode.LEFT || e.which === keyCode.RIGHT) {\n if (this.args.grid.getOptions().editorCellNavOnLRKeys) {\n const cursorPosition = this.selectionStart;\n const textLength = e.target.value.length;\n if (e.keyCode === keyCode.LEFT && cursorPosition === 0) {\n this.args.grid.navigatePrev();\n }\n if (e.keyCode === keyCode.RIGHT && cursorPosition >= textLength - 1) {\n this.args.grid.navigateNext();\n }\n }\n }\n };\n\n save() {\n const gridOptions = this.args.grid.getOptions() || {};\n if (gridOptions.autoCommitEdit) {\n this.args.grid.getEditorLock().commitCurrentEdit();\n } else {\n this.args.commitChanges();\n }\n };\n\n cancel() {\n this.input.value = String(this.defaultValue ?? '');\n this.args.cancelChanges();\n };\n\n hide() {\n Utils.hide(this.wrapper);\n };\n\n show() {\n Utils.show(this.wrapper);\n };\n\n position(position: ElementPosition) {\n Utils.setStyleSize(this.wrapper, 'top', (position.top || 0) - 5);\n Utils.setStyleSize(this.wrapper, 'left', (position.left || 0) - 2);\n };\n\n destroy() {\n if (this.args.compositeEditorOptions) {\n this.input.removeEventListener('change', this.onChange.bind(this));\n } else {\n this.wrapper.querySelector('#save')!.removeEventListener('click', this.save.bind(this));\n this.wrapper.querySelector('#cancel')!.removeEventListener('click', this.cancel.bind(this));\n this.input.removeEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\n }\n this.wrapper.remove();\n };\n\n focus() {\n this.input.focus();\n };\n\n loadValue(item: any) {\n this.input.value = this.defaultValue = item[this.args.column.field];\n this.input.select();\n };\n\n serializeValue() {\n return this.input.value;\n };\n\n applyValue(item: any, state: any) {\n item[this.args.column.field] = state;\n };\n\n isValueChanged() {\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\n };\n\n validate() {\n if (this.args.column.validator) {\n const validationResults = this.args.column.validator(this.input.value, this.args);\n if (!validationResults.valid) {\n return validationResults;\n }\n }\n\n return {\n valid: true,\n msg: null\n };\n };\n}\n\n/*\n * Depending on the value of Grid option 'editorCellNavOnLRKeys', us\n * Navigate to the cell on the left if the cursor is at the beginning of the input string\n * and to the right cell if it's at the end. Otherwise, move the cursor within the text\n */\nfunction handleKeydownLRNav(e: KeyboardEvent & { target: HTMLInputElement; selectionStart: number; }) {\n const cursorPosition = e.selectionStart;\n const textLength = e.target.value.length;\n if ((e.keyCode === keyCode.LEFT && cursorPosition > 0) ||\n e.keyCode === keyCode.RIGHT && cursorPosition < textLength - 1) {\n e.stopImmediatePropagation();\n }\n}\n\nfunction handleKeydownLRNoNav(e: KeyboardEvent) {\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\n e.stopImmediatePropagation();\n }\n}\n\nexport const Editors = {\n Text: TextEditor,\n Integer: IntegerEditor,\n Float: FloatEditor,\n Flatpickr: FlatpickrEditor,\n YesNoSelect: YesNoSelectEditor,\n Checkbox: CheckboxEditor,\n PercentComplete: PercentCompleteEditor,\n LongText: LongTextEditor\n};\n\n// extend Slick namespace on window object when building as iife\nif (IIFE_ONLY && window.Slick) {\n Utils.extend(Slick, {\n Editors\n });\n}\n\n"], - "mappings": "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", - "names": [] + "sourcesContent": ["import type { Column, Editor, EditorArguments, EditorValidationResult, ElementPosition, GridOption, OnCompositeEditorChangeEventArgs } from './models/index';\r\nimport { keyCode as keyCode_, Utils as Utils_ } from './slick.core';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\n\r\n/***\r\n * Contains basic SlickGrid editors.\r\n * @module Editors\r\n * @namespace Slick\r\n */\r\n\r\nexport class TextEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: number | string;\r\n protected navOnLR?: boolean;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\r\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\r\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.focus();\r\n this.input.select();\r\n\r\n // don't show Save/Cancel when it's a Composite Editor and also trigger a onCompositeEditorChange event when input changes\r\n if (this.args.compositeEditorOptions) {\r\n this.input.addEventListener('change', this.onChange.bind(this));\r\n }\r\n }\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n }\r\n\r\n destroy() {\r\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.removeEventListener('change', this.onChange.bind(this));\r\n this.input.remove();\r\n }\r\n\r\n focus() {\r\n this.input.focus();\r\n }\r\n\r\n getValue() {\r\n return this.input.value;\r\n }\r\n\r\n setValue(val: string) {\r\n this.input.value = val;\r\n }\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = item[this.args.column.field] || '';\r\n this.input.value = String(this.defaultValue ?? '');\r\n this.input.defaultValue = String(this.defaultValue ?? '');\r\n this.input.select();\r\n }\r\n\r\n serializeValue() {\r\n return this.input.value;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\r\n }\r\n\r\n validate() {\r\n if (this.args.column.validator) {\r\n const validationResults = this.args.column.validator(this.input.value, this.args);\r\n if (!validationResults.valid) {\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class IntegerEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: string | number;\r\n protected navOnLR?: boolean;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\r\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\r\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.focus();\r\n this.input.select();\r\n\r\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n this.input.addEventListener('change', this.onChange.bind(this));\r\n }\r\n }\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n }\r\n\r\n destroy() {\r\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.removeEventListener('change', this.onChange.bind(this));\r\n this.input.remove();\r\n }\r\n\r\n focus() {\r\n this.input.focus();\r\n }\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = item[this.args.column.field];\r\n this.input.value = String(this.defaultValue ?? '');\r\n this.input.defaultValue = String(this.defaultValue ?? '');\r\n this.input.select();\r\n }\r\n\r\n serializeValue() {\r\n return parseInt(this.input.value, 10) || 0;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\r\n }\r\n\r\n validate() {\r\n if (isNaN(this.input.value as unknown as number)) {\r\n return {\r\n valid: false,\r\n msg: 'Please enter a valid integer'\r\n };\r\n }\r\n\r\n if (this.args.column.validator) {\r\n const validationResults = this.args.column.validator(this.input.value, this.args);\r\n if (!validationResults.valid) {\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class FloatEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: string | number;\r\n protected navOnLR?: boolean;\r\n\r\n /** Default number of decimal places to use with FloatEditor */\r\n static DefaultDecimalPlaces?: number = undefined;\r\n\r\n /** Should we allow empty value when using FloatEditor */\r\n static AllowEmptyValue = false;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n this.navOnLR = this.args.grid.getOptions().editorCellNavOnLRKeys;\r\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\r\n this.input.addEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.focus();\r\n this.input.select();\r\n\r\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n this.input.addEventListener('change', this.onChange.bind(this));\r\n }\r\n };\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n };\r\n\r\n destroy() {\r\n this.input.removeEventListener('keydown', (this.navOnLR ? handleKeydownLRNav : handleKeydownLRNoNav) as EventListener);\r\n this.input.removeEventListener('change', this.onChange.bind(this));\r\n this.input.remove();\r\n };\r\n\r\n focus() {\r\n this.input.focus();\r\n }\r\n\r\n getDecimalPlaces() {\r\n // returns the number of fixed decimal places or null\r\n let rtn: number | undefined = this.args.column.editorFixedDecimalPlaces;\r\n if (!Utils.isDefined(rtn)) {\r\n rtn = FloatEditor.DefaultDecimalPlaces;\r\n }\r\n return (!rtn && rtn !== 0 ? null : rtn);\r\n }\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = item[this.args.column.field];\r\n\r\n const decPlaces = this.getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (this.defaultValue || this.defaultValue === 0)\r\n && (this.defaultValue as number)?.toFixed) {\r\n this.defaultValue = (this.defaultValue as number).toFixed(decPlaces);\r\n }\r\n\r\n this.input.value = String(this.defaultValue ?? '');\r\n this.input.defaultValue = String(this.defaultValue ?? '');\r\n this.input.select();\r\n }\r\n\r\n serializeValue() {\r\n let rtn: number | undefined = parseFloat(this.input.value);\r\n if (FloatEditor.AllowEmptyValue) {\r\n if (!rtn && rtn !== 0) {\r\n rtn = undefined;\r\n }\r\n } else {\r\n rtn = rtn || 0;\r\n }\r\n\r\n const decPlaces = this.getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (rtn || rtn === 0)\r\n && rtn.toFixed) {\r\n rtn = parseFloat(rtn.toFixed(decPlaces));\r\n }\r\n\r\n return rtn as number;\r\n }\r\n\r\n applyValue(item: any, state: number | string) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\r\n }\r\n\r\n validate() {\r\n if (isNaN(this.input.value as unknown as number)) {\r\n return {\r\n valid: false,\r\n msg: 'Please enter a valid number'\r\n };\r\n }\r\n\r\n if (this.args.column.validator) {\r\n const validationResults = this.args.column.validator(this.input.value, this.args);\r\n if (!validationResults.valid) {\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class FlatpickrEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: string | number;\r\n protected flatpickrInstance: any;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n if (typeof flatpickr === 'undefined') {\r\n throw new Error('Flatpickr not loaded but required in SlickGrid.Editors, refer to Flatpickr documentation: https://flatpickr.js.org/getting-started/');\r\n }\r\n }\r\n\r\n init() {\r\n this.input = Utils.createDomElement('input', { type: 'text', className: 'editor-text' }, this.args.container);\r\n this.input.focus();\r\n this.input.select();\r\n const editorOptions = this.args.column.params?.editorOptions; // i.e.: { id: 'start', params: { editorOptions: {altFormat: 'd/m/Y', dateFormat: 'd/m/Y'}} }\r\n this.flatpickrInstance = flatpickr(this.input, {\r\n closeOnSelect: true,\r\n allowInput: true,\r\n altInput: true,\r\n altFormat: editorOptions?.altFormat ?? 'm/d/Y',\r\n dateFormat: editorOptions?.dateFormat ?? 'm/d/Y',\r\n onChange: () => {\r\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n }\r\n },\r\n });\r\n\r\n if (!this.args.compositeEditorOptions) {\r\n setTimeout(() => {\r\n this.show();\r\n this.focus();\r\n }, 50);\r\n }\r\n\r\n Utils.width(this.input, (Utils.width(this.input) as number) - (!this.args.compositeEditorOptions ? 18 : 28));\r\n }\r\n\r\n destroy() {\r\n this.hide();\r\n if (this.flatpickrInstance) {\r\n this.flatpickrInstance.destroy();\r\n }\r\n this.input.remove();\r\n }\r\n\r\n show() {\r\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\r\n this.flatpickrInstance.open();\r\n }\r\n }\r\n\r\n hide() {\r\n if (!this.args.compositeEditorOptions && this.flatpickrInstance) {\r\n this.flatpickrInstance.close();\r\n }\r\n }\r\n\r\n focus() {\r\n this.input.focus();\r\n }\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = item[this.args.column.field];\r\n this.input.value = String(this.defaultValue ?? '');\r\n this.input.defaultValue = String(this.defaultValue ?? '');\r\n this.input.select();\r\n if (this.flatpickrInstance) {\r\n this.flatpickrInstance.setDate(this.defaultValue);\r\n }\r\n }\r\n\r\n serializeValue() {\r\n return this.input.value;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\r\n }\r\n\r\n validate() {\r\n if (this.args.column.validator) {\r\n const validationResults = this.args.column.validator(this.input.value, this.args);\r\n if (!validationResults.valid) {\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class YesNoSelectEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected select!: HTMLSelectElement;\r\n protected defaultValue?: string | number;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n this.select = Utils.createDomElement('select', { tabIndex: 0, className: 'editor-yesno' }, this.args.container);\r\n Utils.createDomElement('option', { value: 'yes', textContent: 'Yes' }, this.select);\r\n Utils.createDomElement('option', { value: 'no', textContent: 'No' }, this.select);\r\n\r\n this.select.focus();\r\n\r\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n this.select.addEventListener('change', this.onChange.bind(this));\r\n }\r\n }\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n }\r\n\r\n destroy() {\r\n this.select.removeEventListener('change', this.onChange.bind(this));\r\n this.select.remove();\r\n }\r\n\r\n focus() {\r\n this.select.focus();\r\n }\r\n\r\n loadValue(item: any) {\r\n this.select.value = ((this.defaultValue = item[this.args.column.field]) ? 'yes' : 'no');\r\n }\r\n\r\n serializeValue() {\r\n return this.select.value === 'yes';\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return this.select.value !== this.defaultValue;\r\n }\r\n\r\n validate() {\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class CheckboxEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: boolean;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n this.input = Utils.createDomElement('input', { className: 'editor-checkbox', type: 'checkbox', value: 'true' }, this.args.container);\r\n this.input.focus();\r\n\r\n // trigger onCompositeEditorChange event when input checkbox changes and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n this.input.addEventListener('change', this.onChange.bind(this));\r\n }\r\n };\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n };\r\n\r\n destroy() {\r\n this.input.removeEventListener('change', this.onChange.bind(this));\r\n this.input.remove();\r\n };\r\n\r\n focus() {\r\n this.input.focus();\r\n };\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = !!(item[this.args.column.field]);\r\n if (this.defaultValue) {\r\n this.input.checked = true;\r\n } else {\r\n this.input.checked = false;\r\n }\r\n };\r\n\r\n serializeValue() {\r\n return this.input.checked;\r\n };\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n }\r\n\r\n isValueChanged() {\r\n return (this.serializeValue() !== this.defaultValue);\r\n }\r\n\r\n validate(): EditorValidationResult {\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n\r\nexport class PercentCompleteEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLInputElement;\r\n protected defaultValue?: number;\r\n protected picker!: HTMLDivElement;\r\n protected slider!: HTMLInputElement | null;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n sliderInputHandler(e: MouseEvent & { target: HTMLButtonElement }) {\r\n this.input.value = e.target.value;\r\n }\r\n\r\n sliderChangeHandler() {\r\n // trigger onCompositeEditorChange event when slider stops and it's a Composite Editor\r\n if (this.args.compositeEditorOptions) {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n }\r\n }\r\n\r\n init() {\r\n this.input = Utils.createDomElement('input', { className: 'editor-percentcomplete', type: 'text' }, this.args.container);\r\n Utils.width(this.input, this.args.container.clientWidth - 25);\r\n\r\n this.picker = Utils.createDomElement('div', { className: 'editor-percentcomplete-picker' }, this.args.container);\r\n Utils.createDomElement('span', { className: 'editor-percentcomplete-picker-icon' }, this.picker);\r\n const containerHelper = Utils.createDomElement('div', { className: 'editor-percentcomplete-helper' }, this.picker);\r\n const containerWrapper = Utils.createDomElement('div', { className: 'editor-percentcomplete-wrapper' }, containerHelper);\r\n Utils.createDomElement('div', { className: 'editor-percentcomplete-slider' }, containerWrapper);\r\n this.slider = Utils.createDomElement('input', { className: 'editor-percentcomplete-slider', type: 'range', value: String(this.defaultValue ?? '') }, containerWrapper);\r\n const containerButtons = Utils.createDomElement('div', { className: 'editor-percentcomplete-buttons' }, containerWrapper);\r\n Utils.createDomElement('button', { value: '0', className: 'slick-btn slick-btn-default', textContent: 'Not started' }, containerButtons);\r\n containerButtons.appendChild(document.createElement('br'));\r\n Utils.createDomElement('button', { value: '50', className: 'slick-btn slick-btn-default', textContent: 'In Progress' }, containerButtons);\r\n containerButtons.appendChild(document.createElement('br'));\r\n Utils.createDomElement('button', { value: '100', className: 'slick-btn slick-btn-default', textContent: 'Complete' }, containerButtons);\r\n\r\n this.input.focus();\r\n this.input.select();\r\n\r\n this.slider.addEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\r\n this.slider.addEventListener('change', this.sliderChangeHandler.bind(this));\r\n\r\n const buttons = this.picker.querySelectorAll('.editor-percentcomplete-buttons button');\r\n [].forEach.call(buttons, (button: HTMLButtonElement) => {\r\n button.addEventListener('click', this.onClick.bind(this) as EventListener);\r\n });\r\n };\r\n\r\n onClick(e: MouseEvent & { target: HTMLButtonElement }) {\r\n this.input.value = String(e.target.value ?? '');\r\n this.slider!.value = String(e.target.value ?? '');\r\n };\r\n\r\n destroy() {\r\n this.slider?.removeEventListener('input', this.sliderInputHandler.bind(this) as EventListener);\r\n this.slider?.removeEventListener('change', this.sliderChangeHandler.bind(this));\r\n this.picker.querySelectorAll('.editor-percentcomplete-buttons button')\r\n .forEach(button => button.removeEventListener('click', this.onClick.bind(this) as EventListener));\r\n this.input.remove();\r\n this.picker.remove();\r\n };\r\n\r\n focus() {\r\n this.input.focus();\r\n };\r\n\r\n loadValue(item: any) {\r\n this.defaultValue = item[this.args.column.field];\r\n this.slider!.value = String(this.defaultValue ?? '');\r\n this.input.value = String(this.defaultValue);\r\n this.input.select();\r\n };\r\n\r\n serializeValue() {\r\n return parseInt(this.input.value, 10) || 0;\r\n };\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n };\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && ((parseInt(this.input.value as any, 10) || 0) !== this.defaultValue);\r\n };\r\n\r\n validate(): EditorValidationResult {\r\n if (isNaN(parseInt(this.input.value, 10))) {\r\n return {\r\n valid: false,\r\n msg: 'Please enter a valid positive number'\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n}\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class LongTextEditor = Column, O extends GridOption = GridOption> implements Editor {\r\n protected input!: HTMLTextAreaElement;\r\n protected wrapper!: HTMLDivElement;\r\n protected defaultValue?: string;\r\n protected selectionStart = 0;\r\n\r\n constructor(protected readonly args: EditorArguments) {\r\n this.init();\r\n }\r\n\r\n init() {\r\n const compositeEditorOptions = this.args.compositeEditorOptions;\r\n this.args.grid.getOptions().editorCellNavOnLRKeys;\r\n const container = compositeEditorOptions ? this.args.container : document.body;\r\n\r\n this.wrapper = Utils.createDomElement('div', { className: 'slick-large-editor-text' }, container);\r\n if (compositeEditorOptions) {\r\n this.wrapper.style.position = 'relative';\r\n Utils.setStyleSize(this.wrapper, 'padding', 0);\r\n Utils.setStyleSize(this.wrapper, 'border', 0);\r\n } else {\r\n this.wrapper.style.position = 'absolute';\r\n }\r\n\r\n this.input = Utils.createDomElement('textarea', { rows: 5, style: { background: 'white', width: '250px', height: '80px', border: '0', outline: '0' } }, this.wrapper);\r\n\r\n // trigger onCompositeEditorChange event when input changes and it's a Composite Editor\r\n if (compositeEditorOptions) {\r\n this.input.addEventListener('change', this.onChange.bind(this));\r\n } else {\r\n const btnContainer = Utils.createDomElement('div', { style: 'text-align:right' }, this.wrapper);\r\n Utils.createDomElement('button', { id: 'save', className: 'slick-btn slick-btn-primary', textContent: 'Save' }, btnContainer);\r\n Utils.createDomElement('button', { id: 'cancel', className: 'slick-btn slick-btn-default', textContent: 'Cancel' }, btnContainer);\r\n\r\n this.wrapper.querySelector('#save')!.addEventListener('click', this.save.bind(this));\r\n this.wrapper.querySelector('#cancel')!.addEventListener('click', this.cancel.bind(this));\r\n this.input.addEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\r\n this.position(this.args.position as ElementPosition);\r\n }\r\n\r\n this.input.focus();\r\n this.input.select();\r\n };\r\n\r\n onChange() {\r\n const activeCell = this.args.grid.getActiveCell();\r\n\r\n // when valid, we'll also apply the new value to the dataContext item object\r\n if (this.validate().valid) {\r\n this.applyValue(this.args.item, this.serializeValue());\r\n }\r\n this.applyValue(this.args.compositeEditorOptions.formValues, this.serializeValue());\r\n this.args.grid.onCompositeEditorChange.notify({\r\n row: activeCell?.row ?? 0,\r\n cell: activeCell?.cell ?? 0,\r\n item: this.args.item,\r\n column: this.args.column,\r\n formValues: this.args.compositeEditorOptions.formValues,\r\n grid: this.args.grid,\r\n editors: this.args.compositeEditorOptions.editors\r\n } as unknown as OnCompositeEditorChangeEventArgs);\r\n };\r\n\r\n handleKeyDown(e: KeyboardEvent & { target: HTMLInputElement }) {\r\n if (e.which === keyCode.ENTER && e.ctrlKey) {\r\n this.save();\r\n } else if (e.which === keyCode.ESCAPE) {\r\n e.preventDefault();\r\n this.cancel();\r\n } else if (e.which === keyCode.TAB && e.shiftKey) {\r\n e.preventDefault();\r\n this.args.grid.navigatePrev();\r\n } else if (e.which === keyCode.TAB) {\r\n e.preventDefault();\r\n this.args.grid.navigateNext();\r\n } else if (e.which === keyCode.LEFT || e.which === keyCode.RIGHT) {\r\n if (this.args.grid.getOptions().editorCellNavOnLRKeys) {\r\n const cursorPosition = this.selectionStart;\r\n const textLength = e.target.value.length;\r\n if (e.keyCode === keyCode.LEFT && cursorPosition === 0) {\r\n this.args.grid.navigatePrev();\r\n }\r\n if (e.keyCode === keyCode.RIGHT && cursorPosition >= textLength - 1) {\r\n this.args.grid.navigateNext();\r\n }\r\n }\r\n }\r\n };\r\n\r\n save() {\r\n const gridOptions = this.args.grid.getOptions() || {};\r\n if (gridOptions.autoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n };\r\n\r\n cancel() {\r\n this.input.value = String(this.defaultValue ?? '');\r\n this.args.cancelChanges();\r\n };\r\n\r\n hide() {\r\n Utils.hide(this.wrapper);\r\n };\r\n\r\n show() {\r\n Utils.show(this.wrapper);\r\n };\r\n\r\n position(position: ElementPosition) {\r\n Utils.setStyleSize(this.wrapper, 'top', (position.top || 0) - 5);\r\n Utils.setStyleSize(this.wrapper, 'left', (position.left || 0) - 2);\r\n };\r\n\r\n destroy() {\r\n if (this.args.compositeEditorOptions) {\r\n this.input.removeEventListener('change', this.onChange.bind(this));\r\n } else {\r\n this.wrapper.querySelector('#save')!.removeEventListener('click', this.save.bind(this));\r\n this.wrapper.querySelector('#cancel')!.removeEventListener('click', this.cancel.bind(this));\r\n this.input.removeEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);\r\n }\r\n this.wrapper.remove();\r\n };\r\n\r\n focus() {\r\n this.input.focus();\r\n };\r\n\r\n loadValue(item: any) {\r\n this.input.value = this.defaultValue = item[this.args.column.field];\r\n this.input.select();\r\n };\r\n\r\n serializeValue() {\r\n return this.input.value;\r\n };\r\n\r\n applyValue(item: any, state: any) {\r\n item[this.args.column.field] = state;\r\n };\r\n\r\n isValueChanged() {\r\n return (!(this.input.value === '' && !Utils.isDefined(this.defaultValue))) && (this.input.value !== this.defaultValue);\r\n };\r\n\r\n validate() {\r\n if (this.args.column.validator) {\r\n const validationResults = this.args.column.validator(this.input.value, this.args);\r\n if (!validationResults.valid) {\r\n return validationResults;\r\n }\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n };\r\n}\r\n\r\n/*\r\n * Depending on the value of Grid option 'editorCellNavOnLRKeys', us\r\n * Navigate to the cell on the left if the cursor is at the beginning of the input string\r\n * and to the right cell if it's at the end. Otherwise, move the cursor within the text\r\n */\r\nfunction handleKeydownLRNav(e: KeyboardEvent & { target: HTMLInputElement; selectionStart: number; }) {\r\n const cursorPosition = e.selectionStart;\r\n const textLength = e.target.value.length;\r\n if ((e.keyCode === keyCode.LEFT && cursorPosition > 0) ||\r\n e.keyCode === keyCode.RIGHT && cursorPosition < textLength - 1) {\r\n e.stopImmediatePropagation();\r\n }\r\n}\r\n\r\nfunction handleKeydownLRNoNav(e: KeyboardEvent) {\r\n if (e.keyCode === keyCode.LEFT || e.keyCode === keyCode.RIGHT) {\r\n e.stopImmediatePropagation();\r\n }\r\n}\r\n\r\nexport const Editors = {\r\n Text: TextEditor,\r\n Integer: IntegerEditor,\r\n Float: FloatEditor,\r\n Flatpickr: FlatpickrEditor,\r\n YesNoSelect: YesNoSelectEditor,\r\n Checkbox: CheckboxEditor,\r\n PercentComplete: PercentCompleteEditor,\r\n LongText: LongTextEditor\r\n};\r\n\r\n// extend Slick namespace on window object when building as iife\r\nif (IIFE_ONLY && window.Slick) {\r\n Utils.extend(Slick, {\r\n Editors\r\n });\r\n}\r\n\r\n"], + "mappings": "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", + "names": ["_a", "_b"] } diff --git a/dist/browser/slick.grid.js b/dist/browser/slick.grid.js index 8de63efd..08257a70 100644 --- a/dist/browser/slick.grid.js +++ b/dist/browser/slick.grid.js @@ -24,7 +24,7 @@ this.externalPubSub = externalPubSub; ////////////////////////////////////////////////////////////////////////////////////////////// // Public API - __publicField(this, "slickGridVersion", "5.11.0"); + __publicField(this, "slickGridVersion", "5.12.0"); /** optional grid state clientId */ __publicField(this, "cid", ""); // Events @@ -170,7 +170,8 @@ doPaging: !0, autosizeColsMode: GridAutosizeColsMode.LegacyOff, autosizeColPaddingPx: 4, - scrollRenderThrottling: 50, + rowTopOffsetRenderType: "top", + scrollRenderThrottling: 10, autosizeTextAvgToMWidthRatio: 0.75, viewportSwitchToScrollModeWidthPercent: void 0, viewportMinWidthPx: void 0, @@ -1678,7 +1679,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////// // Rendering / Scrolling getRowTop(row) { - return this._options.rowHeight * row - this.offset; + return Math.round(this._options.rowHeight * row - this.offset); } getRowFromPosition(y) { return Math.floor((y + this.offset) / this._options.rowHeight); @@ -1721,7 +1722,9 @@ 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), rowDiv = Utils.createDomElement("div", { className: `ui-widget-content ${rowCss}`, role: "row", style: { top: `${this.getRowTop(row) - frozenRowOffset}px` } }), rowDivR; + let rowDiv = Utils.createDomElement("div", { className: `ui-widget-content ${rowCss}`, role: "row" }), frozenRowOffset = this.getFrozenRowOffset(row), topOffset = this.getRowTop(row) - frozenRowOffset; + this._options.rowTopOffsetRenderType === "transform" ? rowDiv.style.transform = `translateY(${topOffset}px)` : rowDiv.style.top = `${topOffset}px`; + let rowDivR; 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++) @@ -2070,8 +2073,8 @@ updateRowPositions() { for (let row in this.rowsCache) if (this.rowsCache) { - let rowNumber = row ? parseInt(row, 10) : 0; - Utils.setStyleSize(this.rowsCache[rowNumber].rowNode[0], "top", this.getRowTop(rowNumber)); + let rowNumber = row ? parseInt(row, 10) : 0, rowNode = this.rowsCache[rowNumber].rowNode[0]; + this._options.rowTopOffsetRenderType === "transform" ? rowNode.style.transform = `translateY(${this.getRowTop(rowNumber)}px)` : rowNode.style.top = `${this.getRowTop(rowNumber)}px`; } } /** (re)Render the grid */ @@ -3111,7 +3114,7 @@ * Distributed under MIT license. * All rights reserved. * - * SlickGrid v5.11.0 + * SlickGrid v5.12.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 0a6024a6..f8877704 100644 --- a/dist/browser/slick.grid.js.map +++ b/dist/browser/slick.grid.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/slick.grid.ts"], - "sourcesContent": ["// @ts-ignore\r\nimport type SortableInstance from 'sortablejs';\r\n\r\nimport type {\r\n AutoSize,\r\n CellViewportRange,\r\n Column,\r\n ColumnSort,\r\n CssStyleHash,\r\n CSSStyleDeclarationWritable,\r\n CustomDataView,\r\n DOMEvent,\r\n DragPosition,\r\n DragRowMove,\r\n Editor,\r\n EditorArguments,\r\n EditorConstructor,\r\n EditController,\r\n Formatter,\r\n FormatterOverrideCallback,\r\n FormatterResultObject,\r\n FormatterResultWithHtml,\r\n FormatterResultWithText,\r\n GridOption as BaseGridOption,\r\n InteractionBase,\r\n ItemMetadata,\r\n MenuCommandItemCallbackArgs,\r\n MultiColumnSort,\r\n OnActivateChangedOptionsEventArgs,\r\n OnActiveCellChangedEventArgs,\r\n OnAddNewRowEventArgs,\r\n OnAutosizeColumnsEventArgs,\r\n OnBeforeUpdateColumnsEventArgs,\r\n OnBeforeAppendCellEventArgs,\r\n OnBeforeCellEditorDestroyEventArgs,\r\n OnBeforeColumnsResizeEventArgs,\r\n OnBeforeEditCellEventArgs,\r\n OnBeforeHeaderCellDestroyEventArgs,\r\n OnBeforeHeaderRowCellDestroyEventArgs,\r\n OnBeforeFooterRowCellDestroyEventArgs,\r\n OnBeforeSetColumnsEventArgs,\r\n OnCellChangeEventArgs,\r\n OnCellCssStylesChangedEventArgs,\r\n OnClickEventArgs,\r\n OnColumnsDragEventArgs,\r\n OnColumnsReorderedEventArgs,\r\n OnColumnsResizedEventArgs,\r\n OnColumnsResizeDblClickEventArgs,\r\n OnCompositeEditorChangeEventArgs,\r\n OnDblClickEventArgs,\r\n OnFooterContextMenuEventArgs,\r\n OnFooterRowCellRenderedEventArgs,\r\n OnHeaderCellRenderedEventArgs,\r\n OnFooterClickEventArgs,\r\n OnHeaderClickEventArgs,\r\n OnHeaderContextMenuEventArgs,\r\n OnHeaderMouseEventArgs,\r\n OnHeaderRowCellRenderedEventArgs,\r\n OnKeyDownEventArgs,\r\n OnPreHeaderContextMenuEventArgs,\r\n OnPreHeaderClickEventArgs,\r\n OnRenderedEventArgs,\r\n OnSelectedRowsChangedEventArgs,\r\n OnSetOptionsEventArgs,\r\n OnScrollEventArgs,\r\n OnValidationErrorEventArgs,\r\n PagingInfo,\r\n RowInfo,\r\n SelectionModel,\r\n SingleColumnSort,\r\n SlickGridModel,\r\n SlickPlugin,\r\n} from './models/index';\r\nimport {\r\n type BasePubSub,\r\n BindingEventService as BindingEventService_,\r\n ColAutosizeMode as ColAutosizeMode_,\r\n GlobalEditorLock as GlobalEditorLock_,\r\n GridAutosizeColsMode as GridAutosizeColsMode_,\r\n keyCode as keyCode_,\r\n preClickClassName as preClickClassName_,\r\n RowSelectionMode as RowSelectionMode_,\r\n type SlickEditorLock,\r\n SlickEvent as SlickEvent_,\r\n SlickEventData as SlickEventData_,\r\n SlickRange as SlickRange_,\r\n Utils as Utils_,\r\n ValueFilterMode as ValueFilterMode_,\r\n WidthEvalMode as WidthEvalMode_,\r\n} from './slick.core';\r\nimport { Draggable as Draggable_, MouseWheel as MouseWheel_, Resizable as Resizable_ } from './slick.interactions';\r\n\r\n// for (iife) load Slick methods from global Slick object, or use imports for (esm)\r\nconst BindingEventService = IIFE_ONLY ? Slick.BindingEventService : BindingEventService_;\r\nconst ColAutosizeMode = IIFE_ONLY ? Slick.ColAutosizeMode : ColAutosizeMode_;\r\nconst SlickEvent = IIFE_ONLY ? Slick.Event : SlickEvent_;\r\nconst SlickEventData = IIFE_ONLY ? Slick.EventData : SlickEventData_;\r\nconst GlobalEditorLock = IIFE_ONLY ? Slick.GlobalEditorLock : GlobalEditorLock_;\r\nconst GridAutosizeColsMode = IIFE_ONLY ? Slick.GridAutosizeColsMode : GridAutosizeColsMode_;\r\nconst keyCode = IIFE_ONLY ? Slick.keyCode : keyCode_;\r\nconst preClickClassName = IIFE_ONLY ? Slick.preClickClassName : preClickClassName_;\r\nconst SlickRange = IIFE_ONLY ? Slick.Range : SlickRange_;\r\nconst RowSelectionMode = IIFE_ONLY ? Slick.RowSelectionMode : RowSelectionMode_;\r\nconst ValueFilterMode = IIFE_ONLY ? Slick.ValueFilterMode : ValueFilterMode_;\r\nconst Utils = IIFE_ONLY ? Slick.Utils : Utils_;\r\nconst WidthEvalMode = IIFE_ONLY ? Slick.WidthEvalMode : WidthEvalMode_;\r\nconst Draggable = IIFE_ONLY ? Slick.Draggable : Draggable_;\r\nconst MouseWheel = IIFE_ONLY ? Slick.MouseWheel : MouseWheel_;\r\nconst Resizable = IIFE_ONLY ? Slick.Resizable : Resizable_;\r\n\r\n/**\r\n * @license\r\n * (c) 2009-present Michael Leibman\r\n * michael{dot}leibman{at}gmail{dot}com\r\n * http://github.com/mleibman/slickgrid\r\n *\r\n * Distributed under MIT license.\r\n * All rights reserved.\r\n *\r\n * SlickGrid v5.11.0\r\n *\r\n * NOTES:\r\n * Cell/row DOM manipulations are done directly bypassing JS DOM manipulation methods.\r\n * This increases the speed dramatically, but can only be done safely because there are no event handlers\r\n * or data associated with any cell/row DOM nodes. Cell editors must make sure they implement .destroy()\r\n * and do proper cleanup.\r\n */\r\n\r\n//////////////////////////////////////////////////////////////////////////////////////////////\r\n// SlickGrid class implementation (available as SlickGrid)\r\n\r\ninterface RowCaching {\r\n rowNode: HTMLElement[] | null,\r\n cellColSpans: Array;\r\n cellNodesByColumnIdx: HTMLElement[];\r\n cellRenderQueue: any[];\r\n}\r\n\r\nexport class SlickGrid = Column, O extends BaseGridOption = BaseGridOption> {\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Public API\r\n slickGridVersion = '5.11.0';\r\n\r\n /** optional grid state clientId */\r\n cid = '';\r\n\r\n // Events\r\n onActiveCellChanged: SlickEvent_;\r\n onActiveCellPositionChanged: SlickEvent_<{ grid: SlickGrid; }>;\r\n onAddNewRow: SlickEvent_;\r\n onAutosizeColumns: SlickEvent_;\r\n onBeforeAppendCell: SlickEvent_;\r\n onBeforeCellEditorDestroy: SlickEvent_;\r\n onBeforeColumnsResize: SlickEvent_;\r\n onBeforeDestroy: SlickEvent_<{ grid: SlickGrid; }>;\r\n onBeforeEditCell: SlickEvent_;\r\n onBeforeFooterRowCellDestroy: SlickEvent_;\r\n onBeforeHeaderCellDestroy: SlickEvent_;\r\n onBeforeHeaderRowCellDestroy: SlickEvent_;\r\n onBeforeSetColumns: SlickEvent_;\r\n onBeforeSort: SlickEvent_;\r\n onBeforeUpdateColumns: SlickEvent_;\r\n onCellChange: SlickEvent_;\r\n onCellCssStylesChanged: SlickEvent_;\r\n onClick: SlickEvent_;\r\n onColumnsReordered: SlickEvent_;\r\n onColumnsDrag: SlickEvent_;\r\n onColumnsResized: SlickEvent_;\r\n onColumnsResizeDblClick: SlickEvent_;\r\n onCompositeEditorChange: SlickEvent_;\r\n onContextMenu: SlickEvent_;\r\n onDrag: SlickEvent_;\r\n onDblClick: SlickEvent_;\r\n onDragInit: SlickEvent_;\r\n onDragStart: SlickEvent_;\r\n onDragEnd: SlickEvent_;\r\n onFooterClick: SlickEvent_;\r\n onFooterContextMenu: SlickEvent_;\r\n onFooterRowCellRendered: SlickEvent_;\r\n onHeaderCellRendered: SlickEvent_;\r\n onHeaderClick: SlickEvent_;\r\n onHeaderContextMenu: SlickEvent_;\r\n onHeaderMouseEnter: SlickEvent_;\r\n onHeaderMouseLeave: SlickEvent_;\r\n onHeaderRowCellRendered: SlickEvent_;\r\n onHeaderRowMouseEnter: SlickEvent_;\r\n onHeaderRowMouseLeave: SlickEvent_;\r\n onPreHeaderContextMenu: SlickEvent_;\r\n onPreHeaderClick: SlickEvent_;\r\n onKeyDown: SlickEvent_;\r\n onMouseEnter: SlickEvent_;\r\n onMouseLeave: SlickEvent_;\r\n onRendered: SlickEvent_;\r\n onScroll: SlickEvent_;\r\n onSelectedRowsChanged: SlickEvent_;\r\n onSetOptions: SlickEvent_;\r\n onActivateChangedOptions: SlickEvent_;\r\n onSort: SlickEvent_;\r\n onValidationError: SlickEvent_;\r\n onViewportChanged: SlickEvent_<{ grid: SlickGrid; }>;\r\n\r\n // ---\r\n // protected variables\r\n\r\n // shared across all grids on the page\r\n protected scrollbarDimensions?: { height: number; width: number; };\r\n protected maxSupportedCssHeight!: number; // browser's breaking point\r\n\r\n protected canvas: HTMLCanvasElement | null = null;\r\n protected canvas_context: CanvasRenderingContext2D | null = null;\r\n\r\n // settings\r\n protected _options!: O;\r\n protected _defaults: BaseGridOption = {\r\n alwaysShowVerticalScroll: false,\r\n alwaysAllowHorizontalScroll: false,\r\n explicitInitialization: false,\r\n rowHeight: 25,\r\n defaultColumnWidth: 80,\r\n enableHtmlRendering: true,\r\n enableAddRow: false,\r\n leaveSpaceForNewRows: false,\r\n editable: false,\r\n autoEdit: true,\r\n autoEditNewRow: true,\r\n autoCommitEdit: false,\r\n suppressActiveCellChangeOnEdit: false,\r\n enableCellNavigation: true,\r\n enableColumnReorder: true,\r\n unorderableColumnCssClass: 'unorderable',\r\n asyncEditorLoading: false,\r\n asyncEditorLoadDelay: 100,\r\n forceFitColumns: false,\r\n enableAsyncPostRender: false,\r\n asyncPostRenderDelay: 50,\r\n enableAsyncPostRenderCleanup: false,\r\n asyncPostRenderCleanupDelay: 40,\r\n auto: false,\r\n nonce: '',\r\n editorLock: GlobalEditorLock,\r\n showColumnHeader: true,\r\n showHeaderRow: false,\r\n headerRowHeight: 25,\r\n createFooterRow: false,\r\n showFooterRow: false,\r\n footerRowHeight: 25,\r\n createPreHeaderPanel: false,\r\n createTopHeaderPanel: false,\r\n showPreHeaderPanel: false,\r\n showTopHeaderPanel: false,\r\n preHeaderPanelHeight: 25,\r\n showTopPanel: false,\r\n topPanelHeight: 25,\r\n preHeaderPanelWidth: 'auto', // mostly useful for Draggable Grouping dropzone to take full width\r\n topHeaderPanelHeight: 25,\r\n topHeaderPanelWidth: 'auto', // mostly useful for Draggable Grouping dropzone to take full width\r\n formatterFactory: null,\r\n editorFactory: null,\r\n cellFlashingCssClass: 'flashing',\r\n rowHighlightCssClass: 'highlight-animate',\r\n rowHighlightDuration: 400,\r\n selectedCellCssClass: 'selected',\r\n multiSelect: true,\r\n enableTextSelectionOnCells: false,\r\n dataItemColumnValueExtractor: null,\r\n frozenBottom: false,\r\n frozenColumn: -1,\r\n frozenRow: -1,\r\n frozenRightViewportMinWidth: 100,\r\n throwWhenFrozenNotAllViewable: false,\r\n fullWidthRows: false,\r\n multiColumnSort: false,\r\n numberedMultiColumnSort: false,\r\n tristateMultiColumnSort: false,\r\n sortColNumberInSeparateSpan: false,\r\n defaultFormatter: this.defaultFormatter,\r\n forceSyncScrolling: false,\r\n addNewRowCssClass: 'new-row',\r\n preserveCopiedSelectionOnPaste: false,\r\n preventDragFromKeys: ['ctrlKey', 'metaKey'],\r\n showCellSelection: true,\r\n viewportClass: undefined,\r\n minRowBuffer: 3,\r\n emulatePagingWhenScrolling: true, // when scrolling off bottom of viewport, place new row at top of viewport\r\n editorCellNavOnLRKeys: false,\r\n enableMouseWheelScrollHandler: true,\r\n doPaging: true,\r\n autosizeColsMode: GridAutosizeColsMode.LegacyOff,\r\n autosizeColPaddingPx: 4,\r\n scrollRenderThrottling: 50,\r\n autosizeTextAvgToMWidthRatio: 0.75,\r\n viewportSwitchToScrollModeWidthPercent: undefined,\r\n viewportMinWidthPx: undefined,\r\n viewportMaxWidthPx: undefined,\r\n suppressCssChangesOnHiddenInit: false,\r\n ffMaxSupportedCssHeight: 6000000,\r\n maxSupportedCssHeight: 1000000000,\r\n sanitizer: undefined, // sanitize function, built in basic sanitizer is: Slick.RegexSanitizer(dirtyHtml)\r\n logSanitizedHtml: false, // log to console when sanitised - recommend true for testing of dev and production\r\n mixinDefaults: true,\r\n shadowRoot: undefined\r\n };\r\n\r\n protected _columnDefaults = {\r\n name: '',\r\n headerCssClass: null,\r\n defaultSortAsc: true,\r\n focusable: true,\r\n hidden: false,\r\n minWidth: 30,\r\n maxWidth: undefined,\r\n rerenderOnResize: false,\r\n reorderable: true,\r\n resizable: true,\r\n sortable: false,\r\n selectable: true,\r\n } as Partial;\r\n\r\n protected _columnAutosizeDefaults: AutoSize = {\r\n ignoreHeaderText: false,\r\n colValueArray: undefined,\r\n allowAddlPercent: undefined,\r\n formatterOverride: undefined,\r\n autosizeMode: ColAutosizeMode.ContentIntelligent,\r\n rowSelectionModeOnInit: undefined,\r\n rowSelectionMode: RowSelectionMode.FirstNRows,\r\n rowSelectionCount: 100,\r\n valueFilterMode: ValueFilterMode.None,\r\n widthEvalMode: WidthEvalMode.Auto,\r\n sizeToRemaining: undefined,\r\n widthPx: undefined,\r\n contentSizePx: 0,\r\n headerWidthPx: 0,\r\n colDataTypeOf: undefined\r\n };\r\n\r\n protected _columnResizeTimer?: any;\r\n protected _executionBlockTimer?: any;\r\n protected _flashCellTimer?: any;\r\n protected _highlightRowTimer?: any;\r\n\r\n // scroller\r\n protected th!: number; // virtual height\r\n protected h!: number; // real scrollable height\r\n protected ph!: number; // page height\r\n protected n!: number; // number of pages\r\n protected cj!: number; // \"jumpiness\" coefficient\r\n\r\n protected page = 0; // current page\r\n protected offset = 0; // current page offset\r\n protected vScrollDir = 1;\r\n protected _bindingEventService = new BindingEventService();\r\n protected initialized = false;\r\n protected _container!: HTMLElement;\r\n protected uid = `slickgrid_${Math.round(1000000 * Math.random())}`;\r\n protected _focusSink!: HTMLDivElement;\r\n protected _focusSink2!: HTMLDivElement;\r\n protected _groupHeaders: HTMLDivElement[] = [];\r\n protected _headerScroller: HTMLDivElement[] = [];\r\n protected _headers: HTMLDivElement[] = [];\r\n protected _headerRows!: HTMLDivElement[];\r\n protected _headerRowScroller!: HTMLDivElement[];\r\n protected _headerRowSpacerL!: HTMLDivElement;\r\n protected _headerRowSpacerR!: HTMLDivElement;\r\n protected _footerRow!: HTMLDivElement[];\r\n protected _footerRowScroller!: HTMLDivElement[];\r\n protected _footerRowSpacerL!: HTMLDivElement;\r\n protected _footerRowSpacerR!: HTMLDivElement;\r\n protected _preHeaderPanel!: HTMLDivElement;\r\n protected _preHeaderPanelScroller!: HTMLDivElement;\r\n protected _preHeaderPanelSpacer!: HTMLDivElement;\r\n protected _preHeaderPanelR!: HTMLDivElement;\r\n protected _preHeaderPanelScrollerR!: HTMLDivElement;\r\n protected _preHeaderPanelSpacerR!: HTMLDivElement;\r\n protected _topHeaderPanel!: HTMLDivElement;\r\n protected _topHeaderPanelScroller!: HTMLDivElement;\r\n protected _topHeaderPanelSpacer!: HTMLDivElement;\r\n protected _topPanelScrollers!: HTMLDivElement[];\r\n protected _topPanels!: HTMLDivElement[];\r\n protected _viewport!: HTMLDivElement[];\r\n protected _canvas!: HTMLDivElement[];\r\n protected _style?: HTMLStyleElement;\r\n protected _boundAncestors: HTMLElement[] = [];\r\n protected stylesheet?: { cssRules: Array<{ selectorText: string; }>; rules: Array<{ selectorText: string; }>; } | null;\r\n protected columnCssRulesL?: Array<{ selectorText: string; }>;\r\n protected columnCssRulesR?: Array<{ selectorText: string; }>;\r\n protected viewportH = 0;\r\n protected viewportW = 0;\r\n protected canvasWidth = 0;\r\n protected canvasWidthL = 0;\r\n protected canvasWidthR = 0;\r\n protected headersWidth = 0;\r\n protected headersWidthL = 0;\r\n protected headersWidthR = 0;\r\n protected viewportHasHScroll = false;\r\n protected viewportHasVScroll = false;\r\n protected headerColumnWidthDiff = 0;\r\n protected headerColumnHeightDiff = 0; // border+padding\r\n protected cellWidthDiff = 0;\r\n protected cellHeightDiff = 0;\r\n protected absoluteColumnMinWidth!: number;\r\n protected hasFrozenRows = false;\r\n protected frozenRowsHeight = 0;\r\n protected actualFrozenRow = -1;\r\n protected paneTopH = 0;\r\n protected paneBottomH = 0;\r\n protected viewportTopH = 0;\r\n protected viewportBottomH = 0;\r\n protected topPanelH = 0;\r\n protected headerRowH = 0;\r\n protected footerRowH = 0;\r\n\r\n protected tabbingDirection = 1;\r\n protected _activeCanvasNode!: HTMLDivElement;\r\n protected _activeViewportNode!: HTMLDivElement;\r\n protected activePosX!: number;\r\n protected activeRow!: number;\r\n protected activeCell!: number;\r\n protected activeCellNode: HTMLDivElement | null = null;\r\n protected currentEditor: Editor | null = null;\r\n protected serializedEditorValue: any;\r\n protected editController?: EditController;\r\n\r\n protected rowsCache: Array = {} as any;\r\n protected renderedRows = 0;\r\n protected numVisibleRows = 0;\r\n protected prevScrollTop = 0;\r\n protected scrollHeight = 0;\r\n protected scrollTop = 0;\r\n protected lastRenderedScrollTop = 0;\r\n protected lastRenderedScrollLeft = 0;\r\n protected prevScrollLeft = 0;\r\n protected scrollLeft = 0;\r\n\r\n protected selectionModel?: SelectionModel;\r\n protected selectedRows: number[] = [];\r\n\r\n protected plugins: SlickPlugin[] = [];\r\n protected cellCssClasses: CssStyleHash = {};\r\n\r\n protected columnsById: Record = {};\r\n protected sortColumns: ColumnSort[] = [];\r\n protected columnPosLeft: number[] = [];\r\n protected columnPosRight: number[] = [];\r\n\r\n protected pagingActive = false;\r\n protected pagingIsLastPage = false;\r\n\r\n protected scrollThrottle!: { enqueue: () => void; dequeue: () => void; };\r\n\r\n // async call handles\r\n protected h_editorLoader: any = null;\r\n protected h_render = null;\r\n protected h_postrender: any = null;\r\n protected h_postrenderCleanup: any = null;\r\n protected postProcessedRows: any = {};\r\n protected postProcessToRow: number = null as any;\r\n protected postProcessFromRow: number = null as any;\r\n protected postProcessedCleanupQueue: Array<{\r\n actionType: string;\r\n groupId: number;\r\n node: HTMLElement | HTMLElement[];\r\n columnIdx?: number;\r\n rowIdx?: number;\r\n }> = [];\r\n protected postProcessgroupId = 0;\r\n\r\n // perf counters\r\n protected counter_rows_rendered = 0;\r\n protected counter_rows_removed = 0;\r\n\r\n protected _paneHeaderL!: HTMLDivElement;\r\n protected _paneHeaderR!: HTMLDivElement;\r\n protected _paneTopL!: HTMLDivElement;\r\n protected _paneTopR!: HTMLDivElement;\r\n protected _paneBottomL!: HTMLDivElement;\r\n protected _paneBottomR!: HTMLDivElement;\r\n protected _headerScrollerL!: HTMLDivElement;\r\n protected _headerScrollerR!: HTMLDivElement;\r\n protected _headerL!: HTMLDivElement;\r\n protected _headerR!: HTMLDivElement;\r\n protected _groupHeadersL!: HTMLDivElement;\r\n protected _groupHeadersR!: HTMLDivElement;\r\n protected _headerRowScrollerL!: HTMLDivElement;\r\n protected _headerRowScrollerR!: HTMLDivElement;\r\n protected _footerRowScrollerL!: HTMLDivElement;\r\n protected _footerRowScrollerR!: HTMLDivElement;\r\n protected _headerRowL!: HTMLDivElement;\r\n protected _headerRowR!: HTMLDivElement;\r\n protected _footerRowL!: HTMLDivElement;\r\n protected _footerRowR!: HTMLDivElement;\r\n protected _topPanelScrollerL!: HTMLDivElement;\r\n protected _topPanelScrollerR!: HTMLDivElement;\r\n protected _topPanelL!: HTMLDivElement;\r\n protected _topPanelR!: HTMLDivElement;\r\n protected _viewportTopL!: HTMLDivElement;\r\n protected _viewportTopR!: HTMLDivElement;\r\n protected _viewportBottomL!: HTMLDivElement;\r\n protected _viewportBottomR!: HTMLDivElement;\r\n protected _canvasTopL!: HTMLDivElement;\r\n protected _canvasTopR!: HTMLDivElement;\r\n protected _canvasBottomL!: HTMLDivElement;\r\n protected _canvasBottomR!: HTMLDivElement;\r\n protected _viewportScrollContainerX!: HTMLDivElement;\r\n protected _viewportScrollContainerY!: HTMLDivElement;\r\n protected _headerScrollContainer!: HTMLDivElement;\r\n protected _headerRowScrollContainer!: HTMLDivElement;\r\n protected _footerRowScrollContainer!: HTMLDivElement;\r\n\r\n // store css attributes if display:none is active in container or parent\r\n protected cssShow = { position: 'absolute', visibility: 'hidden', display: 'block' };\r\n protected _hiddenParents: HTMLElement[] = [];\r\n protected oldProps: Array> = [];\r\n protected enforceFrozenRowHeightRecalc = false;\r\n protected columnResizeDragging = false;\r\n protected slickDraggableInstance: InteractionBase | null = null;\r\n protected slickMouseWheelInstances: Array = [];\r\n protected slickResizableInstances: Array = [];\r\n protected sortableSideLeftInstance?: SortableInstance;\r\n protected sortableSideRightInstance?: SortableInstance;\r\n protected logMessageCount = 0;\r\n protected logMessageMaxCount = 30;\r\n protected _pubSubService?: BasePubSub;\r\n\r\n /**\r\n * Creates a new instance of the grid.\r\n * @class SlickGrid\r\n * @constructor\r\n * @param {Node} container - Container node to create the grid in.\r\n * @param {Array|Object} data - An array of objects for databinding or an external DataView.\r\n * @param {Array} columns - An array of column definitions.\r\n * @param {Object} [options] - Grid Options\r\n * @param {Object} [externalPubSub] - optional External PubSub Service to use by SlickEvent\r\n **/\r\n constructor(protected readonly container: HTMLElement | string, protected data: CustomDataView | TData[], protected columns: C[], options: Partial, protected readonly externalPubSub?: BasePubSub) {\r\n this._container = typeof this.container === 'string'\r\n ? document.querySelector(this.container) as HTMLDivElement\r\n : this.container;\r\n\r\n if (!this._container) {\r\n throw new Error(`SlickGrid requires a valid container, ${this.container} does not exist in the DOM.`);\r\n }\r\n\r\n this._pubSubService = externalPubSub;\r\n this.onActiveCellChanged = new SlickEvent('onActiveCellChanged', externalPubSub);\r\n this.onActiveCellPositionChanged = new SlickEvent<{ grid: SlickGrid; }>('onActiveCellPositionChanged', externalPubSub);\r\n this.onAddNewRow = new SlickEvent('onAddNewRow', externalPubSub);\r\n this.onAutosizeColumns = new SlickEvent('onAutosizeColumns', externalPubSub);\r\n this.onBeforeAppendCell = new SlickEvent('onBeforeAppendCell', externalPubSub);\r\n this.onBeforeCellEditorDestroy = new SlickEvent('onBeforeCellEditorDestroy', externalPubSub);\r\n this.onBeforeColumnsResize = new SlickEvent('onBeforeColumnsResize', externalPubSub);\r\n this.onBeforeDestroy = new SlickEvent<{ grid: SlickGrid; }>('onBeforeDestroy', externalPubSub);\r\n this.onBeforeEditCell = new SlickEvent('onBeforeEditCell', externalPubSub);\r\n this.onBeforeFooterRowCellDestroy = new SlickEvent('onBeforeFooterRowCellDestroy', externalPubSub);\r\n this.onBeforeHeaderCellDestroy = new SlickEvent('onBeforeHeaderCellDestroy', externalPubSub);\r\n this.onBeforeHeaderRowCellDestroy = new SlickEvent('onBeforeHeaderRowCellDestroy', externalPubSub);\r\n this.onBeforeSetColumns = new SlickEvent('onBeforeSetColumns', externalPubSub);\r\n this.onBeforeSort = new SlickEvent('onBeforeSort', externalPubSub);\r\n this.onBeforeUpdateColumns = new SlickEvent('onBeforeUpdateColumns', externalPubSub);\r\n this.onCellChange = new SlickEvent('onCellChange', externalPubSub);\r\n this.onCellCssStylesChanged = new SlickEvent('onCellCssStylesChanged', externalPubSub);\r\n this.onClick = new SlickEvent('onClick', externalPubSub);\r\n this.onColumnsReordered = new SlickEvent('onColumnsReordered', externalPubSub);\r\n this.onColumnsDrag = new SlickEvent('onColumnsDrag', externalPubSub);\r\n this.onColumnsResized = new SlickEvent('onColumnsResized', externalPubSub);\r\n this.onColumnsResizeDblClick = new SlickEvent('onColumnsResizeDblClick', externalPubSub);\r\n this.onCompositeEditorChange = new SlickEvent('onCompositeEditorChange', externalPubSub);\r\n this.onContextMenu = new SlickEvent('onContextMenu', externalPubSub);\r\n this.onDrag = new SlickEvent('onDrag', externalPubSub);\r\n this.onDblClick = new SlickEvent('onDblClick', externalPubSub);\r\n this.onDragInit = new SlickEvent('onDragInit', externalPubSub);\r\n this.onDragStart = new SlickEvent('onDragStart', externalPubSub);\r\n this.onDragEnd = new SlickEvent('onDragEnd', externalPubSub);\r\n this.onFooterClick = new SlickEvent('onFooterClick', externalPubSub);\r\n this.onFooterContextMenu = new SlickEvent('onFooterContextMenu', externalPubSub);\r\n this.onFooterRowCellRendered = new SlickEvent('onFooterRowCellRendered', externalPubSub);\r\n this.onHeaderCellRendered = new SlickEvent('onHeaderCellRendered', externalPubSub);\r\n this.onHeaderClick = new SlickEvent('onHeaderClick', externalPubSub);\r\n this.onHeaderContextMenu = new SlickEvent('onHeaderContextMenu', externalPubSub);\r\n this.onHeaderMouseEnter = new SlickEvent('onHeaderMouseEnter', externalPubSub);\r\n this.onHeaderMouseLeave = new SlickEvent('onHeaderMouseLeave', externalPubSub);\r\n this.onHeaderRowCellRendered = new SlickEvent('onHeaderRowCellRendered', externalPubSub);\r\n this.onHeaderRowMouseEnter = new SlickEvent('onHeaderRowMouseEnter', externalPubSub);\r\n this.onHeaderRowMouseLeave = new SlickEvent('onHeaderRowMouseLeave', externalPubSub);\r\n this.onPreHeaderClick = new SlickEvent('onPreHeaderClick', externalPubSub);\r\n this.onPreHeaderContextMenu = new SlickEvent('onPreHeaderContextMenu', externalPubSub);\r\n this.onKeyDown = new SlickEvent('onKeyDown', externalPubSub);\r\n this.onMouseEnter = new SlickEvent('onMouseEnter', externalPubSub);\r\n this.onMouseLeave = new SlickEvent('onMouseLeave', externalPubSub);\r\n this.onRendered = new SlickEvent('onRendered', externalPubSub);\r\n this.onScroll = new SlickEvent('onScroll', externalPubSub);\r\n this.onSelectedRowsChanged = new SlickEvent('onSelectedRowsChanged', externalPubSub);\r\n this.onSetOptions = new SlickEvent('onSetOptions', externalPubSub);\r\n this.onActivateChangedOptions = new SlickEvent('onActivateChangedOptions', externalPubSub);\r\n this.onSort = new SlickEvent('onSort', externalPubSub);\r\n this.onValidationError = new SlickEvent('onValidationError', externalPubSub);\r\n this.onViewportChanged = new SlickEvent<{ grid: SlickGrid; }>('onViewportChanged', externalPubSub);\r\n\r\n this.initialize(options);\r\n }\r\n\r\n //////////////////////////////////////////////////////////////////////////////////////////////\r\n // Initialization\r\n\r\n /** Initializes the grid. */\r\n init() {\r\n this.finishInitialization();\r\n }\r\n\r\n /**\r\n * Apply HTML code by 3 different ways depending on what is provided as input and what options are enabled.\r\n * 1. value is an HTMLElement or DocumentFragment, then first empty the target and simply append the HTML to the target element.\r\n * 2. value is string and `enableHtmlRendering` is enabled, then use `target.innerHTML = value;`\r\n * 3. value is string and `enableHtmlRendering` is disabled, then use `target.textContent = value;`\r\n * @param target - target element to apply to\r\n * @param val - input value can be either a string or an HTMLElement\r\n * @param options -\r\n * `emptyTarget`, defaults to true, will empty the target.\r\n * `skipEmptyReassignment`, defaults to true, when enabled it will not try to reapply an empty value when the target is already empty\r\n */\r\n applyHtmlCode(target: HTMLElement, val: string | HTMLElement | DocumentFragment, options?: { emptyTarget?: boolean; skipEmptyReassignment?: boolean; }) {\r\n if (target) {\r\n if (val instanceof HTMLElement || val instanceof DocumentFragment) {\r\n // first empty target and then append new HTML element\r\n const emptyTarget = options?.emptyTarget !== false;\r\n if (emptyTarget) {\r\n Utils.emptyElement(target);\r\n }\r\n target.appendChild(val);\r\n } else {\r\n // when it's already empty and we try to reassign empty, it's probably ok to skip the assignment\r\n const skipEmptyReassignment = options?.skipEmptyReassignment !== false;\r\n if (skipEmptyReassignment && !Utils.isDefined(val) && !target.innerHTML) {\r\n return;\r\n }\r\n\r\n let sanitizedText = val;\r\n if (typeof sanitizedText === 'number' || typeof sanitizedText === 'boolean') {\r\n target.textContent = sanitizedText;\r\n } else {\r\n sanitizedText = this.sanitizeHtmlString(val as string);\r\n\r\n // apply HTML when enableHtmlRendering is enabled but make sure we do have a value (without a value, it will simply use `textContent` to clear text content)\r\n if (this._options.enableHtmlRendering && sanitizedText) {\r\n target.innerHTML = sanitizedText;\r\n } else {\r\n target.textContent = sanitizedText;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected initialize(options: Partial) {\r\n // calculate these only once and share between grid instances\r\n if (options?.mixinDefaults) {\r\n // use provided options and then assign defaults\r\n if (!this._options) { this._options = options as O; }\r\n Utils.applyDefaults(this._options, this._defaults);\r\n } else {\r\n this._options = Utils.extend(true, {}, this._defaults, options);\r\n }\r\n this.scrollThrottle = this.actionThrottle(this.render.bind(this), this._options.scrollRenderThrottling as number);\r\n this.maxSupportedCssHeight = this.maxSupportedCssHeight || this.getMaxSupportedCssHeight();\r\n this.validateAndEnforceOptions();\r\n this._columnDefaults.width = this._options.defaultColumnWidth;\r\n\r\n if (!this._options.suppressCssChangesOnHiddenInit) {\r\n this.cacheCssForHiddenInit();\r\n }\r\n\r\n this.updateColumnProps();\r\n\r\n // validate loaded JavaScript modules against requested options\r\n if (this._options.enableColumnReorder && (!Sortable || !Sortable.create)) {\r\n throw new Error('SlickGrid requires Sortable.js module to be loaded');\r\n }\r\n\r\n this.editController = {\r\n commitCurrentEdit: this.commitCurrentEdit.bind(this),\r\n cancelCurrentEdit: this.cancelCurrentEdit.bind(this),\r\n };\r\n\r\n Utils.emptyElement(this._container);\r\n this._container.style.outline = String(0);\r\n this._container.classList.add(this.uid);\r\n this._container.classList.add('ui-widget');\r\n this._container.setAttribute('role', 'grid');\r\n\r\n const containerStyles = window.getComputedStyle(this._container);\r\n if (!(/relative|absolute|fixed/).test(containerStyles.position)) {\r\n this._container.style.position = 'relative';\r\n }\r\n\r\n this._focusSink = Utils.createDomElement('div', { tabIndex: 0, style: { position: 'fixed', width: '0px', height: '0px', top: '0px', left: '0px', outline: '0px' } }, this._container);\r\n\r\n if (this._options.createTopHeaderPanel) {\r\n this._topHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-topheader-panel slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._container);\r\n this._topHeaderPanelScroller.appendChild(document.createElement('div'));\r\n this._topHeaderPanel = Utils.createDomElement('div', null, this._topHeaderPanelScroller);\r\n this._topHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._topHeaderPanelScroller);\r\n\r\n if (!this._options.showTopHeaderPanel) {\r\n Utils.hide(this._topHeaderPanelScroller);\r\n }\r\n }\r\n\r\n // Containers used for scrolling frozen columns and rows\r\n this._paneHeaderL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneHeaderR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-header slick-pane-right', tabIndex: 0 }, this._container);\r\n this._paneTopL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneTopR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-top slick-pane-right', tabIndex: 0 }, this._container);\r\n this._paneBottomL = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-left', tabIndex: 0 }, this._container);\r\n this._paneBottomR = Utils.createDomElement('div', { className: 'slick-pane slick-pane-bottom slick-pane-right', tabIndex: 0 }, this._container);\r\n\r\n if (this._options.createPreHeaderPanel) {\r\n this._preHeaderPanelScroller = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderL);\r\n this._preHeaderPanelScroller.appendChild(document.createElement('div'));\r\n this._preHeaderPanel = Utils.createDomElement('div', null, this._preHeaderPanelScroller);\r\n this._preHeaderPanelSpacer = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScroller);\r\n\r\n this._preHeaderPanelScrollerR = Utils.createDomElement('div', { className: 'slick-preheader-panel ui-state-default slick-state-default', style: { overflow: 'hidden', position: 'relative' } }, this._paneHeaderR);\r\n this._preHeaderPanelR = Utils.createDomElement('div', null, this._preHeaderPanelScrollerR);\r\n this._preHeaderPanelSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._preHeaderPanelScrollerR);\r\n\r\n if (!this._options.showPreHeaderPanel) {\r\n Utils.hide(this._preHeaderPanelScroller);\r\n Utils.hide(this._preHeaderPanelScrollerR);\r\n }\r\n }\r\n\r\n // Append the header scroller containers\r\n this._headerScrollerL = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-left' }, this._paneHeaderL);\r\n this._headerScrollerR = Utils.createDomElement('div', { className: 'slick-header ui-state-default slick-state-default slick-header-right' }, this._paneHeaderR);\r\n\r\n // Cache the header scroller containers\r\n this._headerScroller.push(this._headerScrollerL);\r\n this._headerScroller.push(this._headerScrollerR);\r\n\r\n // Append the columnn containers to the headers\r\n this._headerL = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-left', role: 'row', style: { left: '-1000px' } }, this._headerScrollerL);\r\n this._headerR = Utils.createDomElement('div', { className: 'slick-header-columns slick-header-columns-right', role: 'row', style: { left: '-1000px' } }, this._headerScrollerR);\r\n\r\n // Cache the header columns\r\n this._headers = [this._headerL, this._headerR];\r\n\r\n this._headerRowScrollerL = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopL);\r\n this._headerRowScrollerR = Utils.createDomElement('div', { className: 'slick-headerrow ui-state-default slick-state-default' }, this._paneTopR);\r\n\r\n this._headerRowScroller = [this._headerRowScrollerL, this._headerRowScrollerR];\r\n\r\n this._headerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerL);\r\n this._headerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._headerRowScrollerR);\r\n\r\n this._headerRowL = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-left' }, this._headerRowScrollerL);\r\n this._headerRowR = Utils.createDomElement('div', { className: 'slick-headerrow-columns slick-headerrow-columns-right' }, this._headerRowScrollerR);\r\n\r\n this._headerRows = [this._headerRowL, this._headerRowR];\r\n\r\n // Append the top panel scroller\r\n this._topPanelScrollerL = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopL);\r\n this._topPanelScrollerR = Utils.createDomElement('div', { className: 'slick-top-panel-scroller ui-state-default slick-state-default' }, this._paneTopR);\r\n\r\n this._topPanelScrollers = [this._topPanelScrollerL, this._topPanelScrollerR];\r\n\r\n // Append the top panel\r\n this._topPanelL = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerL);\r\n this._topPanelR = Utils.createDomElement('div', { className: 'slick-top-panel', style: { width: '10000px' } }, this._topPanelScrollerR);\r\n\r\n this._topPanels = [this._topPanelL, this._topPanelR];\r\n\r\n if (!this._options.showColumnHeader) {\r\n this._headerScroller.forEach((el) => {\r\n Utils.hide(el);\r\n });\r\n }\r\n\r\n if (!this._options.showTopPanel) {\r\n this._topPanelScrollers.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n\r\n if (!this._options.showHeaderRow) {\r\n this._headerRowScroller.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n\r\n // Append the viewport containers\r\n this._viewportTopL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-left', tabIndex: 0 }, this._paneTopL);\r\n this._viewportTopR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-top slick-viewport-right', tabIndex: 0 }, this._paneTopR);\r\n this._viewportBottomL = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-left', tabIndex: 0 }, this._paneBottomL);\r\n this._viewportBottomR = Utils.createDomElement('div', { className: 'slick-viewport slick-viewport-bottom slick-viewport-right', tabIndex: 0 }, this._paneBottomR);\r\n\r\n // Cache the viewports\r\n this._viewport = [this._viewportTopL, this._viewportTopR, this._viewportBottomL, this._viewportBottomR];\r\n if (this._options.viewportClass) {\r\n this._viewport.forEach((view) => {\r\n view.classList.add(...Utils.classNameToList((this._options.viewportClass)));\r\n });\r\n }\r\n\r\n // Default the active viewport to the top left\r\n this._activeViewportNode = this._viewportTopL;\r\n\r\n // Append the canvas containers\r\n this._canvasTopL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-left', tabIndex: 0 }, this._viewportTopL);\r\n this._canvasTopR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-top grid-canvas-right', tabIndex: 0 }, this._viewportTopR);\r\n this._canvasBottomL = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-left', tabIndex: 0 }, this._viewportBottomL);\r\n this._canvasBottomR = Utils.createDomElement('div', { className: 'grid-canvas grid-canvas-bottom grid-canvas-right', tabIndex: 0 }, this._viewportBottomR);\r\n\r\n // Cache the canvases\r\n this._canvas = [this._canvasTopL, this._canvasTopR, this._canvasBottomL, this._canvasBottomR];\r\n\r\n this.scrollbarDimensions = this.scrollbarDimensions || this.measureScrollbar();\r\n\r\n // Default the active canvas to the top left\r\n this._activeCanvasNode = this._canvasTopL;\r\n\r\n // top-header\r\n if (this._topHeaderPanelSpacer) {\r\n Utils.width(this._topHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n }\r\n\r\n // pre-header\r\n if (this._preHeaderPanelSpacer) {\r\n Utils.width(this._preHeaderPanelSpacer, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n }\r\n\r\n this._headers.forEach((el) => {\r\n Utils.width(el, this.getHeadersWidth());\r\n });\r\n\r\n Utils.width(this._headerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n Utils.width(this._headerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n\r\n // footer Row\r\n if (this._options.createFooterRow) {\r\n this._footerRowScrollerR = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopR);\r\n this._footerRowScrollerL = Utils.createDomElement('div', { className: 'slick-footerrow ui-state-default slick-state-default' }, this._paneTopL);\r\n\r\n this._footerRowScroller = [this._footerRowScrollerL, this._footerRowScrollerR];\r\n\r\n this._footerRowSpacerL = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerL);\r\n Utils.width(this._footerRowSpacerL, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n this._footerRowSpacerR = Utils.createDomElement('div', { style: { display: 'block', height: '1px', position: 'absolute', top: '0px', left: '0px' } }, this._footerRowScrollerR);\r\n Utils.width(this._footerRowSpacerR, this.getCanvasWidth() + this.scrollbarDimensions.width);\r\n\r\n this._footerRowL = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-left' }, this._footerRowScrollerL);\r\n this._footerRowR = Utils.createDomElement('div', { className: 'slick-footerrow-columns slick-footerrow-columns-right' }, this._footerRowScrollerR);\r\n\r\n this._footerRow = [this._footerRowL, this._footerRowR];\r\n\r\n if (!this._options.showFooterRow) {\r\n this._footerRowScroller.forEach((scroller) => {\r\n Utils.hide(scroller);\r\n });\r\n }\r\n }\r\n\r\n this._focusSink2 = this._focusSink.cloneNode(true) as HTMLDivElement;\r\n this._container.appendChild(this._focusSink2);\r\n\r\n if (!this._options.explicitInitialization) {\r\n this.finishInitialization();\r\n }\r\n }\r\n\r\n protected finishInitialization() {\r\n if (!this.initialized) {\r\n this.initialized = true;\r\n\r\n this.getViewportWidth();\r\n this.getViewportHeight();\r\n\r\n // header columns and cells may have different padding/border skewing width calculations (box-sizing, hello?)\r\n // calculate the diff so we can set consistent sizes\r\n this.measureCellPaddingAndBorder();\r\n\r\n // for usability reasons, all text selection in SlickGrid is disabled\r\n // with the exception of input and textarea elements (selection must\r\n // be enabled there so that editors work as expected); note that\r\n // selection in grid cells (grid body) is already unavailable in\r\n // all browsers except IE\r\n this.disableSelection(this._headers); // disable all text selection in header (including input and textarea)\r\n\r\n if (!this._options.enableTextSelectionOnCells) {\r\n // disable text selection in grid cells except in input and textarea elements\r\n // (this is IE-specific, because selectstart event will only fire in IE)\r\n this._viewport.forEach((view) => {\r\n this._bindingEventService.bind(view, 'selectstart', (event) => {\r\n if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {\r\n return;\r\n }\r\n });\r\n });\r\n }\r\n\r\n this.setFrozenOptions();\r\n this.setPaneVisibility();\r\n this.setScroller();\r\n this.setOverflow();\r\n\r\n this.updateColumnCaches();\r\n this.createColumnHeaders();\r\n this.createColumnFooter();\r\n this.setupColumnSort();\r\n this.createCssRules();\r\n this.resizeCanvas();\r\n this.bindAncestorScrollEvents();\r\n\r\n this._bindingEventService.bind(this._container, 'resize', this.resizeCanvas.bind(this));\r\n this._viewport.forEach((view) => {\r\n this._bindingEventService.bind(view, 'scroll', this.handleScroll.bind(this));\r\n });\r\n\r\n if (this._options.enableMouseWheelScrollHandler) {\r\n this._viewport.forEach((view) => {\r\n this.slickMouseWheelInstances.push(MouseWheel({\r\n element: view,\r\n onMouseWheel: this.handleMouseWheel.bind(this)\r\n }));\r\n });\r\n }\r\n\r\n this._headerScroller.forEach((el) => {\r\n this._bindingEventService.bind(el, 'contextmenu', this.handleHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(el, 'click', this.handleHeaderClick.bind(this) as EventListener);\r\n });\r\n\r\n this._headerRowScroller.forEach((scroller) => {\r\n this._bindingEventService.bind(scroller, 'scroll', this.handleHeaderRowScroll.bind(this) as EventListener);\r\n });\r\n\r\n if (this._options.createFooterRow) {\r\n this._footerRow.forEach((footer) => {\r\n this._bindingEventService.bind(footer, 'contextmenu', this.handleFooterContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(footer, 'click', this.handleFooterClick.bind(this) as EventListener);\r\n });\r\n\r\n this._footerRowScroller.forEach((scroller) => {\r\n this._bindingEventService.bind(scroller, 'scroll', this.handleFooterRowScroll.bind(this) as EventListener);\r\n });\r\n }\r\n\r\n if (this._options.createTopHeaderPanel) {\r\n this._bindingEventService.bind(this._topHeaderPanelScroller, 'scroll', this.handleTopHeaderPanelScroll.bind(this) as EventListener);\r\n }\r\n\r\n if (this._options.createPreHeaderPanel) {\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'scroll', this.handlePreHeaderPanelScroll.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'contextmenu', this.handlePreHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScrollerR, 'contextmenu', this.handlePreHeaderContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScroller, 'click', this.handlePreHeaderClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._preHeaderPanelScrollerR, 'click', this.handlePreHeaderClick.bind(this) as EventListener);\r\n }\r\n\r\n this._bindingEventService.bind(this._focusSink, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n this._bindingEventService.bind(this._focusSink2, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n\r\n this._canvas.forEach((element) => {\r\n this._bindingEventService.bind(element, 'keydown', this.handleKeyDown.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'click', this.handleClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'dblclick', this.handleDblClick.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'contextmenu', this.handleContextMenu.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'mouseover', this.handleCellMouseOver.bind(this) as EventListener);\r\n this._bindingEventService.bind(element, 'mouseout', this.handleCellMouseOut.bind(this) as EventListener);\r\n });\r\n\r\n if (Draggable) {\r\n this.slickDraggableInstance = Draggable({\r\n containerElement: this._container,\r\n allowDragFrom: 'div.slick-cell',\r\n // the slick cell parent must always contain `.dnd` and/or `.cell-reorder` class to be identified as draggable\r\n allowDragFromClosest: 'div.slick-cell.dnd, div.slick-cell.cell-reorder',\r\n preventDragFromKeys: this._options.preventDragFromKeys,\r\n onDragInit: this.handleDragInit.bind(this),\r\n onDragStart: this.handleDragStart.bind(this),\r\n onDrag: this.handleDrag.bind(this),\r\n onDragEnd: this.handleDragEnd.bind(this)\r\n });\r\n }\r\n\r\n if (!this._options.suppressCssChangesOnHiddenInit) {\r\n this.restoreCssFromHiddenInit();\r\n }\r\n }\r\n }\r\n\r\n /** handles \"display:none\" on container or container parents, related to issue: https://github.com/6pac/SlickGrid/issues/568 */\r\n cacheCssForHiddenInit() {\r\n this._hiddenParents = Utils.parents(this._container, ':hidden') as HTMLElement[];\r\n this._hiddenParents.forEach(el => {\r\n const old: Partial = {};\r\n Object.keys(this.cssShow).forEach(name => {\r\n if (this.cssShow) {\r\n old[name as any] = el.style[name as 'position' | 'visibility' | 'display'];\r\n el.style[name as any] = this.cssShow[name as 'position' | 'visibility' | 'display'];\r\n }\r\n });\r\n this.oldProps.push(old);\r\n });\r\n }\r\n\r\n restoreCssFromHiddenInit() {\r\n // finish handle display:none on container or container parents\r\n // - put values back the way they were\r\n let i = 0;\r\n if (this._hiddenParents) {\r\n this._hiddenParents.forEach(el => {\r\n const old = this.oldProps[i++];\r\n Object.keys(this.cssShow).forEach(name => {\r\n if (this.cssShow) {\r\n el.style[name as CSSStyleDeclarationWritable] = (old as any)[name];\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected hasFrozenColumns() {\r\n return this._options.frozenColumn! > -1;\r\n }\r\n\r\n /** Register an external Plugin */\r\n registerPlugin(plugin: T) {\r\n this.plugins.unshift(plugin);\r\n plugin.init(this as unknown as SlickGridModel);\r\n }\r\n\r\n /** Unregister (destroy) an external Plugin */\r\n unregisterPlugin(plugin: SlickPlugin) {\r\n for (let i = this.plugins.length; i >= 0; i--) {\r\n if (this.plugins[i] === plugin) {\r\n this.plugins[i]?.destroy();\r\n this.plugins.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /** Get a Plugin (addon) by its name */\r\n getPluginByName

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