diff --git a/.gitignore b/.gitignore index 2a6d5c4b1..b8cb27abb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ *.zip .npmrc coverage -dist node_modules .vscode .idea/ diff --git a/dist/dd-base-impl.d.ts b/dist/dd-base-impl.d.ts new file mode 100644 index 000000000..be9e828ed --- /dev/null +++ b/dist/dd-base-impl.d.ts @@ -0,0 +1,20 @@ +/** + * dd-base-impl.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +export declare type EventCallback = (event: Event) => boolean | void; +export declare abstract class DDBaseImplement { + /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */ + get disabled(): boolean; + on(event: string, callback: EventCallback): void; + off(event: string): void; + enable(): void; + disable(): void; + destroy(): void; + triggerEvent(eventName: string, event: Event): boolean | void; +} +export interface HTMLElementExtendOpt { + el: HTMLElement; + option: T; + updateOption(T: any): DDBaseImplement; +} diff --git a/dist/dd-base-impl.js b/dist/dd-base-impl.js new file mode 100644 index 000000000..337d66910 --- /dev/null +++ b/dist/dd-base-impl.js @@ -0,0 +1,36 @@ +"use strict"; +/** + * dd-base-impl.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDBaseImplement = void 0; +class DDBaseImplement { + constructor() { + /** @internal */ + this._eventRegister = {}; + } + /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */ + get disabled() { return this._disabled; } + on(event, callback) { + this._eventRegister[event] = callback; + } + off(event) { + delete this._eventRegister[event]; + } + enable() { + this._disabled = false; + } + disable() { + this._disabled = true; + } + destroy() { + delete this._eventRegister; + } + triggerEvent(eventName, event) { + if (!this.disabled && this._eventRegister && this._eventRegister[eventName]) + return this._eventRegister[eventName](event); + } +} +exports.DDBaseImplement = DDBaseImplement; +//# sourceMappingURL=dd-base-impl.js.map \ No newline at end of file diff --git a/dist/dd-base-impl.js.map b/dist/dd-base-impl.js.map new file mode 100644 index 000000000..9dcaf2d7f --- /dev/null +++ b/dist/dd-base-impl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-base-impl.js","sourceRoot":"","sources":["../src/dd-base-impl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,MAAsB,eAAe;IAArC;QAME,gBAAgB;QACN,mBAAc,GAEpB,EAAE,CAAC;IA0BT,CAAC;IAlCC,mHAAmH;IACnH,IAAW,QAAQ,KAAgB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IASpD,EAAE,CAAC,KAAa,EAAE,QAAuB;QAC9C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACxC,CAAC;IAEM,GAAG,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAEM,YAAY,CAAC,SAAiB,EAAE,KAAY;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;YACzE,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;CACF;AAnCD,0CAmCC","sourcesContent":["/**\n * dd-base-impl.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nexport type EventCallback = (event: Event) => boolean|void;\nexport abstract class DDBaseImplement {\n /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */\n public get disabled(): boolean { return this._disabled; }\n\n /** @internal */\n protected _disabled: boolean; // initial state to differentiate from false\n /** @internal */\n protected _eventRegister: {\n [eventName: string]: EventCallback;\n } = {};\n\n public on(event: string, callback: EventCallback): void {\n this._eventRegister[event] = callback;\n }\n\n public off(event: string): void {\n delete this._eventRegister[event];\n }\n\n public enable(): void {\n this._disabled = false;\n }\n\n public disable(): void {\n this._disabled = true;\n }\n\n public destroy(): void {\n delete this._eventRegister;\n }\n\n public triggerEvent(eventName: string, event: Event): boolean|void {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\nexport interface HTMLElementExtendOpt {\n el: HTMLElement;\n option: T;\n updateOption(T): DDBaseImplement;\n}\n"]} \ No newline at end of file diff --git a/dist/dd-draggable.d.ts b/dist/dd-draggable.d.ts new file mode 100644 index 000000000..80edb07ca --- /dev/null +++ b/dist/dd-draggable.d.ts @@ -0,0 +1,28 @@ +/** + * dd-draggable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +import { DDUIData } from './types'; +export interface DDDraggableOpt { + appendTo?: string | HTMLElement; + handle?: string; + helper?: string | HTMLElement | ((event: Event) => HTMLElement); + start?: (event: Event, ui: DDUIData) => void; + stop?: (event: Event) => void; + drag?: (event: Event, ui: DDUIData) => void; +} +declare type DDDragEvent = 'drag' | 'dragstart' | 'dragstop'; +export declare class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt { + el: HTMLElement; + option: DDDraggableOpt; + helper: HTMLElement; + constructor(el: HTMLElement, option?: DDDraggableOpt); + on(event: DDDragEvent, callback: (event: DragEvent) => void): void; + off(event: DDDragEvent): void; + enable(): void; + disable(forDestroy?: boolean): void; + destroy(): void; + updateOption(opts: DDDraggableOpt): DDDraggable; +} +export {}; diff --git a/dist/dd-draggable.js b/dist/dd-draggable.js new file mode 100644 index 000000000..7ada33e09 --- /dev/null +++ b/dist/dd-draggable.js @@ -0,0 +1,313 @@ +"use strict"; +/** + * dd-draggable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDDraggable = void 0; +const dd_manager_1 = require("./dd-manager"); +const utils_1 = require("./utils"); +const dd_base_impl_1 = require("./dd-base-impl"); +const dd_touch_1 = require("./dd-touch"); +// let count = 0; // TEST +class DDDraggable extends dd_base_impl_1.DDBaseImplement { + constructor(el, option = {}) { + super(); + this.el = el; + this.option = option; + // get the element that is actually supposed to be dragged by + let className = option.handle.substring(1); + this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + this._mouseDown = this._mouseDown.bind(this); + this._mouseMove = this._mouseMove.bind(this); + this._mouseUp = this._mouseUp.bind(this); + this.enable(); + } + on(event, callback) { + super.on(event, callback); + } + off(event) { + super.off(event); + } + enable() { + if (this.disabled === false) + return; + super.enable(); + this.dragEl.addEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.dragEl.addEventListener('touchstart', dd_touch_1.touchstart); + this.dragEl.addEventListener('pointerdown', dd_touch_1.pointerdown); + // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment + } + this.el.classList.remove('ui-draggable-disabled'); + this.el.classList.add('ui-draggable'); + } + disable(forDestroy = false) { + if (this.disabled === true) + return; + super.disable(); + this.dragEl.removeEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.dragEl.removeEventListener('touchstart', dd_touch_1.touchstart); + this.dragEl.removeEventListener('pointerdown', dd_touch_1.pointerdown); + } + this.el.classList.remove('ui-draggable'); + if (!forDestroy) + this.el.classList.add('ui-draggable-disabled'); + } + destroy() { + if (this.dragging) + this._mouseUp(this.mouseDownEvent); + this.disable(true); + delete this.el; + delete this.helper; + delete this.option; + super.destroy(); + } + updateOption(opts) { + Object.keys(opts).forEach(key => this.option[key] = opts[key]); + return this; + } + /** @internal call when mouse goes down before a dragstart happens */ + _mouseDown(e) { + // don't let more than one widget handle mouseStart + if (dd_manager_1.DDManager.mouseHandled) + return; + if (e.button !== 0) + return true; // only left click + // make sure we are clicking on a drag handle or child of it... + // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins) + let className = this.option.handle.substring(1); + let el = e.target; + while (el && !el.classList.contains(className)) { + el = el.parentElement; + } + if (!el) + return; + this.mouseDownEvent = e; + delete this.dragging; + delete dd_manager_1.DDManager.dragElement; + delete dd_manager_1.DDManager.dropElement; + // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack + document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble + document.addEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.dragEl.addEventListener('touchmove', dd_touch_1.touchmove); + this.dragEl.addEventListener('touchend', dd_touch_1.touchend); + } + e.preventDefault(); + dd_manager_1.DDManager.mouseHandled = true; + return true; + } + /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */ + _mouseMove(e) { + var _a; + // console.log(`${count++} move ${e.x},${e.y}`) + let s = this.mouseDownEvent; + if (this.dragging) { + this._dragFollow(e); + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'drag' }); + if (this.option.drag) { + this.option.drag(ev, this.ui()); + } + this.triggerEvent('drag', ev); + } + else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) { + /** + * don't start unless we've moved at least 3 pixels + */ + this.dragging = true; + dd_manager_1.DDManager.dragElement = this; + // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave) + let grid = (_a = this.el.gridstackNode) === null || _a === void 0 ? void 0 : _a.grid; + if (grid) { + dd_manager_1.DDManager.dropElement = grid.el.ddElement.ddDroppable; + } + else { + delete dd_manager_1.DDManager.dropElement; + } + this.helper = this._createHelper(e); + this._setupHelperContainmentStyle(); + this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment); + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dragstart' }); + this._setupHelperStyle(e); + if (this.option.start) { + this.option.start(ev, this.ui()); + } + this.triggerEvent('dragstart', ev); + } + e.preventDefault(); + return true; + } + /** @internal call when the mouse gets released to drop the item at current location */ + _mouseUp(e) { + var _a; + document.removeEventListener('mousemove', this._mouseMove, true); + document.removeEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.dragEl.removeEventListener('touchmove', dd_touch_1.touchmove, true); + this.dragEl.removeEventListener('touchend', dd_touch_1.touchend, true); + } + if (this.dragging) { + delete this.dragging; + // reset the drop target if dragging over ourself (already parented, just moving during stop callback below) + if (((_a = dd_manager_1.DDManager.dropElement) === null || _a === void 0 ? void 0 : _a.el) === this.el.parentElement) { + delete dd_manager_1.DDManager.dropElement; + } + this.helperContainment.style.position = this.parentOriginStylePosition || null; + if (this.helper === this.el) { + this._removeHelperStyle(); + } + else { + this.helper.remove(); + } + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dragstop' }); + if (this.option.stop) { + this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after! + } + this.triggerEvent('dragstop', ev); + // call the droppable method to receive the item + if (dd_manager_1.DDManager.dropElement) { + dd_manager_1.DDManager.dropElement.drop(e); + } + } + delete this.helper; + delete this.mouseDownEvent; + delete dd_manager_1.DDManager.dragElement; + delete dd_manager_1.DDManager.dropElement; + delete dd_manager_1.DDManager.mouseHandled; + e.preventDefault(); + } + /** @internal create a clone copy (or user defined method) of the original drag item if set */ + _createHelper(event) { + let helper = this.el; + if (typeof this.option.helper === 'function') { + helper = this.option.helper(event); + } + else if (this.option.helper === 'clone') { + helper = utils_1.Utils.cloneNode(this.el); + } + if (!document.body.contains(helper)) { + utils_1.Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo); + } + if (helper === this.el) { + this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]); + } + return helper; + } + /** @internal set the fix position of the dragged item */ + _setupHelperStyle(e) { + this.helper.classList.add('ui-draggable-dragging'); + // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593 + const style = this.helper.style; + style.pointerEvents = 'none'; // needed for over items to get enter/leave + // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well) + style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %) + style.width = this.dragOffset.width + 'px'; + style.height = this.dragOffset.height + 'px'; + style.willChange = 'left, top'; + style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative' + this._dragFollow(e); // now position it + style.transition = 'none'; // show up instantly + setTimeout(() => { + if (this.helper) { + style.transition = null; // recover animation + } + }, 0); + return this; + } + /** @internal restore back the original style before dragging */ + _removeHelperStyle() { + var _a; + this.helper.classList.remove('ui-draggable-dragging'); + let node = (_a = this.helper) === null || _a === void 0 ? void 0 : _a.gridstackNode; + // don't bother restoring styles if we're gonna remove anyway... + if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) { + let helper = this.helper; + // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed' + let transition = this.dragElementOriginStyle['transition'] || null; + helper.style.transition = this.dragElementOriginStyle['transition'] = 'none'; + DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null); + setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973) + } + delete this.dragElementOriginStyle; + return this; + } + /** @internal updates the top/left position to follow the mouse */ + _dragFollow(e) { + let containmentRect = { left: 0, top: 0 }; + // if (this.helper.style.position === 'absolute') { // we use 'fixed' + // const { left, top } = this.helperContainment.getBoundingClientRect(); + // containmentRect = { left, top }; + // } + const style = this.helper.style; + const offset = this.dragOffset; + style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px'; + style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px'; + } + /** @internal */ + _setupHelperContainmentStyle() { + this.helperContainment = this.helper.parentElement; + if (this.helper.style.position !== 'fixed') { + this.parentOriginStylePosition = this.helperContainment.style.position; + if (window.getComputedStyle(this.helperContainment).position.match(/static/)) { + this.helperContainment.style.position = 'relative'; + } + } + return this; + } + /** @internal */ + _getDragOffset(event, el, parent) { + // in case ancestor has transform/perspective css properties that change the viewpoint + let xformOffsetX = 0; + let xformOffsetY = 0; + if (parent) { + const testEl = document.createElement('div'); + utils_1.Utils.addElStyles(testEl, { + opacity: '0', + position: 'fixed', + top: 0 + 'px', + left: 0 + 'px', + width: '1px', + height: '1px', + zIndex: '-999999', + }); + parent.appendChild(testEl); + const testElPosition = testEl.getBoundingClientRect(); + parent.removeChild(testEl); + xformOffsetX = testElPosition.left; + xformOffsetY = testElPosition.top; + // TODO: scale ? + } + const targetOffset = el.getBoundingClientRect(); + return { + left: targetOffset.left, + top: targetOffset.top, + offsetLeft: -event.clientX + targetOffset.left - xformOffsetX, + offsetTop: -event.clientY + targetOffset.top - xformOffsetY, + width: targetOffset.width, + height: targetOffset.height + }; + } + /** @internal TODO: set to public as called by DDDroppable! */ + ui() { + const containmentEl = this.el.parentElement; + const containmentRect = containmentEl.getBoundingClientRect(); + const offset = this.helper.getBoundingClientRect(); + return { + position: { + top: offset.top - containmentRect.top, + left: offset.left - containmentRect.left + } + /* not used by GridStack for now... + helper: [this.helper], //The object arr representing the helper that's being dragged. + offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object. + */ + }; + } +} +exports.DDDraggable = DDDraggable; +/** @internal properties we change during dragging, and restore back */ +DDDraggable.originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top']; +//# sourceMappingURL=dd-draggable.js.map \ No newline at end of file diff --git a/dist/dd-draggable.js.map b/dist/dd-draggable.js.map new file mode 100644 index 000000000..2e14bfe0e --- /dev/null +++ b/dist/dd-draggable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-draggable.js","sourceRoot":"","sources":["../src/dd-draggable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-draggable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\nimport { Utils } from './utils';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { GridItemHTMLElement, DDUIData } from './types';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, touchend, touchmove, touchstart, pointerdown } from './dd-touch';\n\n// TODO: merge with DDDragOpt ?\nexport interface DDDraggableOpt {\n appendTo?: string | HTMLElement;\n handle?: string;\n helper?: string | HTMLElement | ((event: Event) => HTMLElement);\n // containment?: string | HTMLElement; // TODO: not implemented yet\n // revert?: string | boolean | unknown; // TODO: not implemented yet\n // scroll?: boolean; // native support by HTML5 drag drop, can't be switch to off actually\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n drag?: (event: Event, ui: DDUIData) => void;\n}\n\ninterface DragOffset {\n left: number;\n top: number;\n width: number;\n height: number;\n offsetLeft: number;\n offsetTop: number;\n}\n\ntype DDDragEvent = 'drag' | 'dragstart' | 'dragstop';\n\n// let count = 0; // TEST\n\nexport class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt {\n public el: HTMLElement;\n public option: DDDraggableOpt;\n public helper: HTMLElement; // used by GridStackDDNative\n\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected dragOffset: DragOffset;\n /** @internal */\n protected dragElementOriginStyle: Array;\n /** @internal */\n protected dragEl: HTMLElement;\n /** @internal true while we are dragging an item around */\n protected dragging: boolean;\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected helperContainment: HTMLElement;\n /** @internal properties we change during dragging, and restore back */\n protected static originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top'];\n\n constructor(el: HTMLElement, option: DDDraggableOpt = {}) {\n super();\n this.el = el;\n this.option = option;\n // get the element that is actually supposed to be dragged by\n let className = option.handle.substring(1);\n this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this.enable();\n }\n\n public on(event: DDDragEvent, callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: DDDragEvent): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.dragEl.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.addEventListener('touchstart', touchstart);\n this.dragEl.addEventListener('pointerdown', pointerdown);\n // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n this.el.classList.remove('ui-draggable-disabled');\n this.el.classList.add('ui-draggable');\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.dragEl.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.removeEventListener('touchstart', touchstart);\n this.dragEl.removeEventListener('pointerdown', pointerdown);\n }\n this.el.classList.remove('ui-draggable');\n if (!forDestroy) this.el.classList.add('ui-draggable-disabled');\n }\n\n public destroy(): void {\n if (this.dragging) this._mouseUp(this.mouseDownEvent);\n this.disable(true);\n delete this.el;\n delete this.helper;\n delete this.option;\n super.destroy();\n }\n\n public updateOption(opts: DDDraggableOpt): DDDraggable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n return this;\n }\n\n /** @internal call when mouse goes down before a dragstart happens */\n protected _mouseDown(e: MouseEvent): boolean {\n // don't let more than one widget handle mouseStart\n if (DDManager.mouseHandled) return;\n if (e.button !== 0) return true; // only left click\n\n // make sure we are clicking on a drag handle or child of it...\n // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins)\n let className = this.option.handle.substring(1);\n let el = e.target as HTMLElement;\n while (el && !el.classList.contains(className)) { el = el.parentElement; }\n if (!el) return;\n this.mouseDownEvent = e;\n delete this.dragging;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack\n document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.addEventListener('touchmove', touchmove);\n this.dragEl.addEventListener('touchend', touchend);\n }\n\n e.preventDefault();\n DDManager.mouseHandled = true;\n return true;\n }\n\n /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */\n protected _mouseMove(e: DragEvent): boolean {\n // console.log(`${count++} move ${e.x},${e.y}`)\n let s = this.mouseDownEvent;\n\n if (this.dragging) {\n this._dragFollow(e);\n const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });\n if (this.option.drag) {\n this.option.drag(ev, this.ui());\n }\n this.triggerEvent('drag', ev);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {\n /**\n * don't start unless we've moved at least 3 pixels\n */\n this.dragging = true;\n DDManager.dragElement = this;\n // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)\n let grid = (this.el as GridItemHTMLElement).gridstackNode?.grid;\n if (grid) {\n DDManager.dropElement = (grid.el as DDElementHost).ddElement.ddDroppable;\n } else {\n delete DDManager.dropElement;\n }\n this.helper = this._createHelper(e);\n this._setupHelperContainmentStyle();\n this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });\n\n this._setupHelperStyle(e);\n if (this.option.start) {\n this.option.start(ev, this.ui());\n }\n this.triggerEvent('dragstart', ev);\n }\n e.preventDefault();\n return true;\n }\n\n /** @internal call when the mouse gets released to drop the item at current location */\n protected _mouseUp(e: MouseEvent): void {\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.removeEventListener('touchmove', touchmove, true);\n this.dragEl.removeEventListener('touchend', touchend, true);\n }\n if (this.dragging) {\n delete this.dragging;\n\n // reset the drop target if dragging over ourself (already parented, just moving during stop callback below)\n if (DDManager.dropElement?.el === this.el.parentElement) {\n delete DDManager.dropElement;\n }\n\n this.helperContainment.style.position = this.parentOriginStylePosition || null;\n if (this.helper === this.el) {\n this._removeHelperStyle();\n } else {\n this.helper.remove();\n }\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });\n if (this.option.stop) {\n this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!\n }\n this.triggerEvent('dragstop', ev);\n\n // call the droppable method to receive the item\n if (DDManager.dropElement) {\n DDManager.dropElement.drop(e);\n }\n }\n delete this.helper;\n delete this.mouseDownEvent;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n delete DDManager.mouseHandled;\n e.preventDefault();\n }\n\n /** @internal create a clone copy (or user defined method) of the original drag item if set */\n protected _createHelper(event: DragEvent): HTMLElement {\n let helper = this.el;\n if (typeof this.option.helper === 'function') {\n helper = this.option.helper(event);\n } else if (this.option.helper === 'clone') {\n helper = Utils.cloneNode(this.el);\n }\n if (!document.body.contains(helper)) {\n Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo);\n }\n if (helper === this.el) {\n this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);\n }\n return helper;\n }\n\n /** @internal set the fix position of the dragged item */\n protected _setupHelperStyle(e: DragEvent): DDDraggable {\n this.helper.classList.add('ui-draggable-dragging');\n // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593\n const style = this.helper.style;\n style.pointerEvents = 'none'; // needed for over items to get enter/leave\n // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well)\n style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %)\n style.width = this.dragOffset.width + 'px';\n style.height = this.dragOffset.height + 'px';\n style.willChange = 'left, top';\n style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'\n this._dragFollow(e); // now position it\n style.transition = 'none'; // show up instantly\n setTimeout(() => {\n if (this.helper) {\n style.transition = null; // recover animation\n }\n }, 0);\n return this;\n }\n\n /** @internal restore back the original style before dragging */\n protected _removeHelperStyle(): DDDraggable {\n this.helper.classList.remove('ui-draggable-dragging');\n let node = (this.helper as GridItemHTMLElement)?.gridstackNode;\n // don't bother restoring styles if we're gonna remove anyway...\n if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) {\n let helper = this.helper;\n // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'\n let transition = this.dragElementOriginStyle['transition'] || null;\n helper.style.transition = this.dragElementOriginStyle['transition'] = 'none';\n DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);\n setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)\n }\n delete this.dragElementOriginStyle;\n return this;\n }\n\n /** @internal updates the top/left position to follow the mouse */\n protected _dragFollow(e: DragEvent): void {\n let containmentRect = { left: 0, top: 0 };\n // if (this.helper.style.position === 'absolute') { // we use 'fixed'\n // const { left, top } = this.helperContainment.getBoundingClientRect();\n // containmentRect = { left, top };\n // }\n const style = this.helper.style;\n const offset = this.dragOffset;\n style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';\n style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';\n }\n\n /** @internal */\n protected _setupHelperContainmentStyle(): DDDraggable {\n this.helperContainment = this.helper.parentElement;\n if (this.helper.style.position !== 'fixed') {\n this.parentOriginStylePosition = this.helperContainment.style.position;\n if (window.getComputedStyle(this.helperContainment).position.match(/static/)) {\n this.helperContainment.style.position = 'relative';\n }\n }\n return this;\n }\n\n /** @internal */\n protected _getDragOffset(event: DragEvent, el: HTMLElement, parent: HTMLElement): DragOffset {\n\n // in case ancestor has transform/perspective css properties that change the viewpoint\n let xformOffsetX = 0;\n let xformOffsetY = 0;\n if (parent) {\n const testEl = document.createElement('div');\n Utils.addElStyles(testEl, {\n opacity: '0',\n position: 'fixed',\n top: 0 + 'px',\n left: 0 + 'px',\n width: '1px',\n height: '1px',\n zIndex: '-999999',\n });\n parent.appendChild(testEl);\n const testElPosition = testEl.getBoundingClientRect();\n parent.removeChild(testEl);\n xformOffsetX = testElPosition.left;\n xformOffsetY = testElPosition.top;\n // TODO: scale ?\n }\n\n const targetOffset = el.getBoundingClientRect();\n return {\n left: targetOffset.left,\n top: targetOffset.top,\n offsetLeft: - event.clientX + targetOffset.left - xformOffsetX,\n offsetTop: - event.clientY + targetOffset.top - xformOffsetY,\n width: targetOffset.width,\n height: targetOffset.height\n };\n }\n\n /** @internal TODO: set to public as called by DDDroppable! */\n public ui(): DDUIData {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const offset = this.helper.getBoundingClientRect();\n return {\n position: { //Current CSS position of the helper as { top, left } object\n top: offset.top - containmentRect.top,\n left: offset.left - containmentRect.left\n }\n /* not used by GridStack for now...\n helper: [this.helper], //The object arr representing the helper that's being dragged.\n offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.\n */\n };\n }\n}\n"]} \ No newline at end of file diff --git a/dist/dd-droppable.d.ts b/dist/dd-droppable.d.ts new file mode 100644 index 000000000..3d01bfbb7 --- /dev/null +++ b/dist/dd-droppable.d.ts @@ -0,0 +1,25 @@ +/** + * dd-droppable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +export interface DDDroppableOpt { + accept?: string | ((el: HTMLElement) => boolean); + drop?: (event: DragEvent, ui: any) => void; + over?: (event: DragEvent, ui: any) => void; + out?: (event: DragEvent, ui: any) => void; +} +export declare class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt { + accept: (el: HTMLElement) => boolean; + el: HTMLElement; + option: DDDroppableOpt; + constructor(el: HTMLElement, opts?: DDDroppableOpt); + on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void; + off(event: 'drop' | 'dropover' | 'dropout'): void; + enable(): void; + disable(forDestroy?: boolean): void; + destroy(): void; + updateOption(opts: DDDroppableOpt): DDDroppable; + /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */ + drop(e: MouseEvent): void; +} diff --git a/dist/dd-droppable.js b/dist/dd-droppable.js new file mode 100644 index 000000000..170f93ac3 --- /dev/null +++ b/dist/dd-droppable.js @@ -0,0 +1,149 @@ +"use strict"; +/** + * dd-droppable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDDroppable = void 0; +const dd_manager_1 = require("./dd-manager"); +const dd_base_impl_1 = require("./dd-base-impl"); +const utils_1 = require("./utils"); +const dd_touch_1 = require("./dd-touch"); +// let count = 0; // TEST +class DDDroppable extends dd_base_impl_1.DDBaseImplement { + constructor(el, opts = {}) { + super(); + this.el = el; + this.option = opts; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + this._mouseEnter = this._mouseEnter.bind(this); + this._mouseLeave = this._mouseLeave.bind(this); + this.enable(); + this._setupAccept(); + } + on(event, callback) { + super.on(event, callback); + } + off(event) { + super.off(event); + } + enable() { + if (this.disabled === false) + return; + super.enable(); + this.el.classList.add('ui-droppable'); + this.el.classList.remove('ui-droppable-disabled'); + this.el.addEventListener('mouseenter', this._mouseEnter); + this.el.addEventListener('mouseleave', this._mouseLeave); + if (dd_touch_1.isTouch) { + this.el.addEventListener('pointerenter', dd_touch_1.pointerenter); + this.el.addEventListener('pointerleave', dd_touch_1.pointerleave); + } + } + disable(forDestroy = false) { + if (this.disabled === true) + return; + super.disable(); + this.el.classList.remove('ui-droppable'); + if (!forDestroy) + this.el.classList.add('ui-droppable-disabled'); + this.el.removeEventListener('mouseenter', this._mouseEnter); + this.el.removeEventListener('mouseleave', this._mouseLeave); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('pointerenter', dd_touch_1.pointerenter); + this.el.removeEventListener('pointerleave', dd_touch_1.pointerleave); + } + } + destroy() { + this.disable(true); + this.el.classList.remove('ui-droppable'); + this.el.classList.remove('ui-droppable-disabled'); + super.destroy(); + } + updateOption(opts) { + Object.keys(opts).forEach(key => this.option[key] = opts[key]); + this._setupAccept(); + return this; + } + /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */ + _mouseEnter(e) { + // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST + if (!dd_manager_1.DDManager.dragElement) + return; + if (!this._canDrop()) + return; + e.preventDefault(); + e.stopPropagation(); + // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do + if (dd_manager_1.DDManager.dropElement && dd_manager_1.DDManager.dropElement !== this) { + dd_manager_1.DDManager.dropElement._mouseLeave(e); + } + dd_manager_1.DDManager.dropElement = this; + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dropover' }); + if (this.option.over) { + this.option.over(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('dropover', ev); + this.el.classList.add('ui-droppable-over'); + // console.log('tracking'); // TEST + } + /** @internal called when the item is leaving our area, stop tracking if we had moving item */ + _mouseLeave(e) { + var _a; + // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST + if (!dd_manager_1.DDManager.dragElement || dd_manager_1.DDManager.dropElement !== this) + return; + e.preventDefault(); + e.stopPropagation(); + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dropout' }); + if (this.option.out) { + this.option.out(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('dropout', ev); + if (dd_manager_1.DDManager.dropElement === this) { + delete dd_manager_1.DDManager.dropElement; + // console.log('not tracking'); // TEST + // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children + let parentDrop; + let parent = this.el.parentElement; + while (!parentDrop && parent) { + parentDrop = (_a = parent.ddElement) === null || _a === void 0 ? void 0 : _a.ddDroppable; + parent = parent.parentElement; + } + if (parentDrop) { + parentDrop._mouseEnter(e); + } + } + } + /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */ + drop(e) { + e.preventDefault(); + const ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'drop' }); + if (this.option.drop) { + this.option.drop(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('drop', ev); + } + /** @internal true if element matches the string/method accept option */ + _canDrop() { + return dd_manager_1.DDManager.dragElement && (!this.accept || this.accept(dd_manager_1.DDManager.dragElement.el)); + } + /** @internal */ + _setupAccept() { + if (!this.option.accept) + return this; + if (typeof this.option.accept === 'string') { + this.accept = (el) => el.matches(this.option.accept); + } + else { + this.accept = this.option.accept; + } + return this; + } + /** @internal */ + _ui(drag) { + return Object.assign({ draggable: drag.el }, drag.ui()); + } +} +exports.DDDroppable = DDDroppable; +//# sourceMappingURL=dd-droppable.js.map \ No newline at end of file diff --git a/dist/dd-droppable.js.map b/dist/dd-droppable.js.map new file mode 100644 index 000000000..ffb9ffe81 --- /dev/null +++ b/dist/dd-droppable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-droppable.js","sourceRoot":"","sources":["../src/dd-droppable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-droppable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDManager } from './dd-manager';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, pointerenter, pointerleave } from './dd-touch';\nimport { GridHTMLElement } from './gridstack';\n\nexport interface DDDroppableOpt {\n accept?: string | ((el: HTMLElement) => boolean);\n drop?: (event: DragEvent, ui) => void;\n over?: (event: DragEvent, ui) => void;\n out?: (event: DragEvent, ui) => void;\n}\n\n// let count = 0; // TEST\n\nexport class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n public accept: (el: HTMLElement) => boolean;\n public el: HTMLElement;\n public option: DDDroppableOpt;\n\n constructor(el: HTMLElement, opts: DDDroppableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseEnter = this._mouseEnter.bind(this);\n this._mouseLeave = this._mouseLeave.bind(this);\n this.enable();\n this._setupAccept();\n }\n\n public on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'drop' | 'dropover' | 'dropout'): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.el.classList.add('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n this.el.addEventListener('mouseenter', this._mouseEnter);\n this.el.addEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.addEventListener('pointerenter', pointerenter);\n this.el.addEventListener('pointerleave', pointerleave);\n }\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.el.classList.remove('ui-droppable');\n if (!forDestroy) this.el.classList.add('ui-droppable-disabled');\n this.el.removeEventListener('mouseenter', this._mouseEnter);\n this.el.removeEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.removeEventListener('pointerenter', pointerenter);\n this.el.removeEventListener('pointerleave', pointerleave);\n }\n }\n\n public destroy(): void {\n this.disable(true);\n this.el.classList.remove('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n super.destroy();\n }\n\n public updateOption(opts: DDDroppableOpt): DDDroppable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n this._setupAccept();\n return this;\n }\n\n /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */\n protected _mouseEnter(e: MouseEvent): void {\n // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement) return;\n if (!this._canDrop()) return;\n e.preventDefault();\n e.stopPropagation();\n\n // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do\n if (DDManager.dropElement && DDManager.dropElement !== this) {\n DDManager.dropElement._mouseLeave(e as DragEvent);\n }\n DDManager.dropElement = this;\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });\n if (this.option.over) {\n this.option.over(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropover', ev);\n this.el.classList.add('ui-droppable-over');\n // console.log('tracking'); // TEST\n }\n\n /** @internal called when the item is leaving our area, stop tracking if we had moving item */\n protected _mouseLeave(e: MouseEvent): void {\n // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement || DDManager.dropElement !== this) return;\n e.preventDefault();\n e.stopPropagation();\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });\n if (this.option.out) {\n this.option.out(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropout', ev);\n\n if (DDManager.dropElement === this) {\n delete DDManager.dropElement;\n // console.log('not tracking'); // TEST\n\n // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children\n let parentDrop: DDDroppable;\n let parent: DDElementHost = this.el.parentElement;\n while (!parentDrop && parent) {\n parentDrop = parent.ddElement?.ddDroppable;\n parent = parent.parentElement;\n }\n if (parentDrop) {\n parentDrop._mouseEnter(e);\n }\n }\n }\n\n /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */\n public drop(e: MouseEvent): void {\n e.preventDefault();\n const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });\n if (this.option.drop) {\n this.option.drop(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('drop', ev);\n }\n\n /** @internal true if element matches the string/method accept option */\n protected _canDrop(): boolean {\n return DDManager.dragElement && (!this.accept || this.accept(DDManager.dragElement.el));\n }\n\n /** @internal */\n protected _setupAccept(): DDDroppable {\n if (!this.option.accept) return this;\n if (typeof this.option.accept === 'string') {\n this.accept = (el: HTMLElement) => el.matches(this.option.accept as string);\n } else {\n this.accept = this.option.accept;\n }\n return this;\n }\n\n /** @internal */\n protected _ui(drag: DDDraggable) {\n return {\n draggable: drag.el,\n ...drag.ui()\n };\n }\n}\n\n"]} \ No newline at end of file diff --git a/dist/dd-element.d.ts b/dist/dd-element.d.ts new file mode 100644 index 000000000..35813c6bb --- /dev/null +++ b/dist/dd-element.d.ts @@ -0,0 +1,27 @@ +/** + * dd-elements.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { DDResizable, DDResizableOpt } from './dd-resizable'; +import { GridItemHTMLElement } from './types'; +import { DDDraggable, DDDraggableOpt } from './dd-draggable'; +import { DDDroppable, DDDroppableOpt } from './dd-droppable'; +export interface DDElementHost extends GridItemHTMLElement { + ddElement?: DDElement; +} +export declare class DDElement { + static init(el: DDElementHost): DDElement; + el: DDElementHost; + ddDraggable?: DDDraggable; + ddDroppable?: DDDroppable; + ddResizable?: DDResizable; + constructor(el: DDElementHost); + on(eventName: string, callback: (event: MouseEvent) => void): DDElement; + off(eventName: string): DDElement; + setupDraggable(opts: DDDraggableOpt): DDElement; + cleanDraggable(): DDElement; + setupResizable(opts: DDResizableOpt): DDElement; + cleanResizable(): DDElement; + setupDroppable(opts: DDDroppableOpt): DDElement; + cleanDroppable(): DDElement; +} diff --git a/dist/dd-element.js b/dist/dd-element.js new file mode 100644 index 000000000..f9c1fc71e --- /dev/null +++ b/dist/dd-element.js @@ -0,0 +1,95 @@ +"use strict"; +/** + * dd-elements.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDElement = void 0; +const dd_resizable_1 = require("./dd-resizable"); +const dd_draggable_1 = require("./dd-draggable"); +const dd_droppable_1 = require("./dd-droppable"); +class DDElement { + constructor(el) { + this.el = el; + } + static init(el) { + if (!el.ddElement) { + el.ddElement = new DDElement(el); + } + return el.ddElement; + } + on(eventName, callback) { + if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) { + this.ddDraggable.on(eventName, callback); + } + else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) { + this.ddDroppable.on(eventName, callback); + } + else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) { + this.ddResizable.on(eventName, callback); + } + return this; + } + off(eventName) { + if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) { + this.ddDraggable.off(eventName); + } + else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) { + this.ddDroppable.off(eventName); + } + else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) { + this.ddResizable.off(eventName); + } + return this; + } + setupDraggable(opts) { + if (!this.ddDraggable) { + this.ddDraggable = new dd_draggable_1.DDDraggable(this.el, opts); + } + else { + this.ddDraggable.updateOption(opts); + } + return this; + } + cleanDraggable() { + if (this.ddDraggable) { + this.ddDraggable.destroy(); + delete this.ddDraggable; + } + return this; + } + setupResizable(opts) { + if (!this.ddResizable) { + this.ddResizable = new dd_resizable_1.DDResizable(this.el, opts); + } + else { + this.ddResizable.updateOption(opts); + } + return this; + } + cleanResizable() { + if (this.ddResizable) { + this.ddResizable.destroy(); + delete this.ddResizable; + } + return this; + } + setupDroppable(opts) { + if (!this.ddDroppable) { + this.ddDroppable = new dd_droppable_1.DDDroppable(this.el, opts); + } + else { + this.ddDroppable.updateOption(opts); + } + return this; + } + cleanDroppable() { + if (this.ddDroppable) { + this.ddDroppable.destroy(); + delete this.ddDroppable; + } + return this; + } +} +exports.DDElement = DDElement; +//# sourceMappingURL=dd-element.js.map \ No newline at end of file diff --git a/dist/dd-element.js.map b/dist/dd-element.js.map new file mode 100644 index 000000000..ab7d5eecd --- /dev/null +++ b/dist/dd-element.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-element.js","sourceRoot":"","sources":["../src/dd-element.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-elements.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizable, DDResizableOpt } from './dd-resizable';\nimport { GridItemHTMLElement } from './types';\nimport { DDDraggable, DDDraggableOpt } from './dd-draggable';\nimport { DDDroppable, DDDroppableOpt } from './dd-droppable';\n\nexport interface DDElementHost extends GridItemHTMLElement {\n ddElement?: DDElement;\n}\n\nexport class DDElement {\n\n static init(el: DDElementHost): DDElement {\n if (!el.ddElement) { el.ddElement = new DDElement(el); }\n return el.ddElement;\n }\n\n public el: DDElementHost;\n public ddDraggable?: DDDraggable;\n public ddDroppable?: DDDroppable;\n public ddResizable?: DDResizable;\n\n constructor(el: DDElementHost) {\n this.el = el;\n }\n\n public on(eventName: string, callback: (event: MouseEvent) => void): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.on(eventName as 'drag' | 'dragstart' | 'dragstop', callback);\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.on(eventName as 'drop' | 'dropover' | 'dropout', callback);\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.on(eventName as 'resizestart' | 'resize' | 'resizestop', callback);\n }\n return this;\n }\n\n public off(eventName: string): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.off(eventName as 'drag' | 'dragstart' | 'dragstop');\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.off(eventName as 'drop' | 'dropover' | 'dropout');\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.off(eventName as 'resizestart' | 'resize' | 'resizestop');\n }\n return this;\n }\n\n public setupDraggable(opts: DDDraggableOpt): DDElement {\n if (!this.ddDraggable) {\n this.ddDraggable = new DDDraggable(this.el, opts);\n } else {\n this.ddDraggable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDraggable(): DDElement {\n if (this.ddDraggable) {\n this.ddDraggable.destroy();\n delete this.ddDraggable;\n }\n return this;\n }\n\n public setupResizable(opts: DDResizableOpt): DDElement {\n if (!this.ddResizable) {\n this.ddResizable = new DDResizable(this.el, opts);\n } else {\n this.ddResizable.updateOption(opts);\n }\n return this;\n }\n\n public cleanResizable(): DDElement {\n if (this.ddResizable) {\n this.ddResizable.destroy();\n delete this.ddResizable;\n }\n return this;\n }\n\n public setupDroppable(opts: DDDroppableOpt): DDElement {\n if (!this.ddDroppable) {\n this.ddDroppable = new DDDroppable(this.el, opts);\n } else {\n this.ddDroppable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDroppable(): DDElement {\n if (this.ddDroppable) {\n this.ddDroppable.destroy();\n delete this.ddDroppable;\n }\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/dd-gridstack.d.ts b/dist/dd-gridstack.d.ts new file mode 100644 index 000000000..ba9fb2553 --- /dev/null +++ b/dist/dd-gridstack.d.ts @@ -0,0 +1,36 @@ +/** + * dd-gridstack.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridItemHTMLElement, GridStackElement, DDDragInOpt } from './types'; +import { DDElementHost } from './dd-element'; +/** Drag&Drop drop options */ +export declare type DDDropOpt = { + /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */ + accept?: (el: GridItemHTMLElement) => boolean; +}; +/** drag&drop options currently called from the main code, but others can be passed in grid options */ +export declare type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any; +export declare type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'; +export declare type DDValue = number | string; +/** drag&drop events callbacks */ +export declare type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void; +/** + * HTML Native Mouse and Touch Events Drag and Drop functionality. + */ +export declare class DDGridStack { + /** get the global (but static to this code) DD implementation */ + static get(): DDGridStack; + resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack; + draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack; + dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack; + droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack; + /** true if element is droppable */ + isDroppable(el: DDElementHost): boolean; + /** true if element is draggable */ + isDraggable(el: DDElementHost): boolean; + /** true if element is draggable */ + isResizable(el: DDElementHost): boolean; + on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack; + off(el: GridItemHTMLElement, name: string): DDGridStack; +} diff --git a/dist/dd-gridstack.js b/dist/dd-gridstack.js new file mode 100644 index 000000000..c3572aa0a --- /dev/null +++ b/dist/dd-gridstack.js @@ -0,0 +1,743 @@ +"use strict"; +/** + * dd-gridstack.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDGridStack = void 0; +const gridstack_1 = require("./gridstack"); +const utils_1 = require("./utils"); +const dd_manager_1 = require("./dd-manager"); +const dd_element_1 = require("./dd-element"); +// let count = 0; // TEST +/** + * HTML Native Mouse and Touch Events Drag and Drop functionality. + */ +class DDGridStack { + /** get the global (but static to this code) DD implementation */ + static get() { + return dd; + } + resizable(el, opts, key, value) { + this._getDDElements(el).forEach(dEl => { + if (opts === 'disable' || opts === 'enable') { + dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable() + } + else if (opts === 'destroy') { + dEl.ddResizable && dEl.cleanResizable(); + } + else if (opts === 'option') { + dEl.setupResizable({ [key]: value }); + } + else { + const grid = dEl.el.gridstackNode.grid; + let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles; + let autoHide = !grid.opts.alwaysShowResizeHandle; + let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined; + dEl.setupResizable(Object.assign(Object.assign(Object.assign({}, grid.opts.resizable), { handles, autoHide }), { + start: opts.start, + stop: opts.stop, + resize: opts.resize, + fixedAspectRatio: fixedAspectRatio + })); + } + }); + return this; + } + draggable(el, opts, key, value) { + this._getDDElements(el).forEach(dEl => { + if (opts === 'disable' || opts === 'enable') { + dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable() + } + else if (opts === 'destroy') { + dEl.ddDraggable && dEl.cleanDraggable(); + } + else if (opts === 'option') { + dEl.setupDraggable({ [key]: value }); + } + else { + const grid = dEl.el.gridstackNode.grid; + dEl.setupDraggable(Object.assign(Object.assign({}, grid.opts.draggable), { + // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null), + start: opts.start, + stop: opts.stop, + drag: opts.drag + })); + } + }); + return this; + } + dragIn(el, opts) { + this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts)); + return this; + } + droppable(el, opts, key, value) { + if (typeof opts.accept === 'function' && !opts._accept) { + opts._accept = opts.accept; + opts.accept = (el) => opts._accept(el); + } + this._getDDElements(el).forEach(dEl => { + if (opts === 'disable' || opts === 'enable') { + dEl.ddDroppable && dEl.ddDroppable[opts](); + } + else if (opts === 'destroy') { + if (dEl.ddDroppable) { // error to call destroy if not there + dEl.cleanDroppable(); + } + } + else if (opts === 'option') { + dEl.setupDroppable({ [key]: value }); + } + else { + dEl.setupDroppable(opts); + } + }); + return this; + } + /** true if element is droppable */ + isDroppable(el) { + return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled); + } + /** true if element is draggable */ + isDraggable(el) { + return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled); + } + /** true if element is draggable */ + isResizable(el) { + return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled); + } + on(el, name, callback) { + this._getDDElements(el).forEach(dEl => dEl.on(name, (event) => { + callback(event, dd_manager_1.DDManager.dragElement ? dd_manager_1.DDManager.dragElement.el : event.target, dd_manager_1.DDManager.dragElement ? dd_manager_1.DDManager.dragElement.helper : null); + })); + return this; + } + off(el, name) { + this._getDDElements(el).forEach(dEl => dEl.off(name)); + return this; + } + /** @internal returns a list of DD elements, creating them on the fly by default */ + _getDDElements(els, create = true) { + let hosts = utils_1.Utils.getElements(els); + if (!hosts.length) + return []; + let list = hosts.map(e => e.ddElement || (create ? dd_element_1.DDElement.init(e) : null)); + if (!create) { + list.filter(d => d); + } // remove nulls + return list; + } +} +exports.DDGridStack = DDGridStack; +/** global instance */ +const dd = new DDGridStack; +/******************************************************************************** + * GridStack code that is doing drag&drop extracted here so main class is smaller + * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k) + * https://www.typescriptlang.org/docs/handbook/declaration-merging.html + * https://www.typescriptlang.org/docs/handbook/mixins.html + ********************************************************************************/ +/** @internal called to add drag over to support widgets being added externally */ +gridstack_1.GridStack.prototype._setupAcceptWidget = function () { + // check if we need to disable things + if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) { + dd.droppable(this.el, 'destroy'); + return this; + } + // vars shared across all methods + let cellHeight, cellWidth; + let onDrag = (event, el, helper) => { + let node = el.gridstackNode; + if (!node) + return; + helper = helper || el; + let parent = this.el.getBoundingClientRect(); + let { top, left } = helper.getBoundingClientRect(); + left -= parent.left; + top -= parent.top; + let ui = { position: { top, left } }; + if (node._temporaryRemoved) { + node.x = Math.max(0, Math.round(left / cellWidth)); + node.y = Math.max(0, Math.round(top / cellHeight)); + delete node.autoPosition; + this.engine.nodeBoundFix(node); + // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere + if (!this.engine.willItFit(node)) { + node.autoPosition = true; // ignore x,y and try for any slot... + if (!this.engine.willItFit(node)) { + dd.off(el, 'drag'); // stop calling us + return; // full grid or can't grow + } + if (node._willFitPos) { + // use the auto position instead #1687 + utils_1.Utils.copyPos(node, node._willFitPos); + delete node._willFitPos; + } + } + // re-use the existing node dragging method + this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight); + } + else { + // re-use the existing node dragging that does so much of the collision detection + this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight); + } + }; + dd.droppable(this.el, { + accept: (el) => { + let node = el.gridstackNode; + // set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving + if ((node === null || node === void 0 ? void 0 : node.grid) === this) + return true; + if (!this.opts.acceptWidgets) + return false; + // prevent deeper nesting until rest of 992 can be fixed + if (node === null || node === void 0 ? void 0 : node.subGrid) + return false; + // check for accept method or class matching + let canAccept = true; + if (typeof this.opts.acceptWidgets === 'function') { + canAccept = this.opts.acceptWidgets(el); + } + else { + let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets); + canAccept = el.matches(selector); + } + // finally check to make sure we actually have space left #1571 + if (canAccept && node && this.opts.maxRow) { + let n = { w: node.w, h: node.h, minW: node.minW, minH: node.minH }; // only width/height matters and autoPosition + canAccept = this.engine.willItFit(n); + } + return canAccept; + } + }) + /** + * entering our grid area + */ + .on(this.el, 'dropover', (event, el, helper) => { + // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST + let node = el.gridstackNode; + // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item + if ((node === null || node === void 0 ? void 0 : node.grid) === this && !node._temporaryRemoved) { + // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear) + return false; // prevent parent from receiving msg (which may be a grid as well) + } + // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now + if ((node === null || node === void 0 ? void 0 : node.grid) && node.grid !== this && !node._temporaryRemoved) { + // console.log('dropover without leave'); // TEST + let otherGrid = node.grid; + otherGrid._leave(el, helper); + } + // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us... + cellWidth = this.cellWidth(); + cellHeight = this.getCellHeight(true); + // load any element attributes if we don't have a node + if (!node) { // @ts-ignore private read only on ourself + node = this._readAttr(el); + } + if (!node.grid) { + node._isExternal = true; + el.gridstackNode = node; + } + // calculate the grid size based on element outer size + helper = helper || el; + let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1; + let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1; + // if the item came from another grid, make a copy and save the original info in case we go back there + if (node.grid && node.grid !== this) { + // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific + // console.log('dropover cloning node'); // TEST + if (!el._gridstackNodeOrig) + el._gridstackNodeOrig = node; // shouldn't have multiple nested! + el.gridstackNode = node = Object.assign(Object.assign({}, node), { w, h, grid: this }); + this.engine.cleanupNode(node) + .nodeBoundFix(node); + // restore some internal fields we need after clearing them all + node._initDD = + node._isExternal = // DOM needs to be re-parented on a drop + node._temporaryRemoved = true; // so it can be inserted onDrag below + } + else { + node.w = w; + node.h = h; + node._temporaryRemoved = true; // so we can insert it + } + // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it) + _itemRemoving(node.el, false); + dd.on(el, 'drag', onDrag); + // make sure this is called at least once when going fast #1578 + onDrag(event, el, helper); + return false; // prevent parent from receiving msg (which may be a grid as well) + }) + /** + * Leaving our grid area... + */ + .on(this.el, 'dropout', (event, el, helper) => { + // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST + let node = el.gridstackNode; + if (!node) + return false; + // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean) + // so skip this one if we're not the active grid really.. + if (!node.grid || node.grid === this) { + this._leave(el, helper); + } + return false; // prevent parent from receiving msg (which may be grid as well) + }) + /** + * end - releasing the mouse + */ + .on(this.el, 'drop', (event, el, helper) => { + let node = el.gridstackNode; + // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead + if ((node === null || node === void 0 ? void 0 : node.grid) === this && !node._isExternal) + return false; + let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419 + this.placeholder.remove(); + // notify previous grid of removal + // console.log('drop delete _gridstackNodeOrig') // TEST + let origNode = el._gridstackNodeOrig; + delete el._gridstackNodeOrig; + if (wasAdded && origNode && origNode.grid && origNode.grid !== this) { + let oGrid = origNode.grid; + oGrid.engine.removedNodes.push(origNode); + oGrid._triggerRemoveEvent(); + } + if (!node) + return false; + // use existing placeholder node as it's already in our list with drop location + if (wasAdded) { + this.engine.cleanupNode(node); // removes all internal _xyz values + node.grid = this; + } + dd.off(el, 'drag'); + // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102) + // as the helper will be nuked by jquery-ui otherwise + if (helper !== el) { + helper.remove(); + el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info + if (wasAdded) { + el = el.cloneNode(true); + } + } + else { + el.remove(); // reduce flicker as we change depth here, and size further down + this._removeDD(el); + } + if (!wasAdded) + return false; + el.gridstackNode = node; + node.el = el; + // @ts-ignore + utils_1.Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578 + utils_1.Utils.removePositioningStyles(el); // @ts-ignore + this._writeAttr(el, node); + this.el.appendChild(el); // @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only) + this._updateContainerHeight(); + this.engine.addedNodes.push(node); // @ts-ignore + this._triggerAddEvent(); // @ts-ignore + this._triggerChangeEvent(); + this.engine.endUpdate(); + if (this._gsEventHandler['dropped']) { + this._gsEventHandler['dropped'](Object.assign(Object.assign({}, event), { type: 'dropped' }), origNode && origNode.grid ? origNode : undefined, node); + } + // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up + window.setTimeout(() => { + // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget()) + if (node.el && node.el.parentElement) { + this._prepareDragDropByNode(node); + } + else { + this.engine.removeNode(node); + } + }); + return false; // prevent parent from receiving msg (which may be grid as well) + }); + return this; +}; +/** @internal mark item for removal */ +function _itemRemoving(el, remove) { + let node = el ? el.gridstackNode : undefined; + if (!node || !node.grid) + return; + remove ? node._isAboutToRemove = true : delete node._isAboutToRemove; + remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing'); +} +/** @internal called to setup a trash drop zone if the user specifies it */ +gridstack_1.GridStack.prototype._setupRemoveDrop = function () { + if (!this.opts.staticGrid && typeof this.opts.removable === 'string') { + let trashEl = document.querySelector(this.opts.removable); + if (!trashEl) + return this; + // only register ONE drop-over/dropout callback for the 'trash', and it will + // update the passed in item and parent grid because the 'trash' is a shared resource anyway, + // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly) + if (!dd.isDroppable(trashEl)) { + dd.droppable(trashEl, this.opts.removableOptions) + .on(trashEl, 'dropover', (event, el) => _itemRemoving(el, true)) + .on(trashEl, 'dropout', (event, el) => _itemRemoving(el, false)); + } + } + return this; +}; +/** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + **/ +gridstack_1.GridStack.setupDragIn = function (_dragIn, _dragInOptions) { + let dragIn; + let dragInOptions; + const dragInDefaultOptions = { + handle: '.grid-stack-item-content', + appendTo: 'body', + }; + // cache in the passed in values (form grid init?) so they don't have to resend them each time + if (_dragIn) { + dragIn = _dragIn; + dragInOptions = Object.assign(Object.assign({}, dragInDefaultOptions), (_dragInOptions || {})); + } + if (typeof dragIn !== 'string') + return; + utils_1.Utils.getElements(dragIn).forEach(el => { + if (!dd.isDraggable(el)) + dd.dragIn(el, dragInOptions); + }); +}; +/** @internal prepares the element for drag&drop **/ +gridstack_1.GridStack.prototype._prepareDragDropByNode = function (node) { + let el = node.el; + const noMove = node.noMove || this.opts.disableDrag; + const noResize = node.noResize || this.opts.disableResize; + // check for disabled grid first + if (this.opts.staticGrid || (noMove && noResize)) { + if (node._initDD) { + this._removeDD(el); // nukes everything instead of just disable, will add some styles back next + delete node._initDD; + } + el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435 + return this; + } + if (!node._initDD) { + // variables used/cashed between the 3 start/move/end methods, in addition to node passed above + let cellWidth; + let cellHeight; + /** called when item starts moving/resizing */ + let onStartMoving = (event, ui) => { + // trigger any 'dragstart' / 'resizestart' manually + if (this._gsEventHandler[event.type]) { + this._gsEventHandler[event.type](event, event.target); + } + cellWidth = this.cellWidth(); + cellHeight = this.getCellHeight(true); // force pixels for calculations + this._onStartMoving(el, event, ui, node, cellWidth, cellHeight); + }; + /** called when item is being dragged/resized */ + let dragOrResize = (event, ui) => { + this._dragOrResize(el, event, ui, node, cellWidth, cellHeight); + }; + /** called when the item stops moving/resizing */ + let onEndMoving = (event) => { + this.placeholder.remove(); + delete node._moving; + delete node._lastTried; + // if the item has moved to another grid, we're done here + let target = event.target; + if (!target.gridstackNode || target.gridstackNode.grid !== this) + return; + node.el = target; + if (node._isAboutToRemove) { + let gridToNotify = el.gridstackNode.grid; + if (gridToNotify._gsEventHandler[event.type]) { + gridToNotify._gsEventHandler[event.type](event, target); + } + this._removeDD(el); + gridToNotify.engine.removedNodes.push(node); + gridToNotify._triggerRemoveEvent(); + // break circular links and remove DOM + delete el.gridstackNode; + delete node.el; + el.remove(); + } + else { + utils_1.Utils.removePositioningStyles(target); + if (node._temporaryRemoved) { + // got removed - restore item back to before dragging position + utils_1.Utils.copyPos(node, node._orig); // @ts-ignore + this._writePosAttr(target, node); + this.engine.addNode(node); + } + else { + // move to new placeholder location + this._writePosAttr(target, node); + } + if (this._gsEventHandler[event.type]) { + this._gsEventHandler[event.type](event, target); + } + } + // @ts-ignore + this._extraDragRow = 0; // @ts-ignore + this._updateContainerHeight(); // @ts-ignore + this._triggerChangeEvent(); + this.engine.endUpdate(); + }; + dd.draggable(el, { + start: onStartMoving, + stop: onEndMoving, + drag: dragOrResize + }).resizable(el, { + start: onStartMoving, + stop: onEndMoving, + resize: dragOrResize + }); + node._initDD = true; // we've set DD support now + } + // finally fine tune move vs resize by disabling any part... + dd.draggable(el, noMove ? 'disable' : 'enable') + .resizable(el, noResize ? 'disable' : 'enable'); + return this; +}; +/** @internal called when item is starting a drag/resize */ +gridstack_1.GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) { + this.engine.cleanNodes() + .beginUpdate(node); + // @ts-ignore + this._writePosAttr(this.placeholder, node); + this.el.appendChild(this.placeholder); + // console.log('_onStartMoving placeholder') // TEST + node.el = this.placeholder; + node._lastUiPosition = ui.position; + node._prevYPix = ui.position.top; + node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way) + delete node._lastTried; + if (event.type === 'dropover' && node._temporaryRemoved) { + // console.log('engine.addNode x=' + node.x); // TEST + this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved + node._moving = true; // AFTER, mark as moving object (wanted fix location before) + } + // set the min/max resize info + this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop, this.opts.marginRight, this.opts.marginBottom, this.opts.marginLeft); + if (event.type === 'resizestart') { + dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1)) + .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1)); + if (node.maxW) { + dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); + } + if (node.maxH) { + dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); + } + } +}; +/** @internal called when item leaving our area by either cursor dropout event + * or shape is outside our boundaries. remove it from us, and mark temporary if this was + * our item to start with else restore prev node values from prev grid it came from. + **/ +gridstack_1.GridStack.prototype._leave = function (el, helper) { + let node = el.gridstackNode; + if (!node) + return; + dd.off(el, 'drag'); // no need to track while being outside + // this gets called when cursor leaves and shape is outside, so only do this once + if (node._temporaryRemoved) + return; + node._temporaryRemoved = true; + this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue + node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged + if (this.opts.removable === true) { // boolean vs a class string + // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so + _itemRemoving(el, true); + } + // finally if item originally came from another grid, but left us, restore things back to prev info + if (el._gridstackNodeOrig) { + // console.log('leave delete _gridstackNodeOrig') // TEST + el.gridstackNode = el._gridstackNodeOrig; + delete el._gridstackNodeOrig; + } + else if (node._isExternal) { + // item came from outside (like a toolbar) so nuke any node info + delete node.el; + delete el.gridstackNode; + // and restore all nodes back to original + this.engine.restoreInitial(); + } +}; +/** @internal called when item is being dragged/resized */ +gridstack_1.GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) { + let p = Object.assign({}, node._orig); // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value) + let resizing; + let mLeft = this.opts.marginLeft, mRight = this.opts.marginRight, mTop = this.opts.marginTop, mBottom = this.opts.marginBottom; + // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855 + let mHeight = Math.round(cellHeight * 0.1), mWidth = Math.round(cellWidth * 0.1); + mLeft = Math.min(mLeft, mWidth); + mRight = Math.min(mRight, mWidth); + mTop = Math.min(mTop, mHeight); + mBottom = Math.min(mBottom, mHeight); + if (event.type === 'drag') { + if (node._temporaryRemoved) + return; // handled by dropover + let distance = ui.position.top - node._prevYPix; + node._prevYPix = ui.position.top; + utils_1.Utils.updateScrollPosition(el, ui.position, distance); + // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin) + let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft); + let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop); + p.x = Math.round(left / cellWidth); + p.y = Math.round(top / cellHeight); + // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others + let prev = this._extraDragRow; + if (this.engine.collide(node, p)) { + let row = this.getRow(); + let extra = Math.max(0, (p.y + node.h) - row); + if (this.opts.maxRow && row + extra > this.opts.maxRow) { + extra = Math.max(0, this.opts.maxRow - row); + } // @ts-ignore + this._extraDragRow = extra; // @ts-ignore + } + else + this._extraDragRow = 0; // @ts-ignore + if (this._extraDragRow !== prev) + this._updateContainerHeight(); + if (node.x === p.x && node.y === p.y) + return; // skip same + // DON'T skip one we tried as we might have failed because of coverage <50% before + // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return; + } + else if (event.type === 'resize') { + if (p.x < 0) + return; + // Scrolling page if needed + utils_1.Utils.updateScrollResize(event, el, cellHeight); + // get new size + p.w = Math.round((ui.size.width - mLeft) / cellWidth); + p.h = Math.round((ui.size.height - mTop) / cellHeight); + if (node.w === p.w && node.h === p.h) + return; + if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) + return; // skip one we tried (but failed) + // if we size on left/top side this might move us, so get possible new position as well + let left = ui.position.left + mLeft; + let top = ui.position.top + mTop; + p.x = Math.round(left / cellWidth); + p.y = Math.round(top / cellHeight); + resizing = true; + } + node._lastTried = p; // set as last tried (will nuke if we go there) + let rect = { + x: ui.position.left + mLeft, + y: ui.position.top + mTop, + w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight, + h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom + }; + if (this.engine.moveNodeCheck(node, Object.assign(Object.assign({}, p), { cellWidth, cellHeight, rect, resizing }))) { + node._lastUiPosition = ui.position; + this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft); + delete node._skipDown; + if (resizing && node.subGrid) { + node.subGrid.onParentResize(); + } // @ts-ignore + this._extraDragRow = 0; // @ts-ignore + this._updateContainerHeight(); + let target = event.target; // @ts-ignore + this._writePosAttr(target, node); + if (this._gsEventHandler[event.type]) { + this._gsEventHandler[event.type](event, target); + } + } +}; +/** + * Enables/Disables moving. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ +gridstack_1.GridStack.prototype.movable = function (els, val) { + if (this.opts.staticGrid) + return this; // can't move a static grid! + gridstack_1.GridStack.getElements(els).forEach(el => { + let node = el.gridstackNode; + if (!node) + return; + if (val) + delete node.noMove; + else + node.noMove = true; + this._prepareDragDropByNode(node); // init DD if need be, and adjust + }); + return this; +}; +/** + * Enables/Disables resizing. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ +gridstack_1.GridStack.prototype.resizable = function (els, val) { + if (this.opts.staticGrid) + return this; // can't resize a static grid! + gridstack_1.GridStack.getElements(els).forEach(el => { + let node = el.gridstackNode; + if (!node) + return; + if (val) + delete node.noResize; + else + node.noResize = true; + this._prepareDragDropByNode(node); // init DD if need be, and adjust + }); + return this; +}; +/** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ +gridstack_1.GridStack.prototype.disable = function () { + if (this.opts.staticGrid) + return; + this.enableMove(false); + this.enableResize(false); // @ts-ignore + this._triggerEvent('disable'); + return this; +}; +/** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ +gridstack_1.GridStack.prototype.enable = function () { + if (this.opts.staticGrid) + return; + this.enableMove(true); + this.enableResize(true); // @ts-ignore + this._triggerEvent('enable'); + return this; +}; +/** Enables/disables widget moving. No-op for static grids. */ +gridstack_1.GridStack.prototype.enableMove = function (doEnable) { + if (this.opts.staticGrid) + return this; // can't move a static grid! + this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658 + this.engine.nodes.forEach(n => this.movable(n.el, doEnable)); + return this; +}; +/** Enables/disables widget resizing. No-op for static grids. */ +gridstack_1.GridStack.prototype.enableResize = function (doEnable) { + if (this.opts.staticGrid) + return this; // can't size a static grid! + this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658 + this.engine.nodes.forEach(n => this.resizable(n.el, doEnable)); + return this; +}; +/** removes any drag&drop present (called during destroy) */ +gridstack_1.GridStack.prototype._removeDD = function (el) { + dd.draggable(el, 'destroy').resizable(el, 'destroy'); + if (el.gridstackNode) { + delete el.gridstackNode._initDD; // reset our DD init flag + } + return this; +}; +//# sourceMappingURL=dd-gridstack.js.map \ No newline at end of file diff --git a/dist/dd-gridstack.js.map b/dist/dd-gridstack.js.map new file mode 100644 index 000000000..04e118bda --- /dev/null +++ b/dist/dd-gridstack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-gridstack.js","sourceRoot":"","sources":["../src/dd-gridstack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * dd-gridstack.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { GridItemHTMLElement, GridStackNode, GridStackElement, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\nimport { GridStack } from './gridstack';\r\nimport { Utils } from './utils';\r\nimport { DDManager } from './dd-manager';\r\nimport { DDElement, DDElementHost } from './dd-element';\r\n\r\n/** Drag&Drop drop options */\r\nexport type DDDropOpt = {\r\n /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */\r\n accept?: (el: GridItemHTMLElement) => boolean;\r\n}\r\n\r\n/** drag&drop options currently called from the main code, but others can be passed in grid options */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any;\r\nexport type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight';\r\nexport type DDValue = number | string;\r\n\r\n/** drag&drop events callbacks */\r\nexport type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void;\r\n\r\n// let count = 0; // TEST\r\n\r\n/**\r\n * HTML Native Mouse and Touch Events Drag and Drop functionality.\r\n */\r\nexport class DDGridStack {\r\n\r\n /** get the global (but static to this code) DD implementation */\r\n static get(): DDGridStack {\r\n return dd;\r\n }\r\n\r\n public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddResizable && dEl.cleanResizable();\r\n } else if (opts === 'option') {\r\n dEl.setupResizable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles;\r\n let autoHide = !grid.opts.alwaysShowResizeHandle;\r\n let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined;\r\n dEl.setupResizable({\r\n ...grid.opts.resizable,\r\n ...{ handles, autoHide },\r\n ...{\r\n start: opts.start,\r\n stop: opts.stop,\r\n resize: opts.resize,\r\n fixedAspectRatio: fixedAspectRatio\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddDraggable && dEl.cleanDraggable();\r\n } else if (opts === 'option') {\r\n dEl.setupDraggable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n dEl.setupDraggable({\r\n ...grid.opts.draggable,\r\n ...{\r\n // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null),\r\n start: opts.start,\r\n stop: opts.stop,\r\n drag: opts.drag\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));\r\n return this;\r\n }\r\n\r\n public droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack {\r\n if (typeof opts.accept === 'function' && !opts._accept) {\r\n opts._accept = opts.accept;\r\n opts.accept = (el) => opts._accept(el);\r\n }\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDroppable && dEl.ddDroppable[opts]();\r\n } else if (opts === 'destroy') {\r\n if (dEl.ddDroppable) { // error to call destroy if not there\r\n dEl.cleanDroppable();\r\n }\r\n } else if (opts === 'option') {\r\n dEl.setupDroppable({ [key]: value });\r\n } else {\r\n dEl.setupDroppable(opts);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /** true if element is droppable */\r\n public isDroppable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isDraggable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isResizable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled);\r\n }\r\n\r\n public on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack {\r\n this._getDDElements(el).forEach(dEl =>\r\n dEl.on(name, (event: Event) => {\r\n callback(\r\n event,\r\n DDManager.dragElement ? DDManager.dragElement.el : event.target as GridItemHTMLElement,\r\n DDManager.dragElement ? DDManager.dragElement.helper : null)\r\n })\r\n );\r\n return this;\r\n }\r\n\r\n public off(el: GridItemHTMLElement, name: string): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.off(name));\r\n return this;\r\n }\r\n\r\n /** @internal returns a list of DD elements, creating them on the fly by default */\r\n protected _getDDElements(els: GridStackElement, create = true): DDElement[] {\r\n let hosts = Utils.getElements(els) as DDElementHost[];\r\n if (!hosts.length) return [];\r\n let list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null));\r\n if (!create) { list.filter(d => d); } // remove nulls\r\n return list;\r\n }\r\n}\r\n\r\n/** global instance */\r\nconst dd = new DDGridStack;\r\n\r\n/********************************************************************************\r\n * GridStack code that is doing drag&drop extracted here so main class is smaller\r\n * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k)\r\n * https://www.typescriptlang.org/docs/handbook/declaration-merging.html\r\n * https://www.typescriptlang.org/docs/handbook/mixins.html\r\n ********************************************************************************/\r\n\r\n/** @internal called to add drag over to support widgets being added externally */\r\nGridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {\r\n\r\n // check if we need to disable things\r\n if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {\r\n dd.droppable(this.el, 'destroy');\r\n return this;\r\n }\r\n\r\n // vars shared across all methods\r\n let cellHeight: number, cellWidth: number;\r\n\r\n let onDrag = (event: DragEvent, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n helper = helper || el;\r\n let parent = this.el.getBoundingClientRect();\r\n let {top, left} = helper.getBoundingClientRect();\r\n left -= parent.left;\r\n top -= parent.top;\r\n let ui: DDUIData = {position: {top, left}};\r\n\r\n if (node._temporaryRemoved) {\r\n node.x = Math.max(0, Math.round(left / cellWidth));\r\n node.y = Math.max(0, Math.round(top / cellHeight));\r\n delete node.autoPosition;\r\n this.engine.nodeBoundFix(node);\r\n\r\n // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere\r\n if (!this.engine.willItFit(node)) {\r\n node.autoPosition = true; // ignore x,y and try for any slot...\r\n if (!this.engine.willItFit(node)) {\r\n dd.off(el, 'drag'); // stop calling us\r\n return; // full grid or can't grow\r\n }\r\n if (node._willFitPos) {\r\n // use the auto position instead #1687\r\n Utils.copyPos(node, node._willFitPos);\r\n delete node._willFitPos;\r\n }\r\n }\r\n\r\n // re-use the existing node dragging method\r\n this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);\r\n } else {\r\n // re-use the existing node dragging that does so much of the collision detection\r\n this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);\r\n }\r\n }\r\n\r\n dd.droppable(this.el, {\r\n accept: (el: GridItemHTMLElement) => {\r\n let node: GridStackNode = el.gridstackNode;\r\n // set accept drop to true on ourself (which we ignore) so we don't get \"can't drop\" icon in HTML5 mode while moving\r\n if (node?.grid === this) return true;\r\n if (!this.opts.acceptWidgets) return false;\r\n // prevent deeper nesting until rest of 992 can be fixed\r\n if (node?.subGrid) return false;\r\n // check for accept method or class matching\r\n let canAccept = true;\r\n if (typeof this.opts.acceptWidgets === 'function') {\r\n canAccept = this.opts.acceptWidgets(el);\r\n } else {\r\n let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets as string);\r\n canAccept = el.matches(selector);\r\n }\r\n // finally check to make sure we actually have space left #1571\r\n if (canAccept && node && this.opts.maxRow) {\r\n let n = {w: node.w, h: node.h, minW: node.minW, minH: node.minH}; // only width/height matters and autoPosition\r\n canAccept = this.engine.willItFit(n);\r\n }\r\n return canAccept;\r\n }\r\n })\r\n /**\r\n * entering our grid area\r\n */\r\n .on(this.el, 'dropover', (event: Event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item\r\n if (node?.grid === this && !node._temporaryRemoved) {\r\n // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n }\r\n\r\n // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now\r\n if (node?.grid && node.grid !== this && !node._temporaryRemoved) {\r\n // console.log('dropover without leave'); // TEST\r\n let otherGrid = node.grid;\r\n otherGrid._leave(el, helper);\r\n }\r\n\r\n // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true);\r\n\r\n // load any element attributes if we don't have a node\r\n if (!node) {// @ts-ignore private read only on ourself\r\n node = this._readAttr(el);\r\n }\r\n if (!node.grid) {\r\n node._isExternal = true;\r\n el.gridstackNode = node;\r\n }\r\n\r\n // calculate the grid size based on element outer size\r\n helper = helper || el;\r\n let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;\r\n let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;\r\n\r\n // if the item came from another grid, make a copy and save the original info in case we go back there\r\n if (node.grid && node.grid !== this) {\r\n // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific\r\n // console.log('dropover cloning node'); // TEST\r\n if (!el._gridstackNodeOrig) el._gridstackNodeOrig = node; // shouldn't have multiple nested!\r\n el.gridstackNode = node = {...node, w, h, grid: this};\r\n this.engine.cleanupNode(node)\r\n .nodeBoundFix(node);\r\n // restore some internal fields we need after clearing them all\r\n node._initDD =\r\n node._isExternal = // DOM needs to be re-parented on a drop\r\n node._temporaryRemoved = true; // so it can be inserted onDrag below\r\n } else {\r\n node.w = w; node.h = h;\r\n node._temporaryRemoved = true; // so we can insert it\r\n }\r\n\r\n // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)\r\n _itemRemoving(node.el, false);\r\n\r\n dd.on(el, 'drag', onDrag);\r\n // make sure this is called at least once when going fast #1578\r\n onDrag(event as DragEvent, el, helper);\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n })\r\n /**\r\n * Leaving our grid area...\r\n */\r\n .on(this.el, 'dropout', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n if (!node) return false;\r\n // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)\r\n // so skip this one if we're not the active grid really..\r\n if (!node.grid || node.grid === this) {\r\n this._leave(el, helper);\r\n }\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n })\r\n /**\r\n * end - releasing the mouse\r\n */\r\n .on(this.el, 'drop', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead\r\n if (node?.grid === this && !node._isExternal) return false;\r\n\r\n let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419\r\n this.placeholder.remove();\r\n\r\n // notify previous grid of removal\r\n // console.log('drop delete _gridstackNodeOrig') // TEST\r\n let origNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n if (wasAdded && origNode && origNode.grid && origNode.grid !== this) {\r\n let oGrid = origNode.grid;\r\n oGrid.engine.removedNodes.push(origNode);\r\n oGrid._triggerRemoveEvent();\r\n }\r\n\r\n if (!node) return false;\r\n\r\n // use existing placeholder node as it's already in our list with drop location\r\n if (wasAdded) {\r\n this.engine.cleanupNode(node); // removes all internal _xyz values\r\n node.grid = this;\r\n }\r\n dd.off(el, 'drag');\r\n // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)\r\n // as the helper will be nuked by jquery-ui otherwise\r\n if (helper !== el) {\r\n helper.remove();\r\n el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info\r\n if (wasAdded) {\r\n el = el.cloneNode(true) as GridItemHTMLElement;\r\n }\r\n } else {\r\n el.remove(); // reduce flicker as we change depth here, and size further down\r\n this._removeDD(el);\r\n }\r\n if (!wasAdded) return false;\r\n el.gridstackNode = node;\r\n node.el = el;\r\n // @ts-ignore\r\n Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578\r\n Utils.removePositioningStyles(el);// @ts-ignore\r\n this._writeAttr(el, node);\r\n this.el.appendChild(el);// @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)\r\n this._updateContainerHeight();\r\n this.engine.addedNodes.push(node);// @ts-ignore\r\n this._triggerAddEvent();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n if (this._gsEventHandler['dropped']) {\r\n this._gsEventHandler['dropped']({...event, type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);\r\n }\r\n\r\n // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up\r\n window.setTimeout(() => {\r\n // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())\r\n if (node.el && node.el.parentElement) {\r\n this._prepareDragDropByNode(node);\r\n } else {\r\n this.engine.removeNode(node);\r\n }\r\n });\r\n\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n });\r\n return this;\r\n}\r\n\r\n/** @internal mark item for removal */\r\nfunction _itemRemoving(el: GridItemHTMLElement, remove: boolean) {\r\n let node = el ? el.gridstackNode : undefined;\r\n if (!node || !node.grid) return;\r\n remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;\r\n remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');\r\n}\r\n\r\n/** @internal called to setup a trash drop zone if the user specifies it */\r\nGridStack.prototype._setupRemoveDrop = function(this: GridStack): GridStack {\r\n if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {\r\n let trashEl = document.querySelector(this.opts.removable) as HTMLElement;\r\n if (!trashEl) return this;\r\n // only register ONE drop-over/dropout callback for the 'trash', and it will\r\n // update the passed in item and parent grid because the 'trash' is a shared resource anyway,\r\n // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)\r\n if (!dd.isDroppable(trashEl)) {\r\n dd.droppable(trashEl, this.opts.removableOptions)\r\n .on(trashEl, 'dropover', (event, el) => _itemRemoving(el, true))\r\n .on(trashEl, 'dropout', (event, el) => _itemRemoving(el, false));\r\n }\r\n }\r\n return this;\r\n}\r\n\r\n/**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n **/\r\nGridStack.setupDragIn = function(this: GridStack, _dragIn?: string, _dragInOptions?: DDDragInOpt) {\r\n let dragIn: string;\r\n let dragInOptions: DDDragInOpt;\r\n const dragInDefaultOptions: DDDragInOpt = {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body',\r\n // revert: 'invalid',\r\n // scroll: false,\r\n };\r\n\r\n // cache in the passed in values (form grid init?) so they don't have to resend them each time\r\n if (_dragIn) {\r\n dragIn = _dragIn;\r\n dragInOptions = {...dragInDefaultOptions, ...(_dragInOptions || {})};\r\n }\r\n if (typeof dragIn !== 'string') return;\r\n Utils.getElements(dragIn).forEach(el => {\r\n if (!dd.isDraggable(el)) dd.dragIn(el, dragInOptions);\r\n });\r\n}\r\n\r\n/** @internal prepares the element for drag&drop **/\r\nGridStack.prototype._prepareDragDropByNode = function(this: GridStack, node: GridStackNode): GridStack {\r\n let el = node.el;\r\n const noMove = node.noMove || this.opts.disableDrag;\r\n const noResize = node.noResize || this.opts.disableResize;\r\n\r\n // check for disabled grid first\r\n if (this.opts.staticGrid || (noMove && noResize)) {\r\n if (node._initDD) {\r\n this._removeDD(el); // nukes everything instead of just disable, will add some styles back next\r\n delete node._initDD;\r\n }\r\n el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435\r\n return this;\r\n }\r\n\r\n if (!node._initDD) {\r\n // variables used/cashed between the 3 start/move/end methods, in addition to node passed above\r\n let cellWidth: number;\r\n let cellHeight: number;\r\n\r\n /** called when item starts moving/resizing */\r\n let onStartMoving = (event: Event, ui: DDUIData) => {\r\n // trigger any 'dragstart' / 'resizestart' manually\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, event.target);\r\n }\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true); // force pixels for calculations\r\n\r\n this._onStartMoving(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when item is being dragged/resized */\r\n let dragOrResize = (event: Event, ui: DDUIData) => {\r\n this._dragOrResize(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when the item stops moving/resizing */\r\n let onEndMoving = (event: Event) => {\r\n this.placeholder.remove();\r\n delete node._moving;\r\n delete node._lastTried;\r\n\r\n // if the item has moved to another grid, we're done here\r\n let target: GridItemHTMLElement = event.target as GridItemHTMLElement;\r\n if (!target.gridstackNode || target.gridstackNode.grid !== this) return;\r\n\r\n node.el = target;\r\n\r\n if (node._isAboutToRemove) {\r\n let gridToNotify = el.gridstackNode.grid;\r\n if (gridToNotify._gsEventHandler[event.type]) {\r\n gridToNotify._gsEventHandler[event.type](event, target);\r\n }\r\n this._removeDD(el);\r\n gridToNotify.engine.removedNodes.push(node);\r\n gridToNotify._triggerRemoveEvent();\r\n // break circular links and remove DOM\r\n delete el.gridstackNode;\r\n delete node.el;\r\n el.remove();\r\n } else {\r\n Utils.removePositioningStyles(target);\r\n if (node._temporaryRemoved) {\r\n // got removed - restore item back to before dragging position\r\n Utils.copyPos(node, node._orig);// @ts-ignore\r\n this._writePosAttr(target, node);\r\n this.engine.addNode(node);\r\n } else {\r\n // move to new placeholder location\r\n this._writePosAttr(target, node);\r\n }\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n // @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n }\r\n\r\n dd.draggable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n drag: dragOrResize\r\n }).resizable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n resize: dragOrResize\r\n });\r\n node._initDD = true; // we've set DD support now\r\n }\r\n\r\n // finally fine tune move vs resize by disabling any part...\r\n dd.draggable(el, noMove ? 'disable' : 'enable')\r\n .resizable(el, noResize ? 'disable' : 'enable');\r\n\r\n return this;\r\n}\r\n\r\n/** @internal called when item is starting a drag/resize */\r\nGridStack.prototype._onStartMoving = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(node);\r\n // @ts-ignore\r\n this._writePosAttr(this.placeholder, node)\r\n this.el.appendChild(this.placeholder);\r\n // console.log('_onStartMoving placeholder') // TEST\r\n\r\n node.el = this.placeholder;\r\n node._lastUiPosition = ui.position;\r\n node._prevYPix = ui.position.top;\r\n node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)\r\n delete node._lastTried;\r\n\r\n if (event.type === 'dropover' && node._temporaryRemoved) {\r\n // console.log('engine.addNode x=' + node.x); // TEST\r\n this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved\r\n node._moving = true; // AFTER, mark as moving object (wanted fix location before)\r\n }\r\n\r\n // set the min/max resize info\r\n this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop as number, this.opts.marginRight as number, this.opts.marginBottom as number, this.opts.marginLeft as number);\r\n if (event.type === 'resizestart') {\r\n dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))\r\n .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));\r\n if (node.maxW) { dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); }\r\n if (node.maxH) { dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); }\r\n }\r\n}\r\n\r\n/** @internal called when item leaving our area by either cursor dropout event\r\n * or shape is outside our boundaries. remove it from us, and mark temporary if this was\r\n * our item to start with else restore prev node values from prev grid it came from.\r\n **/\r\nGridStack.prototype._leave = function(this: GridStack, el: GridItemHTMLElement, helper?: GridItemHTMLElement) {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n dd.off(el, 'drag'); // no need to track while being outside\r\n\r\n // this gets called when cursor leaves and shape is outside, so only do this once\r\n if (node._temporaryRemoved) return;\r\n node._temporaryRemoved = true;\r\n\r\n this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue\r\n node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged\r\n\r\n if (this.opts.removable === true) { // boolean vs a class string\r\n // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so\r\n _itemRemoving(el, true);\r\n }\r\n\r\n // finally if item originally came from another grid, but left us, restore things back to prev info\r\n if (el._gridstackNodeOrig) {\r\n // console.log('leave delete _gridstackNodeOrig') // TEST\r\n el.gridstackNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n } else if (node._isExternal) {\r\n // item came from outside (like a toolbar) so nuke any node info\r\n delete node.el;\r\n delete el.gridstackNode;\r\n // and restore all nodes back to original\r\n this.engine.restoreInitial();\r\n }\r\n}\r\n\r\n/** @internal called when item is being dragged/resized */\r\nGridStack.prototype._dragOrResize = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n let p = {...node._orig}; // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value)\r\n let resizing: boolean;\r\n let mLeft = this.opts.marginLeft as number,\r\n mRight = this.opts.marginRight as number,\r\n mTop = this.opts.marginTop as number,\r\n mBottom = this.opts.marginBottom as number;\r\n\r\n // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855\r\n let mHeight = Math.round(cellHeight * 0.1),\r\n mWidth = Math.round(cellWidth * 0.1);\r\n mLeft = Math.min(mLeft, mWidth);\r\n mRight = Math.min(mRight, mWidth);\r\n mTop = Math.min(mTop, mHeight);\r\n mBottom = Math.min(mBottom, mHeight);\r\n\r\n if (event.type === 'drag') {\r\n if (node._temporaryRemoved) return; // handled by dropover\r\n let distance = ui.position.top - node._prevYPix;\r\n node._prevYPix = ui.position.top;\r\n Utils.updateScrollPosition(el, ui.position, distance);\r\n\r\n // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)\r\n let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);\r\n let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others\r\n let prev = this._extraDragRow;\r\n if (this.engine.collide(node, p)) {\r\n let row = this.getRow();\r\n let extra = Math.max(0, (p.y + node.h) - row);\r\n if (this.opts.maxRow && row + extra > this.opts.maxRow) {\r\n extra = Math.max(0, this.opts.maxRow - row);\r\n }// @ts-ignore\r\n this._extraDragRow = extra;// @ts-ignore\r\n } else this._extraDragRow = 0;// @ts-ignore\r\n if (this._extraDragRow !== prev) this._updateContainerHeight();\r\n\r\n if (node.x === p.x && node.y === p.y) return; // skip same\r\n // DON'T skip one we tried as we might have failed because of coverage <50% before\r\n // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;\r\n } else if (event.type === 'resize') {\r\n if (p.x < 0) return;\r\n // Scrolling page if needed\r\n Utils.updateScrollResize(event as MouseEvent, el, cellHeight);\r\n\r\n // get new size\r\n p.w = Math.round((ui.size.width - mLeft) / cellWidth);\r\n p.h = Math.round((ui.size.height - mTop) / cellHeight);\r\n if (node.w === p.w && node.h === p.h) return;\r\n if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) return; // skip one we tried (but failed)\r\n\r\n // if we size on left/top side this might move us, so get possible new position as well\r\n let left = ui.position.left + mLeft;\r\n let top = ui.position.top + mTop;\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n resizing = true;\r\n }\r\n\r\n node._lastTried = p; // set as last tried (will nuke if we go there)\r\n let rect: GridStackPosition = { // screen pix of the dragged box\r\n x: ui.position.left + mLeft,\r\n y: ui.position.top + mTop,\r\n w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,\r\n h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom\r\n };\r\n if (this.engine.moveNodeCheck(node, {...p, cellWidth, cellHeight, rect, resizing})) {\r\n node._lastUiPosition = ui.position;\r\n this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);\r\n delete node._skipDown;\r\n if (resizing && node.subGrid) { (node.subGrid as GridStack).onParentResize(); }// @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();\r\n\r\n let target = event.target as GridItemHTMLElement;// @ts-ignore\r\n this._writePosAttr(target, node);\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Enables/Disables moving.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\nGridStack.prototype.movable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noMove; else node.noMove = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Enables/Disables resizing.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\nGridStack.prototype.resizable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't resize a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noResize; else node.noResize = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\nGridStack.prototype.disable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(false);\r\n this.enableResize(false);// @ts-ignore\r\n this._triggerEvent('disable');\r\n return this;\r\n}\r\n\r\n/**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\nGridStack.prototype.enable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(true);\r\n this.enableResize(true);// @ts-ignore\r\n this._triggerEvent('enable');\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget moving. No-op for static grids. */\r\nGridStack.prototype.enableMove = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.movable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget resizing. No-op for static grids. */\r\nGridStack.prototype.enableResize = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't size a static grid!\r\n this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.resizable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** removes any drag&drop present (called during destroy) */\r\nGridStack.prototype._removeDD = function(this: GridStack, el: GridItemHTMLElement): GridStack {\r\n dd.draggable(el, 'destroy').resizable(el, 'destroy');\r\n if (el.gridstackNode) {\r\n delete el.gridstackNode._initDD; // reset our DD init flag\r\n }\r\n return this;\r\n}\r\n\r\n"]} \ No newline at end of file diff --git a/dist/dd-manager.d.ts b/dist/dd-manager.d.ts new file mode 100644 index 000000000..3c7ee77b9 --- /dev/null +++ b/dist/dd-manager.d.ts @@ -0,0 +1,20 @@ +/** + * dd-manager.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { DDDraggable } from './dd-draggable'; +import { DDDroppable } from './dd-droppable'; +import { DDResizable } from './dd-resizable'; +/** + * globals that are shared across Drag & Drop instances + */ +export declare class DDManager { + /** true if a mouse down event was handled */ + static mouseHandled: boolean; + /** item being dragged */ + static dragElement: DDDraggable; + /** item we are currently over as drop target */ + static dropElement: DDDroppable; + /** current item we're over for resizing purpose (ignore nested grid resize handles) */ + static overResizeElement: DDResizable; +} diff --git a/dist/dd-manager.js b/dist/dd-manager.js new file mode 100644 index 000000000..817cef193 --- /dev/null +++ b/dist/dd-manager.js @@ -0,0 +1,14 @@ +"use strict"; +/** + * dd-manager.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDManager = void 0; +/** + * globals that are shared across Drag & Drop instances + */ +class DDManager { +} +exports.DDManager = DDManager; +//# sourceMappingURL=dd-manager.js.map \ No newline at end of file diff --git a/dist/dd-manager.js.map b/dist/dd-manager.js.map new file mode 100644 index 000000000..606080bd1 --- /dev/null +++ b/dist/dd-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-manager.js","sourceRoot":"","sources":["../src/dd-manager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH;;GAEG;AACH,MAAa,SAAS;CAarB;AAbD,8BAaC","sourcesContent":["/**\n * dd-manager.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDDroppable } from './dd-droppable';\nimport { DDResizable } from './dd-resizable';\n\n/**\n * globals that are shared across Drag & Drop instances\n */\nexport class DDManager {\n /** true if a mouse down event was handled */\n public static mouseHandled: boolean;\n\n /** item being dragged */\n public static dragElement: DDDraggable;\n\n /** item we are currently over as drop target */\n public static dropElement: DDDroppable;\n\n /** current item we're over for resizing purpose (ignore nested grid resize handles) */\n public static overResizeElement: DDResizable;\n\n}\n"]} \ No newline at end of file diff --git a/dist/dd-resizable-handle.d.ts b/dist/dd-resizable-handle.d.ts new file mode 100644 index 000000000..acec9dd52 --- /dev/null +++ b/dist/dd-resizable-handle.d.ts @@ -0,0 +1,14 @@ +/** + * dd-resizable-handle.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +export interface DDResizableHandleOpt { + start?: (event: any) => void; + move?: (event: any) => void; + stop?: (event: any) => void; +} +export declare class DDResizableHandle { + constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt); + /** call this when resize handle needs to be removed and cleaned up */ + destroy(): DDResizableHandle; +} diff --git a/dist/dd-resizable-handle.js b/dist/dd-resizable-handle.js new file mode 100644 index 000000000..5696826f8 --- /dev/null +++ b/dist/dd-resizable-handle.js @@ -0,0 +1,106 @@ +"use strict"; +/** + * dd-resizable-handle.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDResizableHandle = void 0; +const dd_touch_1 = require("./dd-touch"); +class DDResizableHandle { + constructor(host, direction, option) { + /** @internal true after we've moved enough pixels to start a resize */ + this.moving = false; + this.host = host; + this.dir = direction; + this.option = option; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + this._mouseDown = this._mouseDown.bind(this); + this._mouseMove = this._mouseMove.bind(this); + this._mouseUp = this._mouseUp.bind(this); + this._init(); + } + /** @internal */ + _init() { + const el = document.createElement('div'); + el.classList.add('ui-resizable-handle'); + el.classList.add(`${DDResizableHandle.prefix}${this.dir}`); + el.style.zIndex = '100'; + el.style.userSelect = 'none'; + this.el = el; + this.host.appendChild(this.el); + this.el.addEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.el.addEventListener('touchstart', dd_touch_1.touchstart); + this.el.addEventListener('pointerdown', dd_touch_1.pointerdown); + // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment + } + return this; + } + /** call this when resize handle needs to be removed and cleaned up */ + destroy() { + if (this.moving) + this._mouseUp(this.mouseDownEvent); + this.el.removeEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('touchstart', dd_touch_1.touchstart); + this.el.removeEventListener('pointerdown', dd_touch_1.pointerdown); + } + this.host.removeChild(this.el); + delete this.el; + delete this.host; + return this; + } + /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */ + _mouseDown(e) { + this.mouseDownEvent = e; + document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble + document.addEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.el.addEventListener('touchmove', dd_touch_1.touchmove); + this.el.addEventListener('touchend', dd_touch_1.touchend); + } + e.stopPropagation(); + e.preventDefault(); + } + /** @internal */ + _mouseMove(e) { + let s = this.mouseDownEvent; + if (this.moving) { + this._triggerEvent('move', e); + } + else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) { + // don't start unless we've moved at least 3 pixels + this.moving = true; + this._triggerEvent('start', this.mouseDownEvent); + this._triggerEvent('move', e); + } + e.stopPropagation(); + e.preventDefault(); + } + /** @internal */ + _mouseUp(e) { + if (this.moving) { + this._triggerEvent('stop', e); + } + document.removeEventListener('mousemove', this._mouseMove, true); + document.removeEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('touchmove', dd_touch_1.touchmove); + this.el.removeEventListener('touchend', dd_touch_1.touchend); + } + delete this.moving; + delete this.mouseDownEvent; + e.stopPropagation(); + e.preventDefault(); + } + /** @internal */ + _triggerEvent(name, event) { + if (this.option[name]) + this.option[name](event); + return this; + } +} +exports.DDResizableHandle = DDResizableHandle; +/** @internal */ +DDResizableHandle.prefix = 'ui-resizable-'; +//# sourceMappingURL=dd-resizable-handle.js.map \ No newline at end of file diff --git a/dist/dd-resizable-handle.js.map b/dist/dd-resizable-handle.js.map new file mode 100644 index 000000000..3d0304eac --- /dev/null +++ b/dist/dd-resizable-handle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-resizable-handle.js","sourceRoot":"","sources":["../src/dd-resizable-handle.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-resizable-handle.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { isTouch, pointerdown, touchend, touchmove, touchstart } from './dd-touch';\n\nexport interface DDResizableHandleOpt {\n start?: (event) => void;\n move?: (event) => void;\n stop?: (event) => void;\n}\n\nexport class DDResizableHandle {\n /** @internal */\n protected el: HTMLElement;\n /** @internal */\n protected host: HTMLElement;\n /** @internal */\n protected option: DDResizableHandleOpt;\n /** @internal */\n protected dir: string;\n /** @internal true after we've moved enough pixels to start a resize */\n protected moving = false;\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected static prefix = 'ui-resizable-';\n\n constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt) {\n this.host = host;\n this.dir = direction;\n this.option = option;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n\n this._init();\n }\n\n /** @internal */\n protected _init(): DDResizableHandle {\n const el = document.createElement('div');\n el.classList.add('ui-resizable-handle');\n el.classList.add(`${DDResizableHandle.prefix}${this.dir}`);\n el.style.zIndex = '100';\n el.style.userSelect = 'none';\n this.el = el;\n this.host.appendChild(this.el);\n this.el.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.addEventListener('touchstart', touchstart);\n this.el.addEventListener('pointerdown', pointerdown);\n // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n return this;\n }\n\n /** call this when resize handle needs to be removed and cleaned up */\n public destroy(): DDResizableHandle {\n if (this.moving) this._mouseUp(this.mouseDownEvent);\n this.el.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.removeEventListener('touchstart', touchstart);\n this.el.removeEventListener('pointerdown', pointerdown);\n }\n this.host.removeChild(this.el);\n delete this.el;\n delete this.host;\n return this;\n }\n\n /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */\n protected _mouseDown(e: MouseEvent) {\n this.mouseDownEvent = e;\n document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.addEventListener('touchmove', touchmove);\n this.el.addEventListener('touchend', touchend);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseMove(e: MouseEvent) {\n let s = this.mouseDownEvent;\n if (this.moving) {\n this._triggerEvent('move', e);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) {\n // don't start unless we've moved at least 3 pixels\n this.moving = true;\n this._triggerEvent('start', this.mouseDownEvent);\n this._triggerEvent('move', e);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseUp(e: MouseEvent) {\n if (this.moving) {\n this._triggerEvent('stop', e);\n }\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.removeEventListener('touchmove', touchmove);\n this.el.removeEventListener('touchend', touchend);\n }\n delete this.moving;\n delete this.mouseDownEvent;\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _triggerEvent(name: string, event: MouseEvent): DDResizableHandle {\n if (this.option[name]) this.option[name](event);\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/dd-resizable.d.ts b/dist/dd-resizable.d.ts new file mode 100644 index 000000000..bebb4d6f8 --- /dev/null +++ b/dist/dd-resizable.d.ts @@ -0,0 +1,29 @@ +/** + * dd-resizable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +import { DDUIData } from './types'; +export interface DDResizableOpt { + autoHide?: boolean; + handles?: string; + maxHeight?: number; + maxWidth?: number; + minHeight?: number; + minWidth?: number; + fixedAspectRatio?: number; + start?: (event: Event, ui: DDUIData) => void; + stop?: (event: Event) => void; + resize?: (event: Event, ui: DDUIData) => void; +} +export declare class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt { + el: HTMLElement; + option: DDResizableOpt; + constructor(el: HTMLElement, opts?: DDResizableOpt); + on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void; + off(event: 'resizestart' | 'resize' | 'resizestop'): void; + enable(): void; + disable(): void; + destroy(): void; + updateOption(opts: DDResizableOpt): DDResizable; +} diff --git a/dist/dd-resizable.js b/dist/dd-resizable.js new file mode 100644 index 000000000..95eb8cb29 --- /dev/null +++ b/dist/dd-resizable.js @@ -0,0 +1,349 @@ +"use strict"; +/** + * dd-resizable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDResizable = void 0; +const dd_resizable_handle_1 = require("./dd-resizable-handle"); +const dd_base_impl_1 = require("./dd-base-impl"); +const utils_1 = require("./utils"); +const dd_manager_1 = require("./dd-manager"); +class DDResizable extends dd_base_impl_1.DDBaseImplement { + constructor(el, opts = {}) { + super(); + /** @internal */ + this._ui = () => { + const containmentEl = this.el.parentElement; + const containmentRect = containmentEl.getBoundingClientRect(); + const newRect = { + width: this.originalRect.width, + height: this.originalRect.height + this.scrolled, + left: this.originalRect.left, + top: this.originalRect.top - this.scrolled + }; + const rect = this.temporalRect || newRect; + return { + position: { + left: rect.left - containmentRect.left, + top: rect.top - containmentRect.top + }, + size: { + width: rect.width, + height: rect.height + } + /* Gridstack ONLY needs position set above... keep around in case. + element: [this.el], // The object representing the element to be resized + helper: [], // TODO: not support yet - The object representing the helper that's being resized + originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped + originalPosition: { // The position represented as { left, top } before the resizable is resized + left: this.originalRect.left - containmentRect.left, + top: this.originalRect.top - containmentRect.top + }, + originalSize: { // The size represented as { width, height } before the resizable is resized + width: this.originalRect.width, + height: this.originalRect.height + } + */ + }; + }; + this.el = el; + this.option = opts; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + this._mouseOver = this._mouseOver.bind(this); + this._mouseOut = this._mouseOut.bind(this); + this.enable(); + this._setupAutoHide(this.option.autoHide); + this._setupHandlers(); + } + on(event, callback) { + super.on(event, callback); + } + off(event) { + super.off(event); + } + enable() { + super.enable(); + this.el.classList.add('ui-resizable'); + this.el.classList.remove('ui-resizable-disabled'); + this._setupAutoHide(this.option.autoHide); + } + disable() { + super.disable(); + this.el.classList.add('ui-resizable-disabled'); + this.el.classList.remove('ui-resizable'); + this._setupAutoHide(false); + } + destroy() { + this._removeHandlers(); + this._setupAutoHide(false); + this.el.classList.remove('ui-resizable'); + delete this.el; + super.destroy(); + } + updateOption(opts) { + let updateHandles = (opts.handles && opts.handles !== this.option.handles); + let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide); + Object.keys(opts).forEach(key => this.option[key] = opts[key]); + if (updateHandles) { + this._removeHandlers(); + this._setupHandlers(); + } + if (updateAutoHide) { + this._setupAutoHide(this.option.autoHide); + } + return this; + } + /** @internal turns auto hide on/off */ + _setupAutoHide(auto) { + if (auto) { + this.el.classList.add('ui-resizable-autohide'); + // use mouseover and not mouseenter to get better performance and track for nested cases + this.el.addEventListener('mouseover', this._mouseOver); + this.el.addEventListener('mouseout', this._mouseOut); + } + else { + this.el.classList.remove('ui-resizable-autohide'); + this.el.removeEventListener('mouseover', this._mouseOver); + this.el.removeEventListener('mouseout', this._mouseOut); + if (dd_manager_1.DDManager.overResizeElement === this) { + delete dd_manager_1.DDManager.overResizeElement; + } + } + return this; + } + /** @internal */ + _mouseOver(e) { + // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018 + if (dd_manager_1.DDManager.overResizeElement || dd_manager_1.DDManager.dragElement) + return; + dd_manager_1.DDManager.overResizeElement = this; + // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + this.el.classList.remove('ui-resizable-autohide'); + } + /** @internal */ + _mouseOut(e) { + // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + if (dd_manager_1.DDManager.overResizeElement !== this) + return; + delete dd_manager_1.DDManager.overResizeElement; + // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + this.el.classList.add('ui-resizable-autohide'); + } + /** @internal */ + _setupHandlers() { + let handlerDirection = this.option.handles || 'e,s,se'; + if (handlerDirection === 'all') { + handlerDirection = 'n,e,s,w,se,sw,ne,nw'; + } + this.handlers = handlerDirection.split(',') + .map(dir => dir.trim()) + .map(dir => new dd_resizable_handle_1.DDResizableHandle(this.el, dir, { + start: (event) => { + this._resizeStart(event); + }, + stop: (event) => { + this._resizeStop(event); + }, + move: (event) => { + this._resizing(event, dir); + } + })); + return this; + } + /** @internal */ + _resizeStart(event) { + this.originalRect = this.el.getBoundingClientRect(); + this.scrollEl = utils_1.Utils.getScrollElement(this.el); + this.scrollY = this.scrollEl.scrollTop; + this.scrolled = 0; + this.startEvent = event; + this._setupHelper(); + this._applyChange(); + const ev = utils_1.Utils.initEvent(event, { type: 'resizestart', target: this.el }); + if (this.option.start) { + this.option.start(ev, this._ui()); + } + this.el.classList.add('ui-resizable-resizing'); + this.triggerEvent('resizestart', ev); + return this; + } + /** @internal */ + _resizing(event, dir) { + this.scrolled = this.scrollEl.scrollTop - this.scrollY; + this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio); + this._applyChange(); + const ev = utils_1.Utils.initEvent(event, { type: 'resize', target: this.el }); + if (this.option.resize) { + this.option.resize(ev, this._ui()); + } + this.triggerEvent('resize', ev); + return this; + } + /** @internal */ + _resizeStop(event) { + const ev = utils_1.Utils.initEvent(event, { type: 'resizestop', target: this.el }); + if (this.option.stop) { + this.option.stop(ev); // Note: ui() not used by gridstack so don't pass + } + this.el.classList.remove('ui-resizable-resizing'); + this.triggerEvent('resizestop', ev); + this._cleanHelper(); + delete this.startEvent; + delete this.originalRect; + delete this.temporalRect; + delete this.scrollY; + delete this.scrolled; + return this; + } + /** @internal */ + _setupHelper() { + this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]); + this.parentOriginStylePosition = this.el.parentElement.style.position; + if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) { + this.el.parentElement.style.position = 'relative'; + } + this.el.style.position = 'absolute'; + this.el.style.opacity = '0.8'; + return this; + } + /** @internal */ + _cleanHelper() { + DDResizable._originStyleProp.forEach((prop, i) => { + this.el.style[prop] = this.elOriginStyleVal[i] || null; + }); + this.el.parentElement.style.position = this.parentOriginStylePosition || null; + return this; + } + /** @internal */ + _getChange(event, dir, fixedAspectRatio) { + const fixedAspect = typeof (fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio); + const oEvent = this.startEvent; + const newRect = { + width: this.originalRect.width, + height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled), + left: this.originalRect.left, + top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled) + }; + const offsetX = event.clientX - oEvent.clientX; + const offsetY = event.clientY - oEvent.clientY; + if (fixedAspect) { + // If the window is being resized using the corner + if (dir.length > 1) { + if (offsetX > offsetY) { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } + else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + } + else { + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } + else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } + } + else { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } + else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } + else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } + } + else { + if (dir.indexOf('e') > -1) { // East + newRect.width += offsetX; + } + else if (dir.indexOf('w') > -1) { // West + newRect.width -= offsetX; + newRect.left += offsetX; + } + if (dir.indexOf('s') > -1) { // South // HERE + newRect.height += offsetY; + } + else if (dir.indexOf('n') > -1) { // North + newRect.height -= offsetY; + newRect.top += offsetY; + } + } + const constrain = this._constrainSize(newRect.width, newRect.height); + if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors + if (dir.indexOf('w') > -1) { + newRect.left += newRect.width - constrain.width; + } + newRect.width = constrain.width; + } + if (Math.round(newRect.height) !== Math.round(constrain.height)) { + if (dir.indexOf('n') > -1) { + newRect.top += newRect.height - constrain.height; + } + newRect.height = constrain.height; + } + return newRect; + } + /** @internal constrain the size to the set min/max values */ + _constrainSize(oWidth, oHeight) { + const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER; + const minWidth = this.option.minWidth || oWidth; + const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER; + const minHeight = this.option.minHeight || oHeight; + const width = Math.min(maxWidth, Math.max(minWidth, oWidth)); + const height = Math.min(maxHeight, Math.max(minHeight, oHeight)); + return { width, height }; + } + /** @internal */ + _applyChange() { + let containmentRect = { left: 0, top: 0, width: 0, height: 0 }; + if (this.el.style.position === 'absolute') { + const containmentEl = this.el.parentElement; + const { left, top } = containmentEl.getBoundingClientRect(); + containmentRect = { left, top, width: 0, height: 0 }; + } + if (!this.temporalRect) + return this; + Object.keys(this.temporalRect).forEach(key => { + const value = this.temporalRect[key]; + this.el.style[key] = value - containmentRect[key] + 'px'; + }); + return this; + } + /** @internal */ + _removeHandlers() { + this.handlers.forEach(handle => handle.destroy()); + delete this.handlers; + return this; + } +} +exports.DDResizable = DDResizable; +/** @internal */ +DDResizable._originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex']; +//# sourceMappingURL=dd-resizable.js.map \ No newline at end of file diff --git a/dist/dd-resizable.js.map b/dist/dd-resizable.js.map new file mode 100644 index 000000000..35f5401f4 --- /dev/null +++ b/dist/dd-resizable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-resizable.js","sourceRoot":"","sources":["../src/dd-resizable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-resizable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizableHandle } from './dd-resizable-handle';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDUIData, Rect, Size } from './types';\nimport { DDManager } from './dd-manager';\n\n// import { GridItemHTMLElement } from './types'; let count = 0; // TEST\n\n// TODO: merge with DDDragOpt\nexport interface DDResizableOpt {\n autoHide?: boolean;\n handles?: string;\n maxHeight?: number;\n maxWidth?: number;\n minHeight?: number;\n minWidth?: number;\n fixedAspectRatio?: number;\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n resize?: (event: Event, ui: DDUIData) => void;\n}\n\nexport class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n // have to be public else complains for HTMLElementExtendOpt ?\n public el: HTMLElement;\n public option: DDResizableOpt;\n\n /** @internal */\n protected handlers: DDResizableHandle[];\n /** @internal */\n protected originalRect: Rect;\n /** @internal */\n protected temporalRect: Rect;\n /** @internal */\n protected scrollY: number;\n /** @internal */\n protected scrolled: number;\n /** @internal */\n protected scrollEl: HTMLElement;\n /** @internal */\n protected startEvent: MouseEvent;\n /** @internal value saved in the same order as _originStyleProp[] */\n protected elOriginStyleVal: string[];\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected static _originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex'];\n\n constructor(el: HTMLElement, opts: DDResizableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseOver = this._mouseOver.bind(this);\n this._mouseOut = this._mouseOut.bind(this);\n this.enable();\n this._setupAutoHide(this.option.autoHide);\n this._setupHandlers();\n }\n\n public on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'resizestart' | 'resize' | 'resizestop'): void {\n super.off(event);\n }\n\n public enable(): void {\n super.enable();\n this.el.classList.add('ui-resizable');\n this.el.classList.remove('ui-resizable-disabled');\n this._setupAutoHide(this.option.autoHide);\n }\n\n public disable(): void {\n super.disable();\n this.el.classList.add('ui-resizable-disabled');\n this.el.classList.remove('ui-resizable');\n this._setupAutoHide(false);\n }\n\n public destroy(): void {\n this._removeHandlers();\n this._setupAutoHide(false);\n this.el.classList.remove('ui-resizable');\n delete this.el;\n super.destroy();\n }\n\n public updateOption(opts: DDResizableOpt): DDResizable {\n let updateHandles = (opts.handles && opts.handles !== this.option.handles);\n let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide);\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n if (updateHandles) {\n this._removeHandlers();\n this._setupHandlers();\n }\n if (updateAutoHide) {\n this._setupAutoHide(this.option.autoHide);\n }\n return this;\n }\n\n /** @internal turns auto hide on/off */\n protected _setupAutoHide(auto: boolean): DDResizable {\n if (auto) {\n this.el.classList.add('ui-resizable-autohide');\n // use mouseover and not mouseenter to get better performance and track for nested cases\n this.el.addEventListener('mouseover', this._mouseOver);\n this.el.addEventListener('mouseout', this._mouseOut);\n } else {\n this.el.classList.remove('ui-resizable-autohide');\n this.el.removeEventListener('mouseover', this._mouseOver);\n this.el.removeEventListener('mouseout', this._mouseOut);\n if (DDManager.overResizeElement === this) {\n delete DDManager.overResizeElement;\n } \n }\n return this;\n }\n\n /** @internal */\n protected _mouseOver(e: Event) {\n // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018\n if (DDManager.overResizeElement || DDManager.dragElement) return;\n DDManager.overResizeElement = this;\n // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.remove('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _mouseOut(e: Event) {\n // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n if (DDManager.overResizeElement !== this) return;\n delete DDManager.overResizeElement;\n // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.add('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _setupHandlers(): DDResizable {\n let handlerDirection = this.option.handles || 'e,s,se';\n if (handlerDirection === 'all') {\n handlerDirection = 'n,e,s,w,se,sw,ne,nw';\n }\n this.handlers = handlerDirection.split(',')\n .map(dir => dir.trim())\n .map(dir => new DDResizableHandle(this.el, dir, {\n start: (event: MouseEvent) => {\n this._resizeStart(event);\n },\n stop: (event: MouseEvent) => {\n this._resizeStop(event);\n },\n move: (event: MouseEvent) => {\n this._resizing(event, dir);\n }\n }));\n return this;\n }\n\n /** @internal */\n protected _resizeStart(event: MouseEvent): DDResizable {\n this.originalRect = this.el.getBoundingClientRect();\n this.scrollEl = Utils.getScrollElement(this.el);\n this.scrollY = this.scrollEl.scrollTop;\n this.scrolled = 0;\n this.startEvent = event;\n this._setupHelper();\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el });\n if (this.option.start) {\n this.option.start(ev, this._ui());\n }\n this.el.classList.add('ui-resizable-resizing');\n this.triggerEvent('resizestart', ev);\n return this;\n }\n\n /** @internal */\n protected _resizing(event: MouseEvent, dir: string): DDResizable {\n this.scrolled = this.scrollEl.scrollTop - this.scrollY;\n this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio);\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resize', target: this.el });\n if (this.option.resize) {\n this.option.resize(ev, this._ui());\n }\n this.triggerEvent('resize', ev);\n return this;\n }\n\n /** @internal */\n protected _resizeStop(event: MouseEvent): DDResizable {\n const ev = Utils.initEvent(event, { type: 'resizestop', target: this.el });\n if (this.option.stop) {\n this.option.stop(ev); // Note: ui() not used by gridstack so don't pass\n }\n this.el.classList.remove('ui-resizable-resizing');\n this.triggerEvent('resizestop', ev);\n this._cleanHelper();\n delete this.startEvent;\n delete this.originalRect;\n delete this.temporalRect;\n delete this.scrollY;\n delete this.scrolled;\n return this;\n }\n\n /** @internal */\n protected _setupHelper(): DDResizable {\n this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);\n this.parentOriginStylePosition = this.el.parentElement.style.position;\n if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) {\n this.el.parentElement.style.position = 'relative';\n }\n this.el.style.position = 'absolute';\n this.el.style.opacity = '0.8';\n return this;\n }\n\n /** @internal */\n protected _cleanHelper(): DDResizable {\n DDResizable._originStyleProp.forEach((prop, i) => {\n this.el.style[prop] = this.elOriginStyleVal[i] || null;\n });\n this.el.parentElement.style.position = this.parentOriginStylePosition || null;\n return this;\n }\n\n /** @internal */\n protected _getChange(event: MouseEvent, dir: string, fixedAspectRatio?: number): Rect {\n const fixedAspect = typeof(fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio);\n const oEvent = this.startEvent;\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled),\n left: this.originalRect.left,\n top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled)\n };\n\n const offsetX = event.clientX - oEvent.clientX;\n const offsetY = event.clientY - oEvent.clientY;\n\n if (fixedAspect)\n {\n // If the window is being resized using the corner\n if (dir.length > 1) {\n\n if (offsetX > offsetY) {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n } else {\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n \n\n\n } else {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n }\n else\n {\n if (dir.indexOf('e') > -1) { // East\n newRect.width += offsetX;\n } else if (dir.indexOf('w') > -1) { // West\n newRect.width -= offsetX;\n newRect.left += offsetX;\n }\n\n if (dir.indexOf('s') > -1) { // South // HERE\n newRect.height += offsetY;\n } else if (dir.indexOf('n') > -1) { // North\n newRect.height -= offsetY;\n newRect.top += offsetY\n }\n }\n\n const constrain = this._constrainSize(newRect.width, newRect.height);\n if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors\n if (dir.indexOf('w') > -1) {\n newRect.left += newRect.width - constrain.width;\n }\n newRect.width = constrain.width;\n }\n if (Math.round(newRect.height) !== Math.round(constrain.height)) {\n if (dir.indexOf('n') > -1) {\n newRect.top += newRect.height - constrain.height;\n }\n newRect.height = constrain.height;\n }\n return newRect;\n }\n\n /** @internal constrain the size to the set min/max values */\n protected _constrainSize(oWidth: number, oHeight: number): Size {\n const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;\n const minWidth = this.option.minWidth || oWidth;\n const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;\n const minHeight = this.option.minHeight || oHeight;\n const width = Math.min(maxWidth, Math.max(minWidth, oWidth));\n const height = Math.min(maxHeight, Math.max(minHeight, oHeight));\n return { width, height };\n }\n\n /** @internal */\n protected _applyChange(): DDResizable {\n let containmentRect = { left: 0, top: 0, width: 0, height: 0 };\n if (this.el.style.position === 'absolute') {\n const containmentEl = this.el.parentElement;\n const { left, top } = containmentEl.getBoundingClientRect();\n containmentRect = { left, top, width: 0, height: 0 };\n }\n if (!this.temporalRect) return this;\n Object.keys(this.temporalRect).forEach(key => {\n const value = this.temporalRect[key];\n this.el.style[key] = value - containmentRect[key] + 'px';\n });\n return this;\n }\n\n /** @internal */\n protected _removeHandlers(): DDResizable {\n this.handlers.forEach(handle => handle.destroy());\n delete this.handlers;\n return this;\n }\n\n /** @internal */\n protected _ui = (): DDUIData => {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const rect = this.temporalRect || newRect;\n return {\n position: {\n left: rect.left - containmentRect.left,\n top: rect.top - containmentRect.top\n },\n size: {\n width: rect.width,\n height: rect.height\n }\n /* Gridstack ONLY needs position set above... keep around in case.\n element: [this.el], // The object representing the element to be resized\n helper: [], // TODO: not support yet - The object representing the helper that's being resized\n originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped\n originalPosition: { // The position represented as { left, top } before the resizable is resized\n left: this.originalRect.left - containmentRect.left,\n top: this.originalRect.top - containmentRect.top\n },\n originalSize: { // The size represented as { width, height } before the resizable is resized\n width: this.originalRect.width,\n height: this.originalRect.height\n }\n */\n };\n }\n}\n"]} \ No newline at end of file diff --git a/dist/dd-touch.d.ts b/dist/dd-touch.d.ts new file mode 100644 index 000000000..739ff27d9 --- /dev/null +++ b/dist/dd-touch.d.ts @@ -0,0 +1,33 @@ +/** + * touch.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +/** + * Detect touch support - Windows Surface devices and other touch devices + * should we use this instead ? (what we had for always showing resize handles) + * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + */ +export declare const isTouch: boolean; +/** + * Handle the touchstart events + * @param {Object} e The widget element's touchstart event + */ +export declare function touchstart(e: TouchEvent): void; +/** + * Handle the touchmove events + * @param {Object} e The document's touchmove event + */ +export declare function touchmove(e: TouchEvent): void; +/** + * Handle the touchend events + * @param {Object} e The document's touchend event + */ +export declare function touchend(e: TouchEvent): void; +/** + * Note we don't get touchenter/touchleave (which are deprecated) + * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter + * so instead of PointerEvent to still get enter/leave and send the matching mouse event. + */ +export declare function pointerdown(e: PointerEvent): void; +export declare function pointerenter(e: PointerEvent): void; +export declare function pointerleave(e: PointerEvent): void; diff --git a/dist/dd-touch.js b/dist/dd-touch.js new file mode 100644 index 000000000..04b271e65 --- /dev/null +++ b/dist/dd-touch.js @@ -0,0 +1,179 @@ +"use strict"; +/** + * touch.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.pointerleave = exports.pointerenter = exports.pointerdown = exports.touchend = exports.touchmove = exports.touchstart = exports.isTouch = void 0; +const dd_manager_1 = require("./dd-manager"); +/** + * Detect touch support - Windows Surface devices and other touch devices + * should we use this instead ? (what we had for always showing resize handles) + * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + */ +exports.isTouch = ('ontouchstart' in document + || 'ontouchstart' in window + // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this + || (window.DocumentTouch && document instanceof window.DocumentTouch) + || navigator.maxTouchPoints > 0 + || navigator.msMaxTouchPoints > 0); +// interface TouchCoord {x: number, y: number}; +class DDTouch { +} +/** +* Get the x,y position of a touch event +*/ +// function getTouchCoords(e: TouchEvent): TouchCoord { +// return { +// x: e.changedTouches[0].pageX, +// y: e.changedTouches[0].pageY +// }; +// } +/** + * Simulate a mouse event based on a corresponding touch event + * @param {Object} e A touch event + * @param {String} simulatedType The corresponding mouse event + */ +function simulateMouseEvent(e, simulatedType) { + // Ignore multi-touch events + if (e.touches.length > 1) + return; + // Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors + if (e.cancelable) + e.preventDefault(); + const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents'); + // Initialize the simulated mouse event using the touch event's coordinates + simulatedEvent.initMouseEvent(simulatedType, // type + true, // bubbles + true, // cancelable + window, // view + 1, // detail + touch.screenX, // screenX + touch.screenY, // screenY + touch.clientX, // clientX + touch.clientY, // clientY + false, // ctrlKey + false, // altKey + false, // shiftKey + false, // metaKey + 0, // button + null // relatedTarget + ); + // Dispatch the simulated event to the target element + e.target.dispatchEvent(simulatedEvent); +} +/** + * Simulate a mouse event based on a corresponding Pointer event + * @param {Object} e A pointer event + * @param {String} simulatedType The corresponding mouse event + */ +function simulatePointerMouseEvent(e, simulatedType) { + // Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors + if (e.cancelable) + e.preventDefault(); + const simulatedEvent = document.createEvent('MouseEvents'); + // Initialize the simulated mouse event using the touch event's coordinates + simulatedEvent.initMouseEvent(simulatedType, // type + true, // bubbles + true, // cancelable + window, // view + 1, // detail + e.screenX, // screenX + e.screenY, // screenY + e.clientX, // clientX + e.clientY, // clientY + false, // ctrlKey + false, // altKey + false, // shiftKey + false, // metaKey + 0, // button + null // relatedTarget + ); + // Dispatch the simulated event to the target element + e.target.dispatchEvent(simulatedEvent); +} +/** + * Handle the touchstart events + * @param {Object} e The widget element's touchstart event + */ +function touchstart(e) { + // Ignore the event if another widget is already being handled + if (DDTouch.touchHandled) + return; + DDTouch.touchHandled = true; + // Simulate the mouse events + // simulateMouseEvent(e, 'mouseover'); + // simulateMouseEvent(e, 'mousemove'); + simulateMouseEvent(e, 'mousedown'); +} +exports.touchstart = touchstart; +/** + * Handle the touchmove events + * @param {Object} e The document's touchmove event + */ +function touchmove(e) { + // Ignore event if not handled by us + if (!DDTouch.touchHandled) + return; + simulateMouseEvent(e, 'mousemove'); +} +exports.touchmove = touchmove; +/** + * Handle the touchend events + * @param {Object} e The document's touchend event + */ +function touchend(e) { + // Ignore event if not handled + if (!DDTouch.touchHandled) + return; + // cancel delayed leave event when we release on ourself which happens BEFORE we get this! + if (DDTouch.pointerLeaveTimeout) { + window.clearTimeout(DDTouch.pointerLeaveTimeout); + delete DDTouch.pointerLeaveTimeout; + } + const wasDragging = !!dd_manager_1.DDManager.dragElement; + // Simulate the mouseup event + simulateMouseEvent(e, 'mouseup'); + // simulateMouseEvent(event, 'mouseout'); + // If the touch interaction did not move, it should trigger a click + if (!wasDragging) { + simulateMouseEvent(e, 'click'); + } + // Unset the flag to allow other widgets to inherit the touch event + DDTouch.touchHandled = false; +} +exports.touchend = touchend; +/** + * Note we don't get touchenter/touchleave (which are deprecated) + * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter + * so instead of PointerEvent to still get enter/leave and send the matching mouse event. + */ +function pointerdown(e) { + e.target.releasePointerCapture(e.pointerId); // <- Important! +} +exports.pointerdown = pointerdown; +function pointerenter(e) { + // ignore the initial one we get on pointerdown on ourself + if (!dd_manager_1.DDManager.dragElement) { + // console.log('pointerenter ignored'); + return; + } + // console.log('pointerenter'); + simulatePointerMouseEvent(e, 'mouseenter'); +} +exports.pointerenter = pointerenter; +function pointerleave(e) { + // ignore the leave on ourself we get before releasing the mouse over ourself + // by delaying sending the event and having the up event cancel us + if (!dd_manager_1.DDManager.dragElement) { + // console.log('pointerleave ignored'); + return; + } + DDTouch.pointerLeaveTimeout = window.setTimeout(() => { + delete DDTouch.pointerLeaveTimeout; + // console.log('pointerleave delayed'); + simulatePointerMouseEvent(e, 'mouseleave'); + }, 10); +} +exports.pointerleave = pointerleave; +//# sourceMappingURL=dd-touch.js.map \ No newline at end of file diff --git a/dist/dd-touch.js.map b/dist/dd-touch.js.map new file mode 100644 index 000000000..a93dd0005 --- /dev/null +++ b/dist/dd-touch.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-touch.js","sourceRoot":"","sources":["../src/dd-touch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * touch.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\n\n/**\n * Detect touch support - Windows Surface devices and other touch devices\n * should we use this instead ? (what we had for always showing resize handles)\n * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n */\nexport const isTouch: boolean = ( 'ontouchstart' in document\n || 'ontouchstart' in window\n // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this\n || ((window as any).DocumentTouch && document instanceof (window as any).DocumentTouch)\n || navigator.maxTouchPoints > 0\n || (navigator as any).msMaxTouchPoints > 0\n);\n\n// interface TouchCoord {x: number, y: number};\n\nclass DDTouch {\n public static touchHandled: boolean;\n public static pointerLeaveTimeout: number;\n}\n\n/**\n* Get the x,y position of a touch event\n*/\n// function getTouchCoords(e: TouchEvent): TouchCoord {\n// return {\n// x: e.changedTouches[0].pageX,\n// y: e.changedTouches[0].pageY\n// };\n// }\n\n/**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} e A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulateMouseEvent(e: TouchEvent, simulatedType: string) {\n\n // Ignore multi-touch events\n if (e.touches.length > 1) return;\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n/**\n * Simulate a mouse event based on a corresponding Pointer event\n * @param {Object} e A pointer event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulatePointerMouseEvent(e: PointerEvent, simulatedType: string) {\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n\n/**\n * Handle the touchstart events\n * @param {Object} e The widget element's touchstart event\n */\nexport function touchstart(e: TouchEvent) {\n // Ignore the event if another widget is already being handled\n if (DDTouch.touchHandled) return; DDTouch.touchHandled = true;\n\n // Simulate the mouse events\n // simulateMouseEvent(e, 'mouseover');\n // simulateMouseEvent(e, 'mousemove');\n simulateMouseEvent(e, 'mousedown');\n}\n\n/**\n * Handle the touchmove events\n * @param {Object} e The document's touchmove event\n */\nexport function touchmove(e: TouchEvent) {\n // Ignore event if not handled by us\n if (!DDTouch.touchHandled) return;\n\n simulateMouseEvent(e, 'mousemove');\n}\n\n/**\n * Handle the touchend events\n * @param {Object} e The document's touchend event\n */\nexport function touchend(e: TouchEvent) {\n\n // Ignore event if not handled\n if (!DDTouch.touchHandled) return;\n\n // cancel delayed leave event when we release on ourself which happens BEFORE we get this!\n if (DDTouch.pointerLeaveTimeout) {\n window.clearTimeout(DDTouch.pointerLeaveTimeout);\n delete DDTouch.pointerLeaveTimeout;\n }\n\n const wasDragging = !!DDManager.dragElement;\n\n // Simulate the mouseup event\n simulateMouseEvent(e, 'mouseup');\n // simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click\n if (!wasDragging) {\n simulateMouseEvent(e, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event\n DDTouch.touchHandled = false;\n}\n\n/**\n * Note we don't get touchenter/touchleave (which are deprecated)\n * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter\n * so instead of PointerEvent to still get enter/leave and send the matching mouse event.\n */\nexport function pointerdown(e: PointerEvent) {\n (e.target as HTMLElement).releasePointerCapture(e.pointerId) // <- Important!\n}\n\nexport function pointerenter(e: PointerEvent) {\n // ignore the initial one we get on pointerdown on ourself\n if (!DDManager.dragElement) {\n // console.log('pointerenter ignored');\n return;\n }\n // console.log('pointerenter');\n simulatePointerMouseEvent(e, 'mouseenter');\n}\n\nexport function pointerleave(e: PointerEvent) {\n // ignore the leave on ourself we get before releasing the mouse over ourself\n // by delaying sending the event and having the up event cancel us\n if (!DDManager.dragElement) {\n // console.log('pointerleave ignored');\n return;\n }\n DDTouch.pointerLeaveTimeout = window.setTimeout(() => {\n delete DDTouch.pointerLeaveTimeout;\n // console.log('pointerleave delayed');\n simulatePointerMouseEvent(e, 'mouseleave');\n }, 10);\n}\n\n"]} \ No newline at end of file diff --git a/dist/es5/dd-base-impl.d.ts b/dist/es5/dd-base-impl.d.ts new file mode 100644 index 000000000..be9e828ed --- /dev/null +++ b/dist/es5/dd-base-impl.d.ts @@ -0,0 +1,20 @@ +/** + * dd-base-impl.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +export declare type EventCallback = (event: Event) => boolean | void; +export declare abstract class DDBaseImplement { + /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */ + get disabled(): boolean; + on(event: string, callback: EventCallback): void; + off(event: string): void; + enable(): void; + disable(): void; + destroy(): void; + triggerEvent(eventName: string, event: Event): boolean | void; +} +export interface HTMLElementExtendOpt { + el: HTMLElement; + option: T; + updateOption(T: any): DDBaseImplement; +} diff --git a/dist/es5/dd-base-impl.js b/dist/es5/dd-base-impl.js new file mode 100644 index 000000000..d0ce059fe --- /dev/null +++ b/dist/es5/dd-base-impl.js @@ -0,0 +1,41 @@ +"use strict"; +/** + * dd-base-impl.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDBaseImplement = void 0; +var DDBaseImplement = /** @class */ (function () { + function DDBaseImplement() { + /** @internal */ + this._eventRegister = {}; + } + Object.defineProperty(DDBaseImplement.prototype, "disabled", { + /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */ + get: function () { return this._disabled; }, + enumerable: false, + configurable: true + }); + DDBaseImplement.prototype.on = function (event, callback) { + this._eventRegister[event] = callback; + }; + DDBaseImplement.prototype.off = function (event) { + delete this._eventRegister[event]; + }; + DDBaseImplement.prototype.enable = function () { + this._disabled = false; + }; + DDBaseImplement.prototype.disable = function () { + this._disabled = true; + }; + DDBaseImplement.prototype.destroy = function () { + delete this._eventRegister; + }; + DDBaseImplement.prototype.triggerEvent = function (eventName, event) { + if (!this.disabled && this._eventRegister && this._eventRegister[eventName]) + return this._eventRegister[eventName](event); + }; + return DDBaseImplement; +}()); +exports.DDBaseImplement = DDBaseImplement; +//# sourceMappingURL=dd-base-impl.js.map \ No newline at end of file diff --git a/dist/es5/dd-base-impl.js.map b/dist/es5/dd-base-impl.js.map new file mode 100644 index 000000000..ec9207afd --- /dev/null +++ b/dist/es5/dd-base-impl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-base-impl.js","sourceRoot":"","sources":["../../src/dd-base-impl.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH;IAAA;QAME,gBAAgB;QACN,mBAAc,GAEpB,EAAE,CAAC;IA0BT,CAAC;IAjCC,sBAAW,qCAAQ;QADnB,mHAAmH;aACnH,cAAmC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;;;OAAA;IASpD,4BAAE,GAAT,UAAU,KAAa,EAAE,QAAuB;QAC9C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACxC,CAAC;IAEM,6BAAG,GAAV,UAAW,KAAa;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAEM,gCAAM,GAAb;QACE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAEM,iCAAO,GAAd;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAEM,iCAAO,GAAd;QACE,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAEM,sCAAY,GAAnB,UAAoB,SAAiB,EAAE,KAAY;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;YACzE,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IACH,sBAAC;AAAD,CAAC,AAnCD,IAmCC;AAnCqB,0CAAe","sourcesContent":["/**\n * dd-base-impl.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nexport type EventCallback = (event: Event) => boolean|void;\nexport abstract class DDBaseImplement {\n /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */\n public get disabled(): boolean { return this._disabled; }\n\n /** @internal */\n protected _disabled: boolean; // initial state to differentiate from false\n /** @internal */\n protected _eventRegister: {\n [eventName: string]: EventCallback;\n } = {};\n\n public on(event: string, callback: EventCallback): void {\n this._eventRegister[event] = callback;\n }\n\n public off(event: string): void {\n delete this._eventRegister[event];\n }\n\n public enable(): void {\n this._disabled = false;\n }\n\n public disable(): void {\n this._disabled = true;\n }\n\n public destroy(): void {\n delete this._eventRegister;\n }\n\n public triggerEvent(eventName: string, event: Event): boolean|void {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\nexport interface HTMLElementExtendOpt {\n el: HTMLElement;\n option: T;\n updateOption(T): DDBaseImplement;\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-draggable.d.ts b/dist/es5/dd-draggable.d.ts new file mode 100644 index 000000000..80edb07ca --- /dev/null +++ b/dist/es5/dd-draggable.d.ts @@ -0,0 +1,28 @@ +/** + * dd-draggable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +import { DDUIData } from './types'; +export interface DDDraggableOpt { + appendTo?: string | HTMLElement; + handle?: string; + helper?: string | HTMLElement | ((event: Event) => HTMLElement); + start?: (event: Event, ui: DDUIData) => void; + stop?: (event: Event) => void; + drag?: (event: Event, ui: DDUIData) => void; +} +declare type DDDragEvent = 'drag' | 'dragstart' | 'dragstop'; +export declare class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt { + el: HTMLElement; + option: DDDraggableOpt; + helper: HTMLElement; + constructor(el: HTMLElement, option?: DDDraggableOpt); + on(event: DDDragEvent, callback: (event: DragEvent) => void): void; + off(event: DDDragEvent): void; + enable(): void; + disable(forDestroy?: boolean): void; + destroy(): void; + updateOption(opts: DDDraggableOpt): DDDraggable; +} +export {}; diff --git a/dist/es5/dd-draggable.js b/dist/es5/dd-draggable.js new file mode 100644 index 000000000..f9b1b9fb7 --- /dev/null +++ b/dist/es5/dd-draggable.js @@ -0,0 +1,335 @@ +"use strict"; +/** + * dd-draggable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDDraggable = void 0; +var dd_manager_1 = require("./dd-manager"); +var utils_1 = require("./utils"); +var dd_base_impl_1 = require("./dd-base-impl"); +var dd_touch_1 = require("./dd-touch"); +// let count = 0; // TEST +var DDDraggable = /** @class */ (function (_super) { + __extends(DDDraggable, _super); + function DDDraggable(el, option) { + if (option === void 0) { option = {}; } + var _this = _super.call(this) || this; + _this.el = el; + _this.option = option; + // get the element that is actually supposed to be dragged by + var className = option.handle.substring(1); + _this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + _this._mouseDown = _this._mouseDown.bind(_this); + _this._mouseMove = _this._mouseMove.bind(_this); + _this._mouseUp = _this._mouseUp.bind(_this); + _this.enable(); + return _this; + } + DDDraggable.prototype.on = function (event, callback) { + _super.prototype.on.call(this, event, callback); + }; + DDDraggable.prototype.off = function (event) { + _super.prototype.off.call(this, event); + }; + DDDraggable.prototype.enable = function () { + if (this.disabled === false) + return; + _super.prototype.enable.call(this); + this.dragEl.addEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.dragEl.addEventListener('touchstart', dd_touch_1.touchstart); + this.dragEl.addEventListener('pointerdown', dd_touch_1.pointerdown); + // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment + } + this.el.classList.remove('ui-draggable-disabled'); + this.el.classList.add('ui-draggable'); + }; + DDDraggable.prototype.disable = function (forDestroy) { + if (forDestroy === void 0) { forDestroy = false; } + if (this.disabled === true) + return; + _super.prototype.disable.call(this); + this.dragEl.removeEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.dragEl.removeEventListener('touchstart', dd_touch_1.touchstart); + this.dragEl.removeEventListener('pointerdown', dd_touch_1.pointerdown); + } + this.el.classList.remove('ui-draggable'); + if (!forDestroy) + this.el.classList.add('ui-draggable-disabled'); + }; + DDDraggable.prototype.destroy = function () { + if (this.dragging) + this._mouseUp(this.mouseDownEvent); + this.disable(true); + delete this.el; + delete this.helper; + delete this.option; + _super.prototype.destroy.call(this); + }; + DDDraggable.prototype.updateOption = function (opts) { + var _this = this; + Object.keys(opts).forEach(function (key) { return _this.option[key] = opts[key]; }); + return this; + }; + /** @internal call when mouse goes down before a dragstart happens */ + DDDraggable.prototype._mouseDown = function (e) { + // don't let more than one widget handle mouseStart + if (dd_manager_1.DDManager.mouseHandled) + return; + if (e.button !== 0) + return true; // only left click + // make sure we are clicking on a drag handle or child of it... + // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins) + var className = this.option.handle.substring(1); + var el = e.target; + while (el && !el.classList.contains(className)) { + el = el.parentElement; + } + if (!el) + return; + this.mouseDownEvent = e; + delete this.dragging; + delete dd_manager_1.DDManager.dragElement; + delete dd_manager_1.DDManager.dropElement; + // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack + document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble + document.addEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.dragEl.addEventListener('touchmove', dd_touch_1.touchmove); + this.dragEl.addEventListener('touchend', dd_touch_1.touchend); + } + e.preventDefault(); + dd_manager_1.DDManager.mouseHandled = true; + return true; + }; + /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */ + DDDraggable.prototype._mouseMove = function (e) { + var _a; + // console.log(`${count++} move ${e.x},${e.y}`) + var s = this.mouseDownEvent; + if (this.dragging) { + this._dragFollow(e); + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'drag' }); + if (this.option.drag) { + this.option.drag(ev, this.ui()); + } + this.triggerEvent('drag', ev); + } + else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) { + /** + * don't start unless we've moved at least 3 pixels + */ + this.dragging = true; + dd_manager_1.DDManager.dragElement = this; + // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave) + var grid = (_a = this.el.gridstackNode) === null || _a === void 0 ? void 0 : _a.grid; + if (grid) { + dd_manager_1.DDManager.dropElement = grid.el.ddElement.ddDroppable; + } + else { + delete dd_manager_1.DDManager.dropElement; + } + this.helper = this._createHelper(e); + this._setupHelperContainmentStyle(); + this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment); + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dragstart' }); + this._setupHelperStyle(e); + if (this.option.start) { + this.option.start(ev, this.ui()); + } + this.triggerEvent('dragstart', ev); + } + e.preventDefault(); + return true; + }; + /** @internal call when the mouse gets released to drop the item at current location */ + DDDraggable.prototype._mouseUp = function (e) { + var _a; + document.removeEventListener('mousemove', this._mouseMove, true); + document.removeEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.dragEl.removeEventListener('touchmove', dd_touch_1.touchmove, true); + this.dragEl.removeEventListener('touchend', dd_touch_1.touchend, true); + } + if (this.dragging) { + delete this.dragging; + // reset the drop target if dragging over ourself (already parented, just moving during stop callback below) + if (((_a = dd_manager_1.DDManager.dropElement) === null || _a === void 0 ? void 0 : _a.el) === this.el.parentElement) { + delete dd_manager_1.DDManager.dropElement; + } + this.helperContainment.style.position = this.parentOriginStylePosition || null; + if (this.helper === this.el) { + this._removeHelperStyle(); + } + else { + this.helper.remove(); + } + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dragstop' }); + if (this.option.stop) { + this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after! + } + this.triggerEvent('dragstop', ev); + // call the droppable method to receive the item + if (dd_manager_1.DDManager.dropElement) { + dd_manager_1.DDManager.dropElement.drop(e); + } + } + delete this.helper; + delete this.mouseDownEvent; + delete dd_manager_1.DDManager.dragElement; + delete dd_manager_1.DDManager.dropElement; + delete dd_manager_1.DDManager.mouseHandled; + e.preventDefault(); + }; + /** @internal create a clone copy (or user defined method) of the original drag item if set */ + DDDraggable.prototype._createHelper = function (event) { + var _this = this; + var helper = this.el; + if (typeof this.option.helper === 'function') { + helper = this.option.helper(event); + } + else if (this.option.helper === 'clone') { + helper = utils_1.Utils.cloneNode(this.el); + } + if (!document.body.contains(helper)) { + utils_1.Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo); + } + if (helper === this.el) { + this.dragElementOriginStyle = DDDraggable.originStyleProp.map(function (prop) { return _this.el.style[prop]; }); + } + return helper; + }; + /** @internal set the fix position of the dragged item */ + DDDraggable.prototype._setupHelperStyle = function (e) { + var _this = this; + this.helper.classList.add('ui-draggable-dragging'); + // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593 + var style = this.helper.style; + style.pointerEvents = 'none'; // needed for over items to get enter/leave + // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well) + style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %) + style.width = this.dragOffset.width + 'px'; + style.height = this.dragOffset.height + 'px'; + style.willChange = 'left, top'; + style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative' + this._dragFollow(e); // now position it + style.transition = 'none'; // show up instantly + setTimeout(function () { + if (_this.helper) { + style.transition = null; // recover animation + } + }, 0); + return this; + }; + /** @internal restore back the original style before dragging */ + DDDraggable.prototype._removeHelperStyle = function () { + var _this = this; + var _a; + this.helper.classList.remove('ui-draggable-dragging'); + var node = (_a = this.helper) === null || _a === void 0 ? void 0 : _a.gridstackNode; + // don't bother restoring styles if we're gonna remove anyway... + if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) { + var helper_1 = this.helper; + // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed' + var transition_1 = this.dragElementOriginStyle['transition'] || null; + helper_1.style.transition = this.dragElementOriginStyle['transition'] = 'none'; + DDDraggable.originStyleProp.forEach(function (prop) { return helper_1.style[prop] = _this.dragElementOriginStyle[prop] || null; }); + setTimeout(function () { return helper_1.style.transition = transition_1; }, 50); // recover animation from saved vars after a pause (0 isn't enough #1973) + } + delete this.dragElementOriginStyle; + return this; + }; + /** @internal updates the top/left position to follow the mouse */ + DDDraggable.prototype._dragFollow = function (e) { + var containmentRect = { left: 0, top: 0 }; + // if (this.helper.style.position === 'absolute') { // we use 'fixed' + // const { left, top } = this.helperContainment.getBoundingClientRect(); + // containmentRect = { left, top }; + // } + var style = this.helper.style; + var offset = this.dragOffset; + style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px'; + style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px'; + }; + /** @internal */ + DDDraggable.prototype._setupHelperContainmentStyle = function () { + this.helperContainment = this.helper.parentElement; + if (this.helper.style.position !== 'fixed') { + this.parentOriginStylePosition = this.helperContainment.style.position; + if (window.getComputedStyle(this.helperContainment).position.match(/static/)) { + this.helperContainment.style.position = 'relative'; + } + } + return this; + }; + /** @internal */ + DDDraggable.prototype._getDragOffset = function (event, el, parent) { + // in case ancestor has transform/perspective css properties that change the viewpoint + var xformOffsetX = 0; + var xformOffsetY = 0; + if (parent) { + var testEl = document.createElement('div'); + utils_1.Utils.addElStyles(testEl, { + opacity: '0', + position: 'fixed', + top: 0 + 'px', + left: 0 + 'px', + width: '1px', + height: '1px', + zIndex: '-999999', + }); + parent.appendChild(testEl); + var testElPosition = testEl.getBoundingClientRect(); + parent.removeChild(testEl); + xformOffsetX = testElPosition.left; + xformOffsetY = testElPosition.top; + // TODO: scale ? + } + var targetOffset = el.getBoundingClientRect(); + return { + left: targetOffset.left, + top: targetOffset.top, + offsetLeft: -event.clientX + targetOffset.left - xformOffsetX, + offsetTop: -event.clientY + targetOffset.top - xformOffsetY, + width: targetOffset.width, + height: targetOffset.height + }; + }; + /** @internal TODO: set to public as called by DDDroppable! */ + DDDraggable.prototype.ui = function () { + var containmentEl = this.el.parentElement; + var containmentRect = containmentEl.getBoundingClientRect(); + var offset = this.helper.getBoundingClientRect(); + return { + position: { + top: offset.top - containmentRect.top, + left: offset.left - containmentRect.left + } + /* not used by GridStack for now... + helper: [this.helper], //The object arr representing the helper that's being dragged. + offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object. + */ + }; + }; + /** @internal properties we change during dragging, and restore back */ + DDDraggable.originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top']; + return DDDraggable; +}(dd_base_impl_1.DDBaseImplement)); +exports.DDDraggable = DDDraggable; +//# sourceMappingURL=dd-draggable.js.map \ No newline at end of file diff --git a/dist/es5/dd-draggable.js.map b/dist/es5/dd-draggable.js.map new file mode 100644 index 000000000..42dea4139 --- /dev/null +++ b/dist/es5/dd-draggable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-draggable.js","sourceRoot":"","sources":["../../src/dd-draggable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-draggable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\nimport { Utils } from './utils';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { GridItemHTMLElement, DDUIData } from './types';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, touchend, touchmove, touchstart, pointerdown } from './dd-touch';\n\n// TODO: merge with DDDragOpt ?\nexport interface DDDraggableOpt {\n appendTo?: string | HTMLElement;\n handle?: string;\n helper?: string | HTMLElement | ((event: Event) => HTMLElement);\n // containment?: string | HTMLElement; // TODO: not implemented yet\n // revert?: string | boolean | unknown; // TODO: not implemented yet\n // scroll?: boolean; // native support by HTML5 drag drop, can't be switch to off actually\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n drag?: (event: Event, ui: DDUIData) => void;\n}\n\ninterface DragOffset {\n left: number;\n top: number;\n width: number;\n height: number;\n offsetLeft: number;\n offsetTop: number;\n}\n\ntype DDDragEvent = 'drag' | 'dragstart' | 'dragstop';\n\n// let count = 0; // TEST\n\nexport class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt {\n public el: HTMLElement;\n public option: DDDraggableOpt;\n public helper: HTMLElement; // used by GridStackDDNative\n\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected dragOffset: DragOffset;\n /** @internal */\n protected dragElementOriginStyle: Array;\n /** @internal */\n protected dragEl: HTMLElement;\n /** @internal true while we are dragging an item around */\n protected dragging: boolean;\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected helperContainment: HTMLElement;\n /** @internal properties we change during dragging, and restore back */\n protected static originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top'];\n\n constructor(el: HTMLElement, option: DDDraggableOpt = {}) {\n super();\n this.el = el;\n this.option = option;\n // get the element that is actually supposed to be dragged by\n let className = option.handle.substring(1);\n this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this.enable();\n }\n\n public on(event: DDDragEvent, callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: DDDragEvent): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.dragEl.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.addEventListener('touchstart', touchstart);\n this.dragEl.addEventListener('pointerdown', pointerdown);\n // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n this.el.classList.remove('ui-draggable-disabled');\n this.el.classList.add('ui-draggable');\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.dragEl.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.removeEventListener('touchstart', touchstart);\n this.dragEl.removeEventListener('pointerdown', pointerdown);\n }\n this.el.classList.remove('ui-draggable');\n if (!forDestroy) this.el.classList.add('ui-draggable-disabled');\n }\n\n public destroy(): void {\n if (this.dragging) this._mouseUp(this.mouseDownEvent);\n this.disable(true);\n delete this.el;\n delete this.helper;\n delete this.option;\n super.destroy();\n }\n\n public updateOption(opts: DDDraggableOpt): DDDraggable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n return this;\n }\n\n /** @internal call when mouse goes down before a dragstart happens */\n protected _mouseDown(e: MouseEvent): boolean {\n // don't let more than one widget handle mouseStart\n if (DDManager.mouseHandled) return;\n if (e.button !== 0) return true; // only left click\n\n // make sure we are clicking on a drag handle or child of it...\n // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins)\n let className = this.option.handle.substring(1);\n let el = e.target as HTMLElement;\n while (el && !el.classList.contains(className)) { el = el.parentElement; }\n if (!el) return;\n this.mouseDownEvent = e;\n delete this.dragging;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack\n document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.addEventListener('touchmove', touchmove);\n this.dragEl.addEventListener('touchend', touchend);\n }\n\n e.preventDefault();\n DDManager.mouseHandled = true;\n return true;\n }\n\n /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */\n protected _mouseMove(e: DragEvent): boolean {\n // console.log(`${count++} move ${e.x},${e.y}`)\n let s = this.mouseDownEvent;\n\n if (this.dragging) {\n this._dragFollow(e);\n const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });\n if (this.option.drag) {\n this.option.drag(ev, this.ui());\n }\n this.triggerEvent('drag', ev);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {\n /**\n * don't start unless we've moved at least 3 pixels\n */\n this.dragging = true;\n DDManager.dragElement = this;\n // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)\n let grid = (this.el as GridItemHTMLElement).gridstackNode?.grid;\n if (grid) {\n DDManager.dropElement = (grid.el as DDElementHost).ddElement.ddDroppable;\n } else {\n delete DDManager.dropElement;\n }\n this.helper = this._createHelper(e);\n this._setupHelperContainmentStyle();\n this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });\n\n this._setupHelperStyle(e);\n if (this.option.start) {\n this.option.start(ev, this.ui());\n }\n this.triggerEvent('dragstart', ev);\n }\n e.preventDefault();\n return true;\n }\n\n /** @internal call when the mouse gets released to drop the item at current location */\n protected _mouseUp(e: MouseEvent): void {\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.removeEventListener('touchmove', touchmove, true);\n this.dragEl.removeEventListener('touchend', touchend, true);\n }\n if (this.dragging) {\n delete this.dragging;\n\n // reset the drop target if dragging over ourself (already parented, just moving during stop callback below)\n if (DDManager.dropElement?.el === this.el.parentElement) {\n delete DDManager.dropElement;\n }\n\n this.helperContainment.style.position = this.parentOriginStylePosition || null;\n if (this.helper === this.el) {\n this._removeHelperStyle();\n } else {\n this.helper.remove();\n }\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });\n if (this.option.stop) {\n this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!\n }\n this.triggerEvent('dragstop', ev);\n\n // call the droppable method to receive the item\n if (DDManager.dropElement) {\n DDManager.dropElement.drop(e);\n }\n }\n delete this.helper;\n delete this.mouseDownEvent;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n delete DDManager.mouseHandled;\n e.preventDefault();\n }\n\n /** @internal create a clone copy (or user defined method) of the original drag item if set */\n protected _createHelper(event: DragEvent): HTMLElement {\n let helper = this.el;\n if (typeof this.option.helper === 'function') {\n helper = this.option.helper(event);\n } else if (this.option.helper === 'clone') {\n helper = Utils.cloneNode(this.el);\n }\n if (!document.body.contains(helper)) {\n Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo);\n }\n if (helper === this.el) {\n this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);\n }\n return helper;\n }\n\n /** @internal set the fix position of the dragged item */\n protected _setupHelperStyle(e: DragEvent): DDDraggable {\n this.helper.classList.add('ui-draggable-dragging');\n // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593\n const style = this.helper.style;\n style.pointerEvents = 'none'; // needed for over items to get enter/leave\n // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well)\n style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %)\n style.width = this.dragOffset.width + 'px';\n style.height = this.dragOffset.height + 'px';\n style.willChange = 'left, top';\n style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'\n this._dragFollow(e); // now position it\n style.transition = 'none'; // show up instantly\n setTimeout(() => {\n if (this.helper) {\n style.transition = null; // recover animation\n }\n }, 0);\n return this;\n }\n\n /** @internal restore back the original style before dragging */\n protected _removeHelperStyle(): DDDraggable {\n this.helper.classList.remove('ui-draggable-dragging');\n let node = (this.helper as GridItemHTMLElement)?.gridstackNode;\n // don't bother restoring styles if we're gonna remove anyway...\n if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) {\n let helper = this.helper;\n // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'\n let transition = this.dragElementOriginStyle['transition'] || null;\n helper.style.transition = this.dragElementOriginStyle['transition'] = 'none';\n DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);\n setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)\n }\n delete this.dragElementOriginStyle;\n return this;\n }\n\n /** @internal updates the top/left position to follow the mouse */\n protected _dragFollow(e: DragEvent): void {\n let containmentRect = { left: 0, top: 0 };\n // if (this.helper.style.position === 'absolute') { // we use 'fixed'\n // const { left, top } = this.helperContainment.getBoundingClientRect();\n // containmentRect = { left, top };\n // }\n const style = this.helper.style;\n const offset = this.dragOffset;\n style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';\n style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';\n }\n\n /** @internal */\n protected _setupHelperContainmentStyle(): DDDraggable {\n this.helperContainment = this.helper.parentElement;\n if (this.helper.style.position !== 'fixed') {\n this.parentOriginStylePosition = this.helperContainment.style.position;\n if (window.getComputedStyle(this.helperContainment).position.match(/static/)) {\n this.helperContainment.style.position = 'relative';\n }\n }\n return this;\n }\n\n /** @internal */\n protected _getDragOffset(event: DragEvent, el: HTMLElement, parent: HTMLElement): DragOffset {\n\n // in case ancestor has transform/perspective css properties that change the viewpoint\n let xformOffsetX = 0;\n let xformOffsetY = 0;\n if (parent) {\n const testEl = document.createElement('div');\n Utils.addElStyles(testEl, {\n opacity: '0',\n position: 'fixed',\n top: 0 + 'px',\n left: 0 + 'px',\n width: '1px',\n height: '1px',\n zIndex: '-999999',\n });\n parent.appendChild(testEl);\n const testElPosition = testEl.getBoundingClientRect();\n parent.removeChild(testEl);\n xformOffsetX = testElPosition.left;\n xformOffsetY = testElPosition.top;\n // TODO: scale ?\n }\n\n const targetOffset = el.getBoundingClientRect();\n return {\n left: targetOffset.left,\n top: targetOffset.top,\n offsetLeft: - event.clientX + targetOffset.left - xformOffsetX,\n offsetTop: - event.clientY + targetOffset.top - xformOffsetY,\n width: targetOffset.width,\n height: targetOffset.height\n };\n }\n\n /** @internal TODO: set to public as called by DDDroppable! */\n public ui(): DDUIData {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const offset = this.helper.getBoundingClientRect();\n return {\n position: { //Current CSS position of the helper as { top, left } object\n top: offset.top - containmentRect.top,\n left: offset.left - containmentRect.left\n }\n /* not used by GridStack for now...\n helper: [this.helper], //The object arr representing the helper that's being dragged.\n offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.\n */\n };\n }\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-droppable.d.ts b/dist/es5/dd-droppable.d.ts new file mode 100644 index 000000000..3d01bfbb7 --- /dev/null +++ b/dist/es5/dd-droppable.d.ts @@ -0,0 +1,25 @@ +/** + * dd-droppable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +export interface DDDroppableOpt { + accept?: string | ((el: HTMLElement) => boolean); + drop?: (event: DragEvent, ui: any) => void; + over?: (event: DragEvent, ui: any) => void; + out?: (event: DragEvent, ui: any) => void; +} +export declare class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt { + accept: (el: HTMLElement) => boolean; + el: HTMLElement; + option: DDDroppableOpt; + constructor(el: HTMLElement, opts?: DDDroppableOpt); + on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void; + off(event: 'drop' | 'dropover' | 'dropout'): void; + enable(): void; + disable(forDestroy?: boolean): void; + destroy(): void; + updateOption(opts: DDDroppableOpt): DDDroppable; + /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */ + drop(e: MouseEvent): void; +} diff --git a/dist/es5/dd-droppable.js b/dist/es5/dd-droppable.js new file mode 100644 index 000000000..1f04a37a9 --- /dev/null +++ b/dist/es5/dd-droppable.js @@ -0,0 +1,180 @@ +"use strict"; +/** + * dd-droppable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDDroppable = void 0; +var dd_manager_1 = require("./dd-manager"); +var dd_base_impl_1 = require("./dd-base-impl"); +var utils_1 = require("./utils"); +var dd_touch_1 = require("./dd-touch"); +// let count = 0; // TEST +var DDDroppable = /** @class */ (function (_super) { + __extends(DDDroppable, _super); + function DDDroppable(el, opts) { + if (opts === void 0) { opts = {}; } + var _this = _super.call(this) || this; + _this.el = el; + _this.option = opts; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + _this._mouseEnter = _this._mouseEnter.bind(_this); + _this._mouseLeave = _this._mouseLeave.bind(_this); + _this.enable(); + _this._setupAccept(); + return _this; + } + DDDroppable.prototype.on = function (event, callback) { + _super.prototype.on.call(this, event, callback); + }; + DDDroppable.prototype.off = function (event) { + _super.prototype.off.call(this, event); + }; + DDDroppable.prototype.enable = function () { + if (this.disabled === false) + return; + _super.prototype.enable.call(this); + this.el.classList.add('ui-droppable'); + this.el.classList.remove('ui-droppable-disabled'); + this.el.addEventListener('mouseenter', this._mouseEnter); + this.el.addEventListener('mouseleave', this._mouseLeave); + if (dd_touch_1.isTouch) { + this.el.addEventListener('pointerenter', dd_touch_1.pointerenter); + this.el.addEventListener('pointerleave', dd_touch_1.pointerleave); + } + }; + DDDroppable.prototype.disable = function (forDestroy) { + if (forDestroy === void 0) { forDestroy = false; } + if (this.disabled === true) + return; + _super.prototype.disable.call(this); + this.el.classList.remove('ui-droppable'); + if (!forDestroy) + this.el.classList.add('ui-droppable-disabled'); + this.el.removeEventListener('mouseenter', this._mouseEnter); + this.el.removeEventListener('mouseleave', this._mouseLeave); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('pointerenter', dd_touch_1.pointerenter); + this.el.removeEventListener('pointerleave', dd_touch_1.pointerleave); + } + }; + DDDroppable.prototype.destroy = function () { + this.disable(true); + this.el.classList.remove('ui-droppable'); + this.el.classList.remove('ui-droppable-disabled'); + _super.prototype.destroy.call(this); + }; + DDDroppable.prototype.updateOption = function (opts) { + var _this = this; + Object.keys(opts).forEach(function (key) { return _this.option[key] = opts[key]; }); + this._setupAccept(); + return this; + }; + /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */ + DDDroppable.prototype._mouseEnter = function (e) { + // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST + if (!dd_manager_1.DDManager.dragElement) + return; + if (!this._canDrop()) + return; + e.preventDefault(); + e.stopPropagation(); + // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do + if (dd_manager_1.DDManager.dropElement && dd_manager_1.DDManager.dropElement !== this) { + dd_manager_1.DDManager.dropElement._mouseLeave(e); + } + dd_manager_1.DDManager.dropElement = this; + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dropover' }); + if (this.option.over) { + this.option.over(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('dropover', ev); + this.el.classList.add('ui-droppable-over'); + // console.log('tracking'); // TEST + }; + /** @internal called when the item is leaving our area, stop tracking if we had moving item */ + DDDroppable.prototype._mouseLeave = function (e) { + var _a; + // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST + if (!dd_manager_1.DDManager.dragElement || dd_manager_1.DDManager.dropElement !== this) + return; + e.preventDefault(); + e.stopPropagation(); + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'dropout' }); + if (this.option.out) { + this.option.out(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('dropout', ev); + if (dd_manager_1.DDManager.dropElement === this) { + delete dd_manager_1.DDManager.dropElement; + // console.log('not tracking'); // TEST + // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children + var parentDrop = void 0; + var parent_1 = this.el.parentElement; + while (!parentDrop && parent_1) { + parentDrop = (_a = parent_1.ddElement) === null || _a === void 0 ? void 0 : _a.ddDroppable; + parent_1 = parent_1.parentElement; + } + if (parentDrop) { + parentDrop._mouseEnter(e); + } + } + }; + /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */ + DDDroppable.prototype.drop = function (e) { + e.preventDefault(); + var ev = utils_1.Utils.initEvent(e, { target: this.el, type: 'drop' }); + if (this.option.drop) { + this.option.drop(ev, this._ui(dd_manager_1.DDManager.dragElement)); + } + this.triggerEvent('drop', ev); + }; + /** @internal true if element matches the string/method accept option */ + DDDroppable.prototype._canDrop = function () { + return dd_manager_1.DDManager.dragElement && (!this.accept || this.accept(dd_manager_1.DDManager.dragElement.el)); + }; + /** @internal */ + DDDroppable.prototype._setupAccept = function () { + var _this = this; + if (!this.option.accept) + return this; + if (typeof this.option.accept === 'string') { + this.accept = function (el) { return el.matches(_this.option.accept); }; + } + else { + this.accept = this.option.accept; + } + return this; + }; + /** @internal */ + DDDroppable.prototype._ui = function (drag) { + return __assign({ draggable: drag.el }, drag.ui()); + }; + return DDDroppable; +}(dd_base_impl_1.DDBaseImplement)); +exports.DDDroppable = DDDroppable; +//# sourceMappingURL=dd-droppable.js.map \ No newline at end of file diff --git a/dist/es5/dd-droppable.js.map b/dist/es5/dd-droppable.js.map new file mode 100644 index 000000000..44a2cf868 --- /dev/null +++ b/dist/es5/dd-droppable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-droppable.js","sourceRoot":"","sources":["../../src/dd-droppable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-droppable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDManager } from './dd-manager';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, pointerenter, pointerleave } from './dd-touch';\nimport { GridHTMLElement } from './gridstack';\n\nexport interface DDDroppableOpt {\n accept?: string | ((el: HTMLElement) => boolean);\n drop?: (event: DragEvent, ui) => void;\n over?: (event: DragEvent, ui) => void;\n out?: (event: DragEvent, ui) => void;\n}\n\n// let count = 0; // TEST\n\nexport class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n public accept: (el: HTMLElement) => boolean;\n public el: HTMLElement;\n public option: DDDroppableOpt;\n\n constructor(el: HTMLElement, opts: DDDroppableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseEnter = this._mouseEnter.bind(this);\n this._mouseLeave = this._mouseLeave.bind(this);\n this.enable();\n this._setupAccept();\n }\n\n public on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'drop' | 'dropover' | 'dropout'): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.el.classList.add('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n this.el.addEventListener('mouseenter', this._mouseEnter);\n this.el.addEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.addEventListener('pointerenter', pointerenter);\n this.el.addEventListener('pointerleave', pointerleave);\n }\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.el.classList.remove('ui-droppable');\n if (!forDestroy) this.el.classList.add('ui-droppable-disabled');\n this.el.removeEventListener('mouseenter', this._mouseEnter);\n this.el.removeEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.removeEventListener('pointerenter', pointerenter);\n this.el.removeEventListener('pointerleave', pointerleave);\n }\n }\n\n public destroy(): void {\n this.disable(true);\n this.el.classList.remove('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n super.destroy();\n }\n\n public updateOption(opts: DDDroppableOpt): DDDroppable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n this._setupAccept();\n return this;\n }\n\n /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */\n protected _mouseEnter(e: MouseEvent): void {\n // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement) return;\n if (!this._canDrop()) return;\n e.preventDefault();\n e.stopPropagation();\n\n // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do\n if (DDManager.dropElement && DDManager.dropElement !== this) {\n DDManager.dropElement._mouseLeave(e as DragEvent);\n }\n DDManager.dropElement = this;\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });\n if (this.option.over) {\n this.option.over(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropover', ev);\n this.el.classList.add('ui-droppable-over');\n // console.log('tracking'); // TEST\n }\n\n /** @internal called when the item is leaving our area, stop tracking if we had moving item */\n protected _mouseLeave(e: MouseEvent): void {\n // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement || DDManager.dropElement !== this) return;\n e.preventDefault();\n e.stopPropagation();\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });\n if (this.option.out) {\n this.option.out(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropout', ev);\n\n if (DDManager.dropElement === this) {\n delete DDManager.dropElement;\n // console.log('not tracking'); // TEST\n\n // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children\n let parentDrop: DDDroppable;\n let parent: DDElementHost = this.el.parentElement;\n while (!parentDrop && parent) {\n parentDrop = parent.ddElement?.ddDroppable;\n parent = parent.parentElement;\n }\n if (parentDrop) {\n parentDrop._mouseEnter(e);\n }\n }\n }\n\n /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */\n public drop(e: MouseEvent): void {\n e.preventDefault();\n const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });\n if (this.option.drop) {\n this.option.drop(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('drop', ev);\n }\n\n /** @internal true if element matches the string/method accept option */\n protected _canDrop(): boolean {\n return DDManager.dragElement && (!this.accept || this.accept(DDManager.dragElement.el));\n }\n\n /** @internal */\n protected _setupAccept(): DDDroppable {\n if (!this.option.accept) return this;\n if (typeof this.option.accept === 'string') {\n this.accept = (el: HTMLElement) => el.matches(this.option.accept as string);\n } else {\n this.accept = this.option.accept;\n }\n return this;\n }\n\n /** @internal */\n protected _ui(drag: DDDraggable) {\n return {\n draggable: drag.el,\n ...drag.ui()\n };\n }\n}\n\n"]} \ No newline at end of file diff --git a/dist/es5/dd-element.d.ts b/dist/es5/dd-element.d.ts new file mode 100644 index 000000000..35813c6bb --- /dev/null +++ b/dist/es5/dd-element.d.ts @@ -0,0 +1,27 @@ +/** + * dd-elements.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { DDResizable, DDResizableOpt } from './dd-resizable'; +import { GridItemHTMLElement } from './types'; +import { DDDraggable, DDDraggableOpt } from './dd-draggable'; +import { DDDroppable, DDDroppableOpt } from './dd-droppable'; +export interface DDElementHost extends GridItemHTMLElement { + ddElement?: DDElement; +} +export declare class DDElement { + static init(el: DDElementHost): DDElement; + el: DDElementHost; + ddDraggable?: DDDraggable; + ddDroppable?: DDDroppable; + ddResizable?: DDResizable; + constructor(el: DDElementHost); + on(eventName: string, callback: (event: MouseEvent) => void): DDElement; + off(eventName: string): DDElement; + setupDraggable(opts: DDDraggableOpt): DDElement; + cleanDraggable(): DDElement; + setupResizable(opts: DDResizableOpt): DDElement; + cleanResizable(): DDElement; + setupDroppable(opts: DDDroppableOpt): DDElement; + cleanDroppable(): DDElement; +} diff --git a/dist/es5/dd-element.js b/dist/es5/dd-element.js new file mode 100644 index 000000000..f7fb8652c --- /dev/null +++ b/dist/es5/dd-element.js @@ -0,0 +1,96 @@ +"use strict"; +/** + * dd-elements.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDElement = void 0; +var dd_resizable_1 = require("./dd-resizable"); +var dd_draggable_1 = require("./dd-draggable"); +var dd_droppable_1 = require("./dd-droppable"); +var DDElement = /** @class */ (function () { + function DDElement(el) { + this.el = el; + } + DDElement.init = function (el) { + if (!el.ddElement) { + el.ddElement = new DDElement(el); + } + return el.ddElement; + }; + DDElement.prototype.on = function (eventName, callback) { + if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) { + this.ddDraggable.on(eventName, callback); + } + else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) { + this.ddDroppable.on(eventName, callback); + } + else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) { + this.ddResizable.on(eventName, callback); + } + return this; + }; + DDElement.prototype.off = function (eventName) { + if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) { + this.ddDraggable.off(eventName); + } + else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) { + this.ddDroppable.off(eventName); + } + else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) { + this.ddResizable.off(eventName); + } + return this; + }; + DDElement.prototype.setupDraggable = function (opts) { + if (!this.ddDraggable) { + this.ddDraggable = new dd_draggable_1.DDDraggable(this.el, opts); + } + else { + this.ddDraggable.updateOption(opts); + } + return this; + }; + DDElement.prototype.cleanDraggable = function () { + if (this.ddDraggable) { + this.ddDraggable.destroy(); + delete this.ddDraggable; + } + return this; + }; + DDElement.prototype.setupResizable = function (opts) { + if (!this.ddResizable) { + this.ddResizable = new dd_resizable_1.DDResizable(this.el, opts); + } + else { + this.ddResizable.updateOption(opts); + } + return this; + }; + DDElement.prototype.cleanResizable = function () { + if (this.ddResizable) { + this.ddResizable.destroy(); + delete this.ddResizable; + } + return this; + }; + DDElement.prototype.setupDroppable = function (opts) { + if (!this.ddDroppable) { + this.ddDroppable = new dd_droppable_1.DDDroppable(this.el, opts); + } + else { + this.ddDroppable.updateOption(opts); + } + return this; + }; + DDElement.prototype.cleanDroppable = function () { + if (this.ddDroppable) { + this.ddDroppable.destroy(); + delete this.ddDroppable; + } + return this; + }; + return DDElement; +}()); +exports.DDElement = DDElement; +//# sourceMappingURL=dd-element.js.map \ No newline at end of file diff --git a/dist/es5/dd-element.js.map b/dist/es5/dd-element.js.map new file mode 100644 index 000000000..4841a9658 --- /dev/null +++ b/dist/es5/dd-element.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-element.js","sourceRoot":"","sources":["../../src/dd-element.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-elements.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizable, DDResizableOpt } from './dd-resizable';\nimport { GridItemHTMLElement } from './types';\nimport { DDDraggable, DDDraggableOpt } from './dd-draggable';\nimport { DDDroppable, DDDroppableOpt } from './dd-droppable';\n\nexport interface DDElementHost extends GridItemHTMLElement {\n ddElement?: DDElement;\n}\n\nexport class DDElement {\n\n static init(el: DDElementHost): DDElement {\n if (!el.ddElement) { el.ddElement = new DDElement(el); }\n return el.ddElement;\n }\n\n public el: DDElementHost;\n public ddDraggable?: DDDraggable;\n public ddDroppable?: DDDroppable;\n public ddResizable?: DDResizable;\n\n constructor(el: DDElementHost) {\n this.el = el;\n }\n\n public on(eventName: string, callback: (event: MouseEvent) => void): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.on(eventName as 'drag' | 'dragstart' | 'dragstop', callback);\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.on(eventName as 'drop' | 'dropover' | 'dropout', callback);\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.on(eventName as 'resizestart' | 'resize' | 'resizestop', callback);\n }\n return this;\n }\n\n public off(eventName: string): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.off(eventName as 'drag' | 'dragstart' | 'dragstop');\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.off(eventName as 'drop' | 'dropover' | 'dropout');\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.off(eventName as 'resizestart' | 'resize' | 'resizestop');\n }\n return this;\n }\n\n public setupDraggable(opts: DDDraggableOpt): DDElement {\n if (!this.ddDraggable) {\n this.ddDraggable = new DDDraggable(this.el, opts);\n } else {\n this.ddDraggable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDraggable(): DDElement {\n if (this.ddDraggable) {\n this.ddDraggable.destroy();\n delete this.ddDraggable;\n }\n return this;\n }\n\n public setupResizable(opts: DDResizableOpt): DDElement {\n if (!this.ddResizable) {\n this.ddResizable = new DDResizable(this.el, opts);\n } else {\n this.ddResizable.updateOption(opts);\n }\n return this;\n }\n\n public cleanResizable(): DDElement {\n if (this.ddResizable) {\n this.ddResizable.destroy();\n delete this.ddResizable;\n }\n return this;\n }\n\n public setupDroppable(opts: DDDroppableOpt): DDElement {\n if (!this.ddDroppable) {\n this.ddDroppable = new DDDroppable(this.el, opts);\n } else {\n this.ddDroppable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDroppable(): DDElement {\n if (this.ddDroppable) {\n this.ddDroppable.destroy();\n delete this.ddDroppable;\n }\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-gridstack.d.ts b/dist/es5/dd-gridstack.d.ts new file mode 100644 index 000000000..ba9fb2553 --- /dev/null +++ b/dist/es5/dd-gridstack.d.ts @@ -0,0 +1,36 @@ +/** + * dd-gridstack.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridItemHTMLElement, GridStackElement, DDDragInOpt } from './types'; +import { DDElementHost } from './dd-element'; +/** Drag&Drop drop options */ +export declare type DDDropOpt = { + /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */ + accept?: (el: GridItemHTMLElement) => boolean; +}; +/** drag&drop options currently called from the main code, but others can be passed in grid options */ +export declare type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any; +export declare type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'; +export declare type DDValue = number | string; +/** drag&drop events callbacks */ +export declare type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void; +/** + * HTML Native Mouse and Touch Events Drag and Drop functionality. + */ +export declare class DDGridStack { + /** get the global (but static to this code) DD implementation */ + static get(): DDGridStack; + resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack; + draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack; + dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack; + droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack; + /** true if element is droppable */ + isDroppable(el: DDElementHost): boolean; + /** true if element is draggable */ + isDraggable(el: DDElementHost): boolean; + /** true if element is draggable */ + isResizable(el: DDElementHost): boolean; + on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack; + off(el: GridItemHTMLElement, name: string): DDGridStack; +} diff --git a/dist/es5/dd-gridstack.js b/dist/es5/dd-gridstack.js new file mode 100644 index 000000000..631254786 --- /dev/null +++ b/dist/es5/dd-gridstack.js @@ -0,0 +1,769 @@ +"use strict"; +/** + * dd-gridstack.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDGridStack = void 0; +var gridstack_1 = require("./gridstack"); +var utils_1 = require("./utils"); +var dd_manager_1 = require("./dd-manager"); +var dd_element_1 = require("./dd-element"); +// let count = 0; // TEST +/** + * HTML Native Mouse and Touch Events Drag and Drop functionality. + */ +var DDGridStack = /** @class */ (function () { + function DDGridStack() { + } + /** get the global (but static to this code) DD implementation */ + DDGridStack.get = function () { + return dd; + }; + DDGridStack.prototype.resizable = function (el, opts, key, value) { + this._getDDElements(el).forEach(function (dEl) { + var _a; + if (opts === 'disable' || opts === 'enable') { + dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable() + } + else if (opts === 'destroy') { + dEl.ddResizable && dEl.cleanResizable(); + } + else if (opts === 'option') { + dEl.setupResizable((_a = {}, _a[key] = value, _a)); + } + else { + var grid = dEl.el.gridstackNode.grid; + var handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles; + var autoHide = !grid.opts.alwaysShowResizeHandle; + var fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined; + dEl.setupResizable(__assign(__assign(__assign({}, grid.opts.resizable), { handles: handles, autoHide: autoHide }), { + start: opts.start, + stop: opts.stop, + resize: opts.resize, + fixedAspectRatio: fixedAspectRatio + })); + } + }); + return this; + }; + DDGridStack.prototype.draggable = function (el, opts, key, value) { + this._getDDElements(el).forEach(function (dEl) { + var _a; + if (opts === 'disable' || opts === 'enable') { + dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable() + } + else if (opts === 'destroy') { + dEl.ddDraggable && dEl.cleanDraggable(); + } + else if (opts === 'option') { + dEl.setupDraggable((_a = {}, _a[key] = value, _a)); + } + else { + var grid = dEl.el.gridstackNode.grid; + dEl.setupDraggable(__assign(__assign({}, grid.opts.draggable), { + // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null), + start: opts.start, + stop: opts.stop, + drag: opts.drag + })); + } + }); + return this; + }; + DDGridStack.prototype.dragIn = function (el, opts) { + this._getDDElements(el).forEach(function (dEl) { return dEl.setupDraggable(opts); }); + return this; + }; + DDGridStack.prototype.droppable = function (el, opts, key, value) { + if (typeof opts.accept === 'function' && !opts._accept) { + opts._accept = opts.accept; + opts.accept = function (el) { return opts._accept(el); }; + } + this._getDDElements(el).forEach(function (dEl) { + var _a; + if (opts === 'disable' || opts === 'enable') { + dEl.ddDroppable && dEl.ddDroppable[opts](); + } + else if (opts === 'destroy') { + if (dEl.ddDroppable) { // error to call destroy if not there + dEl.cleanDroppable(); + } + } + else if (opts === 'option') { + dEl.setupDroppable((_a = {}, _a[key] = value, _a)); + } + else { + dEl.setupDroppable(opts); + } + }); + return this; + }; + /** true if element is droppable */ + DDGridStack.prototype.isDroppable = function (el) { + return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled); + }; + /** true if element is draggable */ + DDGridStack.prototype.isDraggable = function (el) { + return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled); + }; + /** true if element is draggable */ + DDGridStack.prototype.isResizable = function (el) { + return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled); + }; + DDGridStack.prototype.on = function (el, name, callback) { + this._getDDElements(el).forEach(function (dEl) { + return dEl.on(name, function (event) { + callback(event, dd_manager_1.DDManager.dragElement ? dd_manager_1.DDManager.dragElement.el : event.target, dd_manager_1.DDManager.dragElement ? dd_manager_1.DDManager.dragElement.helper : null); + }); + }); + return this; + }; + DDGridStack.prototype.off = function (el, name) { + this._getDDElements(el).forEach(function (dEl) { return dEl.off(name); }); + return this; + }; + /** @internal returns a list of DD elements, creating them on the fly by default */ + DDGridStack.prototype._getDDElements = function (els, create) { + if (create === void 0) { create = true; } + var hosts = utils_1.Utils.getElements(els); + if (!hosts.length) + return []; + var list = hosts.map(function (e) { return e.ddElement || (create ? dd_element_1.DDElement.init(e) : null); }); + if (!create) { + list.filter(function (d) { return d; }); + } // remove nulls + return list; + }; + return DDGridStack; +}()); +exports.DDGridStack = DDGridStack; +/** global instance */ +var dd = new DDGridStack; +/******************************************************************************** + * GridStack code that is doing drag&drop extracted here so main class is smaller + * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k) + * https://www.typescriptlang.org/docs/handbook/declaration-merging.html + * https://www.typescriptlang.org/docs/handbook/mixins.html + ********************************************************************************/ +/** @internal called to add drag over to support widgets being added externally */ +gridstack_1.GridStack.prototype._setupAcceptWidget = function () { + var _this = this; + // check if we need to disable things + if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) { + dd.droppable(this.el, 'destroy'); + return this; + } + // vars shared across all methods + var cellHeight, cellWidth; + var onDrag = function (event, el, helper) { + var node = el.gridstackNode; + if (!node) + return; + helper = helper || el; + var parent = _this.el.getBoundingClientRect(); + var _a = helper.getBoundingClientRect(), top = _a.top, left = _a.left; + left -= parent.left; + top -= parent.top; + var ui = { position: { top: top, left: left } }; + if (node._temporaryRemoved) { + node.x = Math.max(0, Math.round(left / cellWidth)); + node.y = Math.max(0, Math.round(top / cellHeight)); + delete node.autoPosition; + _this.engine.nodeBoundFix(node); + // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere + if (!_this.engine.willItFit(node)) { + node.autoPosition = true; // ignore x,y and try for any slot... + if (!_this.engine.willItFit(node)) { + dd.off(el, 'drag'); // stop calling us + return; // full grid or can't grow + } + if (node._willFitPos) { + // use the auto position instead #1687 + utils_1.Utils.copyPos(node, node._willFitPos); + delete node._willFitPos; + } + } + // re-use the existing node dragging method + _this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight); + } + else { + // re-use the existing node dragging that does so much of the collision detection + _this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight); + } + }; + dd.droppable(this.el, { + accept: function (el) { + var node = el.gridstackNode; + // set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving + if ((node === null || node === void 0 ? void 0 : node.grid) === _this) + return true; + if (!_this.opts.acceptWidgets) + return false; + // prevent deeper nesting until rest of 992 can be fixed + if (node === null || node === void 0 ? void 0 : node.subGrid) + return false; + // check for accept method or class matching + var canAccept = true; + if (typeof _this.opts.acceptWidgets === 'function') { + canAccept = _this.opts.acceptWidgets(el); + } + else { + var selector = (_this.opts.acceptWidgets === true ? '.grid-stack-item' : _this.opts.acceptWidgets); + canAccept = el.matches(selector); + } + // finally check to make sure we actually have space left #1571 + if (canAccept && node && _this.opts.maxRow) { + var n = { w: node.w, h: node.h, minW: node.minW, minH: node.minH }; // only width/height matters and autoPosition + canAccept = _this.engine.willItFit(n); + } + return canAccept; + } + }) + /** + * entering our grid area + */ + .on(this.el, 'dropover', function (event, el, helper) { + // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST + var node = el.gridstackNode; + // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item + if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._temporaryRemoved) { + // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear) + return false; // prevent parent from receiving msg (which may be a grid as well) + } + // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now + if ((node === null || node === void 0 ? void 0 : node.grid) && node.grid !== _this && !node._temporaryRemoved) { + // console.log('dropover without leave'); // TEST + var otherGrid = node.grid; + otherGrid._leave(el, helper); + } + // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us... + cellWidth = _this.cellWidth(); + cellHeight = _this.getCellHeight(true); + // load any element attributes if we don't have a node + if (!node) { // @ts-ignore private read only on ourself + node = _this._readAttr(el); + } + if (!node.grid) { + node._isExternal = true; + el.gridstackNode = node; + } + // calculate the grid size based on element outer size + helper = helper || el; + var w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1; + var h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1; + // if the item came from another grid, make a copy and save the original info in case we go back there + if (node.grid && node.grid !== _this) { + // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific + // console.log('dropover cloning node'); // TEST + if (!el._gridstackNodeOrig) + el._gridstackNodeOrig = node; // shouldn't have multiple nested! + el.gridstackNode = node = __assign(__assign({}, node), { w: w, h: h, grid: _this }); + _this.engine.cleanupNode(node) + .nodeBoundFix(node); + // restore some internal fields we need after clearing them all + node._initDD = + node._isExternal = // DOM needs to be re-parented on a drop + node._temporaryRemoved = true; // so it can be inserted onDrag below + } + else { + node.w = w; + node.h = h; + node._temporaryRemoved = true; // so we can insert it + } + // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it) + _itemRemoving(node.el, false); + dd.on(el, 'drag', onDrag); + // make sure this is called at least once when going fast #1578 + onDrag(event, el, helper); + return false; // prevent parent from receiving msg (which may be a grid as well) + }) + /** + * Leaving our grid area... + */ + .on(this.el, 'dropout', function (event, el, helper) { + // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST + var node = el.gridstackNode; + if (!node) + return false; + // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean) + // so skip this one if we're not the active grid really.. + if (!node.grid || node.grid === _this) { + _this._leave(el, helper); + } + return false; // prevent parent from receiving msg (which may be grid as well) + }) + /** + * end - releasing the mouse + */ + .on(this.el, 'drop', function (event, el, helper) { + var node = el.gridstackNode; + // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead + if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._isExternal) + return false; + var wasAdded = !!_this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419 + _this.placeholder.remove(); + // notify previous grid of removal + // console.log('drop delete _gridstackNodeOrig') // TEST + var origNode = el._gridstackNodeOrig; + delete el._gridstackNodeOrig; + if (wasAdded && origNode && origNode.grid && origNode.grid !== _this) { + var oGrid = origNode.grid; + oGrid.engine.removedNodes.push(origNode); + oGrid._triggerRemoveEvent(); + } + if (!node) + return false; + // use existing placeholder node as it's already in our list with drop location + if (wasAdded) { + _this.engine.cleanupNode(node); // removes all internal _xyz values + node.grid = _this; + } + dd.off(el, 'drag'); + // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102) + // as the helper will be nuked by jquery-ui otherwise + if (helper !== el) { + helper.remove(); + el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info + if (wasAdded) { + el = el.cloneNode(true); + } + } + else { + el.remove(); // reduce flicker as we change depth here, and size further down + _this._removeDD(el); + } + if (!wasAdded) + return false; + el.gridstackNode = node; + node.el = el; + // @ts-ignore + utils_1.Utils.copyPos(node, _this._readAttr(_this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578 + utils_1.Utils.removePositioningStyles(el); // @ts-ignore + _this._writeAttr(el, node); + _this.el.appendChild(el); // @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only) + _this._updateContainerHeight(); + _this.engine.addedNodes.push(node); // @ts-ignore + _this._triggerAddEvent(); // @ts-ignore + _this._triggerChangeEvent(); + _this.engine.endUpdate(); + if (_this._gsEventHandler['dropped']) { + _this._gsEventHandler['dropped'](__assign(__assign({}, event), { type: 'dropped' }), origNode && origNode.grid ? origNode : undefined, node); + } + // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up + window.setTimeout(function () { + // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget()) + if (node.el && node.el.parentElement) { + _this._prepareDragDropByNode(node); + } + else { + _this.engine.removeNode(node); + } + }); + return false; // prevent parent from receiving msg (which may be grid as well) + }); + return this; +}; +/** @internal mark item for removal */ +function _itemRemoving(el, remove) { + var node = el ? el.gridstackNode : undefined; + if (!node || !node.grid) + return; + remove ? node._isAboutToRemove = true : delete node._isAboutToRemove; + remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing'); +} +/** @internal called to setup a trash drop zone if the user specifies it */ +gridstack_1.GridStack.prototype._setupRemoveDrop = function () { + if (!this.opts.staticGrid && typeof this.opts.removable === 'string') { + var trashEl = document.querySelector(this.opts.removable); + if (!trashEl) + return this; + // only register ONE drop-over/dropout callback for the 'trash', and it will + // update the passed in item and parent grid because the 'trash' is a shared resource anyway, + // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly) + if (!dd.isDroppable(trashEl)) { + dd.droppable(trashEl, this.opts.removableOptions) + .on(trashEl, 'dropover', function (event, el) { return _itemRemoving(el, true); }) + .on(trashEl, 'dropout', function (event, el) { return _itemRemoving(el, false); }); + } + } + return this; +}; +/** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + **/ +gridstack_1.GridStack.setupDragIn = function (_dragIn, _dragInOptions) { + var dragIn; + var dragInOptions; + var dragInDefaultOptions = { + handle: '.grid-stack-item-content', + appendTo: 'body', + }; + // cache in the passed in values (form grid init?) so they don't have to resend them each time + if (_dragIn) { + dragIn = _dragIn; + dragInOptions = __assign(__assign({}, dragInDefaultOptions), (_dragInOptions || {})); + } + if (typeof dragIn !== 'string') + return; + utils_1.Utils.getElements(dragIn).forEach(function (el) { + if (!dd.isDraggable(el)) + dd.dragIn(el, dragInOptions); + }); +}; +/** @internal prepares the element for drag&drop **/ +gridstack_1.GridStack.prototype._prepareDragDropByNode = function (node) { + var _this = this; + var el = node.el; + var noMove = node.noMove || this.opts.disableDrag; + var noResize = node.noResize || this.opts.disableResize; + // check for disabled grid first + if (this.opts.staticGrid || (noMove && noResize)) { + if (node._initDD) { + this._removeDD(el); // nukes everything instead of just disable, will add some styles back next + delete node._initDD; + } + el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435 + return this; + } + if (!node._initDD) { + // variables used/cashed between the 3 start/move/end methods, in addition to node passed above + var cellWidth_1; + var cellHeight_1; + /** called when item starts moving/resizing */ + var onStartMoving = function (event, ui) { + // trigger any 'dragstart' / 'resizestart' manually + if (_this._gsEventHandler[event.type]) { + _this._gsEventHandler[event.type](event, event.target); + } + cellWidth_1 = _this.cellWidth(); + cellHeight_1 = _this.getCellHeight(true); // force pixels for calculations + _this._onStartMoving(el, event, ui, node, cellWidth_1, cellHeight_1); + }; + /** called when item is being dragged/resized */ + var dragOrResize = function (event, ui) { + _this._dragOrResize(el, event, ui, node, cellWidth_1, cellHeight_1); + }; + /** called when the item stops moving/resizing */ + var onEndMoving = function (event) { + _this.placeholder.remove(); + delete node._moving; + delete node._lastTried; + // if the item has moved to another grid, we're done here + var target = event.target; + if (!target.gridstackNode || target.gridstackNode.grid !== _this) + return; + node.el = target; + if (node._isAboutToRemove) { + var gridToNotify = el.gridstackNode.grid; + if (gridToNotify._gsEventHandler[event.type]) { + gridToNotify._gsEventHandler[event.type](event, target); + } + _this._removeDD(el); + gridToNotify.engine.removedNodes.push(node); + gridToNotify._triggerRemoveEvent(); + // break circular links and remove DOM + delete el.gridstackNode; + delete node.el; + el.remove(); + } + else { + utils_1.Utils.removePositioningStyles(target); + if (node._temporaryRemoved) { + // got removed - restore item back to before dragging position + utils_1.Utils.copyPos(node, node._orig); // @ts-ignore + _this._writePosAttr(target, node); + _this.engine.addNode(node); + } + else { + // move to new placeholder location + _this._writePosAttr(target, node); + } + if (_this._gsEventHandler[event.type]) { + _this._gsEventHandler[event.type](event, target); + } + } + // @ts-ignore + _this._extraDragRow = 0; // @ts-ignore + _this._updateContainerHeight(); // @ts-ignore + _this._triggerChangeEvent(); + _this.engine.endUpdate(); + }; + dd.draggable(el, { + start: onStartMoving, + stop: onEndMoving, + drag: dragOrResize + }).resizable(el, { + start: onStartMoving, + stop: onEndMoving, + resize: dragOrResize + }); + node._initDD = true; // we've set DD support now + } + // finally fine tune move vs resize by disabling any part... + dd.draggable(el, noMove ? 'disable' : 'enable') + .resizable(el, noResize ? 'disable' : 'enable'); + return this; +}; +/** @internal called when item is starting a drag/resize */ +gridstack_1.GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) { + this.engine.cleanNodes() + .beginUpdate(node); + // @ts-ignore + this._writePosAttr(this.placeholder, node); + this.el.appendChild(this.placeholder); + // console.log('_onStartMoving placeholder') // TEST + node.el = this.placeholder; + node._lastUiPosition = ui.position; + node._prevYPix = ui.position.top; + node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way) + delete node._lastTried; + if (event.type === 'dropover' && node._temporaryRemoved) { + // console.log('engine.addNode x=' + node.x); // TEST + this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved + node._moving = true; // AFTER, mark as moving object (wanted fix location before) + } + // set the min/max resize info + this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop, this.opts.marginRight, this.opts.marginBottom, this.opts.marginLeft); + if (event.type === 'resizestart') { + dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1)) + .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1)); + if (node.maxW) { + dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); + } + if (node.maxH) { + dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); + } + } +}; +/** @internal called when item leaving our area by either cursor dropout event + * or shape is outside our boundaries. remove it from us, and mark temporary if this was + * our item to start with else restore prev node values from prev grid it came from. + **/ +gridstack_1.GridStack.prototype._leave = function (el, helper) { + var node = el.gridstackNode; + if (!node) + return; + dd.off(el, 'drag'); // no need to track while being outside + // this gets called when cursor leaves and shape is outside, so only do this once + if (node._temporaryRemoved) + return; + node._temporaryRemoved = true; + this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue + node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged + if (this.opts.removable === true) { // boolean vs a class string + // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so + _itemRemoving(el, true); + } + // finally if item originally came from another grid, but left us, restore things back to prev info + if (el._gridstackNodeOrig) { + // console.log('leave delete _gridstackNodeOrig') // TEST + el.gridstackNode = el._gridstackNodeOrig; + delete el._gridstackNodeOrig; + } + else if (node._isExternal) { + // item came from outside (like a toolbar) so nuke any node info + delete node.el; + delete el.gridstackNode; + // and restore all nodes back to original + this.engine.restoreInitial(); + } +}; +/** @internal called when item is being dragged/resized */ +gridstack_1.GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) { + var p = __assign({}, node._orig); // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value) + var resizing; + var mLeft = this.opts.marginLeft, mRight = this.opts.marginRight, mTop = this.opts.marginTop, mBottom = this.opts.marginBottom; + // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855 + var mHeight = Math.round(cellHeight * 0.1), mWidth = Math.round(cellWidth * 0.1); + mLeft = Math.min(mLeft, mWidth); + mRight = Math.min(mRight, mWidth); + mTop = Math.min(mTop, mHeight); + mBottom = Math.min(mBottom, mHeight); + if (event.type === 'drag') { + if (node._temporaryRemoved) + return; // handled by dropover + var distance = ui.position.top - node._prevYPix; + node._prevYPix = ui.position.top; + utils_1.Utils.updateScrollPosition(el, ui.position, distance); + // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin) + var left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft); + var top_1 = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop); + p.x = Math.round(left / cellWidth); + p.y = Math.round(top_1 / cellHeight); + // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others + var prev = this._extraDragRow; + if (this.engine.collide(node, p)) { + var row = this.getRow(); + var extra = Math.max(0, (p.y + node.h) - row); + if (this.opts.maxRow && row + extra > this.opts.maxRow) { + extra = Math.max(0, this.opts.maxRow - row); + } // @ts-ignore + this._extraDragRow = extra; // @ts-ignore + } + else + this._extraDragRow = 0; // @ts-ignore + if (this._extraDragRow !== prev) + this._updateContainerHeight(); + if (node.x === p.x && node.y === p.y) + return; // skip same + // DON'T skip one we tried as we might have failed because of coverage <50% before + // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return; + } + else if (event.type === 'resize') { + if (p.x < 0) + return; + // Scrolling page if needed + utils_1.Utils.updateScrollResize(event, el, cellHeight); + // get new size + p.w = Math.round((ui.size.width - mLeft) / cellWidth); + p.h = Math.round((ui.size.height - mTop) / cellHeight); + if (node.w === p.w && node.h === p.h) + return; + if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) + return; // skip one we tried (but failed) + // if we size on left/top side this might move us, so get possible new position as well + var left = ui.position.left + mLeft; + var top_2 = ui.position.top + mTop; + p.x = Math.round(left / cellWidth); + p.y = Math.round(top_2 / cellHeight); + resizing = true; + } + node._lastTried = p; // set as last tried (will nuke if we go there) + var rect = { + x: ui.position.left + mLeft, + y: ui.position.top + mTop, + w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight, + h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom + }; + if (this.engine.moveNodeCheck(node, __assign(__assign({}, p), { cellWidth: cellWidth, cellHeight: cellHeight, rect: rect, resizing: resizing }))) { + node._lastUiPosition = ui.position; + this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft); + delete node._skipDown; + if (resizing && node.subGrid) { + node.subGrid.onParentResize(); + } // @ts-ignore + this._extraDragRow = 0; // @ts-ignore + this._updateContainerHeight(); + var target = event.target; // @ts-ignore + this._writePosAttr(target, node); + if (this._gsEventHandler[event.type]) { + this._gsEventHandler[event.type](event, target); + } + } +}; +/** + * Enables/Disables moving. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ +gridstack_1.GridStack.prototype.movable = function (els, val) { + var _this = this; + if (this.opts.staticGrid) + return this; // can't move a static grid! + gridstack_1.GridStack.getElements(els).forEach(function (el) { + var node = el.gridstackNode; + if (!node) + return; + if (val) + delete node.noMove; + else + node.noMove = true; + _this._prepareDragDropByNode(node); // init DD if need be, and adjust + }); + return this; +}; +/** + * Enables/Disables resizing. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ +gridstack_1.GridStack.prototype.resizable = function (els, val) { + var _this = this; + if (this.opts.staticGrid) + return this; // can't resize a static grid! + gridstack_1.GridStack.getElements(els).forEach(function (el) { + var node = el.gridstackNode; + if (!node) + return; + if (val) + delete node.noResize; + else + node.noResize = true; + _this._prepareDragDropByNode(node); // init DD if need be, and adjust + }); + return this; +}; +/** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ +gridstack_1.GridStack.prototype.disable = function () { + if (this.opts.staticGrid) + return; + this.enableMove(false); + this.enableResize(false); // @ts-ignore + this._triggerEvent('disable'); + return this; +}; +/** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ +gridstack_1.GridStack.prototype.enable = function () { + if (this.opts.staticGrid) + return; + this.enableMove(true); + this.enableResize(true); // @ts-ignore + this._triggerEvent('enable'); + return this; +}; +/** Enables/disables widget moving. No-op for static grids. */ +gridstack_1.GridStack.prototype.enableMove = function (doEnable) { + var _this = this; + if (this.opts.staticGrid) + return this; // can't move a static grid! + this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658 + this.engine.nodes.forEach(function (n) { return _this.movable(n.el, doEnable); }); + return this; +}; +/** Enables/disables widget resizing. No-op for static grids. */ +gridstack_1.GridStack.prototype.enableResize = function (doEnable) { + var _this = this; + if (this.opts.staticGrid) + return this; // can't size a static grid! + this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658 + this.engine.nodes.forEach(function (n) { return _this.resizable(n.el, doEnable); }); + return this; +}; +/** removes any drag&drop present (called during destroy) */ +gridstack_1.GridStack.prototype._removeDD = function (el) { + dd.draggable(el, 'destroy').resizable(el, 'destroy'); + if (el.gridstackNode) { + delete el.gridstackNode._initDD; // reset our DD init flag + } + return this; +}; +//# sourceMappingURL=dd-gridstack.js.map \ No newline at end of file diff --git a/dist/es5/dd-gridstack.js.map b/dist/es5/dd-gridstack.js.map new file mode 100644 index 000000000..ccc9dc824 --- /dev/null +++ b/dist/es5/dd-gridstack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-gridstack.js","sourceRoot":"","sources":["../../src/dd-gridstack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * dd-gridstack.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { GridItemHTMLElement, GridStackNode, GridStackElement, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\nimport { GridStack } from './gridstack';\r\nimport { Utils } from './utils';\r\nimport { DDManager } from './dd-manager';\r\nimport { DDElement, DDElementHost } from './dd-element';\r\n\r\n/** Drag&Drop drop options */\r\nexport type DDDropOpt = {\r\n /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */\r\n accept?: (el: GridItemHTMLElement) => boolean;\r\n}\r\n\r\n/** drag&drop options currently called from the main code, but others can be passed in grid options */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any;\r\nexport type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight';\r\nexport type DDValue = number | string;\r\n\r\n/** drag&drop events callbacks */\r\nexport type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void;\r\n\r\n// let count = 0; // TEST\r\n\r\n/**\r\n * HTML Native Mouse and Touch Events Drag and Drop functionality.\r\n */\r\nexport class DDGridStack {\r\n\r\n /** get the global (but static to this code) DD implementation */\r\n static get(): DDGridStack {\r\n return dd;\r\n }\r\n\r\n public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddResizable && dEl.cleanResizable();\r\n } else if (opts === 'option') {\r\n dEl.setupResizable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles;\r\n let autoHide = !grid.opts.alwaysShowResizeHandle;\r\n let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined;\r\n dEl.setupResizable({\r\n ...grid.opts.resizable,\r\n ...{ handles, autoHide },\r\n ...{\r\n start: opts.start,\r\n stop: opts.stop,\r\n resize: opts.resize,\r\n fixedAspectRatio: fixedAspectRatio\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddDraggable && dEl.cleanDraggable();\r\n } else if (opts === 'option') {\r\n dEl.setupDraggable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n dEl.setupDraggable({\r\n ...grid.opts.draggable,\r\n ...{\r\n // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null),\r\n start: opts.start,\r\n stop: opts.stop,\r\n drag: opts.drag\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));\r\n return this;\r\n }\r\n\r\n public droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack {\r\n if (typeof opts.accept === 'function' && !opts._accept) {\r\n opts._accept = opts.accept;\r\n opts.accept = (el) => opts._accept(el);\r\n }\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDroppable && dEl.ddDroppable[opts]();\r\n } else if (opts === 'destroy') {\r\n if (dEl.ddDroppable) { // error to call destroy if not there\r\n dEl.cleanDroppable();\r\n }\r\n } else if (opts === 'option') {\r\n dEl.setupDroppable({ [key]: value });\r\n } else {\r\n dEl.setupDroppable(opts);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /** true if element is droppable */\r\n public isDroppable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isDraggable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isResizable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled);\r\n }\r\n\r\n public on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack {\r\n this._getDDElements(el).forEach(dEl =>\r\n dEl.on(name, (event: Event) => {\r\n callback(\r\n event,\r\n DDManager.dragElement ? DDManager.dragElement.el : event.target as GridItemHTMLElement,\r\n DDManager.dragElement ? DDManager.dragElement.helper : null)\r\n })\r\n );\r\n return this;\r\n }\r\n\r\n public off(el: GridItemHTMLElement, name: string): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.off(name));\r\n return this;\r\n }\r\n\r\n /** @internal returns a list of DD elements, creating them on the fly by default */\r\n protected _getDDElements(els: GridStackElement, create = true): DDElement[] {\r\n let hosts = Utils.getElements(els) as DDElementHost[];\r\n if (!hosts.length) return [];\r\n let list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null));\r\n if (!create) { list.filter(d => d); } // remove nulls\r\n return list;\r\n }\r\n}\r\n\r\n/** global instance */\r\nconst dd = new DDGridStack;\r\n\r\n/********************************************************************************\r\n * GridStack code that is doing drag&drop extracted here so main class is smaller\r\n * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k)\r\n * https://www.typescriptlang.org/docs/handbook/declaration-merging.html\r\n * https://www.typescriptlang.org/docs/handbook/mixins.html\r\n ********************************************************************************/\r\n\r\n/** @internal called to add drag over to support widgets being added externally */\r\nGridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {\r\n\r\n // check if we need to disable things\r\n if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {\r\n dd.droppable(this.el, 'destroy');\r\n return this;\r\n }\r\n\r\n // vars shared across all methods\r\n let cellHeight: number, cellWidth: number;\r\n\r\n let onDrag = (event: DragEvent, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n helper = helper || el;\r\n let parent = this.el.getBoundingClientRect();\r\n let {top, left} = helper.getBoundingClientRect();\r\n left -= parent.left;\r\n top -= parent.top;\r\n let ui: DDUIData = {position: {top, left}};\r\n\r\n if (node._temporaryRemoved) {\r\n node.x = Math.max(0, Math.round(left / cellWidth));\r\n node.y = Math.max(0, Math.round(top / cellHeight));\r\n delete node.autoPosition;\r\n this.engine.nodeBoundFix(node);\r\n\r\n // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere\r\n if (!this.engine.willItFit(node)) {\r\n node.autoPosition = true; // ignore x,y and try for any slot...\r\n if (!this.engine.willItFit(node)) {\r\n dd.off(el, 'drag'); // stop calling us\r\n return; // full grid or can't grow\r\n }\r\n if (node._willFitPos) {\r\n // use the auto position instead #1687\r\n Utils.copyPos(node, node._willFitPos);\r\n delete node._willFitPos;\r\n }\r\n }\r\n\r\n // re-use the existing node dragging method\r\n this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);\r\n } else {\r\n // re-use the existing node dragging that does so much of the collision detection\r\n this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);\r\n }\r\n }\r\n\r\n dd.droppable(this.el, {\r\n accept: (el: GridItemHTMLElement) => {\r\n let node: GridStackNode = el.gridstackNode;\r\n // set accept drop to true on ourself (which we ignore) so we don't get \"can't drop\" icon in HTML5 mode while moving\r\n if (node?.grid === this) return true;\r\n if (!this.opts.acceptWidgets) return false;\r\n // prevent deeper nesting until rest of 992 can be fixed\r\n if (node?.subGrid) return false;\r\n // check for accept method or class matching\r\n let canAccept = true;\r\n if (typeof this.opts.acceptWidgets === 'function') {\r\n canAccept = this.opts.acceptWidgets(el);\r\n } else {\r\n let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets as string);\r\n canAccept = el.matches(selector);\r\n }\r\n // finally check to make sure we actually have space left #1571\r\n if (canAccept && node && this.opts.maxRow) {\r\n let n = {w: node.w, h: node.h, minW: node.minW, minH: node.minH}; // only width/height matters and autoPosition\r\n canAccept = this.engine.willItFit(n);\r\n }\r\n return canAccept;\r\n }\r\n })\r\n /**\r\n * entering our grid area\r\n */\r\n .on(this.el, 'dropover', (event: Event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item\r\n if (node?.grid === this && !node._temporaryRemoved) {\r\n // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n }\r\n\r\n // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now\r\n if (node?.grid && node.grid !== this && !node._temporaryRemoved) {\r\n // console.log('dropover without leave'); // TEST\r\n let otherGrid = node.grid;\r\n otherGrid._leave(el, helper);\r\n }\r\n\r\n // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true);\r\n\r\n // load any element attributes if we don't have a node\r\n if (!node) {// @ts-ignore private read only on ourself\r\n node = this._readAttr(el);\r\n }\r\n if (!node.grid) {\r\n node._isExternal = true;\r\n el.gridstackNode = node;\r\n }\r\n\r\n // calculate the grid size based on element outer size\r\n helper = helper || el;\r\n let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;\r\n let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;\r\n\r\n // if the item came from another grid, make a copy and save the original info in case we go back there\r\n if (node.grid && node.grid !== this) {\r\n // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific\r\n // console.log('dropover cloning node'); // TEST\r\n if (!el._gridstackNodeOrig) el._gridstackNodeOrig = node; // shouldn't have multiple nested!\r\n el.gridstackNode = node = {...node, w, h, grid: this};\r\n this.engine.cleanupNode(node)\r\n .nodeBoundFix(node);\r\n // restore some internal fields we need after clearing them all\r\n node._initDD =\r\n node._isExternal = // DOM needs to be re-parented on a drop\r\n node._temporaryRemoved = true; // so it can be inserted onDrag below\r\n } else {\r\n node.w = w; node.h = h;\r\n node._temporaryRemoved = true; // so we can insert it\r\n }\r\n\r\n // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)\r\n _itemRemoving(node.el, false);\r\n\r\n dd.on(el, 'drag', onDrag);\r\n // make sure this is called at least once when going fast #1578\r\n onDrag(event as DragEvent, el, helper);\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n })\r\n /**\r\n * Leaving our grid area...\r\n */\r\n .on(this.el, 'dropout', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n if (!node) return false;\r\n // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)\r\n // so skip this one if we're not the active grid really..\r\n if (!node.grid || node.grid === this) {\r\n this._leave(el, helper);\r\n }\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n })\r\n /**\r\n * end - releasing the mouse\r\n */\r\n .on(this.el, 'drop', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead\r\n if (node?.grid === this && !node._isExternal) return false;\r\n\r\n let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419\r\n this.placeholder.remove();\r\n\r\n // notify previous grid of removal\r\n // console.log('drop delete _gridstackNodeOrig') // TEST\r\n let origNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n if (wasAdded && origNode && origNode.grid && origNode.grid !== this) {\r\n let oGrid = origNode.grid;\r\n oGrid.engine.removedNodes.push(origNode);\r\n oGrid._triggerRemoveEvent();\r\n }\r\n\r\n if (!node) return false;\r\n\r\n // use existing placeholder node as it's already in our list with drop location\r\n if (wasAdded) {\r\n this.engine.cleanupNode(node); // removes all internal _xyz values\r\n node.grid = this;\r\n }\r\n dd.off(el, 'drag');\r\n // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)\r\n // as the helper will be nuked by jquery-ui otherwise\r\n if (helper !== el) {\r\n helper.remove();\r\n el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info\r\n if (wasAdded) {\r\n el = el.cloneNode(true) as GridItemHTMLElement;\r\n }\r\n } else {\r\n el.remove(); // reduce flicker as we change depth here, and size further down\r\n this._removeDD(el);\r\n }\r\n if (!wasAdded) return false;\r\n el.gridstackNode = node;\r\n node.el = el;\r\n // @ts-ignore\r\n Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578\r\n Utils.removePositioningStyles(el);// @ts-ignore\r\n this._writeAttr(el, node);\r\n this.el.appendChild(el);// @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)\r\n this._updateContainerHeight();\r\n this.engine.addedNodes.push(node);// @ts-ignore\r\n this._triggerAddEvent();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n if (this._gsEventHandler['dropped']) {\r\n this._gsEventHandler['dropped']({...event, type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);\r\n }\r\n\r\n // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up\r\n window.setTimeout(() => {\r\n // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())\r\n if (node.el && node.el.parentElement) {\r\n this._prepareDragDropByNode(node);\r\n } else {\r\n this.engine.removeNode(node);\r\n }\r\n });\r\n\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n });\r\n return this;\r\n}\r\n\r\n/** @internal mark item for removal */\r\nfunction _itemRemoving(el: GridItemHTMLElement, remove: boolean) {\r\n let node = el ? el.gridstackNode : undefined;\r\n if (!node || !node.grid) return;\r\n remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;\r\n remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');\r\n}\r\n\r\n/** @internal called to setup a trash drop zone if the user specifies it */\r\nGridStack.prototype._setupRemoveDrop = function(this: GridStack): GridStack {\r\n if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {\r\n let trashEl = document.querySelector(this.opts.removable) as HTMLElement;\r\n if (!trashEl) return this;\r\n // only register ONE drop-over/dropout callback for the 'trash', and it will\r\n // update the passed in item and parent grid because the 'trash' is a shared resource anyway,\r\n // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)\r\n if (!dd.isDroppable(trashEl)) {\r\n dd.droppable(trashEl, this.opts.removableOptions)\r\n .on(trashEl, 'dropover', (event, el) => _itemRemoving(el, true))\r\n .on(trashEl, 'dropout', (event, el) => _itemRemoving(el, false));\r\n }\r\n }\r\n return this;\r\n}\r\n\r\n/**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n **/\r\nGridStack.setupDragIn = function(this: GridStack, _dragIn?: string, _dragInOptions?: DDDragInOpt) {\r\n let dragIn: string;\r\n let dragInOptions: DDDragInOpt;\r\n const dragInDefaultOptions: DDDragInOpt = {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body',\r\n // revert: 'invalid',\r\n // scroll: false,\r\n };\r\n\r\n // cache in the passed in values (form grid init?) so they don't have to resend them each time\r\n if (_dragIn) {\r\n dragIn = _dragIn;\r\n dragInOptions = {...dragInDefaultOptions, ...(_dragInOptions || {})};\r\n }\r\n if (typeof dragIn !== 'string') return;\r\n Utils.getElements(dragIn).forEach(el => {\r\n if (!dd.isDraggable(el)) dd.dragIn(el, dragInOptions);\r\n });\r\n}\r\n\r\n/** @internal prepares the element for drag&drop **/\r\nGridStack.prototype._prepareDragDropByNode = function(this: GridStack, node: GridStackNode): GridStack {\r\n let el = node.el;\r\n const noMove = node.noMove || this.opts.disableDrag;\r\n const noResize = node.noResize || this.opts.disableResize;\r\n\r\n // check for disabled grid first\r\n if (this.opts.staticGrid || (noMove && noResize)) {\r\n if (node._initDD) {\r\n this._removeDD(el); // nukes everything instead of just disable, will add some styles back next\r\n delete node._initDD;\r\n }\r\n el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435\r\n return this;\r\n }\r\n\r\n if (!node._initDD) {\r\n // variables used/cashed between the 3 start/move/end methods, in addition to node passed above\r\n let cellWidth: number;\r\n let cellHeight: number;\r\n\r\n /** called when item starts moving/resizing */\r\n let onStartMoving = (event: Event, ui: DDUIData) => {\r\n // trigger any 'dragstart' / 'resizestart' manually\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, event.target);\r\n }\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true); // force pixels for calculations\r\n\r\n this._onStartMoving(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when item is being dragged/resized */\r\n let dragOrResize = (event: Event, ui: DDUIData) => {\r\n this._dragOrResize(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when the item stops moving/resizing */\r\n let onEndMoving = (event: Event) => {\r\n this.placeholder.remove();\r\n delete node._moving;\r\n delete node._lastTried;\r\n\r\n // if the item has moved to another grid, we're done here\r\n let target: GridItemHTMLElement = event.target as GridItemHTMLElement;\r\n if (!target.gridstackNode || target.gridstackNode.grid !== this) return;\r\n\r\n node.el = target;\r\n\r\n if (node._isAboutToRemove) {\r\n let gridToNotify = el.gridstackNode.grid;\r\n if (gridToNotify._gsEventHandler[event.type]) {\r\n gridToNotify._gsEventHandler[event.type](event, target);\r\n }\r\n this._removeDD(el);\r\n gridToNotify.engine.removedNodes.push(node);\r\n gridToNotify._triggerRemoveEvent();\r\n // break circular links and remove DOM\r\n delete el.gridstackNode;\r\n delete node.el;\r\n el.remove();\r\n } else {\r\n Utils.removePositioningStyles(target);\r\n if (node._temporaryRemoved) {\r\n // got removed - restore item back to before dragging position\r\n Utils.copyPos(node, node._orig);// @ts-ignore\r\n this._writePosAttr(target, node);\r\n this.engine.addNode(node);\r\n } else {\r\n // move to new placeholder location\r\n this._writePosAttr(target, node);\r\n }\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n // @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n }\r\n\r\n dd.draggable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n drag: dragOrResize\r\n }).resizable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n resize: dragOrResize\r\n });\r\n node._initDD = true; // we've set DD support now\r\n }\r\n\r\n // finally fine tune move vs resize by disabling any part...\r\n dd.draggable(el, noMove ? 'disable' : 'enable')\r\n .resizable(el, noResize ? 'disable' : 'enable');\r\n\r\n return this;\r\n}\r\n\r\n/** @internal called when item is starting a drag/resize */\r\nGridStack.prototype._onStartMoving = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(node);\r\n // @ts-ignore\r\n this._writePosAttr(this.placeholder, node)\r\n this.el.appendChild(this.placeholder);\r\n // console.log('_onStartMoving placeholder') // TEST\r\n\r\n node.el = this.placeholder;\r\n node._lastUiPosition = ui.position;\r\n node._prevYPix = ui.position.top;\r\n node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)\r\n delete node._lastTried;\r\n\r\n if (event.type === 'dropover' && node._temporaryRemoved) {\r\n // console.log('engine.addNode x=' + node.x); // TEST\r\n this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved\r\n node._moving = true; // AFTER, mark as moving object (wanted fix location before)\r\n }\r\n\r\n // set the min/max resize info\r\n this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop as number, this.opts.marginRight as number, this.opts.marginBottom as number, this.opts.marginLeft as number);\r\n if (event.type === 'resizestart') {\r\n dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))\r\n .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));\r\n if (node.maxW) { dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); }\r\n if (node.maxH) { dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); }\r\n }\r\n}\r\n\r\n/** @internal called when item leaving our area by either cursor dropout event\r\n * or shape is outside our boundaries. remove it from us, and mark temporary if this was\r\n * our item to start with else restore prev node values from prev grid it came from.\r\n **/\r\nGridStack.prototype._leave = function(this: GridStack, el: GridItemHTMLElement, helper?: GridItemHTMLElement) {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n dd.off(el, 'drag'); // no need to track while being outside\r\n\r\n // this gets called when cursor leaves and shape is outside, so only do this once\r\n if (node._temporaryRemoved) return;\r\n node._temporaryRemoved = true;\r\n\r\n this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue\r\n node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged\r\n\r\n if (this.opts.removable === true) { // boolean vs a class string\r\n // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so\r\n _itemRemoving(el, true);\r\n }\r\n\r\n // finally if item originally came from another grid, but left us, restore things back to prev info\r\n if (el._gridstackNodeOrig) {\r\n // console.log('leave delete _gridstackNodeOrig') // TEST\r\n el.gridstackNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n } else if (node._isExternal) {\r\n // item came from outside (like a toolbar) so nuke any node info\r\n delete node.el;\r\n delete el.gridstackNode;\r\n // and restore all nodes back to original\r\n this.engine.restoreInitial();\r\n }\r\n}\r\n\r\n/** @internal called when item is being dragged/resized */\r\nGridStack.prototype._dragOrResize = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n let p = {...node._orig}; // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value)\r\n let resizing: boolean;\r\n let mLeft = this.opts.marginLeft as number,\r\n mRight = this.opts.marginRight as number,\r\n mTop = this.opts.marginTop as number,\r\n mBottom = this.opts.marginBottom as number;\r\n\r\n // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855\r\n let mHeight = Math.round(cellHeight * 0.1),\r\n mWidth = Math.round(cellWidth * 0.1);\r\n mLeft = Math.min(mLeft, mWidth);\r\n mRight = Math.min(mRight, mWidth);\r\n mTop = Math.min(mTop, mHeight);\r\n mBottom = Math.min(mBottom, mHeight);\r\n\r\n if (event.type === 'drag') {\r\n if (node._temporaryRemoved) return; // handled by dropover\r\n let distance = ui.position.top - node._prevYPix;\r\n node._prevYPix = ui.position.top;\r\n Utils.updateScrollPosition(el, ui.position, distance);\r\n\r\n // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)\r\n let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);\r\n let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others\r\n let prev = this._extraDragRow;\r\n if (this.engine.collide(node, p)) {\r\n let row = this.getRow();\r\n let extra = Math.max(0, (p.y + node.h) - row);\r\n if (this.opts.maxRow && row + extra > this.opts.maxRow) {\r\n extra = Math.max(0, this.opts.maxRow - row);\r\n }// @ts-ignore\r\n this._extraDragRow = extra;// @ts-ignore\r\n } else this._extraDragRow = 0;// @ts-ignore\r\n if (this._extraDragRow !== prev) this._updateContainerHeight();\r\n\r\n if (node.x === p.x && node.y === p.y) return; // skip same\r\n // DON'T skip one we tried as we might have failed because of coverage <50% before\r\n // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;\r\n } else if (event.type === 'resize') {\r\n if (p.x < 0) return;\r\n // Scrolling page if needed\r\n Utils.updateScrollResize(event as MouseEvent, el, cellHeight);\r\n\r\n // get new size\r\n p.w = Math.round((ui.size.width - mLeft) / cellWidth);\r\n p.h = Math.round((ui.size.height - mTop) / cellHeight);\r\n if (node.w === p.w && node.h === p.h) return;\r\n if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) return; // skip one we tried (but failed)\r\n\r\n // if we size on left/top side this might move us, so get possible new position as well\r\n let left = ui.position.left + mLeft;\r\n let top = ui.position.top + mTop;\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n resizing = true;\r\n }\r\n\r\n node._lastTried = p; // set as last tried (will nuke if we go there)\r\n let rect: GridStackPosition = { // screen pix of the dragged box\r\n x: ui.position.left + mLeft,\r\n y: ui.position.top + mTop,\r\n w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,\r\n h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom\r\n };\r\n if (this.engine.moveNodeCheck(node, {...p, cellWidth, cellHeight, rect, resizing})) {\r\n node._lastUiPosition = ui.position;\r\n this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);\r\n delete node._skipDown;\r\n if (resizing && node.subGrid) { (node.subGrid as GridStack).onParentResize(); }// @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();\r\n\r\n let target = event.target as GridItemHTMLElement;// @ts-ignore\r\n this._writePosAttr(target, node);\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Enables/Disables moving.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\nGridStack.prototype.movable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noMove; else node.noMove = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Enables/Disables resizing.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\nGridStack.prototype.resizable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't resize a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noResize; else node.noResize = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\nGridStack.prototype.disable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(false);\r\n this.enableResize(false);// @ts-ignore\r\n this._triggerEvent('disable');\r\n return this;\r\n}\r\n\r\n/**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\nGridStack.prototype.enable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(true);\r\n this.enableResize(true);// @ts-ignore\r\n this._triggerEvent('enable');\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget moving. No-op for static grids. */\r\nGridStack.prototype.enableMove = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.movable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget resizing. No-op for static grids. */\r\nGridStack.prototype.enableResize = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't size a static grid!\r\n this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.resizable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** removes any drag&drop present (called during destroy) */\r\nGridStack.prototype._removeDD = function(this: GridStack, el: GridItemHTMLElement): GridStack {\r\n dd.draggable(el, 'destroy').resizable(el, 'destroy');\r\n if (el.gridstackNode) {\r\n delete el.gridstackNode._initDD; // reset our DD init flag\r\n }\r\n return this;\r\n}\r\n\r\n"]} \ No newline at end of file diff --git a/dist/es5/dd-manager.d.ts b/dist/es5/dd-manager.d.ts new file mode 100644 index 000000000..3c7ee77b9 --- /dev/null +++ b/dist/es5/dd-manager.d.ts @@ -0,0 +1,20 @@ +/** + * dd-manager.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { DDDraggable } from './dd-draggable'; +import { DDDroppable } from './dd-droppable'; +import { DDResizable } from './dd-resizable'; +/** + * globals that are shared across Drag & Drop instances + */ +export declare class DDManager { + /** true if a mouse down event was handled */ + static mouseHandled: boolean; + /** item being dragged */ + static dragElement: DDDraggable; + /** item we are currently over as drop target */ + static dropElement: DDDroppable; + /** current item we're over for resizing purpose (ignore nested grid resize handles) */ + static overResizeElement: DDResizable; +} diff --git a/dist/es5/dd-manager.js b/dist/es5/dd-manager.js new file mode 100644 index 000000000..5c08aaab2 --- /dev/null +++ b/dist/es5/dd-manager.js @@ -0,0 +1,17 @@ +"use strict"; +/** + * dd-manager.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDManager = void 0; +/** + * globals that are shared across Drag & Drop instances + */ +var DDManager = /** @class */ (function () { + function DDManager() { + } + return DDManager; +}()); +exports.DDManager = DDManager; +//# sourceMappingURL=dd-manager.js.map \ No newline at end of file diff --git a/dist/es5/dd-manager.js.map b/dist/es5/dd-manager.js.map new file mode 100644 index 000000000..e908dd69d --- /dev/null +++ b/dist/es5/dd-manager.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-manager.js","sourceRoot":"","sources":["../../src/dd-manager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH;;GAEG;AACH;IAAA;IAaA,CAAC;IAAD,gBAAC;AAAD,CAAC,AAbD,IAaC;AAbY,8BAAS","sourcesContent":["/**\n * dd-manager.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDDroppable } from './dd-droppable';\nimport { DDResizable } from './dd-resizable';\n\n/**\n * globals that are shared across Drag & Drop instances\n */\nexport class DDManager {\n /** true if a mouse down event was handled */\n public static mouseHandled: boolean;\n\n /** item being dragged */\n public static dragElement: DDDraggable;\n\n /** item we are currently over as drop target */\n public static dropElement: DDDroppable;\n\n /** current item we're over for resizing purpose (ignore nested grid resize handles) */\n public static overResizeElement: DDResizable;\n\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-resizable-handle.d.ts b/dist/es5/dd-resizable-handle.d.ts new file mode 100644 index 000000000..acec9dd52 --- /dev/null +++ b/dist/es5/dd-resizable-handle.d.ts @@ -0,0 +1,14 @@ +/** + * dd-resizable-handle.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +export interface DDResizableHandleOpt { + start?: (event: any) => void; + move?: (event: any) => void; + stop?: (event: any) => void; +} +export declare class DDResizableHandle { + constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt); + /** call this when resize handle needs to be removed and cleaned up */ + destroy(): DDResizableHandle; +} diff --git a/dist/es5/dd-resizable-handle.js b/dist/es5/dd-resizable-handle.js new file mode 100644 index 000000000..0ef55fd05 --- /dev/null +++ b/dist/es5/dd-resizable-handle.js @@ -0,0 +1,107 @@ +"use strict"; +/** + * dd-resizable-handle.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDResizableHandle = void 0; +var dd_touch_1 = require("./dd-touch"); +var DDResizableHandle = /** @class */ (function () { + function DDResizableHandle(host, direction, option) { + /** @internal true after we've moved enough pixels to start a resize */ + this.moving = false; + this.host = host; + this.dir = direction; + this.option = option; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + this._mouseDown = this._mouseDown.bind(this); + this._mouseMove = this._mouseMove.bind(this); + this._mouseUp = this._mouseUp.bind(this); + this._init(); + } + /** @internal */ + DDResizableHandle.prototype._init = function () { + var el = document.createElement('div'); + el.classList.add('ui-resizable-handle'); + el.classList.add("" + DDResizableHandle.prefix + this.dir); + el.style.zIndex = '100'; + el.style.userSelect = 'none'; + this.el = el; + this.host.appendChild(this.el); + this.el.addEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.el.addEventListener('touchstart', dd_touch_1.touchstart); + this.el.addEventListener('pointerdown', dd_touch_1.pointerdown); + // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment + } + return this; + }; + /** call this when resize handle needs to be removed and cleaned up */ + DDResizableHandle.prototype.destroy = function () { + if (this.moving) + this._mouseUp(this.mouseDownEvent); + this.el.removeEventListener('mousedown', this._mouseDown); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('touchstart', dd_touch_1.touchstart); + this.el.removeEventListener('pointerdown', dd_touch_1.pointerdown); + } + this.host.removeChild(this.el); + delete this.el; + delete this.host; + return this; + }; + /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */ + DDResizableHandle.prototype._mouseDown = function (e) { + this.mouseDownEvent = e; + document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble + document.addEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.el.addEventListener('touchmove', dd_touch_1.touchmove); + this.el.addEventListener('touchend', dd_touch_1.touchend); + } + e.stopPropagation(); + e.preventDefault(); + }; + /** @internal */ + DDResizableHandle.prototype._mouseMove = function (e) { + var s = this.mouseDownEvent; + if (this.moving) { + this._triggerEvent('move', e); + } + else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) { + // don't start unless we've moved at least 3 pixels + this.moving = true; + this._triggerEvent('start', this.mouseDownEvent); + this._triggerEvent('move', e); + } + e.stopPropagation(); + e.preventDefault(); + }; + /** @internal */ + DDResizableHandle.prototype._mouseUp = function (e) { + if (this.moving) { + this._triggerEvent('stop', e); + } + document.removeEventListener('mousemove', this._mouseMove, true); + document.removeEventListener('mouseup', this._mouseUp, true); + if (dd_touch_1.isTouch) { + this.el.removeEventListener('touchmove', dd_touch_1.touchmove); + this.el.removeEventListener('touchend', dd_touch_1.touchend); + } + delete this.moving; + delete this.mouseDownEvent; + e.stopPropagation(); + e.preventDefault(); + }; + /** @internal */ + DDResizableHandle.prototype._triggerEvent = function (name, event) { + if (this.option[name]) + this.option[name](event); + return this; + }; + /** @internal */ + DDResizableHandle.prefix = 'ui-resizable-'; + return DDResizableHandle; +}()); +exports.DDResizableHandle = DDResizableHandle; +//# sourceMappingURL=dd-resizable-handle.js.map \ No newline at end of file diff --git a/dist/es5/dd-resizable-handle.js.map b/dist/es5/dd-resizable-handle.js.map new file mode 100644 index 000000000..9ad9ba2ce --- /dev/null +++ b/dist/es5/dd-resizable-handle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-resizable-handle.js","sourceRoot":"","sources":["../../src/dd-resizable-handle.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-resizable-handle.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { isTouch, pointerdown, touchend, touchmove, touchstart } from './dd-touch';\n\nexport interface DDResizableHandleOpt {\n start?: (event) => void;\n move?: (event) => void;\n stop?: (event) => void;\n}\n\nexport class DDResizableHandle {\n /** @internal */\n protected el: HTMLElement;\n /** @internal */\n protected host: HTMLElement;\n /** @internal */\n protected option: DDResizableHandleOpt;\n /** @internal */\n protected dir: string;\n /** @internal true after we've moved enough pixels to start a resize */\n protected moving = false;\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected static prefix = 'ui-resizable-';\n\n constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt) {\n this.host = host;\n this.dir = direction;\n this.option = option;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n\n this._init();\n }\n\n /** @internal */\n protected _init(): DDResizableHandle {\n const el = document.createElement('div');\n el.classList.add('ui-resizable-handle');\n el.classList.add(`${DDResizableHandle.prefix}${this.dir}`);\n el.style.zIndex = '100';\n el.style.userSelect = 'none';\n this.el = el;\n this.host.appendChild(this.el);\n this.el.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.addEventListener('touchstart', touchstart);\n this.el.addEventListener('pointerdown', pointerdown);\n // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n return this;\n }\n\n /** call this when resize handle needs to be removed and cleaned up */\n public destroy(): DDResizableHandle {\n if (this.moving) this._mouseUp(this.mouseDownEvent);\n this.el.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.removeEventListener('touchstart', touchstart);\n this.el.removeEventListener('pointerdown', pointerdown);\n }\n this.host.removeChild(this.el);\n delete this.el;\n delete this.host;\n return this;\n }\n\n /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */\n protected _mouseDown(e: MouseEvent) {\n this.mouseDownEvent = e;\n document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.addEventListener('touchmove', touchmove);\n this.el.addEventListener('touchend', touchend);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseMove(e: MouseEvent) {\n let s = this.mouseDownEvent;\n if (this.moving) {\n this._triggerEvent('move', e);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) {\n // don't start unless we've moved at least 3 pixels\n this.moving = true;\n this._triggerEvent('start', this.mouseDownEvent);\n this._triggerEvent('move', e);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseUp(e: MouseEvent) {\n if (this.moving) {\n this._triggerEvent('stop', e);\n }\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.removeEventListener('touchmove', touchmove);\n this.el.removeEventListener('touchend', touchend);\n }\n delete this.moving;\n delete this.mouseDownEvent;\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _triggerEvent(name: string, event: MouseEvent): DDResizableHandle {\n if (this.option[name]) this.option[name](event);\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-resizable.d.ts b/dist/es5/dd-resizable.d.ts new file mode 100644 index 000000000..bebb4d6f8 --- /dev/null +++ b/dist/es5/dd-resizable.d.ts @@ -0,0 +1,29 @@ +/** + * dd-resizable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl'; +import { DDUIData } from './types'; +export interface DDResizableOpt { + autoHide?: boolean; + handles?: string; + maxHeight?: number; + maxWidth?: number; + minHeight?: number; + minWidth?: number; + fixedAspectRatio?: number; + start?: (event: Event, ui: DDUIData) => void; + stop?: (event: Event) => void; + resize?: (event: Event, ui: DDUIData) => void; +} +export declare class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt { + el: HTMLElement; + option: DDResizableOpt; + constructor(el: HTMLElement, opts?: DDResizableOpt); + on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void; + off(event: 'resizestart' | 'resize' | 'resizestop'): void; + enable(): void; + disable(): void; + destroy(): void; + updateOption(opts: DDResizableOpt): DDResizable; +} diff --git a/dist/es5/dd-resizable.js b/dist/es5/dd-resizable.js new file mode 100644 index 000000000..3c4ba6f15 --- /dev/null +++ b/dist/es5/dd-resizable.js @@ -0,0 +1,371 @@ +"use strict"; +/** + * dd-resizable.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DDResizable = void 0; +var dd_resizable_handle_1 = require("./dd-resizable-handle"); +var dd_base_impl_1 = require("./dd-base-impl"); +var utils_1 = require("./utils"); +var dd_manager_1 = require("./dd-manager"); +var DDResizable = /** @class */ (function (_super) { + __extends(DDResizable, _super); + function DDResizable(el, opts) { + if (opts === void 0) { opts = {}; } + var _this = _super.call(this) || this; + /** @internal */ + _this._ui = function () { + var containmentEl = _this.el.parentElement; + var containmentRect = containmentEl.getBoundingClientRect(); + var newRect = { + width: _this.originalRect.width, + height: _this.originalRect.height + _this.scrolled, + left: _this.originalRect.left, + top: _this.originalRect.top - _this.scrolled + }; + var rect = _this.temporalRect || newRect; + return { + position: { + left: rect.left - containmentRect.left, + top: rect.top - containmentRect.top + }, + size: { + width: rect.width, + height: rect.height + } + /* Gridstack ONLY needs position set above... keep around in case. + element: [this.el], // The object representing the element to be resized + helper: [], // TODO: not support yet - The object representing the helper that's being resized + originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped + originalPosition: { // The position represented as { left, top } before the resizable is resized + left: this.originalRect.left - containmentRect.left, + top: this.originalRect.top - containmentRect.top + }, + originalSize: { // The size represented as { width, height } before the resizable is resized + width: this.originalRect.width, + height: this.originalRect.height + } + */ + }; + }; + _this.el = el; + _this.option = opts; + // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions) + _this._mouseOver = _this._mouseOver.bind(_this); + _this._mouseOut = _this._mouseOut.bind(_this); + _this.enable(); + _this._setupAutoHide(_this.option.autoHide); + _this._setupHandlers(); + return _this; + } + DDResizable.prototype.on = function (event, callback) { + _super.prototype.on.call(this, event, callback); + }; + DDResizable.prototype.off = function (event) { + _super.prototype.off.call(this, event); + }; + DDResizable.prototype.enable = function () { + _super.prototype.enable.call(this); + this.el.classList.add('ui-resizable'); + this.el.classList.remove('ui-resizable-disabled'); + this._setupAutoHide(this.option.autoHide); + }; + DDResizable.prototype.disable = function () { + _super.prototype.disable.call(this); + this.el.classList.add('ui-resizable-disabled'); + this.el.classList.remove('ui-resizable'); + this._setupAutoHide(false); + }; + DDResizable.prototype.destroy = function () { + this._removeHandlers(); + this._setupAutoHide(false); + this.el.classList.remove('ui-resizable'); + delete this.el; + _super.prototype.destroy.call(this); + }; + DDResizable.prototype.updateOption = function (opts) { + var _this = this; + var updateHandles = (opts.handles && opts.handles !== this.option.handles); + var updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide); + Object.keys(opts).forEach(function (key) { return _this.option[key] = opts[key]; }); + if (updateHandles) { + this._removeHandlers(); + this._setupHandlers(); + } + if (updateAutoHide) { + this._setupAutoHide(this.option.autoHide); + } + return this; + }; + /** @internal turns auto hide on/off */ + DDResizable.prototype._setupAutoHide = function (auto) { + if (auto) { + this.el.classList.add('ui-resizable-autohide'); + // use mouseover and not mouseenter to get better performance and track for nested cases + this.el.addEventListener('mouseover', this._mouseOver); + this.el.addEventListener('mouseout', this._mouseOut); + } + else { + this.el.classList.remove('ui-resizable-autohide'); + this.el.removeEventListener('mouseover', this._mouseOver); + this.el.removeEventListener('mouseout', this._mouseOut); + if (dd_manager_1.DDManager.overResizeElement === this) { + delete dd_manager_1.DDManager.overResizeElement; + } + } + return this; + }; + /** @internal */ + DDResizable.prototype._mouseOver = function (e) { + // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018 + if (dd_manager_1.DDManager.overResizeElement || dd_manager_1.DDManager.dragElement) + return; + dd_manager_1.DDManager.overResizeElement = this; + // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + this.el.classList.remove('ui-resizable-autohide'); + }; + /** @internal */ + DDResizable.prototype._mouseOut = function (e) { + // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + if (dd_manager_1.DDManager.overResizeElement !== this) + return; + delete dd_manager_1.DDManager.overResizeElement; + // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`) + this.el.classList.add('ui-resizable-autohide'); + }; + /** @internal */ + DDResizable.prototype._setupHandlers = function () { + var _this = this; + var handlerDirection = this.option.handles || 'e,s,se'; + if (handlerDirection === 'all') { + handlerDirection = 'n,e,s,w,se,sw,ne,nw'; + } + this.handlers = handlerDirection.split(',') + .map(function (dir) { return dir.trim(); }) + .map(function (dir) { return new dd_resizable_handle_1.DDResizableHandle(_this.el, dir, { + start: function (event) { + _this._resizeStart(event); + }, + stop: function (event) { + _this._resizeStop(event); + }, + move: function (event) { + _this._resizing(event, dir); + } + }); }); + return this; + }; + /** @internal */ + DDResizable.prototype._resizeStart = function (event) { + this.originalRect = this.el.getBoundingClientRect(); + this.scrollEl = utils_1.Utils.getScrollElement(this.el); + this.scrollY = this.scrollEl.scrollTop; + this.scrolled = 0; + this.startEvent = event; + this._setupHelper(); + this._applyChange(); + var ev = utils_1.Utils.initEvent(event, { type: 'resizestart', target: this.el }); + if (this.option.start) { + this.option.start(ev, this._ui()); + } + this.el.classList.add('ui-resizable-resizing'); + this.triggerEvent('resizestart', ev); + return this; + }; + /** @internal */ + DDResizable.prototype._resizing = function (event, dir) { + this.scrolled = this.scrollEl.scrollTop - this.scrollY; + this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio); + this._applyChange(); + var ev = utils_1.Utils.initEvent(event, { type: 'resize', target: this.el }); + if (this.option.resize) { + this.option.resize(ev, this._ui()); + } + this.triggerEvent('resize', ev); + return this; + }; + /** @internal */ + DDResizable.prototype._resizeStop = function (event) { + var ev = utils_1.Utils.initEvent(event, { type: 'resizestop', target: this.el }); + if (this.option.stop) { + this.option.stop(ev); // Note: ui() not used by gridstack so don't pass + } + this.el.classList.remove('ui-resizable-resizing'); + this.triggerEvent('resizestop', ev); + this._cleanHelper(); + delete this.startEvent; + delete this.originalRect; + delete this.temporalRect; + delete this.scrollY; + delete this.scrolled; + return this; + }; + /** @internal */ + DDResizable.prototype._setupHelper = function () { + var _this = this; + this.elOriginStyleVal = DDResizable._originStyleProp.map(function (prop) { return _this.el.style[prop]; }); + this.parentOriginStylePosition = this.el.parentElement.style.position; + if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) { + this.el.parentElement.style.position = 'relative'; + } + this.el.style.position = 'absolute'; + this.el.style.opacity = '0.8'; + return this; + }; + /** @internal */ + DDResizable.prototype._cleanHelper = function () { + var _this = this; + DDResizable._originStyleProp.forEach(function (prop, i) { + _this.el.style[prop] = _this.elOriginStyleVal[i] || null; + }); + this.el.parentElement.style.position = this.parentOriginStylePosition || null; + return this; + }; + /** @internal */ + DDResizable.prototype._getChange = function (event, dir, fixedAspectRatio) { + var fixedAspect = typeof (fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio); + var oEvent = this.startEvent; + var newRect = { + width: this.originalRect.width, + height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled), + left: this.originalRect.left, + top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled) + }; + var offsetX = event.clientX - oEvent.clientX; + var offsetY = event.clientY - oEvent.clientY; + if (fixedAspect) { + // If the window is being resized using the corner + if (dir.length > 1) { + if (offsetX > offsetY) { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } + else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + } + else { + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } + else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } + } + else { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } + else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } + else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } + } + else { + if (dir.indexOf('e') > -1) { // East + newRect.width += offsetX; + } + else if (dir.indexOf('w') > -1) { // West + newRect.width -= offsetX; + newRect.left += offsetX; + } + if (dir.indexOf('s') > -1) { // South // HERE + newRect.height += offsetY; + } + else if (dir.indexOf('n') > -1) { // North + newRect.height -= offsetY; + newRect.top += offsetY; + } + } + var constrain = this._constrainSize(newRect.width, newRect.height); + if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors + if (dir.indexOf('w') > -1) { + newRect.left += newRect.width - constrain.width; + } + newRect.width = constrain.width; + } + if (Math.round(newRect.height) !== Math.round(constrain.height)) { + if (dir.indexOf('n') > -1) { + newRect.top += newRect.height - constrain.height; + } + newRect.height = constrain.height; + } + return newRect; + }; + /** @internal constrain the size to the set min/max values */ + DDResizable.prototype._constrainSize = function (oWidth, oHeight) { + var maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER; + var minWidth = this.option.minWidth || oWidth; + var maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER; + var minHeight = this.option.minHeight || oHeight; + var width = Math.min(maxWidth, Math.max(minWidth, oWidth)); + var height = Math.min(maxHeight, Math.max(minHeight, oHeight)); + return { width: width, height: height }; + }; + /** @internal */ + DDResizable.prototype._applyChange = function () { + var _this = this; + var containmentRect = { left: 0, top: 0, width: 0, height: 0 }; + if (this.el.style.position === 'absolute') { + var containmentEl = this.el.parentElement; + var _a = containmentEl.getBoundingClientRect(), left = _a.left, top_1 = _a.top; + containmentRect = { left: left, top: top_1, width: 0, height: 0 }; + } + if (!this.temporalRect) + return this; + Object.keys(this.temporalRect).forEach(function (key) { + var value = _this.temporalRect[key]; + _this.el.style[key] = value - containmentRect[key] + 'px'; + }); + return this; + }; + /** @internal */ + DDResizable.prototype._removeHandlers = function () { + this.handlers.forEach(function (handle) { return handle.destroy(); }); + delete this.handlers; + return this; + }; + /** @internal */ + DDResizable._originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex']; + return DDResizable; +}(dd_base_impl_1.DDBaseImplement)); +exports.DDResizable = DDResizable; +//# sourceMappingURL=dd-resizable.js.map \ No newline at end of file diff --git a/dist/es5/dd-resizable.js.map b/dist/es5/dd-resizable.js.map new file mode 100644 index 000000000..cb7ad646c --- /dev/null +++ b/dist/es5/dd-resizable.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-resizable.js","sourceRoot":"","sources":["../../src/dd-resizable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * dd-resizable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizableHandle } from './dd-resizable-handle';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDUIData, Rect, Size } from './types';\nimport { DDManager } from './dd-manager';\n\n// import { GridItemHTMLElement } from './types'; let count = 0; // TEST\n\n// TODO: merge with DDDragOpt\nexport interface DDResizableOpt {\n autoHide?: boolean;\n handles?: string;\n maxHeight?: number;\n maxWidth?: number;\n minHeight?: number;\n minWidth?: number;\n fixedAspectRatio?: number;\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n resize?: (event: Event, ui: DDUIData) => void;\n}\n\nexport class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n // have to be public else complains for HTMLElementExtendOpt ?\n public el: HTMLElement;\n public option: DDResizableOpt;\n\n /** @internal */\n protected handlers: DDResizableHandle[];\n /** @internal */\n protected originalRect: Rect;\n /** @internal */\n protected temporalRect: Rect;\n /** @internal */\n protected scrollY: number;\n /** @internal */\n protected scrolled: number;\n /** @internal */\n protected scrollEl: HTMLElement;\n /** @internal */\n protected startEvent: MouseEvent;\n /** @internal value saved in the same order as _originStyleProp[] */\n protected elOriginStyleVal: string[];\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected static _originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex'];\n\n constructor(el: HTMLElement, opts: DDResizableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseOver = this._mouseOver.bind(this);\n this._mouseOut = this._mouseOut.bind(this);\n this.enable();\n this._setupAutoHide(this.option.autoHide);\n this._setupHandlers();\n }\n\n public on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'resizestart' | 'resize' | 'resizestop'): void {\n super.off(event);\n }\n\n public enable(): void {\n super.enable();\n this.el.classList.add('ui-resizable');\n this.el.classList.remove('ui-resizable-disabled');\n this._setupAutoHide(this.option.autoHide);\n }\n\n public disable(): void {\n super.disable();\n this.el.classList.add('ui-resizable-disabled');\n this.el.classList.remove('ui-resizable');\n this._setupAutoHide(false);\n }\n\n public destroy(): void {\n this._removeHandlers();\n this._setupAutoHide(false);\n this.el.classList.remove('ui-resizable');\n delete this.el;\n super.destroy();\n }\n\n public updateOption(opts: DDResizableOpt): DDResizable {\n let updateHandles = (opts.handles && opts.handles !== this.option.handles);\n let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide);\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n if (updateHandles) {\n this._removeHandlers();\n this._setupHandlers();\n }\n if (updateAutoHide) {\n this._setupAutoHide(this.option.autoHide);\n }\n return this;\n }\n\n /** @internal turns auto hide on/off */\n protected _setupAutoHide(auto: boolean): DDResizable {\n if (auto) {\n this.el.classList.add('ui-resizable-autohide');\n // use mouseover and not mouseenter to get better performance and track for nested cases\n this.el.addEventListener('mouseover', this._mouseOver);\n this.el.addEventListener('mouseout', this._mouseOut);\n } else {\n this.el.classList.remove('ui-resizable-autohide');\n this.el.removeEventListener('mouseover', this._mouseOver);\n this.el.removeEventListener('mouseout', this._mouseOut);\n if (DDManager.overResizeElement === this) {\n delete DDManager.overResizeElement;\n } \n }\n return this;\n }\n\n /** @internal */\n protected _mouseOver(e: Event) {\n // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018\n if (DDManager.overResizeElement || DDManager.dragElement) return;\n DDManager.overResizeElement = this;\n // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.remove('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _mouseOut(e: Event) {\n // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n if (DDManager.overResizeElement !== this) return;\n delete DDManager.overResizeElement;\n // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.add('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _setupHandlers(): DDResizable {\n let handlerDirection = this.option.handles || 'e,s,se';\n if (handlerDirection === 'all') {\n handlerDirection = 'n,e,s,w,se,sw,ne,nw';\n }\n this.handlers = handlerDirection.split(',')\n .map(dir => dir.trim())\n .map(dir => new DDResizableHandle(this.el, dir, {\n start: (event: MouseEvent) => {\n this._resizeStart(event);\n },\n stop: (event: MouseEvent) => {\n this._resizeStop(event);\n },\n move: (event: MouseEvent) => {\n this._resizing(event, dir);\n }\n }));\n return this;\n }\n\n /** @internal */\n protected _resizeStart(event: MouseEvent): DDResizable {\n this.originalRect = this.el.getBoundingClientRect();\n this.scrollEl = Utils.getScrollElement(this.el);\n this.scrollY = this.scrollEl.scrollTop;\n this.scrolled = 0;\n this.startEvent = event;\n this._setupHelper();\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el });\n if (this.option.start) {\n this.option.start(ev, this._ui());\n }\n this.el.classList.add('ui-resizable-resizing');\n this.triggerEvent('resizestart', ev);\n return this;\n }\n\n /** @internal */\n protected _resizing(event: MouseEvent, dir: string): DDResizable {\n this.scrolled = this.scrollEl.scrollTop - this.scrollY;\n this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio);\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resize', target: this.el });\n if (this.option.resize) {\n this.option.resize(ev, this._ui());\n }\n this.triggerEvent('resize', ev);\n return this;\n }\n\n /** @internal */\n protected _resizeStop(event: MouseEvent): DDResizable {\n const ev = Utils.initEvent(event, { type: 'resizestop', target: this.el });\n if (this.option.stop) {\n this.option.stop(ev); // Note: ui() not used by gridstack so don't pass\n }\n this.el.classList.remove('ui-resizable-resizing');\n this.triggerEvent('resizestop', ev);\n this._cleanHelper();\n delete this.startEvent;\n delete this.originalRect;\n delete this.temporalRect;\n delete this.scrollY;\n delete this.scrolled;\n return this;\n }\n\n /** @internal */\n protected _setupHelper(): DDResizable {\n this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);\n this.parentOriginStylePosition = this.el.parentElement.style.position;\n if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) {\n this.el.parentElement.style.position = 'relative';\n }\n this.el.style.position = 'absolute';\n this.el.style.opacity = '0.8';\n return this;\n }\n\n /** @internal */\n protected _cleanHelper(): DDResizable {\n DDResizable._originStyleProp.forEach((prop, i) => {\n this.el.style[prop] = this.elOriginStyleVal[i] || null;\n });\n this.el.parentElement.style.position = this.parentOriginStylePosition || null;\n return this;\n }\n\n /** @internal */\n protected _getChange(event: MouseEvent, dir: string, fixedAspectRatio?: number): Rect {\n const fixedAspect = typeof(fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio);\n const oEvent = this.startEvent;\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled),\n left: this.originalRect.left,\n top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled)\n };\n\n const offsetX = event.clientX - oEvent.clientX;\n const offsetY = event.clientY - oEvent.clientY;\n\n if (fixedAspect)\n {\n // If the window is being resized using the corner\n if (dir.length > 1) {\n\n if (offsetX > offsetY) {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n } else {\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n \n\n\n } else {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n }\n else\n {\n if (dir.indexOf('e') > -1) { // East\n newRect.width += offsetX;\n } else if (dir.indexOf('w') > -1) { // West\n newRect.width -= offsetX;\n newRect.left += offsetX;\n }\n\n if (dir.indexOf('s') > -1) { // South // HERE\n newRect.height += offsetY;\n } else if (dir.indexOf('n') > -1) { // North\n newRect.height -= offsetY;\n newRect.top += offsetY\n }\n }\n\n const constrain = this._constrainSize(newRect.width, newRect.height);\n if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors\n if (dir.indexOf('w') > -1) {\n newRect.left += newRect.width - constrain.width;\n }\n newRect.width = constrain.width;\n }\n if (Math.round(newRect.height) !== Math.round(constrain.height)) {\n if (dir.indexOf('n') > -1) {\n newRect.top += newRect.height - constrain.height;\n }\n newRect.height = constrain.height;\n }\n return newRect;\n }\n\n /** @internal constrain the size to the set min/max values */\n protected _constrainSize(oWidth: number, oHeight: number): Size {\n const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;\n const minWidth = this.option.minWidth || oWidth;\n const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;\n const minHeight = this.option.minHeight || oHeight;\n const width = Math.min(maxWidth, Math.max(minWidth, oWidth));\n const height = Math.min(maxHeight, Math.max(minHeight, oHeight));\n return { width, height };\n }\n\n /** @internal */\n protected _applyChange(): DDResizable {\n let containmentRect = { left: 0, top: 0, width: 0, height: 0 };\n if (this.el.style.position === 'absolute') {\n const containmentEl = this.el.parentElement;\n const { left, top } = containmentEl.getBoundingClientRect();\n containmentRect = { left, top, width: 0, height: 0 };\n }\n if (!this.temporalRect) return this;\n Object.keys(this.temporalRect).forEach(key => {\n const value = this.temporalRect[key];\n this.el.style[key] = value - containmentRect[key] + 'px';\n });\n return this;\n }\n\n /** @internal */\n protected _removeHandlers(): DDResizable {\n this.handlers.forEach(handle => handle.destroy());\n delete this.handlers;\n return this;\n }\n\n /** @internal */\n protected _ui = (): DDUIData => {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const rect = this.temporalRect || newRect;\n return {\n position: {\n left: rect.left - containmentRect.left,\n top: rect.top - containmentRect.top\n },\n size: {\n width: rect.width,\n height: rect.height\n }\n /* Gridstack ONLY needs position set above... keep around in case.\n element: [this.el], // The object representing the element to be resized\n helper: [], // TODO: not support yet - The object representing the helper that's being resized\n originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped\n originalPosition: { // The position represented as { left, top } before the resizable is resized\n left: this.originalRect.left - containmentRect.left,\n top: this.originalRect.top - containmentRect.top\n },\n originalSize: { // The size represented as { width, height } before the resizable is resized\n width: this.originalRect.width,\n height: this.originalRect.height\n }\n */\n };\n }\n}\n"]} \ No newline at end of file diff --git a/dist/es5/dd-touch.d.ts b/dist/es5/dd-touch.d.ts new file mode 100644 index 000000000..739ff27d9 --- /dev/null +++ b/dist/es5/dd-touch.d.ts @@ -0,0 +1,33 @@ +/** + * touch.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +/** + * Detect touch support - Windows Surface devices and other touch devices + * should we use this instead ? (what we had for always showing resize handles) + * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + */ +export declare const isTouch: boolean; +/** + * Handle the touchstart events + * @param {Object} e The widget element's touchstart event + */ +export declare function touchstart(e: TouchEvent): void; +/** + * Handle the touchmove events + * @param {Object} e The document's touchmove event + */ +export declare function touchmove(e: TouchEvent): void; +/** + * Handle the touchend events + * @param {Object} e The document's touchend event + */ +export declare function touchend(e: TouchEvent): void; +/** + * Note we don't get touchenter/touchleave (which are deprecated) + * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter + * so instead of PointerEvent to still get enter/leave and send the matching mouse event. + */ +export declare function pointerdown(e: PointerEvent): void; +export declare function pointerenter(e: PointerEvent): void; +export declare function pointerleave(e: PointerEvent): void; diff --git a/dist/es5/dd-touch.js b/dist/es5/dd-touch.js new file mode 100644 index 000000000..105f162b9 --- /dev/null +++ b/dist/es5/dd-touch.js @@ -0,0 +1,182 @@ +"use strict"; +/** + * touch.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.pointerleave = exports.pointerenter = exports.pointerdown = exports.touchend = exports.touchmove = exports.touchstart = exports.isTouch = void 0; +var dd_manager_1 = require("./dd-manager"); +/** + * Detect touch support - Windows Surface devices and other touch devices + * should we use this instead ? (what we had for always showing resize handles) + * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) + */ +exports.isTouch = ('ontouchstart' in document + || 'ontouchstart' in window + // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this + || (window.DocumentTouch && document instanceof window.DocumentTouch) + || navigator.maxTouchPoints > 0 + || navigator.msMaxTouchPoints > 0); +// interface TouchCoord {x: number, y: number}; +var DDTouch = /** @class */ (function () { + function DDTouch() { + } + return DDTouch; +}()); +/** +* Get the x,y position of a touch event +*/ +// function getTouchCoords(e: TouchEvent): TouchCoord { +// return { +// x: e.changedTouches[0].pageX, +// y: e.changedTouches[0].pageY +// }; +// } +/** + * Simulate a mouse event based on a corresponding touch event + * @param {Object} e A touch event + * @param {String} simulatedType The corresponding mouse event + */ +function simulateMouseEvent(e, simulatedType) { + // Ignore multi-touch events + if (e.touches.length > 1) + return; + // Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors + if (e.cancelable) + e.preventDefault(); + var touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents'); + // Initialize the simulated mouse event using the touch event's coordinates + simulatedEvent.initMouseEvent(simulatedType, // type + true, // bubbles + true, // cancelable + window, // view + 1, // detail + touch.screenX, // screenX + touch.screenY, // screenY + touch.clientX, // clientX + touch.clientY, // clientY + false, // ctrlKey + false, // altKey + false, // shiftKey + false, // metaKey + 0, // button + null // relatedTarget + ); + // Dispatch the simulated event to the target element + e.target.dispatchEvent(simulatedEvent); +} +/** + * Simulate a mouse event based on a corresponding Pointer event + * @param {Object} e A pointer event + * @param {String} simulatedType The corresponding mouse event + */ +function simulatePointerMouseEvent(e, simulatedType) { + // Prevent "Ignored attempt to cancel a touchmove event with cancelable=false" errors + if (e.cancelable) + e.preventDefault(); + var simulatedEvent = document.createEvent('MouseEvents'); + // Initialize the simulated mouse event using the touch event's coordinates + simulatedEvent.initMouseEvent(simulatedType, // type + true, // bubbles + true, // cancelable + window, // view + 1, // detail + e.screenX, // screenX + e.screenY, // screenY + e.clientX, // clientX + e.clientY, // clientY + false, // ctrlKey + false, // altKey + false, // shiftKey + false, // metaKey + 0, // button + null // relatedTarget + ); + // Dispatch the simulated event to the target element + e.target.dispatchEvent(simulatedEvent); +} +/** + * Handle the touchstart events + * @param {Object} e The widget element's touchstart event + */ +function touchstart(e) { + // Ignore the event if another widget is already being handled + if (DDTouch.touchHandled) + return; + DDTouch.touchHandled = true; + // Simulate the mouse events + // simulateMouseEvent(e, 'mouseover'); + // simulateMouseEvent(e, 'mousemove'); + simulateMouseEvent(e, 'mousedown'); +} +exports.touchstart = touchstart; +/** + * Handle the touchmove events + * @param {Object} e The document's touchmove event + */ +function touchmove(e) { + // Ignore event if not handled by us + if (!DDTouch.touchHandled) + return; + simulateMouseEvent(e, 'mousemove'); +} +exports.touchmove = touchmove; +/** + * Handle the touchend events + * @param {Object} e The document's touchend event + */ +function touchend(e) { + // Ignore event if not handled + if (!DDTouch.touchHandled) + return; + // cancel delayed leave event when we release on ourself which happens BEFORE we get this! + if (DDTouch.pointerLeaveTimeout) { + window.clearTimeout(DDTouch.pointerLeaveTimeout); + delete DDTouch.pointerLeaveTimeout; + } + var wasDragging = !!dd_manager_1.DDManager.dragElement; + // Simulate the mouseup event + simulateMouseEvent(e, 'mouseup'); + // simulateMouseEvent(event, 'mouseout'); + // If the touch interaction did not move, it should trigger a click + if (!wasDragging) { + simulateMouseEvent(e, 'click'); + } + // Unset the flag to allow other widgets to inherit the touch event + DDTouch.touchHandled = false; +} +exports.touchend = touchend; +/** + * Note we don't get touchenter/touchleave (which are deprecated) + * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter + * so instead of PointerEvent to still get enter/leave and send the matching mouse event. + */ +function pointerdown(e) { + e.target.releasePointerCapture(e.pointerId); // <- Important! +} +exports.pointerdown = pointerdown; +function pointerenter(e) { + // ignore the initial one we get on pointerdown on ourself + if (!dd_manager_1.DDManager.dragElement) { + // console.log('pointerenter ignored'); + return; + } + // console.log('pointerenter'); + simulatePointerMouseEvent(e, 'mouseenter'); +} +exports.pointerenter = pointerenter; +function pointerleave(e) { + // ignore the leave on ourself we get before releasing the mouse over ourself + // by delaying sending the event and having the up event cancel us + if (!dd_manager_1.DDManager.dragElement) { + // console.log('pointerleave ignored'); + return; + } + DDTouch.pointerLeaveTimeout = window.setTimeout(function () { + delete DDTouch.pointerLeaveTimeout; + // console.log('pointerleave delayed'); + simulatePointerMouseEvent(e, 'mouseleave'); + }, 10); +} +exports.pointerleave = pointerleave; +//# sourceMappingURL=dd-touch.js.map \ No newline at end of file diff --git a/dist/es5/dd-touch.js.map b/dist/es5/dd-touch.js.map new file mode 100644 index 000000000..70f4f3237 --- /dev/null +++ b/dist/es5/dd-touch.js.map @@ -0,0 +1 @@ +{"version":3,"file":"dd-touch.js","sourceRoot":"","sources":["../../src/dd-touch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * touch.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\n\n/**\n * Detect touch support - Windows Surface devices and other touch devices\n * should we use this instead ? (what we had for always showing resize handles)\n * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n */\nexport const isTouch: boolean = ( 'ontouchstart' in document\n || 'ontouchstart' in window\n // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this\n || ((window as any).DocumentTouch && document instanceof (window as any).DocumentTouch)\n || navigator.maxTouchPoints > 0\n || (navigator as any).msMaxTouchPoints > 0\n);\n\n// interface TouchCoord {x: number, y: number};\n\nclass DDTouch {\n public static touchHandled: boolean;\n public static pointerLeaveTimeout: number;\n}\n\n/**\n* Get the x,y position of a touch event\n*/\n// function getTouchCoords(e: TouchEvent): TouchCoord {\n// return {\n// x: e.changedTouches[0].pageX,\n// y: e.changedTouches[0].pageY\n// };\n// }\n\n/**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} e A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulateMouseEvent(e: TouchEvent, simulatedType: string) {\n\n // Ignore multi-touch events\n if (e.touches.length > 1) return;\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n/**\n * Simulate a mouse event based on a corresponding Pointer event\n * @param {Object} e A pointer event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulatePointerMouseEvent(e: PointerEvent, simulatedType: string) {\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n\n/**\n * Handle the touchstart events\n * @param {Object} e The widget element's touchstart event\n */\nexport function touchstart(e: TouchEvent) {\n // Ignore the event if another widget is already being handled\n if (DDTouch.touchHandled) return; DDTouch.touchHandled = true;\n\n // Simulate the mouse events\n // simulateMouseEvent(e, 'mouseover');\n // simulateMouseEvent(e, 'mousemove');\n simulateMouseEvent(e, 'mousedown');\n}\n\n/**\n * Handle the touchmove events\n * @param {Object} e The document's touchmove event\n */\nexport function touchmove(e: TouchEvent) {\n // Ignore event if not handled by us\n if (!DDTouch.touchHandled) return;\n\n simulateMouseEvent(e, 'mousemove');\n}\n\n/**\n * Handle the touchend events\n * @param {Object} e The document's touchend event\n */\nexport function touchend(e: TouchEvent) {\n\n // Ignore event if not handled\n if (!DDTouch.touchHandled) return;\n\n // cancel delayed leave event when we release on ourself which happens BEFORE we get this!\n if (DDTouch.pointerLeaveTimeout) {\n window.clearTimeout(DDTouch.pointerLeaveTimeout);\n delete DDTouch.pointerLeaveTimeout;\n }\n\n const wasDragging = !!DDManager.dragElement;\n\n // Simulate the mouseup event\n simulateMouseEvent(e, 'mouseup');\n // simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click\n if (!wasDragging) {\n simulateMouseEvent(e, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event\n DDTouch.touchHandled = false;\n}\n\n/**\n * Note we don't get touchenter/touchleave (which are deprecated)\n * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter\n * so instead of PointerEvent to still get enter/leave and send the matching mouse event.\n */\nexport function pointerdown(e: PointerEvent) {\n (e.target as HTMLElement).releasePointerCapture(e.pointerId) // <- Important!\n}\n\nexport function pointerenter(e: PointerEvent) {\n // ignore the initial one we get on pointerdown on ourself\n if (!DDManager.dragElement) {\n // console.log('pointerenter ignored');\n return;\n }\n // console.log('pointerenter');\n simulatePointerMouseEvent(e, 'mouseenter');\n}\n\nexport function pointerleave(e: PointerEvent) {\n // ignore the leave on ourself we get before releasing the mouse over ourself\n // by delaying sending the event and having the up event cancel us\n if (!DDManager.dragElement) {\n // console.log('pointerleave ignored');\n return;\n }\n DDTouch.pointerLeaveTimeout = window.setTimeout(() => {\n delete DDTouch.pointerLeaveTimeout;\n // console.log('pointerleave delayed');\n simulatePointerMouseEvent(e, 'mouseleave');\n }, 10);\n}\n\n"]} \ No newline at end of file diff --git a/dist/es5/gridstack-all.js b/dist/es5/gridstack-all.js new file mode 100644 index 000000000..3ec5cfee0 --- /dev/null +++ b/dist/es5/gridstack-all.js @@ -0,0 +1,3 @@ +/*! For license information please see gridstack-all.js.LICENSE.txt */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.GridStack=e():t.GridStack=e()}(self,(function(){return function(){"use strict";var t={74:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.DDBaseImplement=void 0;var i=function(){function t(){this._eventRegister={}}return Object.defineProperty(t.prototype,"disabled",{get:function(){return this._disabled},enumerable:!1,configurable:!0}),t.prototype.on=function(t,e){this._eventRegister[t]=e},t.prototype.off=function(t){delete this._eventRegister[t]},t.prototype.enable=function(){this._disabled=!1},t.prototype.disable=function(){this._disabled=!0},t.prototype.destroy=function(){delete this._eventRegister},t.prototype.triggerEvent=function(t,e){if(!this.disabled&&this._eventRegister&&this._eventRegister[t])return this._eventRegister[t](e)},t}();e.DDBaseImplement=i},366:function(t,e,i){var o,n=this&&this.__extends||(o=function(t,e){return o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])},o(t,e)},function(t,e){function i(){this.constructor=t}o(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0}),e.DDDraggable=void 0;var s=i(839),r=i(867),a=i(74),l=i(537),h=function(t){function e(e,i){void 0===i&&(i={});var o=t.call(this)||this;o.el=e,o.option=i;var n=i.handle.substring(1);return o.dragEl=e.classList.contains(n)?e:e.querySelector(i.handle)||e,o._mouseDown=o._mouseDown.bind(o),o._mouseMove=o._mouseMove.bind(o),o._mouseUp=o._mouseUp.bind(o),o.enable(),o}return n(e,t),e.prototype.on=function(e,i){t.prototype.on.call(this,e,i)},e.prototype.off=function(e){t.prototype.off.call(this,e)},e.prototype.enable=function(){!1!==this.disabled&&(t.prototype.enable.call(this),this.dragEl.addEventListener("mousedown",this._mouseDown),l.isTouch&&(this.dragEl.addEventListener("touchstart",l.touchstart),this.dragEl.addEventListener("pointerdown",l.pointerdown)),this.el.classList.remove("ui-draggable-disabled"),this.el.classList.add("ui-draggable"))},e.prototype.disable=function(e){void 0===e&&(e=!1),!0!==this.disabled&&(t.prototype.disable.call(this),this.dragEl.removeEventListener("mousedown",this._mouseDown),l.isTouch&&(this.dragEl.removeEventListener("touchstart",l.touchstart),this.dragEl.removeEventListener("pointerdown",l.pointerdown)),this.el.classList.remove("ui-draggable"),e||this.el.classList.add("ui-draggable-disabled"))},e.prototype.destroy=function(){this.dragging&&this._mouseUp(this.mouseDownEvent),this.disable(!0),delete this.el,delete this.helper,delete this.option,t.prototype.destroy.call(this)},e.prototype.updateOption=function(t){var e=this;return Object.keys(t).forEach((function(i){return e.option[i]=t[i]})),this},e.prototype._mouseDown=function(t){if(!s.DDManager.mouseHandled){if(0!==t.button)return!0;for(var e=this.option.handle.substring(1),i=t.target;i&&!i.classList.contains(e);)i=i.parentElement;if(i)return this.mouseDownEvent=t,delete this.dragging,delete s.DDManager.dragElement,delete s.DDManager.dropElement,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),l.isTouch&&(this.dragEl.addEventListener("touchmove",l.touchmove),this.dragEl.addEventListener("touchend",l.touchend)),t.preventDefault(),s.DDManager.mouseHandled=!0,!0}},e.prototype._mouseMove=function(t){var e,i=this.mouseDownEvent;if(this.dragging){this._dragFollow(t);var o=r.Utils.initEvent(t,{target:this.el,type:"drag"});this.option.drag&&this.option.drag(o,this.ui()),this.triggerEvent("drag",o)}else if(Math.abs(t.x-i.x)+Math.abs(t.y-i.y)>3){this.dragging=!0,s.DDManager.dragElement=this;var n=null===(e=this.el.gridstackNode)||void 0===e?void 0:e.grid;n?s.DDManager.dropElement=n.el.ddElement.ddDroppable:delete s.DDManager.dropElement,this.helper=this._createHelper(t),this._setupHelperContainmentStyle(),this.dragOffset=this._getDragOffset(t,this.el,this.helperContainment),o=r.Utils.initEvent(t,{target:this.el,type:"dragstart"}),this._setupHelperStyle(t),this.option.start&&this.option.start(o,this.ui()),this.triggerEvent("dragstart",o)}return t.preventDefault(),!0},e.prototype._mouseUp=function(t){var e;if(document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),l.isTouch&&(this.dragEl.removeEventListener("touchmove",l.touchmove,!0),this.dragEl.removeEventListener("touchend",l.touchend,!0)),this.dragging){delete this.dragging,(null===(e=s.DDManager.dropElement)||void 0===e?void 0:e.el)===this.el.parentElement&&delete s.DDManager.dropElement,this.helperContainment.style.position=this.parentOriginStylePosition||null,this.helper===this.el?this._removeHelperStyle():this.helper.remove();var i=r.Utils.initEvent(t,{target:this.el,type:"dragstop"});this.option.stop&&this.option.stop(i),this.triggerEvent("dragstop",i),s.DDManager.dropElement&&s.DDManager.dropElement.drop(t)}delete this.helper,delete this.mouseDownEvent,delete s.DDManager.dragElement,delete s.DDManager.dropElement,delete s.DDManager.mouseHandled,t.preventDefault()},e.prototype._createHelper=function(t){var i=this,o=this.el;return"function"==typeof this.option.helper?o=this.option.helper(t):"clone"===this.option.helper&&(o=r.Utils.cloneNode(this.el)),document.body.contains(o)||r.Utils.appendTo(o,"parent"===this.option.appendTo?this.el.parentNode:this.option.appendTo),o===this.el&&(this.dragElementOriginStyle=e.originStyleProp.map((function(t){return i.el.style[t]}))),o},e.prototype._setupHelperStyle=function(t){var e=this;this.helper.classList.add("ui-draggable-dragging");var i=this.helper.style;return i.pointerEvents="none",i["min-width"]=0,i.width=this.dragOffset.width+"px",i.height=this.dragOffset.height+"px",i.willChange="left, top",i.position="fixed",this._dragFollow(t),i.transition="none",setTimeout((function(){e.helper&&(i.transition=null)}),0),this},e.prototype._removeHelperStyle=function(){var t,i=this;this.helper.classList.remove("ui-draggable-dragging");var o=null===(t=this.helper)||void 0===t?void 0:t.gridstackNode;if(this.dragElementOriginStyle&&(!o||!o._isAboutToRemove)){var n=this.helper,s=this.dragElementOriginStyle.transition||null;n.style.transition=this.dragElementOriginStyle.transition="none",e.originStyleProp.forEach((function(t){return n.style[t]=i.dragElementOriginStyle[t]||null})),setTimeout((function(){return n.style.transition=s}),50)}return delete this.dragElementOriginStyle,this},e.prototype._dragFollow=function(t){var e=this.helper.style,i=this.dragOffset;e.left=t.clientX+i.offsetLeft-0+"px",e.top=t.clientY+i.offsetTop-0+"px"},e.prototype._setupHelperContainmentStyle=function(){return this.helperContainment=this.helper.parentElement,"fixed"!==this.helper.style.position&&(this.parentOriginStylePosition=this.helperContainment.style.position,window.getComputedStyle(this.helperContainment).position.match(/static/)&&(this.helperContainment.style.position="relative")),this},e.prototype._getDragOffset=function(t,e,i){var o=0,n=0;if(i){var s=document.createElement("div");r.Utils.addElStyles(s,{opacity:"0",position:"fixed",top:"0px",left:"0px",width:"1px",height:"1px",zIndex:"-999999"}),i.appendChild(s);var a=s.getBoundingClientRect();i.removeChild(s),o=a.left,n=a.top}var l=e.getBoundingClientRect();return{left:l.left,top:l.top,offsetLeft:-t.clientX+l.left-o,offsetTop:-t.clientY+l.top-n,width:l.width,height:l.height}},e.prototype.ui=function(){var t=this.el.parentElement.getBoundingClientRect(),e=this.helper.getBoundingClientRect();return{position:{top:e.top-t.top,left:e.left-t.left}}},e.originStyleProp=["transition","pointerEvents","position","left","top"],e}(a.DDBaseImplement);e.DDDraggable=h},677:function(t,e,i){var o,n=this&&this.__extends||(o=function(t,e){return o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])},o(t,e)},function(t,e){function i(){this.constructor=t}o(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}),s=this&&this.__assign||function(){return s=Object.assign||function(t){for(var e,i=1,o=arguments.length;i-1?this.ddDraggable.on(t,e):this.ddDroppable&&["drop","dropover","dropout"].indexOf(t)>-1?this.ddDroppable.on(t,e):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(t)>-1&&this.ddResizable.on(t,e),this},t.prototype.off=function(t){return this.ddDraggable&&["drag","dragstart","dragstop"].indexOf(t)>-1?this.ddDraggable.off(t):this.ddDroppable&&["drop","dropover","dropout"].indexOf(t)>-1?this.ddDroppable.off(t):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(t)>-1&&this.ddResizable.off(t),this},t.prototype.setupDraggable=function(t){return this.ddDraggable?this.ddDraggable.updateOption(t):this.ddDraggable=new n.DDDraggable(this.el,t),this},t.prototype.cleanDraggable=function(){return this.ddDraggable&&(this.ddDraggable.destroy(),delete this.ddDraggable),this},t.prototype.setupResizable=function(t){return this.ddResizable?this.ddResizable.updateOption(t):this.ddResizable=new o.DDResizable(this.el,t),this},t.prototype.cleanResizable=function(){return this.ddResizable&&(this.ddResizable.destroy(),delete this.ddResizable),this},t.prototype.setupDroppable=function(t){return this.ddDroppable?this.ddDroppable.updateOption(t):this.ddDroppable=new s.DDDroppable(this.el,t),this},t.prototype.cleanDroppable=function(){return this.ddDroppable&&(this.ddDroppable.destroy(),delete this.ddDroppable),this},t}();e.DDElement=r},502:function(t,e,i){var o=this&&this.__assign||function(){return o=Object.assign||function(t){for(var e,i=1,o=arguments.length;in._lastUiPosition.left?-p:d),y=i.position.top+(i.position.top>n._lastUiPosition.top?-c:u);h.x=Math.round(v/r),h.y=Math.round(y/a);var _=this._extraDragRow;if(this.engine.collide(n,h)){var b=this.getRow(),w=Math.max(0,h.y+n.h-b);this.opts.maxRow&&b+w>this.opts.maxRow&&(w=Math.max(0,this.opts.maxRow-b)),this._extraDragRow=w}else this._extraDragRow=0;if(this._extraDragRow!==_&&this._updateContainerHeight(),n.x===h.x&&n.y===h.y)return}else if("resize"===e.type){if(h.x<0)return;if(s.Utils.updateScrollResize(e,t,a),h.w=Math.round((i.size.width-d)/r),h.h=Math.round((i.size.height-u)/a),n.w===h.w&&n.h===h.h)return;if(n._lastTried&&n._lastTried.w===h.w&&n._lastTried.h===h.h)return;v=i.position.left+d;var E=i.position.top+u;h.x=Math.round(v/r),h.y=Math.round(E/a),l=!0}n._lastTried=h;var D={x:i.position.left+d,y:i.position.top+u,w:(i.size?i.size.width:n.w*r)-d-p,h:(i.size?i.size.height:n.h*a)-u-c};if(this.engine.moveNodeCheck(n,o(o({},h),{cellWidth:r,cellHeight:a,rect:D,resizing:l}))){n._lastUiPosition=i.position,this.engine.cacheRects(r,a,u,p,c,d),delete n._skipDown,l&&n.subGrid&&n.subGrid.onParentResize(),this._extraDragRow=0,this._updateContainerHeight();var x=e.target;this._writePosAttr(x,n),this._gsEventHandler[e.type]&&this._gsEventHandler[e.type](e,x)}},n.GridStack.prototype.movable=function(t,e){var i=this;return this.opts.staticGrid||n.GridStack.getElements(t).forEach((function(t){var o=t.gridstackNode;o&&(e?delete o.noMove:o.noMove=!0,i._prepareDragDropByNode(o))})),this},n.GridStack.prototype.resizable=function(t,e){var i=this;return this.opts.staticGrid||n.GridStack.getElements(t).forEach((function(t){var o=t.gridstackNode;o&&(e?delete o.noResize:o.noResize=!0,i._prepareDragDropByNode(o))})),this},n.GridStack.prototype.disable=function(){if(!this.opts.staticGrid)return this.enableMove(!1),this.enableResize(!1),this._triggerEvent("disable"),this},n.GridStack.prototype.enable=function(){if(!this.opts.staticGrid)return this.enableMove(!0),this.enableResize(!0),this._triggerEvent("enable"),this},n.GridStack.prototype.enableMove=function(t){var e=this;return this.opts.staticGrid||(this.opts.disableDrag=!t,this.engine.nodes.forEach((function(i){return e.movable(i.el,t)}))),this},n.GridStack.prototype.enableResize=function(t){var e=this;return this.opts.staticGrid||(this.opts.disableResize=!t,this.engine.nodes.forEach((function(i){return e.resizable(i.el,t)}))),this},n.GridStack.prototype._removeDD=function(t){return h.draggable(t,"destroy").resizable(t,"destroy"),t.gridstackNode&&delete t.gridstackNode._initDD,this}},839:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.DDManager=void 0;e.DDManager=function(){}},664:function(t,e,i){Object.defineProperty(e,"__esModule",{value:!0}),e.DDResizableHandle=void 0;var o=i(537),n=function(){function t(t,e,i){this.moving=!1,this.host=t,this.dir=e,this.option=i,this._mouseDown=this._mouseDown.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseUp=this._mouseUp.bind(this),this._init()}return t.prototype._init=function(){var e=document.createElement("div");return e.classList.add("ui-resizable-handle"),e.classList.add(""+t.prefix+this.dir),e.style.zIndex="100",e.style.userSelect="none",this.el=e,this.host.appendChild(this.el),this.el.addEventListener("mousedown",this._mouseDown),o.isTouch&&(this.el.addEventListener("touchstart",o.touchstart),this.el.addEventListener("pointerdown",o.pointerdown)),this},t.prototype.destroy=function(){return this.moving&&this._mouseUp(this.mouseDownEvent),this.el.removeEventListener("mousedown",this._mouseDown),o.isTouch&&(this.el.removeEventListener("touchstart",o.touchstart),this.el.removeEventListener("pointerdown",o.pointerdown)),this.host.removeChild(this.el),delete this.el,delete this.host,this},t.prototype._mouseDown=function(t){this.mouseDownEvent=t,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),o.isTouch&&(this.el.addEventListener("touchmove",o.touchmove),this.el.addEventListener("touchend",o.touchend)),t.stopPropagation(),t.preventDefault()},t.prototype._mouseMove=function(t){var e=this.mouseDownEvent;this.moving?this._triggerEvent("move",t):Math.abs(t.x-e.x)+Math.abs(t.y-e.y)>2&&(this.moving=!0,this._triggerEvent("start",this.mouseDownEvent),this._triggerEvent("move",t)),t.stopPropagation(),t.preventDefault()},t.prototype._mouseUp=function(t){this.moving&&this._triggerEvent("stop",t),document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),o.isTouch&&(this.el.removeEventListener("touchmove",o.touchmove),this.el.removeEventListener("touchend",o.touchend)),delete this.moving,delete this.mouseDownEvent,t.stopPropagation(),t.preventDefault()},t.prototype._triggerEvent=function(t,e){return this.option[t]&&this.option[t](e),this},t.prefix="ui-resizable-",t}();e.DDResizableHandle=n},904:function(t,e,i){var o,n=this&&this.__extends||(o=function(t,e){return o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])},o(t,e)},function(t,e){function i(){this.constructor=t}o(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)});Object.defineProperty(e,"__esModule",{value:!0}),e.DDResizable=void 0;var s=i(664),r=i(74),a=i(867),l=i(839),h=function(t){function e(e,i){void 0===i&&(i={});var o=t.call(this)||this;return o._ui=function(){var t=o.el.parentElement.getBoundingClientRect(),e={width:o.originalRect.width,height:o.originalRect.height+o.scrolled,left:o.originalRect.left,top:o.originalRect.top-o.scrolled},i=o.temporalRect||e;return{position:{left:i.left-t.left,top:i.top-t.top},size:{width:i.width,height:i.height}}},o.el=e,o.option=i,o._mouseOver=o._mouseOver.bind(o),o._mouseOut=o._mouseOut.bind(o),o.enable(),o._setupAutoHide(o.option.autoHide),o._setupHandlers(),o}return n(e,t),e.prototype.on=function(e,i){t.prototype.on.call(this,e,i)},e.prototype.off=function(e){t.prototype.off.call(this,e)},e.prototype.enable=function(){t.prototype.enable.call(this),this.el.classList.add("ui-resizable"),this.el.classList.remove("ui-resizable-disabled"),this._setupAutoHide(this.option.autoHide)},e.prototype.disable=function(){t.prototype.disable.call(this),this.el.classList.add("ui-resizable-disabled"),this.el.classList.remove("ui-resizable"),this._setupAutoHide(!1)},e.prototype.destroy=function(){this._removeHandlers(),this._setupAutoHide(!1),this.el.classList.remove("ui-resizable"),delete this.el,t.prototype.destroy.call(this)},e.prototype.updateOption=function(t){var e=this,i=t.handles&&t.handles!==this.option.handles,o=t.autoHide&&t.autoHide!==this.option.autoHide;return Object.keys(t).forEach((function(i){return e.option[i]=t[i]})),i&&(this._removeHandlers(),this._setupHandlers()),o&&this._setupAutoHide(this.option.autoHide),this},e.prototype._setupAutoHide=function(t){return t?(this.el.classList.add("ui-resizable-autohide"),this.el.addEventListener("mouseover",this._mouseOver),this.el.addEventListener("mouseout",this._mouseOut)):(this.el.classList.remove("ui-resizable-autohide"),this.el.removeEventListener("mouseover",this._mouseOver),this.el.removeEventListener("mouseout",this._mouseOut),l.DDManager.overResizeElement===this&&delete l.DDManager.overResizeElement),this},e.prototype._mouseOver=function(t){l.DDManager.overResizeElement||l.DDManager.dragElement||(l.DDManager.overResizeElement=this,this.el.classList.remove("ui-resizable-autohide"))},e.prototype._mouseOut=function(t){l.DDManager.overResizeElement===this&&(delete l.DDManager.overResizeElement,this.el.classList.add("ui-resizable-autohide"))},e.prototype._setupHandlers=function(){var t=this,e=this.option.handles||"e,s,se";return"all"===e&&(e="n,e,s,w,se,sw,ne,nw"),this.handlers=e.split(",").map((function(t){return t.trim()})).map((function(e){return new s.DDResizableHandle(t.el,e,{start:function(e){t._resizeStart(e)},stop:function(e){t._resizeStop(e)},move:function(i){t._resizing(i,e)}})})),this},e.prototype._resizeStart=function(t){this.originalRect=this.el.getBoundingClientRect(),this.scrollEl=a.Utils.getScrollElement(this.el),this.scrollY=this.scrollEl.scrollTop,this.scrolled=0,this.startEvent=t,this._setupHelper(),this._applyChange();var e=a.Utils.initEvent(t,{type:"resizestart",target:this.el});return this.option.start&&this.option.start(e,this._ui()),this.el.classList.add("ui-resizable-resizing"),this.triggerEvent("resizestart",e),this},e.prototype._resizing=function(t,e){this.scrolled=this.scrollEl.scrollTop-this.scrollY,this.temporalRect=this._getChange(t,e,this.option.fixedAspectRatio),this._applyChange();var i=a.Utils.initEvent(t,{type:"resize",target:this.el});return this.option.resize&&this.option.resize(i,this._ui()),this.triggerEvent("resize",i),this},e.prototype._resizeStop=function(t){var e=a.Utils.initEvent(t,{type:"resizestop",target:this.el});return this.option.stop&&this.option.stop(e),this.el.classList.remove("ui-resizable-resizing"),this.triggerEvent("resizestop",e),this._cleanHelper(),delete this.startEvent,delete this.originalRect,delete this.temporalRect,delete this.scrollY,delete this.scrolled,this},e.prototype._setupHelper=function(){var t=this;return this.elOriginStyleVal=e._originStyleProp.map((function(e){return t.el.style[e]})),this.parentOriginStylePosition=this.el.parentElement.style.position,window.getComputedStyle(this.el.parentElement).position.match(/static/)&&(this.el.parentElement.style.position="relative"),this.el.style.position="absolute",this.el.style.opacity="0.8",this},e.prototype._cleanHelper=function(){var t=this;return e._originStyleProp.forEach((function(e,i){t.el.style[e]=t.elOriginStyleVal[i]||null})),this.el.parentElement.style.position=this.parentOriginStylePosition||null,this},e.prototype._getChange=function(t,e,i){var o=void 0!==i&&0!=i&&!isNaN(i)&&isFinite(i),n=this.startEvent,s={width:this.originalRect.width,height:this.originalRect.height+(o?0:this.scrolled),left:this.originalRect.left,top:this.originalRect.top-(o?0:this.scrolled)},r=t.clientX-n.clientX,a=t.clientY-n.clientY;o?e.length>1?r>a?e.indexOf("e")>-1?(s.width+=r,s.height+=Math.round(r/i)):e.indexOf("w")>-1&&(s.width-=r,s.left+=r,s.height-=Math.round(r/i),s.top+=Math.round(r/i)):e.indexOf("s")>-1?(s.height+=a,s.width+=Math.round(a*i)):e.indexOf("n")>-1&&(s.height-=a,s.top+=a,s.width-=Math.round(a*i),s.left+=Math.round(a*i)):(e.indexOf("e")>-1?(s.width+=r,s.height+=Math.round(r/i)):e.indexOf("w")>-1&&(s.width-=r,s.left+=r,s.height-=Math.round(r/i),s.top+=Math.round(r/i)),e.indexOf("s")>-1?(s.height+=a,s.width+=Math.round(a*i)):e.indexOf("n")>-1&&(s.height-=a,s.top+=a,s.width-=Math.round(a*i),s.left+=Math.round(a*i))):(e.indexOf("e")>-1?s.width+=r:e.indexOf("w")>-1&&(s.width-=r,s.left+=r),e.indexOf("s")>-1?s.height+=a:e.indexOf("n")>-1&&(s.height-=a,s.top+=a));var l=this._constrainSize(s.width,s.height);return Math.round(s.width)!==Math.round(l.width)&&(e.indexOf("w")>-1&&(s.left+=s.width-l.width),s.width=l.width),Math.round(s.height)!==Math.round(l.height)&&(e.indexOf("n")>-1&&(s.top+=s.height-l.height),s.height=l.height),s},e.prototype._constrainSize=function(t,e){var i=this.option.maxWidth||Number.MAX_SAFE_INTEGER,o=this.option.minWidth||t,n=this.option.maxHeight||Number.MAX_SAFE_INTEGER,s=this.option.minHeight||e;return{width:Math.min(i,Math.max(o,t)),height:Math.min(n,Math.max(s,e))}},e.prototype._applyChange=function(){var t=this,e={left:0,top:0,width:0,height:0};if("absolute"===this.el.style.position){var i=this.el.parentElement.getBoundingClientRect(),o=i.left,n=i.top;e={left:o,top:n,width:0,height:0}}return this.temporalRect?(Object.keys(this.temporalRect).forEach((function(i){var o=t.temporalRect[i];t.el.style[i]=o-e[i]+"px"})),this):this},e.prototype._removeHandlers=function(){return this.handlers.forEach((function(t){return t.destroy()})),delete this.handlers,this},e._originStyleProp=["width","height","position","left","top","opacity","zIndex"],e}(r.DDBaseImplement);e.DDResizable=h},537:function(t,e,i){Object.defineProperty(e,"__esModule",{value:!0}),e.pointerleave=e.pointerenter=e.pointerdown=e.touchend=e.touchmove=e.touchstart=e.isTouch=void 0;var o=i(839);e.isTouch="ontouchstart"in document||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0;var n=function(){};function s(t,e){if(!(t.touches.length>1)){t.cancelable&&t.preventDefault();var i=t.changedTouches[0],o=document.createEvent("MouseEvents");o.initMouseEvent(e,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),t.target.dispatchEvent(o)}}function r(t,e){t.cancelable&&t.preventDefault();var i=document.createEvent("MouseEvents");i.initMouseEvent(e,!0,!0,window,1,t.screenX,t.screenY,t.clientX,t.clientY,!1,!1,!1,!1,0,null),t.target.dispatchEvent(i)}e.touchstart=function(t){n.touchHandled||(n.touchHandled=!0,s(t,"mousedown"))},e.touchmove=function(t){n.touchHandled&&s(t,"mousemove")},e.touchend=function(t){if(n.touchHandled){n.pointerLeaveTimeout&&(window.clearTimeout(n.pointerLeaveTimeout),delete n.pointerLeaveTimeout);var e=!!o.DDManager.dragElement;s(t,"mouseup"),e||s(t,"click"),n.touchHandled=!1}},e.pointerdown=function(t){t.target.releasePointerCapture(t.pointerId)},e.pointerenter=function(t){o.DDManager.dragElement&&r(t,"mouseenter")},e.pointerleave=function(t){o.DDManager.dragElement&&(n.pointerLeaveTimeout=window.setTimeout((function(){delete n.pointerLeaveTimeout,r(t,"mouseleave")}),10))}},506:function(t,e,i){var o=this&&this.__assign||function(){return o=Object.assign||function(t){for(var e,i=1,o=arguments.length;it.y&&!this.float&&(!this.collide(i,o(o({},i),{y:t.y}),t)||!this.collide(i,o(o({},i),{y:e.y-i.h}),t))?(t._skipDown=t._skipDown||e.y>t.y,h=this.moveNode(t,o(o(o({},e),{y:i.y+i.h}),l)),i.locked&&h?n.Utils.copyPos(e,t):!i.locked&&h&&s.pack&&(this._packNodes(),e.y=i.y+i.h,n.Utils.copyPos(t,e)),a=a||h):h=this.moveNode(i,o(o(o({},i),{y:e.y+e.h,skip:t}),l)),!h)return a;i=void 0}return a},t.prototype.collide=function(t,e,i){return void 0===e&&(e=t),this.nodes.find((function(o){return o!==t&&o!==i&&n.Utils.isIntercepted(o,e)}))},t.prototype.collideAll=function(t,e,i){return void 0===e&&(e=t),this.nodes.filter((function(o){return o!==t&&o!==i&&n.Utils.isIntercepted(o,e)}))},t.prototype.collideCoverage=function(t,e,i){if(e.rect&&t._rect){var n,s=t._rect,r=o({},e.rect);return r.y>s.y?(r.h+=r.y-s.y,r.y=s.y):r.h+=s.y-r.y,r.x>s.x?(r.w+=r.x-s.x,r.x=s.x):r.w+=s.x-r.x,i.forEach((function(t){if(!t.locked&&t._rect){var e=t._rect,i=Number.MAX_VALUE,o=Number.MAX_VALUE,a=.5;s.ye.y+e.h&&(i=(e.y+e.h-r.y)/e.h),s.xe.x+e.w&&(o=(e.x+e.w-r.x)/e.w);var l=Math.min(o,i);l>a&&(a=l,n=t)}})),n}},t.prototype.cacheRects=function(t,e,i,o,n,s){return this.nodes.forEach((function(r){return r._rect={y:r.y*e+i,x:r.x*t+s,w:r.w*t-s-o,h:r.h*e-i-n}})),this},t.prototype.swap=function(t,e){if(!e||e.locked||!t||t.locked)return!1;function i(){var i=e.x,o=e.y;return e.x=t.x,e.y=t.y,t.h!=e.h?(t.x=i,t.y=e.y+e.h):t.w!=e.w?(t.x=e.x+e.w,t.y=o):(t.x=i,t.y=o),t._dirty=e._dirty=!0,!0}var o;if(t.w===e.w&&t.h===e.h&&(t.x===e.x||t.y===e.y)&&(o=n.Utils.isTouching(t,e)))return i();if(!1!==o){if(t.w===e.w&&t.x===e.x&&(o||(o=n.Utils.isTouching(t,e)))){if(e.ye._orig.y;)--i,t.collide(e,{x:e.x,y:i,w:e.w,h:e.h})||(e._dirty=!0,e.y=i)})):this.nodes.forEach((function(e,i){if(!e.locked)for(;e.y>0;){var o=0===i?0:e.y-1;if(0!==i&&t.collide(e,{x:e.x,y:o,w:e.w,h:e.h}))break;e._dirty=e.y!==o,e.y=o}}))),this},t.prototype.prepareNode=function(e,i){(e=e||{})._id=e._id||t._idSeq++,void 0!==e.x&&void 0!==e.y&&null!==e.x&&null!==e.y||(e.autoPosition=!0);var o={x:0,y:0,w:1,h:1};return n.Utils.defaults(e,o),e.autoPosition||delete e.autoPosition,e.noResize||delete e.noResize,e.noMove||delete e.noMove,"string"==typeof e.x&&(e.x=Number(e.x)),"string"==typeof e.y&&(e.y=Number(e.y)),"string"==typeof e.w&&(e.w=Number(e.w)),"string"==typeof e.h&&(e.h=Number(e.h)),isNaN(e.x)&&(e.x=o.x,e.autoPosition=!0),isNaN(e.y)&&(e.y=o.y,e.autoPosition=!0),isNaN(e.w)&&(e.w=o.w),isNaN(e.h)&&(e.h=o.h),this.nodeBoundFix(e,i)},t.prototype.nodeBoundFix=function(t,e){var i=t._orig||n.Utils.copyPos({},t);return t.maxW&&(t.w=Math.min(t.w,t.maxW)),t.maxH&&(t.h=Math.min(t.h,t.maxH)),t.minW&&t.minW<=this.column&&(t.w=Math.max(t.w,t.minW)),t.minH&&(t.h=Math.max(t.h,t.minH)),t.w>this.column?(this.column<12&&!this._inColumnResize&&(t.w=Math.min(12,t.w),this.cacheOneLayout(t,12)),t.w=this.column):t.w<1&&(t.w=1),this.maxRow&&t.h>this.maxRow?t.h=this.maxRow:t.h<1&&(t.h=1),t.x<0&&(t.x=0),t.y<0&&(t.y=0),t.x+t.w>this.column&&(e?t.w=this.column-t.x:t.x=this.column-t.w),this.maxRow&&t.y+t.h>this.maxRow&&(e?t.h=this.maxRow-t.y:t.y=this.maxRow-t.h),n.Utils.samePos(t,i)||(t._dirty=!0),t},t.prototype.getDirtyNodes=function(t){return t?this.nodes.filter((function(t){return t._dirty&&!n.Utils.samePos(t,t._orig)})):this.nodes.filter((function(t){return t._dirty}))},t.prototype._notify=function(t){if(this.batchMode||!this.onChange)return this;var e=(t||[]).concat(this.getDirtyNodes());return this.onChange(e),this},t.prototype.cleanNodes=function(){return this.batchMode||this.nodes.forEach((function(t){delete t._dirty,delete t._lastTried})),this},t.prototype.saveInitial=function(){return this.nodes.forEach((function(t){t._orig=n.Utils.copyPos({},t),delete t._dirty})),this._hasLocked=this.nodes.some((function(t){return t.locked})),this},t.prototype.restoreInitial=function(){return this.nodes.forEach((function(t){n.Utils.samePos(t,t._orig)||(n.Utils.copyPos(t,t._orig),t._dirty=!0)})),this._notify(),this},t.prototype.addNode=function(t,e){void 0===e&&(e=!1);var i=this.nodes.find((function(e){return e._id===t._id}));if(i)return i;if(delete(t=this._inColumnResize?this.nodeBoundFix(t):this.prepareNode(t))._temporaryRemoved,delete t._removeDOM,t.autoPosition){this.sortNodes();for(var o=function(e){var i=e%s.column,o=Math.floor(e/s.column);if(i+t.w>s.column)return"continue";var r={x:i,y:o,w:t.w,h:t.h};return s.nodes.find((function(t){return n.Utils.isIntercepted(r,t)}))?void 0:(t.x=i,t.y=o,delete t.autoPosition,"break")},s=this,r=0;"break"!==o(r);++r);}return this.nodes.push(t),e&&this.addedNodes.push(t),this._fixCollisions(t),this.batchMode||this._packNodes()._notify(),t},t.prototype.removeNode=function(t,e,i){return void 0===e&&(e=!0),void 0===i&&(i=!1),this.nodes.find((function(e){return e===t}))?(i&&this.removedNodes.push(t),e&&(t._removeDOM=!0),this.nodes=this.nodes.filter((function(e){return e!==t})),this._packNodes()._notify([t])):this},t.prototype.removeAll=function(t){return void 0===t&&(t=!0),delete this._layouts,0===this.nodes.length?this:(t&&this.nodes.forEach((function(t){return t._removeDOM=!0})),this.removedNodes=this.nodes,this.nodes=[],this._notify(this.removedNodes))},t.prototype.moveNodeCheck=function(e,i){var s,r=this;if(!this.changedPosConstrain(e,i))return!1;if(i.pack=!0,!this.maxRow)return this.moveNode(e,i);var a=new t({column:this.column,float:this.float,nodes:this.nodes.map((function(t){return t===e?s=o({},t):o({},t)}))});if(!s)return!1;var l=a.moveNode(s,i)&&a.getRow()<=this.maxRow;if(!l&&!i.resizing){var h=this.collide(e,i);if(h&&this.swap(e,h))return this._notify(),!0}return!!l&&(a.nodes.filter((function(t){return t._dirty})).forEach((function(t){var e=r.nodes.find((function(e){return e._id===t._id}));e&&(n.Utils.copyPos(e,t),e._dirty=!0)})),this._notify(),!0)},t.prototype.willItFit=function(e){if(delete e._willFitPos,!this.maxRow)return!0;var i=new t({column:this.column,float:this.float,nodes:this.nodes.map((function(t){return o({},t)}))}),s=o({},e);return this.cleanupNode(s),delete s.el,delete s._id,delete s.content,delete s.grid,i.addNode(s),i.getRow()<=this.maxRow&&(e._willFitPos=n.Utils.copyPos({},s),!0)},t.prototype.changedPosConstrain=function(t,e){return e.w=e.w||t.w,e.h=e.h||t.h,t.x!==e.x||t.y!==e.y||(t.maxW&&(e.w=Math.min(e.w,t.maxW)),t.maxH&&(e.h=Math.min(e.h,t.maxH)),t.minW&&(e.w=Math.max(e.w,t.minW)),t.minH&&(e.h=Math.max(e.h,t.minH)),t.w!==e.w||t.h!==e.h)},t.prototype.moveNode=function(t,e){if(!t||!e)return!1;void 0===e.pack&&(e.pack=!0),"number"!=typeof e.x&&(e.x=t.x),"number"!=typeof e.y&&(e.y=t.y),"number"!=typeof e.w&&(e.w=t.w),"number"!=typeof e.h&&(e.h=t.h);var i=t.w!==e.w||t.h!==e.h,o=n.Utils.copyPos({},t,!0);if(n.Utils.copyPos(o,e),o=this.nodeBoundFix(o,i),n.Utils.copyPos(e,o),n.Utils.samePos(t,e))return!1;var s=n.Utils.copyPos({},t),r=this.collideAll(t,o,e.skip),a=!0;if(r.length){var l=t._moving&&!e.nested?this.collideCoverage(t,e,r):r[0];a=!!l&&!this._fixCollisions(t,o,l,e)}return a&&(t._dirty=!0,n.Utils.copyPos(t,o)),e.pack&&this._packNodes()._notify(),!n.Utils.samePos(t,s)},t.prototype.getRow=function(){return this.nodes.reduce((function(t,e){return Math.max(t,e.y+e.h)}),0)},t.prototype.beginUpdate=function(t){return t._updating||(t._updating=!0,delete t._skipDown,this.batchMode||this.saveInitial()),this},t.prototype.endUpdate=function(){var t=this.nodes.find((function(t){return t._updating}));return t&&(delete t._updating,delete t._skipDown),this},t.prototype.save=function(t){var e;void 0===t&&(t=!0);var i=null===(e=this._layouts)||void 0===e?void 0:e.length,n=i&&this.column!==i-1?this._layouts[i-1]:null,s=[];return this.sortNodes(),this.nodes.forEach((function(e){var i=null==n?void 0:n.find((function(t){return t._id===e._id})),r=o({},e);for(var a in i&&(r.x=i.x,r.y=i.y,r.w=i.w),r)"_"!==a[0]&&null!==r[a]&&void 0!==r[a]||delete r[a];delete r.grid,t||delete r.el,r.autoPosition||delete r.autoPosition,r.noResize||delete r.noResize,r.noMove||delete r.noMove,r.locked||delete r.locked,s.push(r)})),s},t.prototype.layoutsNodesChange=function(t){var e=this;return!this._layouts||this._inColumnResize||this._layouts.forEach((function(i,o){if(!i||o===e.column)return e;if(ot){d=this._layouts[e]||[];var p=this._layouts.length-1;!d.length&&t!==p&&(null===(s=this._layouts[p])||void 0===s?void 0:s.length)&&(t=p,this._layouts[p].forEach((function(t){var e=i.find((function(e){return e._id===t._id}));e&&(e.x=t.x,e.y=t.y,e.w=t.w)})))}if(d.forEach((function(t){var e=i.findIndex((function(e){return e._id===t._id}));-1!==e&&(i[e].x=t.x,i[e].y=t.y,i[e].w=t.w,a.push(i[e]),i.splice(e,1))})),i.length)if("function"==typeof o)o(e,t,a,i);else if(!l){var u=e/t,c="move"===o||"moveScale"===o,g="scale"===o||"moveScale"===o;i.forEach((function(i){i.x=1===e?0:c?Math.round(i.x*u):Math.min(i.x,e-1),i.w=1===e||1===t?1:g?Math.round(i.w*u)||1:Math.min(i.w,e),a.push(i)})),i=[]}return a=n.Utils.sort(a,-1,e),this._inColumnResize=!0,this.nodes=[],a.forEach((function(t){r.addNode(t,!1),delete t._orig})),this.batchUpdate(!1),delete this._inColumnResize,this},t.prototype.cacheLayout=function(e,i,o){void 0===o&&(o=!1);var n=[];return e.forEach((function(e,i){e._id=e._id||t._idSeq++,n[i]={x:e.x,y:e.y,w:e.w,_id:e._id}})),this._layouts=o?[]:this._layouts||[],this._layouts[i]=n,this},t.prototype.cacheOneLayout=function(e,i){e._id=e._id||t._idSeq++;var o={x:e.x,y:e.y,w:e.w,_id:e._id};this._layouts=this._layouts||[],this._layouts[i]=this._layouts[i]||[];var n=this._layouts[i].findIndex((function(t){return t._id===e._id}));return-1===n?this._layouts[i].push(o):this._layouts[i][n]=o,this},t.prototype.cleanupNode=function(t){for(var e in t)"_"===e[0]&&"_id"!==e&&delete t[e];return this},t._idSeq=1,t}();e.GridStackEngine=s},324:function(t,e,i){var o=this&&this.__assign||function(){return o=Object.assign||function(t){for(var e,i=1,o=arguments.length;i',o=n.body.children[0],e.appendChild(o)}var s=t.init(i,o);if(s.opts.children){var r=s.opts.children;delete s.opts.children,s.load(r)}return s},t.registerEngine=function(e){t.engineClass=e},Object.defineProperty(t.prototype,"placeholder",{get:function(){if(!this._placeholder){var t=document.createElement("div");t.className="placeholder-content",this.opts.placeholderText&&(t.innerHTML=this.opts.placeholderText),this._placeholder=document.createElement("div"),this._placeholder.classList.add(this.opts.placeholderClass,h.itemClass,this.opts.itemClass),this.placeholder.appendChild(t)}return this._placeholder},enumerable:!1,configurable:!0}),t.prototype.change=function(){this._triggerChangeEvent()},t.prototype.addWidget=function(e,i){if(arguments.length>2){console.warn("gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon");var o=arguments,n=1,s={x:o[n++],y:o[n++],w:o[n++],h:o[n++],autoPosition:o[n++],minW:o[n++],maxW:o[n++],minH:o[n++],maxH:o[n++],id:o[n++]};return this.addWidget(e,s)}function r(t){return void 0!==t.x||void 0!==t.y||void 0!==t.w||void 0!==t.h||void 0!==t.content}var a;if("string"==typeof e)(h=document.implementation.createHTMLDocument("")).body.innerHTML=e,a=h.body.children[0];else if(0===arguments.length||1===arguments.length&&r(e)){var h,d=e&&e.content||"";i=e,(h=document.implementation.createHTMLDocument("")).body.innerHTML='
'+d+"
",a=h.body.children[0]}else a=e;var p=this._readAttr(a);i=l.Utils.cloneDeep(i)||{},l.Utils.defaults(i,p);var u=this.engine.prepareNode(i);if(this._writeAttr(a,i),this._insertNotAppend?this.el.prepend(a):this.el.appendChild(a),this._prepareElement(a,!0,i),this._updateContainerHeight(),u.subGrid&&!u.subGrid.el){var c=void 0,g=u.subGrid;"auto"===g.column&&(g.column=u.w,g.disableOneColumnMode=!0,c=!0),d=u.el.querySelector(".grid-stack-item-content"),u.subGrid=t.addGrid(d,u.subGrid),c&&(u.subGrid._autoColumn=!0)}return this._triggerAddEvent(),this._triggerChangeEvent(),a},t.prototype.save=function(t,e){void 0===t&&(t=!0),void 0===e&&(e=!1);var i=this.engine.save(t);if(i.forEach((function(e){if(t&&e.el&&!e.subGrid){var i=e.el.querySelector(".grid-stack-item-content");e.content=i?i.innerHTML:void 0,e.content||delete e.content}else t||delete e.content,e.subGrid&&(e.subGrid=e.subGrid.save(t,!0));delete e.el})),e){var o=l.Utils.cloneDeep(this.opts);o.marginBottom===o.marginTop&&o.marginRight===o.marginLeft&&o.marginTop===o.marginRight&&(o.margin=o.marginTop,delete o.marginTop,delete o.marginRight,delete o.marginBottom,delete o.marginLeft),o.rtl===("rtl"===this.el.style.direction)&&(o.rtl="auto"),this._isAutoCellHeight&&(o.cellHeight="auto"),this._autoColumn&&(o.column="auto",delete o.disableOneColumnMode);var n=o._alwaysShowResizeHandle;return delete o._alwaysShowResizeHandle,void 0!==n?o.alwaysShowResizeHandle=n:delete o.alwaysShowResizeHandle,l.Utils.removeInternalAndSame(o,h),o.children=i,o}return i},t.prototype.load=function(e,i){var o=this;void 0===i&&(i=!0);var n=t.Utils.sort(r(e),-1,this._prevColumn||this.getColumn());this._insertNotAppend=!0,this._prevColumn&&this._prevColumn!==this.opts.column&&n.some((function(t){return t.x+t.w>o.opts.column}))&&(this._ignoreLayoutsNodeChange=!0,this.engine.cacheLayout(n,this._prevColumn,!0));var s=[];return this.batchUpdate(),i&&r(this.engine.nodes).forEach((function(t){n.find((function(e){return t.id===e.id}))||("function"==typeof i?i(o,t,!1):(s.push(t),o.removeWidget(t.el,!0,!1)))})),n.forEach((function(t){var e=t.id||0===t.id?o.engine.nodes.find((function(e){return e.id===t.id})):void 0;if(e){if(o.update(e.el,t),t.subGrid&&t.subGrid.children){var n=e.el.querySelector(".grid-stack");n&&n.gridstack&&(n.gridstack.load(t.subGrid.children),o._insertNotAppend=!0)}}else i&&(t="function"==typeof i?i(o,t,!0).gridstackNode:o.addWidget(t).gridstackNode)})),this.engine.removedNodes=s,this.batchUpdate(!1),delete this._ignoreLayoutsNodeChange,delete this._insertNotAppend,this},t.prototype.batchUpdate=function(t){return void 0===t&&(t=!0),this.engine.batchUpdate(t),t||(this._triggerRemoveEvent(),this._triggerAddEvent(),this._triggerChangeEvent()),this},t.prototype.getCellHeight=function(t){if(void 0===t&&(t=!1),this.opts.cellHeight&&"auto"!==this.opts.cellHeight&&(!t||!this.opts.cellHeightUnit||"px"===this.opts.cellHeightUnit))return this.opts.cellHeight;var e=this.el.querySelector("."+this.opts.itemClass);if(e){var i=l.Utils.toNumber(e.getAttribute("gs-h"));return Math.round(e.offsetHeight/i)}var o=parseInt(this.el.getAttribute("gs-current-row"));return o?Math.round(this.el.getBoundingClientRect().height/o):this.opts.cellHeight},t.prototype.cellHeight=function(t,e){if(void 0===e&&(e=!0),e&&void 0!==t&&this._isAutoCellHeight!==("auto"===t)&&(this._isAutoCellHeight="auto"===t,this._updateWindowResizeEvent()),"initial"!==t&&"auto"!==t||(t=void 0),void 0===t){var i=-this.opts.marginRight-this.opts.marginLeft+this.opts.marginTop+this.opts.marginBottom;t=this.cellWidth()+i}var o=l.Utils.parseHeight(t);return this.opts.cellHeightUnit===o.unit&&this.opts.cellHeight===o.h||(this.opts.cellHeightUnit=o.unit,this.opts.cellHeight=o.h,e&&this._updateStyles(!0,this.getRow())),this},t.prototype.cellWidth=function(){return this._widthOrContainer()/this.getColumn()},t.prototype._widthOrContainer=function(){return this.el.clientWidth||this.el.parentElement.clientWidth||window.innerWidth},t.prototype.compact=function(){return this.engine.compact(),this._triggerChangeEvent(),this},t.prototype.column=function(t,e){if(void 0===e&&(e="moveScale"),t<1||this.opts.column===t)return this;var i,o=this.getColumn();return 1===t?this._prevColumn=o:delete this._prevColumn,this.el.classList.remove("grid-stack-"+o),this.el.classList.add("grid-stack-"+t),this.opts.column=this.engine.column=t,1===t&&this.opts.oneColumnModeDomSort&&(i=[],this.getGridItems().forEach((function(t){t.gridstackNode&&i.push(t.gridstackNode)})),i.length||(i=void 0)),this.engine.updateNodeWidths(o,t,i,e),this._isAutoCellHeight&&this.cellHeight(),this._ignoreLayoutsNodeChange=!0,this._triggerChangeEvent(),delete this._ignoreLayoutsNodeChange,this},t.prototype.getColumn=function(){return this.opts.column},t.prototype.getGridItems=function(){var t=this;return Array.from(this.el.children).filter((function(e){return e.matches("."+t.opts.itemClass)&&!e.matches("."+t.opts.placeholderClass)}))},t.prototype.destroy=function(t){if(void 0===t&&(t=!0),this.el)return this._updateWindowResizeEvent(!0),this.setStatic(!0,!1),this.setAnimation(!1),t?this.el.parentNode.removeChild(this.el):(this.removeAll(t),this.el.classList.remove(this.opts._styleSheetClass)),this._removeStylesheet(),this.el.removeAttribute("gs-current-row"),delete this.opts._isNested,delete this.opts,delete this._placeholder,delete this.engine,delete this.el.gridstack,delete this.el,this},t.prototype.float=function(t){return this.opts.float!==t&&(this.opts.float=this.engine.float=t,this._triggerChangeEvent()),this},t.prototype.getFloat=function(){return this.engine.float},t.prototype.getCellFromPixel=function(t,e){void 0===e&&(e=!1);var i,o=this.el.getBoundingClientRect();i=e?{top:o.top+document.documentElement.scrollTop,left:o.left}:{top:this.el.offsetTop,left:this.el.offsetLeft};var n=t.left-i.left,s=t.top-i.top,r=o.width/this.getColumn(),a=o.height/parseInt(this.el.getAttribute("gs-current-row"));return{x:Math.floor(n/r),y:Math.floor(s/a)}},t.prototype.getRow=function(){return Math.max(this.engine.getRow(),this.opts.minRow)},t.prototype.isAreaEmpty=function(t,e,i,o){return this.engine.isAreaEmpty(t,e,i,o)},t.prototype.makeWidget=function(e){var i=t.getElement(e);return this._prepareElement(i,!0),this._updateContainerHeight(),this._triggerAddEvent(),this._triggerChangeEvent(),i},t.prototype.on=function(t,e){var i=this;if(-1!==t.indexOf(" "))return t.split(" ").forEach((function(t){return i.on(t,e)})),this;if("change"===t||"added"===t||"removed"===t||"enable"===t||"disable"===t){var o="enable"===t||"disable"===t;this._gsEventHandler[t]=o?function(t){return e(t)}:function(t){return e(t,t.detail)},this.el.addEventListener(t,this._gsEventHandler[t])}else"drag"===t||"dragstart"===t||"dragstop"===t||"resizestart"===t||"resize"===t||"resizestop"===t||"dropped"===t?this._gsEventHandler[t]=e:console.log("GridStack.on("+t+') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');return this},t.prototype.off=function(t){var e=this;return-1!==t.indexOf(" ")?(t.split(" ").forEach((function(t){return e.off(t)})),this):("change"!==t&&"added"!==t&&"removed"!==t&&"enable"!==t&&"disable"!==t||this._gsEventHandler[t]&&this.el.removeEventListener(t,this._gsEventHandler[t]),delete this._gsEventHandler[t],this)},t.prototype.removeWidget=function(e,i,o){var n=this;return void 0===i&&(i=!0),void 0===o&&(o=!0),t.getElements(e).forEach((function(t){if(t.parentElement===n.el){var e=t.gridstackNode;e||(e=n.engine.nodes.find((function(e){return t===e.el}))),e&&(delete t.gridstackNode,n._removeDD(t),n.engine.removeNode(e,i,o),i&&t.parentElement&&t.remove())}})),o&&(this._triggerRemoveEvent(),this._triggerChangeEvent()),this},t.prototype.removeAll=function(t){var e=this;return void 0===t&&(t=!0),this.engine.nodes.forEach((function(t){delete t.el.gridstackNode,e._removeDD(t.el)})),this.engine.removeAll(t),this._triggerRemoveEvent(),this},t.prototype.setAnimation=function(t){return t?this.el.classList.add("grid-stack-animate"):this.el.classList.remove("grid-stack-animate"),this},t.prototype.setStatic=function(t,e){var i=this;return void 0===e&&(e=!0),this.opts.staticGrid===t||(this.opts.staticGrid=t,this._setupRemoveDrop(),this._setupAcceptWidget(),this.engine.nodes.forEach((function(t){return i._prepareDragDropByNode(t)})),e&&this._setStaticClass()),this},t.prototype.update=function(e,i){var o=this;if(arguments.length>2){console.warn("gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon");var n=arguments,s=1;return i={x:n[s++],y:n[s++],w:n[s++],h:n[s++]},this.update(e,i)}return t.getElements(e).forEach((function(t){if(t&&t.gridstackNode){var e=t.gridstackNode,n=l.Utils.cloneDeep(i);delete n.autoPosition;var s,r=["x","y","w","h"];if(r.some((function(t){return void 0!==n[t]&&n[t]!==e[t]}))&&(s={},r.forEach((function(t){s[t]=void 0!==n[t]?n[t]:e[t],delete n[t]}))),!s&&(n.minW||n.minH||n.maxW||n.maxH)&&(s={}),n.content){var a=t.querySelector(".grid-stack-item-content");a&&a.innerHTML!==n.content&&(a.innerHTML=n.content),delete n.content}var h=!1,d=!1;for(var p in n)"_"!==p[0]&&e[p]!==n[p]&&(e[p]=n[p],h=!0,d=d||!o.opts.staticGrid&&("noResize"===p||"noMove"===p||"locked"===p));s&&(o.engine.cleanNodes().beginUpdate(e).moveNode(e,s),o._updateContainerHeight(),o._triggerChangeEvent(),o.engine.endUpdate()),h&&o._writeAttr(t,e),d&&o._prepareDragDropByNode(e)}})),this},t.prototype.margin=function(t){if(!("string"==typeof t&&t.split(" ").length>1)){var e=l.Utils.parseHeight(t);if(this.opts.marginUnit===e.unit&&this.opts.margin===e.h)return}return this.opts.margin=t,this.opts.marginTop=this.opts.marginBottom=this.opts.marginLeft=this.opts.marginRight=void 0,this._initMargin(),this._updateStyles(!0),this},t.prototype.getMargin=function(){return this.opts.margin},t.prototype.willItFit=function(t){if(arguments.length>1){console.warn("gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon");var e=arguments,i=0,o={x:e[i++],y:e[i++],w:e[i++],h:e[i++],autoPosition:e[i++]};return this.willItFit(o)}return this.engine.willItFit(t)},t.prototype._triggerChangeEvent=function(){if(this.engine.batchMode)return this;var t=this.engine.getDirtyNodes(!0);return t&&t.length&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(t),this._triggerEvent("change",t)),this.engine.saveInitial(),this},t.prototype._triggerAddEvent=function(){return this.engine.batchMode||this.engine.addedNodes&&this.engine.addedNodes.length>0&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(this.engine.addedNodes),this.engine.addedNodes.forEach((function(t){delete t._dirty})),this._triggerEvent("added",this.engine.addedNodes),this.engine.addedNodes=[]),this},t.prototype._triggerRemoveEvent=function(){return this.engine.batchMode||this.engine.removedNodes&&this.engine.removedNodes.length>0&&(this._triggerEvent("removed",this.engine.removedNodes),this.engine.removedNodes=[]),this},t.prototype._triggerEvent=function(t,e){var i=e?new CustomEvent(t,{bubbles:!1,detail:e}):new Event(t);return this.el.dispatchEvent(i),this},t.prototype._removeStylesheet=function(){return this._styles&&(l.Utils.removeStylesheet(this._styles._id),delete this._styles),this},t.prototype._updateStyles=function(t,e){if(void 0===t&&(t=!1),t&&this._removeStylesheet(),this._updateContainerHeight(),0===this.opts.cellHeight)return this;var i=this.opts.cellHeight,o=this.opts.cellHeightUnit,n="."+this.opts._styleSheetClass+" > ."+this.opts.itemClass;if(!this._styles){var s="gridstack-style-"+(1e5*Math.random()).toFixed(),r=this.opts.styleInHead?void 0:this.el.parentNode;if(this._styles=l.Utils.createStylesheet(s,r),!this._styles)return this;this._styles._id=s,this._styles._max=0,l.Utils.addCSSRule(this._styles,n,"min-height: "+i+o);var a=this.opts.marginTop+this.opts.marginUnit,h=this.opts.marginBottom+this.opts.marginUnit,d=this.opts.marginRight+this.opts.marginUnit,p=this.opts.marginLeft+this.opts.marginUnit,u=n+" > .grid-stack-item-content",c="."+this.opts._styleSheetClass+" > .grid-stack-placeholder > .placeholder-content";l.Utils.addCSSRule(this._styles,u,"top: "+a+"; right: "+d+"; bottom: "+h+"; left: "+p+";"),l.Utils.addCSSRule(this._styles,c,"top: "+a+"; right: "+d+"; bottom: "+h+"; left: "+p+";"),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-ne","right: "+d),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-e","right: "+d),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-se","right: "+d+"; bottom: "+h),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-nw","left: "+p),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-w","left: "+p),l.Utils.addCSSRule(this._styles,n+" > .ui-resizable-sw","left: "+p+"; bottom: "+h)}if((e=e||this._styles._max)>this._styles._max){for(var g=function(t){return i*t+o},f=this._styles._max+1;f<=e;f++){var m=g(f);l.Utils.addCSSRule(this._styles,n+'[gs-y="'+(f-1)+'"]',"top: "+g(f-1)),l.Utils.addCSSRule(this._styles,n+'[gs-h="'+f+'"]',"height: "+m),l.Utils.addCSSRule(this._styles,n+'[gs-min-h="'+f+'"]',"min-height: "+m),l.Utils.addCSSRule(this._styles,n+'[gs-max-h="'+f+'"]',"max-height: "+m)}this._styles._max=e}return this},t.prototype._updateContainerHeight=function(){if(!this.engine||this.engine.batchMode)return this;var t=this.getRow()+this._extraDragRow;if(this.el.setAttribute("gs-current-row",String(t)),0===t)return this.el.style.removeProperty("height"),this;var e=this.opts.cellHeight,i=this.opts.cellHeightUnit;return e?(this.el.style.height=t*e+i,this):this},t.prototype._prepareElement=function(t,e,i){void 0===e&&(e=!1),i||(t.classList.add(this.opts.itemClass),i=this._readAttr(t)),t.gridstackNode=i,i.el=t,i.grid=this;var n=o({},i);return i=this.engine.addNode(i,e),l.Utils.same(i,n)||this._writeAttr(t,i),this._prepareDragDropByNode(i),this},t.prototype._writePosAttr=function(t,e){return void 0!==e.x&&null!==e.x&&t.setAttribute("gs-x",String(e.x)),void 0!==e.y&&null!==e.y&&t.setAttribute("gs-y",String(e.y)),e.w&&t.setAttribute("gs-w",String(e.w)),e.h&&t.setAttribute("gs-h",String(e.h)),this},t.prototype._writeAttr=function(t,e){if(!e)return this;this._writePosAttr(t,e);var i={autoPosition:"gs-auto-position",minW:"gs-min-w",minH:"gs-min-h",maxW:"gs-max-w",maxH:"gs-max-h",noResize:"gs-no-resize",noMove:"gs-no-move",locked:"gs-locked",id:"gs-id",resizeHandles:"gs-resize-handles"};for(var o in i)e[o]?t.setAttribute(i[o],String(e[o])):t.removeAttribute(i[o]);return this},t.prototype._readAttr=function(t){var e={};for(var i in e.x=l.Utils.toNumber(t.getAttribute("gs-x")),e.y=l.Utils.toNumber(t.getAttribute("gs-y")),e.w=l.Utils.toNumber(t.getAttribute("gs-w")),e.h=l.Utils.toNumber(t.getAttribute("gs-h")),e.maxW=l.Utils.toNumber(t.getAttribute("gs-max-w")),e.minW=l.Utils.toNumber(t.getAttribute("gs-min-w")),e.maxH=l.Utils.toNumber(t.getAttribute("gs-max-h")),e.minH=l.Utils.toNumber(t.getAttribute("gs-min-h")),e.autoPosition=l.Utils.toBool(t.getAttribute("gs-auto-position")),e.noResize=l.Utils.toBool(t.getAttribute("gs-no-resize")),e.noMove=l.Utils.toBool(t.getAttribute("gs-no-move")),e.locked=l.Utils.toBool(t.getAttribute("gs-locked")),e.resizeHandles=t.getAttribute("gs-resize-handles"),e.id=t.getAttribute("gs-id"),e){if(!e.hasOwnProperty(i))return;e[i]||0===e[i]||delete e[i]}return e},t.prototype._setStaticClass=function(){var t,e,i=["grid-stack-static"];return this.opts.staticGrid?((t=this.el.classList).add.apply(t,i),this.el.setAttribute("gs-static","true")):((e=this.el.classList).remove.apply(e,i),this.el.removeAttribute("gs-static")),this},t.prototype.onParentResize=function(){var t=this;if(this.el&&this.el.clientWidth){var e=!1;if(this._autoColumn&&this.opts._isNested)this.opts.column!==this.opts._isNested.w&&(e=!0,this.column(this.opts._isNested.w,"none"));else{var i=!this.opts.disableOneColumnMode&&this.el.clientWidth<=this.opts.oneColumnSize;1===this.opts.column!==i&&(e=!0,this.opts.animate&&this.setAnimation(!1),this.column(i?1:this._prevColumn),this.opts.animate&&this.setAnimation(!0))}return this._isAutoCellHeight&&(!e&&this.opts.cellHeightThrottle?(this._cellHeightThrottle||(this._cellHeightThrottle=l.Utils.throttle((function(){return t.cellHeight()}),this.opts.cellHeightThrottle)),this._cellHeightThrottle()):this.cellHeight()),this.engine.nodes.forEach((function(t){t.subGrid&&t.subGrid.onParentResize()})),this}},t.prototype._updateWindowResizeEvent=function(t){void 0===t&&(t=!1);var e=(this._isAutoCellHeight||!this.opts.disableOneColumnMode)&&!this.opts._isNested;return t||!e||this._windowResizeBind?!t&&e||!this._windowResizeBind||(window.removeEventListener("resize",this._windowResizeBind),delete this._windowResizeBind):(this._windowResizeBind=this.onParentResize.bind(this),window.addEventListener("resize",this._windowResizeBind)),this},t.getElement=function(t){return void 0===t&&(t=".grid-stack-item"),l.Utils.getElement(t)},t.getElements=function(t){return void 0===t&&(t=".grid-stack-item"),l.Utils.getElements(t)},t.getGridElement=function(e){return t.getElement(e)},t.getGridElements=function(t){return l.Utils.getElements(t)},t.prototype._initMargin=function(){var t,e=0,i=[];return"string"==typeof this.opts.margin&&(i=this.opts.margin.split(" ")),2===i.length?(this.opts.marginTop=this.opts.marginBottom=i[0],this.opts.marginLeft=this.opts.marginRight=i[1]):4===i.length?(this.opts.marginTop=i[0],this.opts.marginRight=i[1],this.opts.marginBottom=i[2],this.opts.marginLeft=i[3]):(t=l.Utils.parseHeight(this.opts.margin),this.opts.marginUnit=t.unit,e=this.opts.margin=t.h),void 0===this.opts.marginTop?this.opts.marginTop=e:(t=l.Utils.parseHeight(this.opts.marginTop),this.opts.marginTop=t.h,delete this.opts.margin),void 0===this.opts.marginBottom?this.opts.marginBottom=e:(t=l.Utils.parseHeight(this.opts.marginBottom),this.opts.marginBottom=t.h,delete this.opts.margin),void 0===this.opts.marginRight?this.opts.marginRight=e:(t=l.Utils.parseHeight(this.opts.marginRight),this.opts.marginRight=t.h,delete this.opts.margin),void 0===this.opts.marginLeft?this.opts.marginLeft=e:(t=l.Utils.parseHeight(this.opts.marginLeft),this.opts.marginLeft=t.h,delete this.opts.margin),this.opts.marginUnit=t.unit,this.opts.marginTop===this.opts.marginBottom&&this.opts.marginLeft===this.opts.marginRight&&this.opts.marginTop===this.opts.marginRight&&(this.opts.margin=this.opts.marginTop),this},t.setupDragIn=function(t,e){},t.prototype.movable=function(t,e){return this},t.prototype.resizable=function(t,e){return this},t.prototype.disable=function(){return this},t.prototype.enable=function(){return this},t.prototype.enableMove=function(t){return this},t.prototype.enableResize=function(t){return this},t.prototype._removeDD=function(t){return this},t.prototype._setupAcceptWidget=function(){return this},t.prototype._setupRemoveDrop=function(){return this},t.prototype._prepareDragDropByNode=function(t){return this},t.prototype._onStartMoving=function(t,e,i,o,n,s){},t.prototype._dragOrResize=function(t,e,i,o,n,s){},t.prototype._leave=function(t,e){},t.prototype.commit=function(){return l.obsolete(this,this.batchUpdate(!1),"commit","batchUpdate","5.2"),this},t.Utils=l.Utils,t.Engine=a.GridStackEngine,t.GDRev="6.0.1-dev",t}();e.GridStack=d;var p=i(537);s(i(502),e)},855:function(t,e){Object.defineProperty(e,"__esModule",{value:!0})},867:function(t,e){var i=this&&this.__assign||function(){return i=Object.assign||function(t){for(var e,i=1,o=arguments.length;i=e.y+e.h||t.y+t.h<=e.y||t.x+t.w<=e.x||t.x>=e.x+e.w)},t.isTouching=function(e,i){return t.isIntercepted(e,{x:i.x-.5,y:i.y-.5,w:i.w+1,h:i.h+1})},t.sort=function(t,e,i){return i=i||t.reduce((function(t,e){return Math.max(e.x+e.w,t)}),0)||12,-1===e?t.sort((function(t,e){return e.x+e.y*i-(t.x+t.y*i)})):t.sort((function(t,e){return t.x+t.y*i-(e.x+e.y*i)}))},t.createStylesheet=function(t,e){var i=document.createElement("style");return i.setAttribute("type","text/css"),i.setAttribute("gs-style-id",t),i.styleSheet?i.styleSheet.cssText="":i.appendChild(document.createTextNode("")),e?e.insertBefore(i,e.firstChild):(e=document.getElementsByTagName("head")[0]).appendChild(i),i.sheet},t.removeStylesheet=function(t){var e=document.querySelector("STYLE[gs-style-id="+t+"]");e&&e.parentNode&&e.remove()},t.addCSSRule=function(t,e,i){"function"==typeof t.addRule?t.addRule(e,i):"function"==typeof t.insertRule&&t.insertRule(e+"{"+i+"}")},t.toBool=function(t){return"boolean"==typeof t?t:"string"==typeof t?!(""===(t=t.toLowerCase())||"no"===t||"false"===t||"0"===t):Boolean(t)},t.toNumber=function(t){return null===t||0===t.length?void 0:Number(t)},t.parseHeight=function(t){var e,i="px";if("string"==typeof t){var o=t.match(/^(-[0-9]+\.[0-9]+|[0-9]*\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);if(!o)throw new Error("Invalid height");i=o[2]||"px",e=parseFloat(o[1])}else e=t;return{h:e,unit:i}},t.defaults=function(t){for(var e=this,i=[],o=1;on){var s=o.bottom-n,r=o.top,a=this.getScrollElement(t);if(null!==a){var l=a.scrollTop;o.top<0&&i<0?t.offsetHeight>n?a.scrollTop+=i:a.scrollTop+=Math.abs(r)>Math.abs(i)?i:r:i>0&&(t.offsetHeight>n?a.scrollTop+=i:a.scrollTop+=s>i?i:s),e.top+=a.scrollTop-l}}},t.updateScrollResize=function(t,e,i){var o=this.getScrollElement(e),n=o.clientHeight,s=o===this.getScrollElement()?0:o.getBoundingClientRect().top,r=t.clientY-s,a=r>n-i;r boolean|void;\nexport abstract class DDBaseImplement {\n /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */\n public get disabled(): boolean { return this._disabled; }\n\n /** @internal */\n protected _disabled: boolean; // initial state to differentiate from false\n /** @internal */\n protected _eventRegister: {\n [eventName: string]: EventCallback;\n } = {};\n\n public on(event: string, callback: EventCallback): void {\n this._eventRegister[event] = callback;\n }\n\n public off(event: string): void {\n delete this._eventRegister[event];\n }\n\n public enable(): void {\n this._disabled = false;\n }\n\n public disable(): void {\n this._disabled = true;\n }\n\n public destroy(): void {\n delete this._eventRegister;\n }\n\n public triggerEvent(eventName: string, event: Event): boolean|void {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\nexport interface HTMLElementExtendOpt {\n el: HTMLElement;\n option: T;\n updateOption(T): DDBaseImplement;\n}\n","/**\n * dd-draggable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\nimport { Utils } from './utils';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { GridItemHTMLElement, DDUIData } from './types';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, touchend, touchmove, touchstart, pointerdown } from './dd-touch';\n\n// TODO: merge with DDDragOpt ?\nexport interface DDDraggableOpt {\n appendTo?: string | HTMLElement;\n handle?: string;\n helper?: string | HTMLElement | ((event: Event) => HTMLElement);\n // containment?: string | HTMLElement; // TODO: not implemented yet\n // revert?: string | boolean | unknown; // TODO: not implemented yet\n // scroll?: boolean; // native support by HTML5 drag drop, can't be switch to off actually\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n drag?: (event: Event, ui: DDUIData) => void;\n}\n\ninterface DragOffset {\n left: number;\n top: number;\n width: number;\n height: number;\n offsetLeft: number;\n offsetTop: number;\n}\n\ntype DDDragEvent = 'drag' | 'dragstart' | 'dragstop';\n\n// let count = 0; // TEST\n\nexport class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt {\n public el: HTMLElement;\n public option: DDDraggableOpt;\n public helper: HTMLElement; // used by GridStackDDNative\n\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected dragOffset: DragOffset;\n /** @internal */\n protected dragElementOriginStyle: Array;\n /** @internal */\n protected dragEl: HTMLElement;\n /** @internal true while we are dragging an item around */\n protected dragging: boolean;\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected helperContainment: HTMLElement;\n /** @internal properties we change during dragging, and restore back */\n protected static originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top'];\n\n constructor(el: HTMLElement, option: DDDraggableOpt = {}) {\n super();\n this.el = el;\n this.option = option;\n // get the element that is actually supposed to be dragged by\n let className = option.handle.substring(1);\n this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this.enable();\n }\n\n public on(event: DDDragEvent, callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: DDDragEvent): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.dragEl.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.addEventListener('touchstart', touchstart);\n this.dragEl.addEventListener('pointerdown', pointerdown);\n // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n this.el.classList.remove('ui-draggable-disabled');\n this.el.classList.add('ui-draggable');\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.dragEl.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.removeEventListener('touchstart', touchstart);\n this.dragEl.removeEventListener('pointerdown', pointerdown);\n }\n this.el.classList.remove('ui-draggable');\n if (!forDestroy) this.el.classList.add('ui-draggable-disabled');\n }\n\n public destroy(): void {\n if (this.dragging) this._mouseUp(this.mouseDownEvent);\n this.disable(true);\n delete this.el;\n delete this.helper;\n delete this.option;\n super.destroy();\n }\n\n public updateOption(opts: DDDraggableOpt): DDDraggable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n return this;\n }\n\n /** @internal call when mouse goes down before a dragstart happens */\n protected _mouseDown(e: MouseEvent): boolean {\n // don't let more than one widget handle mouseStart\n if (DDManager.mouseHandled) return;\n if (e.button !== 0) return true; // only left click\n\n // make sure we are clicking on a drag handle or child of it...\n // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins)\n let className = this.option.handle.substring(1);\n let el = e.target as HTMLElement;\n while (el && !el.classList.contains(className)) { el = el.parentElement; }\n if (!el) return;\n this.mouseDownEvent = e;\n delete this.dragging;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack\n document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.addEventListener('touchmove', touchmove);\n this.dragEl.addEventListener('touchend', touchend);\n }\n\n e.preventDefault();\n DDManager.mouseHandled = true;\n return true;\n }\n\n /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */\n protected _mouseMove(e: DragEvent): boolean {\n // console.log(`${count++} move ${e.x},${e.y}`)\n let s = this.mouseDownEvent;\n\n if (this.dragging) {\n this._dragFollow(e);\n const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });\n if (this.option.drag) {\n this.option.drag(ev, this.ui());\n }\n this.triggerEvent('drag', ev);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {\n /**\n * don't start unless we've moved at least 3 pixels\n */\n this.dragging = true;\n DDManager.dragElement = this;\n // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)\n let grid = (this.el as GridItemHTMLElement).gridstackNode?.grid;\n if (grid) {\n DDManager.dropElement = (grid.el as DDElementHost).ddElement.ddDroppable;\n } else {\n delete DDManager.dropElement;\n }\n this.helper = this._createHelper(e);\n this._setupHelperContainmentStyle();\n this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });\n\n this._setupHelperStyle(e);\n if (this.option.start) {\n this.option.start(ev, this.ui());\n }\n this.triggerEvent('dragstart', ev);\n }\n e.preventDefault();\n return true;\n }\n\n /** @internal call when the mouse gets released to drop the item at current location */\n protected _mouseUp(e: MouseEvent): void {\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.removeEventListener('touchmove', touchmove, true);\n this.dragEl.removeEventListener('touchend', touchend, true);\n }\n if (this.dragging) {\n delete this.dragging;\n\n // reset the drop target if dragging over ourself (already parented, just moving during stop callback below)\n if (DDManager.dropElement?.el === this.el.parentElement) {\n delete DDManager.dropElement;\n }\n\n this.helperContainment.style.position = this.parentOriginStylePosition || null;\n if (this.helper === this.el) {\n this._removeHelperStyle();\n } else {\n this.helper.remove();\n }\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });\n if (this.option.stop) {\n this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!\n }\n this.triggerEvent('dragstop', ev);\n\n // call the droppable method to receive the item\n if (DDManager.dropElement) {\n DDManager.dropElement.drop(e);\n }\n }\n delete this.helper;\n delete this.mouseDownEvent;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n delete DDManager.mouseHandled;\n e.preventDefault();\n }\n\n /** @internal create a clone copy (or user defined method) of the original drag item if set */\n protected _createHelper(event: DragEvent): HTMLElement {\n let helper = this.el;\n if (typeof this.option.helper === 'function') {\n helper = this.option.helper(event);\n } else if (this.option.helper === 'clone') {\n helper = Utils.cloneNode(this.el);\n }\n if (!document.body.contains(helper)) {\n Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo);\n }\n if (helper === this.el) {\n this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);\n }\n return helper;\n }\n\n /** @internal set the fix position of the dragged item */\n protected _setupHelperStyle(e: DragEvent): DDDraggable {\n this.helper.classList.add('ui-draggable-dragging');\n // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593\n const style = this.helper.style;\n style.pointerEvents = 'none'; // needed for over items to get enter/leave\n // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well)\n style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %)\n style.width = this.dragOffset.width + 'px';\n style.height = this.dragOffset.height + 'px';\n style.willChange = 'left, top';\n style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'\n this._dragFollow(e); // now position it\n style.transition = 'none'; // show up instantly\n setTimeout(() => {\n if (this.helper) {\n style.transition = null; // recover animation\n }\n }, 0);\n return this;\n }\n\n /** @internal restore back the original style before dragging */\n protected _removeHelperStyle(): DDDraggable {\n this.helper.classList.remove('ui-draggable-dragging');\n let node = (this.helper as GridItemHTMLElement)?.gridstackNode;\n // don't bother restoring styles if we're gonna remove anyway...\n if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) {\n let helper = this.helper;\n // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'\n let transition = this.dragElementOriginStyle['transition'] || null;\n helper.style.transition = this.dragElementOriginStyle['transition'] = 'none';\n DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);\n setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)\n }\n delete this.dragElementOriginStyle;\n return this;\n }\n\n /** @internal updates the top/left position to follow the mouse */\n protected _dragFollow(e: DragEvent): void {\n let containmentRect = { left: 0, top: 0 };\n // if (this.helper.style.position === 'absolute') { // we use 'fixed'\n // const { left, top } = this.helperContainment.getBoundingClientRect();\n // containmentRect = { left, top };\n // }\n const style = this.helper.style;\n const offset = this.dragOffset;\n style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';\n style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';\n }\n\n /** @internal */\n protected _setupHelperContainmentStyle(): DDDraggable {\n this.helperContainment = this.helper.parentElement;\n if (this.helper.style.position !== 'fixed') {\n this.parentOriginStylePosition = this.helperContainment.style.position;\n if (window.getComputedStyle(this.helperContainment).position.match(/static/)) {\n this.helperContainment.style.position = 'relative';\n }\n }\n return this;\n }\n\n /** @internal */\n protected _getDragOffset(event: DragEvent, el: HTMLElement, parent: HTMLElement): DragOffset {\n\n // in case ancestor has transform/perspective css properties that change the viewpoint\n let xformOffsetX = 0;\n let xformOffsetY = 0;\n if (parent) {\n const testEl = document.createElement('div');\n Utils.addElStyles(testEl, {\n opacity: '0',\n position: 'fixed',\n top: 0 + 'px',\n left: 0 + 'px',\n width: '1px',\n height: '1px',\n zIndex: '-999999',\n });\n parent.appendChild(testEl);\n const testElPosition = testEl.getBoundingClientRect();\n parent.removeChild(testEl);\n xformOffsetX = testElPosition.left;\n xformOffsetY = testElPosition.top;\n // TODO: scale ?\n }\n\n const targetOffset = el.getBoundingClientRect();\n return {\n left: targetOffset.left,\n top: targetOffset.top,\n offsetLeft: - event.clientX + targetOffset.left - xformOffsetX,\n offsetTop: - event.clientY + targetOffset.top - xformOffsetY,\n width: targetOffset.width,\n height: targetOffset.height\n };\n }\n\n /** @internal TODO: set to public as called by DDDroppable! */\n public ui(): DDUIData {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const offset = this.helper.getBoundingClientRect();\n return {\n position: { //Current CSS position of the helper as { top, left } object\n top: offset.top - containmentRect.top,\n left: offset.left - containmentRect.left\n }\n /* not used by GridStack for now...\n helper: [this.helper], //The object arr representing the helper that's being dragged.\n offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.\n */\n };\n }\n}\n","/**\n * dd-droppable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDManager } from './dd-manager';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, pointerenter, pointerleave } from './dd-touch';\nimport { GridHTMLElement } from './gridstack';\n\nexport interface DDDroppableOpt {\n accept?: string | ((el: HTMLElement) => boolean);\n drop?: (event: DragEvent, ui) => void;\n over?: (event: DragEvent, ui) => void;\n out?: (event: DragEvent, ui) => void;\n}\n\n// let count = 0; // TEST\n\nexport class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n public accept: (el: HTMLElement) => boolean;\n public el: HTMLElement;\n public option: DDDroppableOpt;\n\n constructor(el: HTMLElement, opts: DDDroppableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseEnter = this._mouseEnter.bind(this);\n this._mouseLeave = this._mouseLeave.bind(this);\n this.enable();\n this._setupAccept();\n }\n\n public on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'drop' | 'dropover' | 'dropout'): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.el.classList.add('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n this.el.addEventListener('mouseenter', this._mouseEnter);\n this.el.addEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.addEventListener('pointerenter', pointerenter);\n this.el.addEventListener('pointerleave', pointerleave);\n }\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.el.classList.remove('ui-droppable');\n if (!forDestroy) this.el.classList.add('ui-droppable-disabled');\n this.el.removeEventListener('mouseenter', this._mouseEnter);\n this.el.removeEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.removeEventListener('pointerenter', pointerenter);\n this.el.removeEventListener('pointerleave', pointerleave);\n }\n }\n\n public destroy(): void {\n this.disable(true);\n this.el.classList.remove('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n super.destroy();\n }\n\n public updateOption(opts: DDDroppableOpt): DDDroppable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n this._setupAccept();\n return this;\n }\n\n /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */\n protected _mouseEnter(e: MouseEvent): void {\n // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement) return;\n if (!this._canDrop()) return;\n e.preventDefault();\n e.stopPropagation();\n\n // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do\n if (DDManager.dropElement && DDManager.dropElement !== this) {\n DDManager.dropElement._mouseLeave(e as DragEvent);\n }\n DDManager.dropElement = this;\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });\n if (this.option.over) {\n this.option.over(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropover', ev);\n this.el.classList.add('ui-droppable-over');\n // console.log('tracking'); // TEST\n }\n\n /** @internal called when the item is leaving our area, stop tracking if we had moving item */\n protected _mouseLeave(e: MouseEvent): void {\n // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement || DDManager.dropElement !== this) return;\n e.preventDefault();\n e.stopPropagation();\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });\n if (this.option.out) {\n this.option.out(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropout', ev);\n\n if (DDManager.dropElement === this) {\n delete DDManager.dropElement;\n // console.log('not tracking'); // TEST\n\n // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children\n let parentDrop: DDDroppable;\n let parent: DDElementHost = this.el.parentElement;\n while (!parentDrop && parent) {\n parentDrop = parent.ddElement?.ddDroppable;\n parent = parent.parentElement;\n }\n if (parentDrop) {\n parentDrop._mouseEnter(e);\n }\n }\n }\n\n /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */\n public drop(e: MouseEvent): void {\n e.preventDefault();\n const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });\n if (this.option.drop) {\n this.option.drop(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('drop', ev);\n }\n\n /** @internal true if element matches the string/method accept option */\n protected _canDrop(): boolean {\n return DDManager.dragElement && (!this.accept || this.accept(DDManager.dragElement.el));\n }\n\n /** @internal */\n protected _setupAccept(): DDDroppable {\n if (!this.option.accept) return this;\n if (typeof this.option.accept === 'string') {\n this.accept = (el: HTMLElement) => el.matches(this.option.accept as string);\n } else {\n this.accept = this.option.accept;\n }\n return this;\n }\n\n /** @internal */\n protected _ui(drag: DDDraggable) {\n return {\n draggable: drag.el,\n ...drag.ui()\n };\n }\n}\n\n","/**\n * dd-elements.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizable, DDResizableOpt } from './dd-resizable';\nimport { GridItemHTMLElement } from './types';\nimport { DDDraggable, DDDraggableOpt } from './dd-draggable';\nimport { DDDroppable, DDDroppableOpt } from './dd-droppable';\n\nexport interface DDElementHost extends GridItemHTMLElement {\n ddElement?: DDElement;\n}\n\nexport class DDElement {\n\n static init(el: DDElementHost): DDElement {\n if (!el.ddElement) { el.ddElement = new DDElement(el); }\n return el.ddElement;\n }\n\n public el: DDElementHost;\n public ddDraggable?: DDDraggable;\n public ddDroppable?: DDDroppable;\n public ddResizable?: DDResizable;\n\n constructor(el: DDElementHost) {\n this.el = el;\n }\n\n public on(eventName: string, callback: (event: MouseEvent) => void): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.on(eventName as 'drag' | 'dragstart' | 'dragstop', callback);\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.on(eventName as 'drop' | 'dropover' | 'dropout', callback);\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.on(eventName as 'resizestart' | 'resize' | 'resizestop', callback);\n }\n return this;\n }\n\n public off(eventName: string): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.off(eventName as 'drag' | 'dragstart' | 'dragstop');\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.off(eventName as 'drop' | 'dropover' | 'dropout');\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.off(eventName as 'resizestart' | 'resize' | 'resizestop');\n }\n return this;\n }\n\n public setupDraggable(opts: DDDraggableOpt): DDElement {\n if (!this.ddDraggable) {\n this.ddDraggable = new DDDraggable(this.el, opts);\n } else {\n this.ddDraggable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDraggable(): DDElement {\n if (this.ddDraggable) {\n this.ddDraggable.destroy();\n delete this.ddDraggable;\n }\n return this;\n }\n\n public setupResizable(opts: DDResizableOpt): DDElement {\n if (!this.ddResizable) {\n this.ddResizable = new DDResizable(this.el, opts);\n } else {\n this.ddResizable.updateOption(opts);\n }\n return this;\n }\n\n public cleanResizable(): DDElement {\n if (this.ddResizable) {\n this.ddResizable.destroy();\n delete this.ddResizable;\n }\n return this;\n }\n\n public setupDroppable(opts: DDDroppableOpt): DDElement {\n if (!this.ddDroppable) {\n this.ddDroppable = new DDDroppable(this.el, opts);\n } else {\n this.ddDroppable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDroppable(): DDElement {\n if (this.ddDroppable) {\n this.ddDroppable.destroy();\n delete this.ddDroppable;\n }\n return this;\n }\n}\n","/**\r\n * dd-gridstack.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { GridItemHTMLElement, GridStackNode, GridStackElement, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\nimport { GridStack } from './gridstack';\r\nimport { Utils } from './utils';\r\nimport { DDManager } from './dd-manager';\r\nimport { DDElement, DDElementHost } from './dd-element';\r\n\r\n/** Drag&Drop drop options */\r\nexport type DDDropOpt = {\r\n /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */\r\n accept?: (el: GridItemHTMLElement) => boolean;\r\n}\r\n\r\n/** drag&drop options currently called from the main code, but others can be passed in grid options */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any;\r\nexport type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight';\r\nexport type DDValue = number | string;\r\n\r\n/** drag&drop events callbacks */\r\nexport type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void;\r\n\r\n// let count = 0; // TEST\r\n\r\n/**\r\n * HTML Native Mouse and Touch Events Drag and Drop functionality.\r\n */\r\nexport class DDGridStack {\r\n\r\n /** get the global (but static to this code) DD implementation */\r\n static get(): DDGridStack {\r\n return dd;\r\n }\r\n\r\n public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddResizable && dEl.cleanResizable();\r\n } else if (opts === 'option') {\r\n dEl.setupResizable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles;\r\n let autoHide = !grid.opts.alwaysShowResizeHandle;\r\n let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined;\r\n dEl.setupResizable({\r\n ...grid.opts.resizable,\r\n ...{ handles, autoHide },\r\n ...{\r\n start: opts.start,\r\n stop: opts.stop,\r\n resize: opts.resize,\r\n fixedAspectRatio: fixedAspectRatio\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddDraggable && dEl.cleanDraggable();\r\n } else if (opts === 'option') {\r\n dEl.setupDraggable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n dEl.setupDraggable({\r\n ...grid.opts.draggable,\r\n ...{\r\n // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null),\r\n start: opts.start,\r\n stop: opts.stop,\r\n drag: opts.drag\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));\r\n return this;\r\n }\r\n\r\n public droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack {\r\n if (typeof opts.accept === 'function' && !opts._accept) {\r\n opts._accept = opts.accept;\r\n opts.accept = (el) => opts._accept(el);\r\n }\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDroppable && dEl.ddDroppable[opts]();\r\n } else if (opts === 'destroy') {\r\n if (dEl.ddDroppable) { // error to call destroy if not there\r\n dEl.cleanDroppable();\r\n }\r\n } else if (opts === 'option') {\r\n dEl.setupDroppable({ [key]: value });\r\n } else {\r\n dEl.setupDroppable(opts);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /** true if element is droppable */\r\n public isDroppable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isDraggable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isResizable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled);\r\n }\r\n\r\n public on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack {\r\n this._getDDElements(el).forEach(dEl =>\r\n dEl.on(name, (event: Event) => {\r\n callback(\r\n event,\r\n DDManager.dragElement ? DDManager.dragElement.el : event.target as GridItemHTMLElement,\r\n DDManager.dragElement ? DDManager.dragElement.helper : null)\r\n })\r\n );\r\n return this;\r\n }\r\n\r\n public off(el: GridItemHTMLElement, name: string): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.off(name));\r\n return this;\r\n }\r\n\r\n /** @internal returns a list of DD elements, creating them on the fly by default */\r\n protected _getDDElements(els: GridStackElement, create = true): DDElement[] {\r\n let hosts = Utils.getElements(els) as DDElementHost[];\r\n if (!hosts.length) return [];\r\n let list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null));\r\n if (!create) { list.filter(d => d); } // remove nulls\r\n return list;\r\n }\r\n}\r\n\r\n/** global instance */\r\nconst dd = new DDGridStack;\r\n\r\n/********************************************************************************\r\n * GridStack code that is doing drag&drop extracted here so main class is smaller\r\n * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k)\r\n * https://www.typescriptlang.org/docs/handbook/declaration-merging.html\r\n * https://www.typescriptlang.org/docs/handbook/mixins.html\r\n ********************************************************************************/\r\n\r\n/** @internal called to add drag over to support widgets being added externally */\r\nGridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {\r\n\r\n // check if we need to disable things\r\n if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {\r\n dd.droppable(this.el, 'destroy');\r\n return this;\r\n }\r\n\r\n // vars shared across all methods\r\n let cellHeight: number, cellWidth: number;\r\n\r\n let onDrag = (event: DragEvent, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n helper = helper || el;\r\n let parent = this.el.getBoundingClientRect();\r\n let {top, left} = helper.getBoundingClientRect();\r\n left -= parent.left;\r\n top -= parent.top;\r\n let ui: DDUIData = {position: {top, left}};\r\n\r\n if (node._temporaryRemoved) {\r\n node.x = Math.max(0, Math.round(left / cellWidth));\r\n node.y = Math.max(0, Math.round(top / cellHeight));\r\n delete node.autoPosition;\r\n this.engine.nodeBoundFix(node);\r\n\r\n // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere\r\n if (!this.engine.willItFit(node)) {\r\n node.autoPosition = true; // ignore x,y and try for any slot...\r\n if (!this.engine.willItFit(node)) {\r\n dd.off(el, 'drag'); // stop calling us\r\n return; // full grid or can't grow\r\n }\r\n if (node._willFitPos) {\r\n // use the auto position instead #1687\r\n Utils.copyPos(node, node._willFitPos);\r\n delete node._willFitPos;\r\n }\r\n }\r\n\r\n // re-use the existing node dragging method\r\n this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);\r\n } else {\r\n // re-use the existing node dragging that does so much of the collision detection\r\n this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);\r\n }\r\n }\r\n\r\n dd.droppable(this.el, {\r\n accept: (el: GridItemHTMLElement) => {\r\n let node: GridStackNode = el.gridstackNode;\r\n // set accept drop to true on ourself (which we ignore) so we don't get \"can't drop\" icon in HTML5 mode while moving\r\n if (node?.grid === this) return true;\r\n if (!this.opts.acceptWidgets) return false;\r\n // prevent deeper nesting until rest of 992 can be fixed\r\n if (node?.subGrid) return false;\r\n // check for accept method or class matching\r\n let canAccept = true;\r\n if (typeof this.opts.acceptWidgets === 'function') {\r\n canAccept = this.opts.acceptWidgets(el);\r\n } else {\r\n let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets as string);\r\n canAccept = el.matches(selector);\r\n }\r\n // finally check to make sure we actually have space left #1571\r\n if (canAccept && node && this.opts.maxRow) {\r\n let n = {w: node.w, h: node.h, minW: node.minW, minH: node.minH}; // only width/height matters and autoPosition\r\n canAccept = this.engine.willItFit(n);\r\n }\r\n return canAccept;\r\n }\r\n })\r\n /**\r\n * entering our grid area\r\n */\r\n .on(this.el, 'dropover', (event: Event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item\r\n if (node?.grid === this && !node._temporaryRemoved) {\r\n // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n }\r\n\r\n // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now\r\n if (node?.grid && node.grid !== this && !node._temporaryRemoved) {\r\n // console.log('dropover without leave'); // TEST\r\n let otherGrid = node.grid;\r\n otherGrid._leave(el, helper);\r\n }\r\n\r\n // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true);\r\n\r\n // load any element attributes if we don't have a node\r\n if (!node) {// @ts-ignore private read only on ourself\r\n node = this._readAttr(el);\r\n }\r\n if (!node.grid) {\r\n node._isExternal = true;\r\n el.gridstackNode = node;\r\n }\r\n\r\n // calculate the grid size based on element outer size\r\n helper = helper || el;\r\n let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;\r\n let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;\r\n\r\n // if the item came from another grid, make a copy and save the original info in case we go back there\r\n if (node.grid && node.grid !== this) {\r\n // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific\r\n // console.log('dropover cloning node'); // TEST\r\n if (!el._gridstackNodeOrig) el._gridstackNodeOrig = node; // shouldn't have multiple nested!\r\n el.gridstackNode = node = {...node, w, h, grid: this};\r\n this.engine.cleanupNode(node)\r\n .nodeBoundFix(node);\r\n // restore some internal fields we need after clearing them all\r\n node._initDD =\r\n node._isExternal = // DOM needs to be re-parented on a drop\r\n node._temporaryRemoved = true; // so it can be inserted onDrag below\r\n } else {\r\n node.w = w; node.h = h;\r\n node._temporaryRemoved = true; // so we can insert it\r\n }\r\n\r\n // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)\r\n _itemRemoving(node.el, false);\r\n\r\n dd.on(el, 'drag', onDrag);\r\n // make sure this is called at least once when going fast #1578\r\n onDrag(event as DragEvent, el, helper);\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n })\r\n /**\r\n * Leaving our grid area...\r\n */\r\n .on(this.el, 'dropout', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n if (!node) return false;\r\n // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)\r\n // so skip this one if we're not the active grid really..\r\n if (!node.grid || node.grid === this) {\r\n this._leave(el, helper);\r\n }\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n })\r\n /**\r\n * end - releasing the mouse\r\n */\r\n .on(this.el, 'drop', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead\r\n if (node?.grid === this && !node._isExternal) return false;\r\n\r\n let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419\r\n this.placeholder.remove();\r\n\r\n // notify previous grid of removal\r\n // console.log('drop delete _gridstackNodeOrig') // TEST\r\n let origNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n if (wasAdded && origNode && origNode.grid && origNode.grid !== this) {\r\n let oGrid = origNode.grid;\r\n oGrid.engine.removedNodes.push(origNode);\r\n oGrid._triggerRemoveEvent();\r\n }\r\n\r\n if (!node) return false;\r\n\r\n // use existing placeholder node as it's already in our list with drop location\r\n if (wasAdded) {\r\n this.engine.cleanupNode(node); // removes all internal _xyz values\r\n node.grid = this;\r\n }\r\n dd.off(el, 'drag');\r\n // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)\r\n // as the helper will be nuked by jquery-ui otherwise\r\n if (helper !== el) {\r\n helper.remove();\r\n el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info\r\n if (wasAdded) {\r\n el = el.cloneNode(true) as GridItemHTMLElement;\r\n }\r\n } else {\r\n el.remove(); // reduce flicker as we change depth here, and size further down\r\n this._removeDD(el);\r\n }\r\n if (!wasAdded) return false;\r\n el.gridstackNode = node;\r\n node.el = el;\r\n // @ts-ignore\r\n Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578\r\n Utils.removePositioningStyles(el);// @ts-ignore\r\n this._writeAttr(el, node);\r\n this.el.appendChild(el);// @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)\r\n this._updateContainerHeight();\r\n this.engine.addedNodes.push(node);// @ts-ignore\r\n this._triggerAddEvent();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n if (this._gsEventHandler['dropped']) {\r\n this._gsEventHandler['dropped']({...event, type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);\r\n }\r\n\r\n // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up\r\n window.setTimeout(() => {\r\n // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())\r\n if (node.el && node.el.parentElement) {\r\n this._prepareDragDropByNode(node);\r\n } else {\r\n this.engine.removeNode(node);\r\n }\r\n });\r\n\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n });\r\n return this;\r\n}\r\n\r\n/** @internal mark item for removal */\r\nfunction _itemRemoving(el: GridItemHTMLElement, remove: boolean) {\r\n let node = el ? el.gridstackNode : undefined;\r\n if (!node || !node.grid) return;\r\n remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;\r\n remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');\r\n}\r\n\r\n/** @internal called to setup a trash drop zone if the user specifies it */\r\nGridStack.prototype._setupRemoveDrop = function(this: GridStack): GridStack {\r\n if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {\r\n let trashEl = document.querySelector(this.opts.removable) as HTMLElement;\r\n if (!trashEl) return this;\r\n // only register ONE drop-over/dropout callback for the 'trash', and it will\r\n // update the passed in item and parent grid because the 'trash' is a shared resource anyway,\r\n // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)\r\n if (!dd.isDroppable(trashEl)) {\r\n dd.droppable(trashEl, this.opts.removableOptions)\r\n .on(trashEl, 'dropover', (event, el) => _itemRemoving(el, true))\r\n .on(trashEl, 'dropout', (event, el) => _itemRemoving(el, false));\r\n }\r\n }\r\n return this;\r\n}\r\n\r\n/**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n **/\r\nGridStack.setupDragIn = function(this: GridStack, _dragIn?: string, _dragInOptions?: DDDragInOpt) {\r\n let dragIn: string;\r\n let dragInOptions: DDDragInOpt;\r\n const dragInDefaultOptions: DDDragInOpt = {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body',\r\n // revert: 'invalid',\r\n // scroll: false,\r\n };\r\n\r\n // cache in the passed in values (form grid init?) so they don't have to resend them each time\r\n if (_dragIn) {\r\n dragIn = _dragIn;\r\n dragInOptions = {...dragInDefaultOptions, ...(_dragInOptions || {})};\r\n }\r\n if (typeof dragIn !== 'string') return;\r\n Utils.getElements(dragIn).forEach(el => {\r\n if (!dd.isDraggable(el)) dd.dragIn(el, dragInOptions);\r\n });\r\n}\r\n\r\n/** @internal prepares the element for drag&drop **/\r\nGridStack.prototype._prepareDragDropByNode = function(this: GridStack, node: GridStackNode): GridStack {\r\n let el = node.el;\r\n const noMove = node.noMove || this.opts.disableDrag;\r\n const noResize = node.noResize || this.opts.disableResize;\r\n\r\n // check for disabled grid first\r\n if (this.opts.staticGrid || (noMove && noResize)) {\r\n if (node._initDD) {\r\n this._removeDD(el); // nukes everything instead of just disable, will add some styles back next\r\n delete node._initDD;\r\n }\r\n el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435\r\n return this;\r\n }\r\n\r\n if (!node._initDD) {\r\n // variables used/cashed between the 3 start/move/end methods, in addition to node passed above\r\n let cellWidth: number;\r\n let cellHeight: number;\r\n\r\n /** called when item starts moving/resizing */\r\n let onStartMoving = (event: Event, ui: DDUIData) => {\r\n // trigger any 'dragstart' / 'resizestart' manually\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, event.target);\r\n }\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true); // force pixels for calculations\r\n\r\n this._onStartMoving(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when item is being dragged/resized */\r\n let dragOrResize = (event: Event, ui: DDUIData) => {\r\n this._dragOrResize(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when the item stops moving/resizing */\r\n let onEndMoving = (event: Event) => {\r\n this.placeholder.remove();\r\n delete node._moving;\r\n delete node._lastTried;\r\n\r\n // if the item has moved to another grid, we're done here\r\n let target: GridItemHTMLElement = event.target as GridItemHTMLElement;\r\n if (!target.gridstackNode || target.gridstackNode.grid !== this) return;\r\n\r\n node.el = target;\r\n\r\n if (node._isAboutToRemove) {\r\n let gridToNotify = el.gridstackNode.grid;\r\n if (gridToNotify._gsEventHandler[event.type]) {\r\n gridToNotify._gsEventHandler[event.type](event, target);\r\n }\r\n this._removeDD(el);\r\n gridToNotify.engine.removedNodes.push(node);\r\n gridToNotify._triggerRemoveEvent();\r\n // break circular links and remove DOM\r\n delete el.gridstackNode;\r\n delete node.el;\r\n el.remove();\r\n } else {\r\n Utils.removePositioningStyles(target);\r\n if (node._temporaryRemoved) {\r\n // got removed - restore item back to before dragging position\r\n Utils.copyPos(node, node._orig);// @ts-ignore\r\n this._writePosAttr(target, node);\r\n this.engine.addNode(node);\r\n } else {\r\n // move to new placeholder location\r\n this._writePosAttr(target, node);\r\n }\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n // @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n }\r\n\r\n dd.draggable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n drag: dragOrResize\r\n }).resizable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n resize: dragOrResize\r\n });\r\n node._initDD = true; // we've set DD support now\r\n }\r\n\r\n // finally fine tune move vs resize by disabling any part...\r\n dd.draggable(el, noMove ? 'disable' : 'enable')\r\n .resizable(el, noResize ? 'disable' : 'enable');\r\n\r\n return this;\r\n}\r\n\r\n/** @internal called when item is starting a drag/resize */\r\nGridStack.prototype._onStartMoving = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(node);\r\n // @ts-ignore\r\n this._writePosAttr(this.placeholder, node)\r\n this.el.appendChild(this.placeholder);\r\n // console.log('_onStartMoving placeholder') // TEST\r\n\r\n node.el = this.placeholder;\r\n node._lastUiPosition = ui.position;\r\n node._prevYPix = ui.position.top;\r\n node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)\r\n delete node._lastTried;\r\n\r\n if (event.type === 'dropover' && node._temporaryRemoved) {\r\n // console.log('engine.addNode x=' + node.x); // TEST\r\n this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved\r\n node._moving = true; // AFTER, mark as moving object (wanted fix location before)\r\n }\r\n\r\n // set the min/max resize info\r\n this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop as number, this.opts.marginRight as number, this.opts.marginBottom as number, this.opts.marginLeft as number);\r\n if (event.type === 'resizestart') {\r\n dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))\r\n .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));\r\n if (node.maxW) { dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); }\r\n if (node.maxH) { dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); }\r\n }\r\n}\r\n\r\n/** @internal called when item leaving our area by either cursor dropout event\r\n * or shape is outside our boundaries. remove it from us, and mark temporary if this was\r\n * our item to start with else restore prev node values from prev grid it came from.\r\n **/\r\nGridStack.prototype._leave = function(this: GridStack, el: GridItemHTMLElement, helper?: GridItemHTMLElement) {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n dd.off(el, 'drag'); // no need to track while being outside\r\n\r\n // this gets called when cursor leaves and shape is outside, so only do this once\r\n if (node._temporaryRemoved) return;\r\n node._temporaryRemoved = true;\r\n\r\n this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue\r\n node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged\r\n\r\n if (this.opts.removable === true) { // boolean vs a class string\r\n // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so\r\n _itemRemoving(el, true);\r\n }\r\n\r\n // finally if item originally came from another grid, but left us, restore things back to prev info\r\n if (el._gridstackNodeOrig) {\r\n // console.log('leave delete _gridstackNodeOrig') // TEST\r\n el.gridstackNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n } else if (node._isExternal) {\r\n // item came from outside (like a toolbar) so nuke any node info\r\n delete node.el;\r\n delete el.gridstackNode;\r\n // and restore all nodes back to original\r\n this.engine.restoreInitial();\r\n }\r\n}\r\n\r\n/** @internal called when item is being dragged/resized */\r\nGridStack.prototype._dragOrResize = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n let p = {...node._orig}; // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value)\r\n let resizing: boolean;\r\n let mLeft = this.opts.marginLeft as number,\r\n mRight = this.opts.marginRight as number,\r\n mTop = this.opts.marginTop as number,\r\n mBottom = this.opts.marginBottom as number;\r\n\r\n // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855\r\n let mHeight = Math.round(cellHeight * 0.1),\r\n mWidth = Math.round(cellWidth * 0.1);\r\n mLeft = Math.min(mLeft, mWidth);\r\n mRight = Math.min(mRight, mWidth);\r\n mTop = Math.min(mTop, mHeight);\r\n mBottom = Math.min(mBottom, mHeight);\r\n\r\n if (event.type === 'drag') {\r\n if (node._temporaryRemoved) return; // handled by dropover\r\n let distance = ui.position.top - node._prevYPix;\r\n node._prevYPix = ui.position.top;\r\n Utils.updateScrollPosition(el, ui.position, distance);\r\n\r\n // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)\r\n let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);\r\n let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others\r\n let prev = this._extraDragRow;\r\n if (this.engine.collide(node, p)) {\r\n let row = this.getRow();\r\n let extra = Math.max(0, (p.y + node.h) - row);\r\n if (this.opts.maxRow && row + extra > this.opts.maxRow) {\r\n extra = Math.max(0, this.opts.maxRow - row);\r\n }// @ts-ignore\r\n this._extraDragRow = extra;// @ts-ignore\r\n } else this._extraDragRow = 0;// @ts-ignore\r\n if (this._extraDragRow !== prev) this._updateContainerHeight();\r\n\r\n if (node.x === p.x && node.y === p.y) return; // skip same\r\n // DON'T skip one we tried as we might have failed because of coverage <50% before\r\n // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;\r\n } else if (event.type === 'resize') {\r\n if (p.x < 0) return;\r\n // Scrolling page if needed\r\n Utils.updateScrollResize(event as MouseEvent, el, cellHeight);\r\n\r\n // get new size\r\n p.w = Math.round((ui.size.width - mLeft) / cellWidth);\r\n p.h = Math.round((ui.size.height - mTop) / cellHeight);\r\n if (node.w === p.w && node.h === p.h) return;\r\n if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) return; // skip one we tried (but failed)\r\n\r\n // if we size on left/top side this might move us, so get possible new position as well\r\n let left = ui.position.left + mLeft;\r\n let top = ui.position.top + mTop;\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n resizing = true;\r\n }\r\n\r\n node._lastTried = p; // set as last tried (will nuke if we go there)\r\n let rect: GridStackPosition = { // screen pix of the dragged box\r\n x: ui.position.left + mLeft,\r\n y: ui.position.top + mTop,\r\n w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,\r\n h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom\r\n };\r\n if (this.engine.moveNodeCheck(node, {...p, cellWidth, cellHeight, rect, resizing})) {\r\n node._lastUiPosition = ui.position;\r\n this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);\r\n delete node._skipDown;\r\n if (resizing && node.subGrid) { (node.subGrid as GridStack).onParentResize(); }// @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();\r\n\r\n let target = event.target as GridItemHTMLElement;// @ts-ignore\r\n this._writePosAttr(target, node);\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Enables/Disables moving.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\nGridStack.prototype.movable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noMove; else node.noMove = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Enables/Disables resizing.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\nGridStack.prototype.resizable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't resize a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noResize; else node.noResize = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\nGridStack.prototype.disable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(false);\r\n this.enableResize(false);// @ts-ignore\r\n this._triggerEvent('disable');\r\n return this;\r\n}\r\n\r\n/**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\nGridStack.prototype.enable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(true);\r\n this.enableResize(true);// @ts-ignore\r\n this._triggerEvent('enable');\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget moving. No-op for static grids. */\r\nGridStack.prototype.enableMove = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.movable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget resizing. No-op for static grids. */\r\nGridStack.prototype.enableResize = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't size a static grid!\r\n this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.resizable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** removes any drag&drop present (called during destroy) */\r\nGridStack.prototype._removeDD = function(this: GridStack, el: GridItemHTMLElement): GridStack {\r\n dd.draggable(el, 'destroy').resizable(el, 'destroy');\r\n if (el.gridstackNode) {\r\n delete el.gridstackNode._initDD; // reset our DD init flag\r\n }\r\n return this;\r\n}\r\n\r\n","/**\n * dd-manager.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDDroppable } from './dd-droppable';\nimport { DDResizable } from './dd-resizable';\n\n/**\n * globals that are shared across Drag & Drop instances\n */\nexport class DDManager {\n /** true if a mouse down event was handled */\n public static mouseHandled: boolean;\n\n /** item being dragged */\n public static dragElement: DDDraggable;\n\n /** item we are currently over as drop target */\n public static dropElement: DDDroppable;\n\n /** current item we're over for resizing purpose (ignore nested grid resize handles) */\n public static overResizeElement: DDResizable;\n\n}\n","/**\n * dd-resizable-handle.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { isTouch, pointerdown, touchend, touchmove, touchstart } from './dd-touch';\n\nexport interface DDResizableHandleOpt {\n start?: (event) => void;\n move?: (event) => void;\n stop?: (event) => void;\n}\n\nexport class DDResizableHandle {\n /** @internal */\n protected el: HTMLElement;\n /** @internal */\n protected host: HTMLElement;\n /** @internal */\n protected option: DDResizableHandleOpt;\n /** @internal */\n protected dir: string;\n /** @internal true after we've moved enough pixels to start a resize */\n protected moving = false;\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected static prefix = 'ui-resizable-';\n\n constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt) {\n this.host = host;\n this.dir = direction;\n this.option = option;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n\n this._init();\n }\n\n /** @internal */\n protected _init(): DDResizableHandle {\n const el = document.createElement('div');\n el.classList.add('ui-resizable-handle');\n el.classList.add(`${DDResizableHandle.prefix}${this.dir}`);\n el.style.zIndex = '100';\n el.style.userSelect = 'none';\n this.el = el;\n this.host.appendChild(this.el);\n this.el.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.addEventListener('touchstart', touchstart);\n this.el.addEventListener('pointerdown', pointerdown);\n // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n return this;\n }\n\n /** call this when resize handle needs to be removed and cleaned up */\n public destroy(): DDResizableHandle {\n if (this.moving) this._mouseUp(this.mouseDownEvent);\n this.el.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.removeEventListener('touchstart', touchstart);\n this.el.removeEventListener('pointerdown', pointerdown);\n }\n this.host.removeChild(this.el);\n delete this.el;\n delete this.host;\n return this;\n }\n\n /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */\n protected _mouseDown(e: MouseEvent) {\n this.mouseDownEvent = e;\n document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.addEventListener('touchmove', touchmove);\n this.el.addEventListener('touchend', touchend);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseMove(e: MouseEvent) {\n let s = this.mouseDownEvent;\n if (this.moving) {\n this._triggerEvent('move', e);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) {\n // don't start unless we've moved at least 3 pixels\n this.moving = true;\n this._triggerEvent('start', this.mouseDownEvent);\n this._triggerEvent('move', e);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseUp(e: MouseEvent) {\n if (this.moving) {\n this._triggerEvent('stop', e);\n }\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.removeEventListener('touchmove', touchmove);\n this.el.removeEventListener('touchend', touchend);\n }\n delete this.moving;\n delete this.mouseDownEvent;\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _triggerEvent(name: string, event: MouseEvent): DDResizableHandle {\n if (this.option[name]) this.option[name](event);\n return this;\n }\n}\n","/**\n * dd-resizable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizableHandle } from './dd-resizable-handle';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDUIData, Rect, Size } from './types';\nimport { DDManager } from './dd-manager';\n\n// import { GridItemHTMLElement } from './types'; let count = 0; // TEST\n\n// TODO: merge with DDDragOpt\nexport interface DDResizableOpt {\n autoHide?: boolean;\n handles?: string;\n maxHeight?: number;\n maxWidth?: number;\n minHeight?: number;\n minWidth?: number;\n fixedAspectRatio?: number;\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n resize?: (event: Event, ui: DDUIData) => void;\n}\n\nexport class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n // have to be public else complains for HTMLElementExtendOpt ?\n public el: HTMLElement;\n public option: DDResizableOpt;\n\n /** @internal */\n protected handlers: DDResizableHandle[];\n /** @internal */\n protected originalRect: Rect;\n /** @internal */\n protected temporalRect: Rect;\n /** @internal */\n protected scrollY: number;\n /** @internal */\n protected scrolled: number;\n /** @internal */\n protected scrollEl: HTMLElement;\n /** @internal */\n protected startEvent: MouseEvent;\n /** @internal value saved in the same order as _originStyleProp[] */\n protected elOriginStyleVal: string[];\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected static _originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex'];\n\n constructor(el: HTMLElement, opts: DDResizableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseOver = this._mouseOver.bind(this);\n this._mouseOut = this._mouseOut.bind(this);\n this.enable();\n this._setupAutoHide(this.option.autoHide);\n this._setupHandlers();\n }\n\n public on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'resizestart' | 'resize' | 'resizestop'): void {\n super.off(event);\n }\n\n public enable(): void {\n super.enable();\n this.el.classList.add('ui-resizable');\n this.el.classList.remove('ui-resizable-disabled');\n this._setupAutoHide(this.option.autoHide);\n }\n\n public disable(): void {\n super.disable();\n this.el.classList.add('ui-resizable-disabled');\n this.el.classList.remove('ui-resizable');\n this._setupAutoHide(false);\n }\n\n public destroy(): void {\n this._removeHandlers();\n this._setupAutoHide(false);\n this.el.classList.remove('ui-resizable');\n delete this.el;\n super.destroy();\n }\n\n public updateOption(opts: DDResizableOpt): DDResizable {\n let updateHandles = (opts.handles && opts.handles !== this.option.handles);\n let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide);\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n if (updateHandles) {\n this._removeHandlers();\n this._setupHandlers();\n }\n if (updateAutoHide) {\n this._setupAutoHide(this.option.autoHide);\n }\n return this;\n }\n\n /** @internal turns auto hide on/off */\n protected _setupAutoHide(auto: boolean): DDResizable {\n if (auto) {\n this.el.classList.add('ui-resizable-autohide');\n // use mouseover and not mouseenter to get better performance and track for nested cases\n this.el.addEventListener('mouseover', this._mouseOver);\n this.el.addEventListener('mouseout', this._mouseOut);\n } else {\n this.el.classList.remove('ui-resizable-autohide');\n this.el.removeEventListener('mouseover', this._mouseOver);\n this.el.removeEventListener('mouseout', this._mouseOut);\n if (DDManager.overResizeElement === this) {\n delete DDManager.overResizeElement;\n } \n }\n return this;\n }\n\n /** @internal */\n protected _mouseOver(e: Event) {\n // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018\n if (DDManager.overResizeElement || DDManager.dragElement) return;\n DDManager.overResizeElement = this;\n // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.remove('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _mouseOut(e: Event) {\n // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n if (DDManager.overResizeElement !== this) return;\n delete DDManager.overResizeElement;\n // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.add('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _setupHandlers(): DDResizable {\n let handlerDirection = this.option.handles || 'e,s,se';\n if (handlerDirection === 'all') {\n handlerDirection = 'n,e,s,w,se,sw,ne,nw';\n }\n this.handlers = handlerDirection.split(',')\n .map(dir => dir.trim())\n .map(dir => new DDResizableHandle(this.el, dir, {\n start: (event: MouseEvent) => {\n this._resizeStart(event);\n },\n stop: (event: MouseEvent) => {\n this._resizeStop(event);\n },\n move: (event: MouseEvent) => {\n this._resizing(event, dir);\n }\n }));\n return this;\n }\n\n /** @internal */\n protected _resizeStart(event: MouseEvent): DDResizable {\n this.originalRect = this.el.getBoundingClientRect();\n this.scrollEl = Utils.getScrollElement(this.el);\n this.scrollY = this.scrollEl.scrollTop;\n this.scrolled = 0;\n this.startEvent = event;\n this._setupHelper();\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el });\n if (this.option.start) {\n this.option.start(ev, this._ui());\n }\n this.el.classList.add('ui-resizable-resizing');\n this.triggerEvent('resizestart', ev);\n return this;\n }\n\n /** @internal */\n protected _resizing(event: MouseEvent, dir: string): DDResizable {\n this.scrolled = this.scrollEl.scrollTop - this.scrollY;\n this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio);\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resize', target: this.el });\n if (this.option.resize) {\n this.option.resize(ev, this._ui());\n }\n this.triggerEvent('resize', ev);\n return this;\n }\n\n /** @internal */\n protected _resizeStop(event: MouseEvent): DDResizable {\n const ev = Utils.initEvent(event, { type: 'resizestop', target: this.el });\n if (this.option.stop) {\n this.option.stop(ev); // Note: ui() not used by gridstack so don't pass\n }\n this.el.classList.remove('ui-resizable-resizing');\n this.triggerEvent('resizestop', ev);\n this._cleanHelper();\n delete this.startEvent;\n delete this.originalRect;\n delete this.temporalRect;\n delete this.scrollY;\n delete this.scrolled;\n return this;\n }\n\n /** @internal */\n protected _setupHelper(): DDResizable {\n this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);\n this.parentOriginStylePosition = this.el.parentElement.style.position;\n if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) {\n this.el.parentElement.style.position = 'relative';\n }\n this.el.style.position = 'absolute';\n this.el.style.opacity = '0.8';\n return this;\n }\n\n /** @internal */\n protected _cleanHelper(): DDResizable {\n DDResizable._originStyleProp.forEach((prop, i) => {\n this.el.style[prop] = this.elOriginStyleVal[i] || null;\n });\n this.el.parentElement.style.position = this.parentOriginStylePosition || null;\n return this;\n }\n\n /** @internal */\n protected _getChange(event: MouseEvent, dir: string, fixedAspectRatio?: number): Rect {\n const fixedAspect = typeof(fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio);\n const oEvent = this.startEvent;\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled),\n left: this.originalRect.left,\n top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled)\n };\n\n const offsetX = event.clientX - oEvent.clientX;\n const offsetY = event.clientY - oEvent.clientY;\n\n if (fixedAspect)\n {\n // If the window is being resized using the corner\n if (dir.length > 1) {\n\n if (offsetX > offsetY) {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n } else {\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n \n\n\n } else {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n }\n else\n {\n if (dir.indexOf('e') > -1) { // East\n newRect.width += offsetX;\n } else if (dir.indexOf('w') > -1) { // West\n newRect.width -= offsetX;\n newRect.left += offsetX;\n }\n\n if (dir.indexOf('s') > -1) { // South // HERE\n newRect.height += offsetY;\n } else if (dir.indexOf('n') > -1) { // North\n newRect.height -= offsetY;\n newRect.top += offsetY\n }\n }\n\n const constrain = this._constrainSize(newRect.width, newRect.height);\n if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors\n if (dir.indexOf('w') > -1) {\n newRect.left += newRect.width - constrain.width;\n }\n newRect.width = constrain.width;\n }\n if (Math.round(newRect.height) !== Math.round(constrain.height)) {\n if (dir.indexOf('n') > -1) {\n newRect.top += newRect.height - constrain.height;\n }\n newRect.height = constrain.height;\n }\n return newRect;\n }\n\n /** @internal constrain the size to the set min/max values */\n protected _constrainSize(oWidth: number, oHeight: number): Size {\n const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;\n const minWidth = this.option.minWidth || oWidth;\n const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;\n const minHeight = this.option.minHeight || oHeight;\n const width = Math.min(maxWidth, Math.max(minWidth, oWidth));\n const height = Math.min(maxHeight, Math.max(minHeight, oHeight));\n return { width, height };\n }\n\n /** @internal */\n protected _applyChange(): DDResizable {\n let containmentRect = { left: 0, top: 0, width: 0, height: 0 };\n if (this.el.style.position === 'absolute') {\n const containmentEl = this.el.parentElement;\n const { left, top } = containmentEl.getBoundingClientRect();\n containmentRect = { left, top, width: 0, height: 0 };\n }\n if (!this.temporalRect) return this;\n Object.keys(this.temporalRect).forEach(key => {\n const value = this.temporalRect[key];\n this.el.style[key] = value - containmentRect[key] + 'px';\n });\n return this;\n }\n\n /** @internal */\n protected _removeHandlers(): DDResizable {\n this.handlers.forEach(handle => handle.destroy());\n delete this.handlers;\n return this;\n }\n\n /** @internal */\n protected _ui = (): DDUIData => {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const rect = this.temporalRect || newRect;\n return {\n position: {\n left: rect.left - containmentRect.left,\n top: rect.top - containmentRect.top\n },\n size: {\n width: rect.width,\n height: rect.height\n }\n /* Gridstack ONLY needs position set above... keep around in case.\n element: [this.el], // The object representing the element to be resized\n helper: [], // TODO: not support yet - The object representing the helper that's being resized\n originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped\n originalPosition: { // The position represented as { left, top } before the resizable is resized\n left: this.originalRect.left - containmentRect.left,\n top: this.originalRect.top - containmentRect.top\n },\n originalSize: { // The size represented as { width, height } before the resizable is resized\n width: this.originalRect.width,\n height: this.originalRect.height\n }\n */\n };\n }\n}\n","/**\n * touch.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\n\n/**\n * Detect touch support - Windows Surface devices and other touch devices\n * should we use this instead ? (what we had for always showing resize handles)\n * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n */\nexport const isTouch: boolean = ( 'ontouchstart' in document\n || 'ontouchstart' in window\n // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this\n || ((window as any).DocumentTouch && document instanceof (window as any).DocumentTouch)\n || navigator.maxTouchPoints > 0\n || (navigator as any).msMaxTouchPoints > 0\n);\n\n// interface TouchCoord {x: number, y: number};\n\nclass DDTouch {\n public static touchHandled: boolean;\n public static pointerLeaveTimeout: number;\n}\n\n/**\n* Get the x,y position of a touch event\n*/\n// function getTouchCoords(e: TouchEvent): TouchCoord {\n// return {\n// x: e.changedTouches[0].pageX,\n// y: e.changedTouches[0].pageY\n// };\n// }\n\n/**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} e A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulateMouseEvent(e: TouchEvent, simulatedType: string) {\n\n // Ignore multi-touch events\n if (e.touches.length > 1) return;\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n/**\n * Simulate a mouse event based on a corresponding Pointer event\n * @param {Object} e A pointer event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulatePointerMouseEvent(e: PointerEvent, simulatedType: string) {\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n\n/**\n * Handle the touchstart events\n * @param {Object} e The widget element's touchstart event\n */\nexport function touchstart(e: TouchEvent) {\n // Ignore the event if another widget is already being handled\n if (DDTouch.touchHandled) return; DDTouch.touchHandled = true;\n\n // Simulate the mouse events\n // simulateMouseEvent(e, 'mouseover');\n // simulateMouseEvent(e, 'mousemove');\n simulateMouseEvent(e, 'mousedown');\n}\n\n/**\n * Handle the touchmove events\n * @param {Object} e The document's touchmove event\n */\nexport function touchmove(e: TouchEvent) {\n // Ignore event if not handled by us\n if (!DDTouch.touchHandled) return;\n\n simulateMouseEvent(e, 'mousemove');\n}\n\n/**\n * Handle the touchend events\n * @param {Object} e The document's touchend event\n */\nexport function touchend(e: TouchEvent) {\n\n // Ignore event if not handled\n if (!DDTouch.touchHandled) return;\n\n // cancel delayed leave event when we release on ourself which happens BEFORE we get this!\n if (DDTouch.pointerLeaveTimeout) {\n window.clearTimeout(DDTouch.pointerLeaveTimeout);\n delete DDTouch.pointerLeaveTimeout;\n }\n\n const wasDragging = !!DDManager.dragElement;\n\n // Simulate the mouseup event\n simulateMouseEvent(e, 'mouseup');\n // simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click\n if (!wasDragging) {\n simulateMouseEvent(e, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event\n DDTouch.touchHandled = false;\n}\n\n/**\n * Note we don't get touchenter/touchleave (which are deprecated)\n * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter\n * so instead of PointerEvent to still get enter/leave and send the matching mouse event.\n */\nexport function pointerdown(e: PointerEvent) {\n (e.target as HTMLElement).releasePointerCapture(e.pointerId) // <- Important!\n}\n\nexport function pointerenter(e: PointerEvent) {\n // ignore the initial one we get on pointerdown on ourself\n if (!DDManager.dragElement) {\n // console.log('pointerenter ignored');\n return;\n }\n // console.log('pointerenter');\n simulatePointerMouseEvent(e, 'mouseenter');\n}\n\nexport function pointerleave(e: PointerEvent) {\n // ignore the leave on ourself we get before releasing the mouse over ourself\n // by delaying sending the event and having the up event cancel us\n if (!DDManager.dragElement) {\n // console.log('pointerleave ignored');\n return;\n }\n DDTouch.pointerLeaveTimeout = window.setTimeout(() => {\n delete DDTouch.pointerLeaveTimeout;\n // console.log('pointerleave delayed');\n simulatePointerMouseEvent(e, 'mouseleave');\n }, 10);\n}\n\n","/**\n * gridstack-engine.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { Utils } from './utils';\nimport { GridStackNode, ColumnOptions, GridStackPosition, GridStackMoveOpts } from './types';\n\n/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */\ntype OnChangeCB = (nodes: GridStackNode[]) => void;\n\n/** options used during creation - similar to GridStackOptions */\nexport interface GridStackEngineOptions {\n column?: number;\n maxRow?: number;\n float?: boolean;\n nodes?: GridStackNode[];\n onChange?: OnChangeCB;\n}\n\n/**\n * Defines the GridStack engine that does most no DOM grid manipulation.\n * See GridStack methods and vars for descriptions.\n *\n * NOTE: values should not be modified directly - call the main GridStack API instead\n */\nexport class GridStackEngine {\n public column: number;\n public maxRow: number;\n public nodes: GridStackNode[];\n public addedNodes: GridStackNode[] = [];\n public removedNodes: GridStackNode[] = [];\n public batchMode: boolean;\n /** @internal callback to update the DOM attributes */\n protected onChange: OnChangeCB;\n /** @internal */\n protected _float: boolean;\n /** @internal */\n protected _prevFloat: boolean;\n /** @internal cached layouts of difference column count so we can restore ack (eg 12 -> 1 -> 12) */\n protected _layouts?: GridStackNode[][]; // maps column # to array of values nodes\n /** @internal true while we are resizing widgets during column resize to skip certain parts */\n protected _inColumnResize: boolean;\n /** @internal true if we have some items locked */\n protected _hasLocked: boolean;\n /** @internal unique global internal _id counter NOT starting at 0 */\n protected static _idSeq = 1;\n\n public constructor(opts: GridStackEngineOptions = {}) {\n this.column = opts.column || 12;\n this.maxRow = opts.maxRow;\n this._float = opts.float;\n this.nodes = opts.nodes || [];\n this.onChange = opts.onChange;\n }\n\n public batchUpdate(flag = true): GridStackEngine {\n if (!!this.batchMode === flag) return this;\n this.batchMode = flag;\n if (flag) {\n this._prevFloat = this._float;\n this._float = true; // let things go anywhere for now... will restore and possibly reposition later\n this.saveInitial(); // since begin update (which is called multiple times) won't do this\n } else {\n this._float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes()._notify();\n }\n return this;\n }\n\n // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip\n protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean {\n return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y);\n }\n\n /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.\n * return true if we moved. */\n protected _fixCollisions(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {}): boolean {\n this.sortNodes(-1); // from last to first, so recursive collision move items in the right order\n\n collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none...\n if (!collide) return false;\n\n // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size\n if (node._moving && !opt.nested && !this.float) {\n if (this.swap(node, collide)) return true;\n }\n\n // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)\n let area = nn;\n if (this._useEntireRowArea(node, nn)) {\n area = {x: 0, w: this.column, y: nn.y, h: nn.h};\n collide = this.collide(node, area, opt.skip); // force new hit\n }\n\n let didMove = false;\n let newOpt: GridStackMoveOpts = {nested: true, pack: false};\n while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each\n let moved: boolean;\n // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,\n // but remember that skip down so we only do this once (and push others otherwise).\n if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&\n // can take space we had, or before where we're going\n (!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {\n node._skipDown = (node._skipDown || nn.y > node.y);\n moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});\n if (collide.locked && moved) {\n Utils.copyPos(nn, node); // moving after lock become our new desired location\n } else if (!collide.locked && moved && opt.pack) {\n // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way\n this._packNodes();\n nn.y = collide.y + collide.h;\n Utils.copyPos(node, nn);\n }\n didMove = didMove || moved;\n } else {\n // move collide down *after* where we will be, ignoring where we are now (don't collide with us)\n moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt});\n }\n if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)\n collide = undefined;\n }\n return didMove;\n }\n\n /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */\n public collide(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode {\n return this.nodes.find(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n public collideAll(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode[] {\n return this.nodes.filter(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n\n /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */\n public collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode {\n if (!o.rect || !node._rect) return;\n let r0 = node._rect; // where started\n let r = {...o.rect}; // where we are\n\n // update dragged rect to show where it's coming from (above or below, etc...)\n if (r.y > r0.y) {\n r.h += r.y - r0.y;\n r.y = r0.y;\n } else {\n r.h += r0.y - r.y;\n }\n if (r.x > r0.x) {\n r.w += r.x - r0.x;\n r.x = r0.x;\n } else {\n r.w += r0.x - r.x;\n }\n\n let collide: GridStackNode;\n collides.forEach(n => {\n if (n.locked || !n._rect) return;\n let r2 = n._rect; // overlapping target\n let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50%\n // depending on which side we started from, compute the overlap % of coverage\n // (ex: from above/below we only compute the max horizontal line coverage)\n if (r0.y < r2.y) { // from above\n yOver = ((r.y + r.h) - r2.y) / r2.h;\n } else if (r0.y+r0.h > r2.y+r2.h) { // from below\n yOver = ((r2.y + r2.h) - r.y) / r2.h;\n }\n if (r0.x < r2.x) { // from the left\n xOver = ((r.x + r.w) - r2.x) / r2.w;\n } else if (r0.x+r0.w > r2.x+r2.w) { // from the right\n xOver = ((r2.x + r2.w) - r.x) / r2.w;\n }\n let over = Math.min(xOver, yOver);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n return collide;\n }\n\n /** called to cache the nodes pixel rectangles used for collision detection during drag */\n public cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine\n {\n this.nodes.forEach(n =>\n n._rect = {\n y: n.y * h + top,\n x: n.x * w + left,\n w: n.w * w - left - right,\n h: n.h * h - top - bottom\n }\n );\n return this;\n }\n\n /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */\n public swap(a: GridStackNode, b: GridStackNode): boolean {\n if (!b || b.locked || !a || a.locked) return false;\n\n function _doSwap(): true { // assumes a is before b IFF they have different height (put after rather than exact swap)\n let x = b.x, y = b.y;\n b.x = a.x; b.y = a.y; // b -> a position\n if (a.h != b.h) {\n a.x = x; a.y = b.y + b.h; // a -> goes after b\n } else if (a.w != b.w) {\n a.x = b.x + b.w; a.y = y; // a -> goes after b\n } else {\n a.x = x; a.y = y; // a -> old b position\n }\n a._dirty = b._dirty = true;\n return true;\n }\n let touching: boolean; // remember if we called it (vs undefined)\n\n // same size and same row or column, and touching\n if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = Utils.isTouching(a, b)))\n return _doSwap();\n if (touching === false) return; // IFF ran test and fail, bail out\n\n // check for taking same columns (but different height) and touching\n if (a.w === b.w && a.x === b.x && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.y < a.y) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n if (touching === false) return;\n\n // check if taking same row (but different width) and touching\n if (a.h === b.h && a.y === b.y && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.x < a.x) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n return false;\n }\n\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\n let nn: GridStackNode = {x: x || 0, y: y || 0, w: w || 1, h: h || 1};\n return !this.collide(nn);\n }\n\n /** re-layout grid items to reclaim any empty space */\n public compact(): GridStackEngine {\n if (this.nodes.length === 0) return this;\n this.batchUpdate()\n .sortNodes();\n let copyNodes = this.nodes;\n this.nodes = []; // pretend we have no nodes to conflict layout to start with...\n copyNodes.forEach(node => {\n if (!node.locked) {\n node.autoPosition = true;\n }\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // will force attr update\n });\n return this.batchUpdate(false);\n }\n\n /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */\n public set float(val: boolean) {\n if (this._float === val) return;\n this._float = val || false;\n if (!val) {\n this._packNodes()._notify();\n }\n }\n\n /** float getter method */\n public get float(): boolean { return this._float || false; }\n\n /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */\n public sortNodes(dir?: -1 | 1): GridStackEngine {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n return this;\n }\n\n /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */\n protected _packNodes(): GridStackEngine {\n if (this.batchMode) { return this; }\n this.sortNodes(); // first to last\n\n if (this.float) {\n // restore original Y pos\n this.nodes.forEach(n => {\n if (n._updating || n._orig === undefined || n.y === n._orig.y) return;\n let newY = n.y;\n while (newY > n._orig.y) {\n --newY;\n let collide = this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!collide) {\n n._dirty = true;\n n.y = newY;\n }\n }\n });\n } else {\n // top gravity pack\n this.nodes.forEach((n, i) => {\n if (n.locked) return;\n while (n.y > 0) {\n let newY = i === 0 ? 0 : n.y - 1;\n let canBeMoved = i === 0 || !this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!canBeMoved) break;\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n });\n }\n return this;\n }\n\n /**\n * given a random node, makes sure it's coordinates/values are valid in the current grid\n * @param node to adjust\n * @param resizing if out of bound, resize down or move into the grid to fit ?\n */\n public prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode {\n node = node || {};\n node._id = node._id || GridStackEngine._idSeq++;\n\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n\n // assign defaults for missing required fields\n let defaults: GridStackNode = { x: 0, y: 0, w: 1, h: 1};\n Utils.defaults(node, defaults);\n\n if (!node.autoPosition) { delete node.autoPosition; }\n if (!node.noResize) { delete node.noResize; }\n if (!node.noMove) { delete node.noMove; }\n\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (typeof node.x == 'string') { node.x = Number(node.x); }\n if (typeof node.y == 'string') { node.y = Number(node.y); }\n if (typeof node.w == 'string') { node.w = Number(node.w); }\n if (typeof node.h == 'string') { node.h = Number(node.h); }\n if (isNaN(node.x)) { node.x = defaults.x; node.autoPosition = true; }\n if (isNaN(node.y)) { node.y = defaults.y; node.autoPosition = true; }\n if (isNaN(node.w)) { node.w = defaults.w; }\n if (isNaN(node.h)) { node.h = defaults.h; }\n\n return this.nodeBoundFix(node, resizing);\n }\n\n /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */\n public nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode {\n\n let before = node._orig || Utils.copyPos({}, node);\n\n if (node.maxW) { node.w = Math.min(node.w, node.maxW); }\n if (node.maxH) { node.h = Math.min(node.h, node.maxH); }\n if (node.minW && node.minW <= this.column) { node.w = Math.max(node.w, node.minW); }\n if (node.minH) { node.h = Math.max(node.h, node.minH); }\n\n if (node.w > this.column) {\n // if user loaded a larger than allowed widget for current # of columns,\n // remember it's full width so we can restore back (1 -> 12 column) #1655\n // IFF we're not in the middle of column resizing!\n if (this.column < 12 && !this._inColumnResize) {\n node.w = Math.min(12, node.w);\n this.cacheOneLayout(node, 12);\n }\n node.w = this.column;\n } else if (node.w < 1) {\n node.w = 1;\n }\n\n if (this.maxRow && node.h > this.maxRow) {\n node.h = this.maxRow;\n } else if (node.h < 1) {\n node.h = 1;\n }\n\n if (node.x < 0) {\n node.x = 0;\n }\n if (node.y < 0) {\n node.y = 0;\n }\n\n if (node.x + node.w > this.column) {\n if (resizing) {\n node.w = this.column - node.x;\n } else {\n node.x = this.column - node.w;\n }\n }\n if (this.maxRow && node.y + node.h > this.maxRow) {\n if (resizing) {\n node.h = this.maxRow - node.y;\n } else {\n node.y = this.maxRow - node.h;\n }\n }\n\n if (!Utils.samePos(node, before)) {\n node._dirty = true;\n }\n\n return node;\n }\n\n /** returns a list of modified nodes from their original values */\n public getDirtyNodes(verify?: boolean): GridStackNode[] {\n // compare original x,y,w,h instead as _dirty can be a temporary state\n if (verify) {\n return this.nodes.filter(n => n._dirty && !Utils.samePos(n, n._orig));\n }\n return this.nodes.filter(n => n._dirty);\n }\n\n /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */\n protected _notify(removedNodes?: GridStackNode[]): GridStackEngine {\n if (this.batchMode || !this.onChange) return this;\n let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes());\n this.onChange(dirtyNodes);\n return this;\n }\n\n /** @internal remove dirty and last tried info */\n public cleanNodes(): GridStackEngine {\n if (this.batchMode) return this;\n this.nodes.forEach(n => {\n delete n._dirty;\n delete n._lastTried;\n });\n return this;\n }\n\n /** @internal called to save initial position/size to track real dirty state.\n * Note: should be called right after we call change event (so next API is can detect changes)\n * as well as right before we start move/resize/enter (so we can restore items to prev values) */\n public saveInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n n._orig = Utils.copyPos({}, n);\n delete n._dirty;\n });\n this._hasLocked = this.nodes.some(n => n.locked);\n return this;\n }\n\n /** @internal restore all the nodes back to initial values (called when we leave) */\n public restoreInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n if (Utils.samePos(n, n._orig)) return;\n Utils.copyPos(n, n._orig);\n n._dirty = true;\n });\n this._notify();\n return this;\n }\n\n /** call to add the given node to our list, fixing collision and re-packing */\n public addNode(node: GridStackNode, triggerAddEvent = false): GridStackNode {\n let dup = this.nodes.find(n => n._id === node._id);\n if (dup) return dup; // prevent inserting twice! return it instead.\n\n // skip prepareNode if we're in middle of column resize (not new) but do check for bounds!\n node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);\n delete node._temporaryRemoved;\n delete node._removeDOM;\n\n if (node.autoPosition) {\n this.sortNodes();\n\n for (let i = 0;; ++i) {\n let x = i % this.column;\n let y = Math.floor(i / this.column);\n if (x + node.w > this.column) {\n continue;\n }\n let box = {x, y, w: node.w, h: node.h};\n if (!this.nodes.find(n => Utils.isIntercepted(box, n))) {\n node.x = x;\n node.y = y;\n delete node.autoPosition; // found our slot\n break;\n }\n }\n }\n\n this.nodes.push(node);\n if (triggerAddEvent) { this.addedNodes.push(node); }\n\n this._fixCollisions(node);\n if (!this.batchMode) { this._packNodes()._notify(); }\n return node;\n }\n\n public removeNode(node: GridStackNode, removeDOM = true, triggerEvent = false): GridStackEngine {\n if (!this.nodes.find(n => n === node)) {\n // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)\n return this;\n }\n if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag)\n this.removedNodes.push(node);\n }\n if (removeDOM) node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.\n this.nodes = this.nodes.filter(n => n !== node);\n return this._packNodes()\n ._notify([node]);\n }\n\n public removeAll(removeDOM = true): GridStackEngine {\n delete this._layouts;\n if (this.nodes.length === 0) return this;\n removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n this.removedNodes = this.nodes;\n this.nodes = [];\n return this._notify(this.removedNodes);\n }\n\n /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.\n * In more complicated cases (maxRow) it will attempt at moving the item and fixing\n * others in a clone first, then apply those changes if still within specs. */\n public moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean {\n // if (node.locked) return false;\n if (!this.changedPosConstrain(node, o)) return false;\n o.pack = true;\n\n // simpler case: move item directly...\n if (!this.maxRow) {\n return this.moveNode(node, o);\n }\n\n // complex case: create a clone with NO maxRow (will check for out of bounds at the end)\n let clonedNode: GridStackNode;\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {\n if (n === node) {\n clonedNode = {...n};\n return clonedNode;\n }\n return {...n};\n })\n });\n if (!clonedNode) return false;\n\n // make sure we are still valid size\n let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow;\n // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing\n if (!canMove && !o.resizing) {\n let collide = this.collide(node, o);\n if (collide && this.swap(node, collide)) {\n this._notify();\n return true;\n }\n }\n if (!canMove) return false;\n\n // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over!\n // Note: we can't use the list directly as elements and other parts point to actual node, so copy content\n clone.nodes.filter(n => n._dirty).forEach(c => {\n let n = this.nodes.find(a => a._id === c._id);\n if (!n) return;\n Utils.copyPos(n, c);\n n._dirty = true;\n });\n this._notify();\n return true;\n }\n\n /** return true if can fit in grid height constrain only (always true if no maxRow) */\n public willItFit(node: GridStackNode): boolean {\n delete node._willFitPos;\n if (!this.maxRow) return true;\n // create a clone with NO maxRow and check if still within size\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {return {...n}})\n });\n let n = {...node}; // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687\n this.cleanupNode(n);\n delete n.el; delete n._id; delete n.content; delete n.grid;\n clone.addNode(n);\n if (clone.getRow() <= this.maxRow) {\n node._willFitPos = Utils.copyPos({}, n);\n return true;\n }\n return false;\n }\n\n /** true if x,y or w,h are different after clamping to min/max */\n public changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean {\n // first make sure w,h are set for caller\n p.w = p.w || node.w;\n p.h = p.h || node.h;\n if (node.x !== p.x || node.y !== p.y) return true;\n // check constrained w,h\n if (node.maxW) { p.w = Math.min(p.w, node.maxW); }\n if (node.maxH) { p.h = Math.min(p.h, node.maxH); }\n if (node.minW) { p.w = Math.max(p.w, node.minW); }\n if (node.minH) { p.h = Math.max(p.h, node.minH); }\n return (node.w !== p.w || node.h !== p.h);\n }\n\n /** return true if the passed in node was actually moved (checks for no-op and locked) */\n public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {\n if (!node || /*node.locked ||*/ !o) return false;\n if (o.pack === undefined) o.pack = true;\n\n // constrain the passed in values and check if we're still changing our node\n if (typeof o.x !== 'number') { o.x = node.x; }\n if (typeof o.y !== 'number') { o.y = node.y; }\n if (typeof o.w !== 'number') { o.w = node.w; }\n if (typeof o.h !== 'number') { o.h = node.h; }\n let resizing = (node.w !== o.w || node.h !== o.h);\n let nn: GridStackNode = Utils.copyPos({}, node, true); // get min/max out first, then opt positions next\n Utils.copyPos(nn, o);\n nn = this.nodeBoundFix(nn, resizing);\n Utils.copyPos(o, nn);\n\n if (Utils.samePos(node, o)) return false;\n let prevPos: GridStackPosition = Utils.copyPos({}, node);\n\n // check if we will need to fix collision at our new location\n let collides = this.collideAll(node, nn, o.skip);\n let needToMove = true;\n if (collides.length) {\n // now check to make sure we actually collided over 50% surface area while dragging\n let collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0];\n if (collide) {\n needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved...\n } else {\n needToMove = false; // we didn't cover >50% for a move, skip...\n }\n }\n\n // now move (to the original ask vs the collision version which might differ) and repack things\n if (needToMove) {\n node._dirty = true;\n Utils.copyPos(node, nn);\n }\n if (o.pack) {\n this._packNodes()\n ._notify();\n }\n return !Utils.samePos(node, prevPos); // pack might have moved things back\n }\n\n public getRow(): number {\n return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0);\n }\n\n public beginUpdate(node: GridStackNode): GridStackEngine {\n if (!node._updating) {\n node._updating = true;\n delete node._skipDown;\n if (!this.batchMode) this.saveInitial();\n }\n return this;\n }\n\n public endUpdate(): GridStackEngine {\n let n = this.nodes.find(n => n._updating);\n if (n) {\n delete n._updating;\n delete n._skipDown;\n }\n return this;\n }\n\n /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout),\n * returning a list of widgets for serialization */\n public save(saveElement = true): GridStackNode[] {\n // use the highest layout for any saved info so we can have full detail on reload #1849\n let len = this._layouts?.length;\n let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null;\n let list: GridStackNode[] = [];\n this.sortNodes();\n this.nodes.forEach(n => {\n let wl = layout?.find(l => l._id === n._id);\n let w: GridStackNode = {...n};\n // use layout info instead if set\n if (wl) { w.x = wl.x; w.y = wl.y; w.w = wl.w; }\n // delete internals\n for (let key in w) { if (key[0] === '_' || w[key] === null || w[key] === undefined ) delete w[key]; }\n delete w.grid;\n if (!saveElement) delete w.el;\n // delete default values (will be re-created on read)\n if (!w.autoPosition) delete w.autoPosition;\n if (!w.noResize) delete w.noResize;\n if (!w.noMove) delete w.noMove;\n if (!w.locked) delete w.locked;\n list.push(w);\n });\n return list;\n }\n\n /** @internal called whenever a node is added or moved - updates the cached layouts */\n public layoutsNodesChange(nodes: GridStackNode[]): GridStackEngine {\n if (!this._layouts || this._inColumnResize) return this;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach((layout, column) => {\n if (!layout || column === this.column) return this;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785\n let ratio = column / this.column;\n nodes.forEach(node => {\n if (!node._orig) return; // didn't change (newly added ?)\n let n = layout.find(l => l._id === node._id);\n if (!n) return; // no cache for new nodes. Will use those values.\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._orig.y) {\n n.y += (node.y - node._orig.y);\n }\n // X changed, scale from new position\n if (node.x !== node._orig.x) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.w !== node._orig.w) {\n n.w = Math.round(node.w * ratio);\n }\n // ...height always carries over from cache\n });\n }\n });\n return this;\n }\n\n /**\n * @internal Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * @param prevColumn previous number of columns\n * @param column new column number\n * @param nodes different sorted list (ex: DOM order) instead of current list\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n public updateNodeWidths(prevColumn: number, column: number, nodes: GridStackNode[], layout: ColumnOptions = 'moveScale'): GridStackEngine {\n if (!this.nodes.length || !column || prevColumn === column) return this;\n\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n this.cacheLayout(this.nodes, prevColumn);\n this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision\n let newNodes: GridStackNode[] = [];\n\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n let domOrder = false;\n if (column === 1 && nodes?.length) {\n domOrder = true;\n let top = 0;\n nodes.forEach(n => {\n n.x = 0;\n n.w = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.h;\n });\n newNodes = nodes;\n nodes = [];\n } else {\n nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n\n // see if we have cached previous layout IFF we are going up in size (restore) otherwise always\n // generate next size down from where we are (looks more natural as you gradually size down).\n let cacheNodes: GridStackNode[] = [];\n if (column > prevColumn) {\n cacheNodes = this._layouts[column] || [];\n // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate\n // by pretending we came from that larger column by assigning those values as starting point\n let lastIndex = this._layouts.length - 1;\n if (!cacheNodes.length && prevColumn !== lastIndex && this._layouts[lastIndex]?.length) {\n prevColumn = lastIndex;\n this._layouts[lastIndex].forEach(cacheNode => {\n let n = nodes.find(n => n._id === cacheNode._id);\n if (n) {\n // still current, use cache info positions\n n.x = cacheNode.x;\n n.y = cacheNode.y;\n n.w = cacheNode.w;\n }\n });\n }\n }\n\n // if we found cache re-use those nodes that are still current\n cacheNodes.forEach(cacheNode => {\n let j = nodes.findIndex(n => n._id === cacheNode._id);\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].w = cacheNode.w;\n newNodes.push(nodes[j]);\n nodes.splice(j, 1);\n }\n });\n // ...and add any extra non-cached ones\n if (nodes.length) {\n if (typeof layout === 'function') {\n layout(column, prevColumn, newNodes, nodes);\n } else if (!domOrder) {\n let ratio = column / prevColumn;\n let move = (layout === 'move' || layout === 'moveScale');\n let scale = (layout === 'scale' || layout === 'moveScale');\n nodes.forEach(node => {\n // NOTE: x + w could be outside of the grid, but addNode() below will handle that\n node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));\n node.w = ((column === 1 || prevColumn === 1) ? 1 :\n scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));\n newNodes.push(node);\n });\n nodes = [];\n }\n }\n\n // finally re-layout them in reverse order (to get correct placement)\n newNodes = Utils.sort(newNodes, -1, column);\n this._inColumnResize = true; // prevent cache update\n this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout\n newNodes.forEach(node => {\n this.addNode(node, false); // 'false' for add event trigger\n delete node._orig; // make sure the commit doesn't try to restore things back to original\n });\n this.batchUpdate(false);\n delete this._inColumnResize;\n return this;\n }\n\n /**\n * call to cache the given layout internally to the given location so we can restore back when column changes size\n * @param nodes list of nodes\n * @param column corresponding column index to save it under\n * @param clear if true, will force other caches to be removed (default false)\n */\n public cacheLayout(nodes: GridStackNode[], column: number, clear = false): GridStackEngine {\n let copy: GridStackNode[] = [];\n nodes.forEach((n, i) => {\n n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set\n copy[i] = {x: n.x, y: n.y, w: n.w, _id: n._id} // only thing we change is x,y,w and id to find it back\n });\n this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick\n this._layouts[column] = copy;\n return this;\n }\n\n /**\n * call to cache the given node layout internally to the given location so we can restore back when column changes size\n * @param node single node to cache\n * @param column corresponding column index to save it under\n */\n public cacheOneLayout(n: GridStackNode, column: number): GridStackEngine {\n n._id = n._id || GridStackEngine._idSeq++;\n let layout: GridStackNode = {x: n.x, y: n.y, w: n.w, _id: n._id}\n this._layouts = this._layouts || [];\n this._layouts[column] = this._layouts[column] || [];\n let index = this._layouts[column].findIndex(l => l._id === n._id);\n index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout;\n return this;\n }\n\n\n /** called to remove all internal values but the _id */\n public cleanupNode(node: GridStackNode): GridStackEngine {\n for (let prop in node) {\n if (prop[0] === '_' && prop !== '_id') delete node[prop];\n }\n return this;\n }\n}\n","/*!\r\n * GridStack 6.0.1-dev\r\n * https://gridstackjs.com/\r\n *\r\n * Copyright (c) 2021-2022 Alain Dumesny\r\n * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE\r\n */\r\nimport { GridStackEngine } from './gridstack-engine';\r\nimport { Utils, HeightData, obsolete } from './utils';\r\nimport { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback,\r\n GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\n\r\n// export all dependent file as well to make it easier for users to just import the main file\r\nexport * from './types';\r\nexport * from './utils';\r\nexport * from './gridstack-engine';\r\n\r\nexport interface GridHTMLElement extends HTMLElement {\r\n gridstack?: GridStack; // grid's parent DOM element points back to grid class\r\n}\r\n/** list of possible events, or space separated list of them */\r\nexport type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' |\r\n 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string;\r\n\r\n/** Defines the coordinates of an object */\r\nexport interface MousePosition {\r\n top: number;\r\n left: number;\r\n}\r\n\r\n/** Defines the position of a cell inside the grid*/\r\nexport interface CellPosition {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface GridCSSStyleSheet extends CSSStyleSheet {\r\n _id?: string; // random id we will use to style us\r\n _max?: number; // internal tracker of the max # of rows we created\\\r\n}\r\n\r\n// default values for grid options - used during init and when saving out\r\nconst GridDefaults: GridStackOptions = {\r\n column: 12,\r\n minRow: 0,\r\n maxRow: 0,\r\n itemClass: 'grid-stack-item',\r\n placeholderClass: 'grid-stack-placeholder',\r\n placeholderText: '',\r\n handle: '.grid-stack-item-content',\r\n handleClass: null,\r\n styleInHead: false,\r\n cellHeight: 'auto',\r\n cellHeightThrottle: 100,\r\n margin: 10,\r\n auto: true,\r\n oneColumnSize: 768,\r\n float: false,\r\n staticGrid: false,\r\n animate: true,\r\n alwaysShowResizeHandle: 'mobile',\r\n resizable: {\r\n handles: 'se'\r\n },\r\n draggable: {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body'\r\n },\r\n disableDrag: false,\r\n disableResize: false,\r\n rtl: 'auto',\r\n removable: false,\r\n removableOptions: {\r\n accept: '.grid-stack-item'\r\n },\r\n marginUnit: 'px',\r\n cellHeightUnit: 'px',\r\n disableOneColumnMode: false,\r\n oneColumnModeDomSort: false,\r\n};\r\n\r\n/**\r\n * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.\r\n * Note: your grid elements MUST have the following classes for the CSS layout to work:\r\n * @example\r\n *
\r\n *
\r\n *
Item 1
\r\n *
\r\n *
\r\n */\r\nexport class GridStack {\r\n\r\n /**\r\n * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will\r\n * simply return the existing instance (ignore any passed options). There is also an initAll() version that support\r\n * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.\r\n * @param options grid options (optional)\r\n * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n *\r\n * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later\r\n * let grid = document.querySelector('.grid-stack').gridstack;\r\n */\r\n public static init(options: GridStackOptions = {}, elOrString: GridStackElement = '.grid-stack'): GridStack {\r\n let el = GridStack.getGridElement(elOrString);\r\n if (!el) {\r\n if (typeof elOrString === 'string') {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + elOrString + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n } else {\r\n console.error('GridStack.init() no grid element was passed.');\r\n }\r\n return null;\r\n }\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n }\r\n return el.gridstack\r\n }\r\n\r\n /**\r\n * Will initialize a list of elements (given a selector) and return an array of grids.\r\n * @param options grid options (optional)\r\n * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grids = GridStack.initAll();\r\n * grids.forEach(...)\r\n */\r\n public static initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[] {\r\n let grids: GridStack[] = [];\r\n GridStack.getGridElements(selector).forEach(el => {\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n delete options.dragIn; delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)\r\n }\r\n grids.push(el.gridstack);\r\n });\r\n if (grids.length === 0) {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + selector + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n }\r\n return grids;\r\n }\r\n\r\n /**\r\n * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then\r\n * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from\r\n * JSON serialized data, including options.\r\n * @param parent HTML element parent to the grid\r\n * @param opt grids options used to initialize the grid, and list of children\r\n */\r\n public static addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack {\r\n if (!parent) return null;\r\n\r\n // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead\r\n let el = parent;\r\n if (!parent.classList.contains('grid-stack')) {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n parent.appendChild(el);\r\n }\r\n\r\n // create grid class and load any children\r\n let grid = GridStack.init(opt, el);\r\n if (grid.opts.children) {\r\n let children = grid.opts.children;\r\n delete grid.opts.children;\r\n grid.load(children);\r\n }\r\n return grid;\r\n }\r\n\r\n /** call this method to register your engine instead of the default one.\r\n * See instead `GridStackOptions.engineClass` if you only need to\r\n * replace just one instance.\r\n */\r\n static registerEngine(engineClass: typeof GridStackEngine) {\r\n GridStack.engineClass = engineClass;\r\n }\r\n\r\n /** scoping so users can call GridStack.Utils.sort() for example */\r\n public static Utils = Utils;\r\n\r\n /** scoping so users can call new GridStack.Engine(12) for example */\r\n public static Engine = GridStackEngine;\r\n\r\n /** the HTML element tied to this grid after it's been initialized */\r\n public el: GridHTMLElement;\r\n\r\n /** engine used to implement non DOM grid functionality */\r\n public engine: GridStackEngine;\r\n\r\n /** grid options - public for classes to access, but use methods to modify! */\r\n public opts: GridStackOptions;\r\n\r\n protected static engineClass: typeof GridStackEngine;\r\n\r\n /** @internal create placeholder DIV as needed */\r\n public get placeholder(): HTMLElement {\r\n if (!this._placeholder) {\r\n let placeholderChild = document.createElement('div'); // child so padding match item-content\r\n placeholderChild.className = 'placeholder-content';\r\n if (this.opts.placeholderText) {\r\n placeholderChild.innerHTML = this.opts.placeholderText;\r\n }\r\n this._placeholder = document.createElement('div');\r\n this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass);\r\n this.placeholder.appendChild(placeholderChild);\r\n }\r\n return this._placeholder;\r\n }\r\n /** @internal */\r\n protected _placeholder: HTMLElement;\r\n /** @internal */\r\n protected _prevColumn: number;\r\n /** @internal */\r\n protected _ignoreLayoutsNodeChange: boolean;\r\n /** @internal */\r\n public _gsEventHandler = {};\r\n /** @internal */\r\n protected _styles: GridCSSStyleSheet;\r\n /** @internal flag to keep cells square during resize */\r\n protected _isAutoCellHeight: boolean;\r\n /** @internal track event binding to window resize so we can remove */\r\n protected _windowResizeBind: () => void;\r\n /** @internal limit auto cell resizing method */\r\n protected _cellHeightThrottle: () => void;\r\n /** @internal true when loading items to insert first rather than append */\r\n protected _insertNotAppend: boolean;\r\n /** @internal extra row added when dragging at the bottom of the grid */\r\n protected _extraDragRow = 0;\r\n /** @internal true if nested grid should get column count from our width */\r\n protected _autoColumn?: boolean;\r\n\r\n /**\r\n * Construct a grid item from the given element and options\r\n * @param el\r\n * @param opts\r\n */\r\n public constructor(el: GridHTMLElement, opts: GridStackOptions = {}) {\r\n this.el = el; // exposed HTML element to the user\r\n opts = opts || {}; // handles null/undefined/0\r\n\r\n // if row property exists, replace minRow and maxRow instead\r\n if (opts.row) {\r\n opts.minRow = opts.maxRow = opts.row;\r\n delete opts.row;\r\n }\r\n let rowAttr = Utils.toNumber(el.getAttribute('gs-row'));\r\n\r\n // flag only valid in sub-grids (handled by parent, not here)\r\n if (opts.column === 'auto') {\r\n delete opts.column;\r\n }\r\n // 'minWidth' legacy support in 5.1\r\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\r\n let anyOpts = opts as any;\r\n if (anyOpts.minWidth !== undefined) {\r\n opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;\r\n delete anyOpts.minWidth;\r\n }\r\n // save original setting so we can restore on save\r\n if (opts.alwaysShowResizeHandle !== undefined) {\r\n (opts as any)._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;\r\n }\r\n\r\n // elements DOM attributes override any passed options (like CSS style) - merge the two together\r\n let defaults: GridStackOptions = {...Utils.cloneDeep(GridDefaults),\r\n column: Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column,\r\n minRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow,\r\n maxRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow,\r\n staticGrid: Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid,\r\n _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0),\r\n draggable: {\r\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle,\r\n },\r\n removableOptions: {\r\n accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept,\r\n },\r\n };\r\n if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead\r\n defaults.animate = Utils.toBool(el.getAttribute('gs-animate'))\r\n }\r\n\r\n this.opts = Utils.defaults(opts, defaults);\r\n opts = null; // make sure we use this.opts instead\r\n this._initMargin(); // part of settings defaults...\r\n\r\n // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)\r\n if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {\r\n this._prevColumn = this.getColumn();\r\n this.opts.column = 1;\r\n }\r\n\r\n if (this.opts.rtl === 'auto') {\r\n this.opts.rtl = (el.style.direction === 'rtl');\r\n }\r\n if (this.opts.rtl) {\r\n this.el.classList.add('grid-stack-rtl');\r\n }\r\n\r\n // check if we're been nested, and if so update our style and keep pointer around (used during save)\r\n let parentGridItemEl = Utils.closestByClass(this.el, GridDefaults.itemClass) as GridItemHTMLElement;\r\n if (parentGridItemEl && parentGridItemEl.gridstackNode) {\r\n this.opts._isNested = parentGridItemEl.gridstackNode;\r\n this.opts._isNested.subGrid = this;\r\n parentGridItemEl.classList.add('grid-stack-nested');\r\n this.el.classList.add('grid-stack-nested');\r\n }\r\n\r\n this._isAutoCellHeight = (this.opts.cellHeight === 'auto');\r\n if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {\r\n // make the cell content square initially (will use resize/column event to keep it square)\r\n this.cellHeight(undefined, false);\r\n } else {\r\n // append unit if any are set\r\n if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) {\r\n this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;\r\n delete this.opts.cellHeightUnit;\r\n }\r\n this.cellHeight(this.opts.cellHeight, false);\r\n }\r\n\r\n // see if we need to adjust auto-hide\r\n if (this.opts.alwaysShowResizeHandle === 'mobile') {\r\n this.opts.alwaysShowResizeHandle = isTouch;\r\n }\r\n\r\n this.el.classList.add(this.opts._styleSheetClass);\r\n\r\n this._setStaticClass();\r\n\r\n let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;\r\n this.engine = new engineClass({\r\n column: this.getColumn(),\r\n float: this.opts.float,\r\n maxRow: this.opts.maxRow,\r\n onChange: (cbNodes) => {\r\n let maxH = 0;\r\n this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) });\r\n cbNodes.forEach(n => {\r\n let el = n.el;\r\n if (!el) return;\r\n if (n._removeDOM) {\r\n if (el) el.remove();\r\n delete n._removeDOM;\r\n } else {\r\n this._writePosAttr(el, n);\r\n }\r\n });\r\n this._updateStyles(false, maxH); // false = don't recreate, just append if need be\r\n }\r\n });\r\n\r\n if (this.opts.auto) {\r\n this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...\r\n let elements: {el: HTMLElement; i: number}[] = [];\r\n this.getGridItems().forEach(el => { // get dom elements (not nodes yet)\r\n let x = parseInt(el.getAttribute('gs-x'));\r\n let y = parseInt(el.getAttribute('gs-y'));\r\n elements.push({\r\n el,\r\n // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order\r\n i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * this.getColumn()\r\n });\r\n });\r\n elements.sort((a, b) => a.i - b.i).forEach(e => this._prepareElement(e.el));\r\n this.batchUpdate(false);\r\n }\r\n\r\n this.setAnimation(this.opts.animate);\r\n\r\n this._updateStyles();\r\n if (this.opts.column != 12) {\r\n this.el.classList.add('grid-stack-' + this.opts.column);\r\n }\r\n\r\n // legacy support to appear 'per grid` options when really global.\r\n if (this.opts.dragIn) GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);\r\n delete this.opts.dragIn;\r\n delete this.opts.dragInOptions;\r\n\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this._updateWindowResizeEvent();\r\n }\r\n\r\n public change() {\r\n this._triggerChangeEvent();\r\n }\r\n\r\n /**\r\n * add a new widget and returns it.\r\n *\r\n * Widget will be always placed even if result height is more than actual grid height.\r\n * You need to use `willItFit()` before calling addWidget for additional check.\r\n * See also `makeWidget()`.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.addWidget({w: 3, content: 'hello'});\r\n * grid.addWidget('
hello
', {w: 3});\r\n *\r\n * @param el GridStackWidget (which can have content string as well), html element, or string definition to add\r\n * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget\r\n */\r\n public addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1,\r\n opt: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++],\r\n minW:a[i++], maxW:a[i++], minH:a[i++], maxH:a[i++], id:a[i++] };\r\n return this.addWidget(els, opt);\r\n }\r\n\r\n function isGridStackWidget(w: GridStackWidget): w is GridStackWidget { // https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0\r\n return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;\r\n }\r\n\r\n let el: HTMLElement;\r\n if (typeof els === 'string') {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = els;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {\r\n let content = els ? (els as GridStackWidget).content || '' : '';\r\n options = els;\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
${content}
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else {\r\n el = els as HTMLElement;\r\n }\r\n\r\n // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos\r\n // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node.\r\n // So make sure we load any DOM attributes that are not specified in passed in options (which override)\r\n let domAttr = this._readAttr(el);\r\n options = Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it\r\n Utils.defaults(options, domAttr);\r\n let node = this.engine.prepareNode(options);\r\n this._writeAttr(el, options);\r\n\r\n if (this._insertNotAppend) {\r\n this.el.prepend(el);\r\n } else {\r\n this.el.appendChild(el);\r\n }\r\n\r\n // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id\r\n this._prepareElement(el, true, options);\r\n this._updateContainerHeight();\r\n\r\n // check if nested grid definition is present\r\n if (node.subGrid && !(node.subGrid as GridStack).el) { // see if there is a sub-grid to create too\r\n // if column special case it set, remember that flag and set default\r\n let autoColumn: boolean;\r\n let ops = node.subGrid as GridStackOptions;\r\n if (ops.column === 'auto') {\r\n ops.column = node.w;\r\n ops.disableOneColumnMode = true; // driven by parent\r\n autoColumn = true;\r\n }\r\n let content = node.el.querySelector('.grid-stack-item-content') as HTMLElement;\r\n node.subGrid = GridStack.addGrid(content, node.subGrid as GridStackOptions);\r\n if (autoColumn) { node.subGrid._autoColumn = true; }\r\n }\r\n\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n /**\r\n * saves the current layout returning a list of widgets for serialization which might include any nested grids.\r\n * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will\r\n * be removed.\r\n * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()\r\n * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.\r\n * @returns list of widgets or full grid option, including .children list of widgets\r\n */\r\n public save(saveContent = true, saveGridOpt = false): GridStackWidget[] | GridStackOptions {\r\n // return copied nodes we can modify at will...\r\n let list = this.engine.save(saveContent);\r\n\r\n // check for HTML content and nested grids\r\n list.forEach(n => {\r\n if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content\r\n let sub = n.el.querySelector('.grid-stack-item-content');\r\n n.content = sub ? sub.innerHTML : undefined;\r\n if (!n.content) delete n.content;\r\n } else {\r\n if (!saveContent) { delete n.content; }\r\n // check for nested grid\r\n if (n.subGrid) {\r\n n.subGrid = (n.subGrid as GridStack).save(saveContent, true) as GridStackOptions;\r\n }\r\n }\r\n delete n.el;\r\n });\r\n\r\n // check if save entire grid options (needed for recursive) + children...\r\n if (saveGridOpt) {\r\n let o: GridStackOptions = Utils.cloneDeep(this.opts);\r\n // delete default values that will be recreated on launch\r\n if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {\r\n o.margin = o.marginTop;\r\n delete o.marginTop; delete o.marginRight; delete o.marginBottom; delete o.marginLeft;\r\n }\r\n if (o.rtl === (this.el.style.direction === 'rtl')) { o.rtl = 'auto' }\r\n if (this._isAutoCellHeight) {\r\n o.cellHeight = 'auto'\r\n }\r\n if (this._autoColumn) {\r\n o.column = 'auto';\r\n delete o.disableOneColumnMode;\r\n }\r\n const origShow = (o as any)._alwaysShowResizeHandle;\r\n delete (o as any)._alwaysShowResizeHandle;\r\n if (origShow !== undefined) {\r\n o.alwaysShowResizeHandle = origShow;\r\n } else {\r\n delete o.alwaysShowResizeHandle;\r\n }\r\n Utils.removeInternalAndSame(o, GridDefaults);\r\n o.children = list;\r\n return o;\r\n }\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.\r\n *\r\n * @param layout list of widgets definition to update/create\r\n * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving\r\n * the user control of insertion.\r\n *\r\n * @example\r\n * see http://gridstackjs.com/demo/serialization.html\r\n **/\r\n public load(layout: GridStackWidget[], addAndRemove: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement) = true): GridStack {\r\n let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort\r\n this._insertNotAppend = true; // since create in reverse order...\r\n\r\n // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save\r\n // the original wanted layout so we can scale back up correctly #1471\r\n if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) {\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this.engine.cacheLayout(items, this._prevColumn, true);\r\n }\r\n\r\n let removed: GridStackNode[] = [];\r\n this.batchUpdate();\r\n\r\n // see if any items are missing from new layout and need to be removed first\r\n if (addAndRemove) {\r\n let copyNodes = [...this.engine.nodes]; // don't loop through array you modify\r\n copyNodes.forEach(n => {\r\n let item = items.find(w => n.id === w.id);\r\n if (!item) {\r\n if (typeof(addAndRemove) === 'function') {\r\n addAndRemove(this, n, false);\r\n } else {\r\n removed.push(n); // batch keep track\r\n this.removeWidget(n.el, true, false);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // now add/update the widgets\r\n items.forEach(w => {\r\n let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined;\r\n if (item) {\r\n this.update(item.el, w);\r\n if (w.subGrid && (w.subGrid as GridStackOptions).children) { // update any sub grid as well\r\n let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;\r\n if (sub && sub.gridstack) {\r\n sub.gridstack.load((w.subGrid as GridStackOptions).children); // TODO: support updating grid options ?\r\n this._insertNotAppend = true; // got reset by above call\r\n }\r\n }\r\n } else if (addAndRemove) {\r\n if (typeof(addAndRemove) === 'function') {\r\n w = addAndRemove(this, w, true).gridstackNode;\r\n } else {\r\n w = this.addWidget(w).gridstackNode;\r\n }\r\n }\r\n });\r\n\r\n this.engine.removedNodes = removed;\r\n this.batchUpdate(false);\r\n\r\n // after commit, clear that flag\r\n delete this._ignoreLayoutsNodeChange;\r\n delete this._insertNotAppend;\r\n return this;\r\n }\r\n\r\n /**\r\n * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)\r\n * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.\r\n */\r\n public batchUpdate(flag = true): GridStack {\r\n this.engine.batchUpdate(flag);\r\n if (!flag) {\r\n this._triggerRemoveEvent();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets current cell height.\r\n */\r\n public getCellHeight(forcePixel = false): number {\r\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&\r\n (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {\r\n return this.opts.cellHeight as number;\r\n }\r\n // else get first cell height\r\n let el = this.el.querySelector('.' + this.opts.itemClass) as HTMLElement;\r\n if (el) {\r\n let height = Utils.toNumber(el.getAttribute('gs-h'));\r\n return Math.round(el.offsetHeight / height);\r\n }\r\n // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)\r\n let rows = parseInt(this.el.getAttribute('gs-current-row'));\r\n return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight as number;\r\n }\r\n\r\n /**\r\n * Update current cell height - see `GridStackOptions.cellHeight` for format.\r\n * This method rebuilds an internal CSS style sheet.\r\n * Note: You can expect performance issues if call this method too often.\r\n *\r\n * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),\r\n * if pass 0 the CSS will be generated by the application instead.\r\n * @param update (Optional) if false, styles will not be updated\r\n *\r\n * @example\r\n * grid.cellHeight(100); // same as 100px\r\n * grid.cellHeight('70px');\r\n * grid.cellHeight(grid.cellWidth() * 1.2);\r\n */\r\n public cellHeight(val?: numberOrString, update = true): GridStack {\r\n\r\n // if not called internally, check if we're changing mode\r\n if (update && val !== undefined) {\r\n if (this._isAutoCellHeight !== (val === 'auto')) {\r\n this._isAutoCellHeight = (val === 'auto');\r\n this._updateWindowResizeEvent();\r\n }\r\n }\r\n if (val === 'initial' || val === 'auto') { val = undefined; }\r\n\r\n // make item content be square\r\n if (val === undefined) {\r\n let marginDiff = - (this.opts.marginRight as number) - (this.opts.marginLeft as number)\r\n + (this.opts.marginTop as number) + (this.opts.marginBottom as number);\r\n val = this.cellWidth() + marginDiff;\r\n }\r\n\r\n let data = Utils.parseHeight(val);\r\n if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {\r\n return this;\r\n }\r\n this.opts.cellHeightUnit = data.unit;\r\n this.opts.cellHeight = data.h;\r\n\r\n if (update) {\r\n this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows\r\n }\r\n return this;\r\n }\r\n\r\n /** Gets current cell width. */\r\n public cellWidth(): number {\r\n return this._widthOrContainer() / this.getColumn();\r\n }\r\n /** return our expected width (or parent) for 1 column check */\r\n protected _widthOrContainer(): number {\r\n // use `offsetWidth` or `clientWidth` (no scrollbar) ?\r\n // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);\r\n }\r\n\r\n /** re-layout grid items to reclaim any empty space */\r\n public compact(): GridStack {\r\n this.engine.compact();\r\n this._triggerChangeEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,\r\n * as well as cache the original layout so you can revert back to previous positions without loss.\r\n * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],\r\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\r\n * @param column - Integer > 0 (default 12).\r\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\r\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\r\n */\r\n public column(column: number, layout: ColumnOptions = 'moveScale'): GridStack {\r\n if (column < 1 || this.opts.column === column) return this;\r\n let oldColumn = this.getColumn();\r\n\r\n // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)\r\n // then remember the original columns so we can restore.\r\n if (column === 1) {\r\n this._prevColumn = oldColumn;\r\n } else {\r\n delete this._prevColumn;\r\n }\r\n\r\n this.el.classList.remove('grid-stack-' + oldColumn);\r\n this.el.classList.add('grid-stack-' + column);\r\n this.opts.column = this.engine.column = column;\r\n\r\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\r\n let domNodes: GridStackNode[];\r\n if (column === 1 && this.opts.oneColumnModeDomSort) {\r\n domNodes = [];\r\n this.getGridItems().forEach(el => { // get dom elements in order\r\n if (el.gridstackNode) { domNodes.push(el.gridstackNode); }\r\n });\r\n if (!domNodes.length) { domNodes = undefined; }\r\n }\r\n this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);\r\n if (this._isAutoCellHeight) this.cellHeight();\r\n\r\n // and trigger our event last...\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this._triggerChangeEvent();\r\n delete this._ignoreLayoutsNodeChange;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * get the number of columns in the grid (default 12)\r\n */\r\n public getColumn(): number {\r\n return this.opts.column as number;\r\n }\r\n\r\n /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */\r\n public getGridItems(): GridItemHTMLElement[] {\r\n return Array.from(this.el.children)\r\n .filter((el: HTMLElement) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass)) as GridItemHTMLElement[];\r\n }\r\n\r\n /**\r\n * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.\r\n * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).\r\n */\r\n public destroy(removeDOM = true): GridStack {\r\n if (!this.el) return; // prevent multiple calls\r\n this._updateWindowResizeEvent(true);\r\n this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)\r\n this.setAnimation(false);\r\n if (!removeDOM) {\r\n this.removeAll(removeDOM);\r\n this.el.classList.remove(this.opts._styleSheetClass);\r\n } else {\r\n this.el.parentNode.removeChild(this.el);\r\n }\r\n this._removeStylesheet();\r\n this.el.removeAttribute('gs-current-row');\r\n delete this.opts._isNested;\r\n delete this.opts;\r\n delete this._placeholder;\r\n delete this.engine;\r\n delete this.el.gridstack; // remove circular dependency that would prevent a freeing\r\n delete this.el;\r\n return this;\r\n }\r\n\r\n /**\r\n * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)\r\n */\r\n public float(val: boolean): GridStack {\r\n if (this.opts.float !== val) {\r\n this.opts.float = this.engine.float = val;\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get the current float mode\r\n */\r\n public getFloat(): boolean {\r\n return this.engine.float;\r\n }\r\n\r\n /**\r\n * Get the position of the cell under a pixel on screen.\r\n * @param position the position of the pixel to resolve in\r\n * absolute coordinates, as an object with top and left properties\r\n * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).\r\n * Useful when grid is within `position: relative` element\r\n *\r\n * Returns an object with properties `x` and `y` i.e. the column and row in the grid.\r\n */\r\n public getCellFromPixel(position: MousePosition, useDocRelative = false): CellPosition {\r\n let box = this.el.getBoundingClientRect();\r\n // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)\r\n let containerPos: {top: number, left: number};\r\n if (useDocRelative) {\r\n containerPos = {top: box.top + document.documentElement.scrollTop, left: box.left};\r\n // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)\r\n } else {\r\n containerPos = {top: this.el.offsetTop, left: this.el.offsetLeft}\r\n // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)\r\n }\r\n let relativeLeft = position.left - containerPos.left;\r\n let relativeTop = position.top - containerPos.top;\r\n\r\n let columnWidth = (box.width / this.getColumn());\r\n let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));\r\n\r\n return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)};\r\n }\r\n\r\n /** returns the current number of rows, which will be at least `minRow` if set */\r\n public getRow(): number {\r\n return Math.max(this.engine.getRow(), this.opts.minRow);\r\n }\r\n\r\n /**\r\n * Checks if specified area is empty.\r\n * @param x the position x.\r\n * @param y the position y.\r\n * @param w the width of to check\r\n * @param h the height of to check\r\n */\r\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\r\n return this.engine.isAreaEmpty(x, y, w, h);\r\n }\r\n\r\n /**\r\n * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.\r\n * If you want gridstack to add the elements for you, use `addWidget()` instead.\r\n * Makes the given element a widget and returns it.\r\n * @param els widget or single selector to convert.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.el.appendChild('
');\r\n * grid.makeWidget('#gsi-1');\r\n */\r\n public makeWidget(els: GridStackElement): GridItemHTMLElement {\r\n let el = GridStack.getElement(els);\r\n this._prepareElement(el, true);\r\n this._updateContainerHeight();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n return el;\r\n }\r\n\r\n /**\r\n * Event handler that extracts our CustomEvent data out automatically for receiving custom\r\n * notifications (see doc for supported events)\r\n * @param name of the event (see possible values) or list of names space separated\r\n * @param callback function called with event and optional second/third param\r\n * (see README documentation for each signature).\r\n *\r\n * @example\r\n * grid.on('added', function(e, items) { log('added ', items)} );\r\n * or\r\n * grid.on('added removed change', function(e, items) { log(e.type, items)} );\r\n *\r\n * Note: in some cases it is the same as calling native handler and parsing the event.\r\n * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );\r\n *\r\n */\r\n public on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.on(name, callback));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // native CustomEvent handlers - cash the generic handlers so we can easily remove\r\n let noData = (name === 'enable' || name === 'disable');\r\n if (noData) {\r\n this._gsEventHandler[name] = (event: Event) => callback(event);\r\n } else {\r\n this._gsEventHandler[name] = (event: CustomEvent) => callback(event, event.detail);\r\n }\r\n this.el.addEventListener(name, this._gsEventHandler[name]);\r\n } else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {\r\n // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.\r\n // do same for start event to make it easier...\r\n this._gsEventHandler[name] = callback;\r\n } else {\r\n console.log('GridStack.on(' + name + ') event not supported, but you can still use $(\".grid-stack\").on(...) while jquery-ui is still used internally.');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * unsubscribe from the 'on' event below\r\n * @param name of the event (see possible values)\r\n */\r\n public off(name: GridStackEvent): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.off(name));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // remove native CustomEvent handlers\r\n if (this._gsEventHandler[name]) {\r\n this.el.removeEventListener(name, this._gsEventHandler[name]);\r\n }\r\n }\r\n delete this._gsEventHandler[name];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes widget from the grid.\r\n * @param el widget or selector to modify\r\n * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).\r\n * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).\r\n */\r\n public removeWidget(els: GridStackElement, removeDOM = true, triggerEvent = true): GridStack {\r\n GridStack.getElements(els).forEach(el => {\r\n if (el.parentElement !== this.el) return; // not our child!\r\n let node = el.gridstackNode;\r\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\r\n if (!node) {\r\n node = this.engine.nodes.find(n => el === n.el);\r\n }\r\n if (!node) return;\r\n\r\n // remove our DOM data (circular link) and drag&drop permanently\r\n delete el.gridstackNode;\r\n this._removeDD(el);\r\n\r\n this.engine.removeNode(node, removeDOM, triggerEvent);\r\n\r\n if (removeDOM && el.parentElement) {\r\n el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM\r\n }\r\n });\r\n if (triggerEvent) {\r\n this._triggerRemoveEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all widgets from the grid.\r\n * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).\r\n */\r\n public removeAll(removeDOM = true): GridStack {\r\n // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently\r\n this.engine.nodes.forEach(n => {\r\n delete n.el.gridstackNode;\r\n this._removeDD(n.el);\r\n });\r\n this.engine.removeAll(removeDOM);\r\n this._triggerRemoveEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid animation state. Toggles the `grid-stack-animate` class.\r\n * @param doAnimate if true the grid will animate.\r\n */\r\n public setAnimation(doAnimate: boolean): GridStack {\r\n if (doAnimate) {\r\n this.el.classList.add('grid-stack-animate');\r\n } else {\r\n this.el.classList.remove('grid-stack-animate');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.\r\n * Also toggle the grid-stack-static class.\r\n * @param val if true the grid become static.\r\n */\r\n public setStatic(val: boolean, updateClass = true): GridStack {\r\n if (this.opts.staticGrid === val) return this;\r\n this.opts.staticGrid = val;\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this.engine.nodes.forEach(n => this._prepareDragDropByNode(n)); // either delete or init Drag&drop\r\n if (updateClass) { this._setStaticClass(); }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed.\r\n * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)\r\n * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.\r\n */\r\n public update(els: GridStackElement, opt: GridStackWidget): GridStack {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1;\r\n opt = { x:a[i++], y:a[i++], w:a[i++], h:a[i++] };\r\n return this.update(els, opt);\r\n }\r\n\r\n GridStack.getElements(els).forEach(el => {\r\n if (!el || !el.gridstackNode) return;\r\n let n = el.gridstackNode;\r\n let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items\r\n delete w.autoPosition;\r\n\r\n // move/resize widget if anything changed\r\n let keys = ['x', 'y', 'w', 'h'];\r\n let m: GridStackWidget;\r\n if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) {\r\n m = {};\r\n keys.forEach(k => {\r\n m[k] = (w[k] !== undefined) ? w[k] : n[k];\r\n delete w[k];\r\n });\r\n }\r\n // for a move as well IFF there is any min/max fields set\r\n if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {\r\n m = {}; // will use node position but validate values\r\n }\r\n\r\n // check for content changing\r\n if (w.content) {\r\n let sub = el.querySelector('.grid-stack-item-content');\r\n if (sub && sub.innerHTML !== w.content) {\r\n sub.innerHTML = w.content;\r\n }\r\n delete w.content;\r\n }\r\n\r\n // any remaining fields are assigned, but check for dragging changes, resize constrain\r\n let changed = false;\r\n let ddChanged = false;\r\n for (const key in w) {\r\n if (key[0] !== '_' && n[key] !== w[key]) {\r\n n[key] = w[key];\r\n changed = true;\r\n ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));\r\n }\r\n }\r\n\r\n // finally move the widget\r\n if (m) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(n)\r\n .moveNode(n, m);\r\n this._updateContainerHeight();\r\n this._triggerChangeEvent();\r\n this.engine.endUpdate();\r\n }\r\n if (changed) { // move will only update x,y,w,h so update the rest too\r\n this._writeAttr(el, n);\r\n }\r\n if (ddChanged) {\r\n this._prepareDragDropByNode(n);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number).\r\n * @param value margin value\r\n */\r\n public margin(value: numberOrString): GridStack {\r\n let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);\r\n // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)\r\n if (!isMultiValue) {\r\n let data = Utils.parseHeight(value);\r\n if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) return;\r\n }\r\n // re-use existing margin handling\r\n this.opts.margin = value;\r\n this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;\r\n this._initMargin();\r\n\r\n this._updateStyles(true); // true = force re-create\r\n\r\n return this;\r\n }\r\n\r\n /** returns current margin number value (undefined if 4 sides don't match) */\r\n public getMargin(): number { return this.opts.margin as number; }\r\n\r\n /**\r\n * Returns true if the height of the grid will be less than the vertical\r\n * constraint. Always returns true if grid doesn't have height constraint.\r\n * @param node contains x,y,w,h,auto-position options\r\n *\r\n * @example\r\n * if (grid.willItFit(newWidget)) {\r\n * grid.addWidget(newWidget);\r\n * } else {\r\n * alert('Not enough free space to place the widget');\r\n * }\r\n */\r\n public willItFit(node: GridStackWidget): boolean {\r\n // support legacy call for now\r\n if (arguments.length > 1) {\r\n console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 0,\r\n w: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++] };\r\n return this.willItFit(w);\r\n }\r\n return this.engine.willItFit(node);\r\n }\r\n\r\n /** @internal */\r\n protected _triggerChangeEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n let elements = this.engine.getDirtyNodes(true); // verify they really changed\r\n if (elements && elements.length) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(elements);\r\n }\r\n this._triggerEvent('change', elements);\r\n }\r\n this.engine.saveInitial(); // we called, now reset initial values & dirty flags\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerAddEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(this.engine.addedNodes);\r\n }\r\n // prevent added nodes from also triggering 'change' event (which is called next)\r\n this.engine.addedNodes.forEach(n => { delete n._dirty; });\r\n this._triggerEvent('added', this.engine.addedNodes);\r\n this.engine.addedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n public _triggerRemoveEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {\r\n this._triggerEvent('removed', this.engine.removedNodes);\r\n this.engine.removedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerEvent(name: string, data?: GridStackNode[]): GridStack {\r\n let event = data ? new CustomEvent(name, {bubbles: false, detail: data}) : new Event(name);\r\n this.el.dispatchEvent(event);\r\n return this;\r\n }\r\n\r\n /** @internal called to delete the current dynamic style sheet used for our layout */\r\n protected _removeStylesheet(): GridStack {\r\n\r\n if (this._styles) {\r\n Utils.removeStylesheet(this._styles._id);\r\n delete this._styles;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal updated/create the CSS styles for row based layout and initial margin setting */\r\n protected _updateStyles(forceUpdate = false, maxH?: number): GridStack {\r\n // call to delete existing one if we change cellHeight / margin\r\n if (forceUpdate) {\r\n this._removeStylesheet();\r\n }\r\n\r\n this._updateContainerHeight();\r\n\r\n // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??\r\n if (this.opts.cellHeight === 0) {\r\n return this;\r\n }\r\n\r\n let cellHeight = this.opts.cellHeight as number;\r\n let cellHeightUnit = this.opts.cellHeightUnit;\r\n let prefix = `.${this.opts._styleSheetClass} > .${this.opts.itemClass}`;\r\n\r\n // create one as needed\r\n if (!this._styles) {\r\n let id = 'gridstack-style-' + (Math.random() * 100000).toFixed();\r\n // insert style to parent (instead of 'head' by default) to support WebComponent\r\n let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement;\r\n this._styles = Utils.createStylesheet(id, styleLocation);\r\n if (!this._styles) return this;\r\n this._styles._id = id;\r\n this._styles._max = 0;\r\n\r\n // these are done once only\r\n Utils.addCSSRule(this._styles, prefix, `min-height: ${cellHeight}${cellHeightUnit}`);\r\n // content margins\r\n let top: string = this.opts.marginTop + this.opts.marginUnit;\r\n let bottom: string = this.opts.marginBottom + this.opts.marginUnit;\r\n let right: string = this.opts.marginRight + this.opts.marginUnit;\r\n let left: string = this.opts.marginLeft + this.opts.marginUnit;\r\n let content = `${prefix} > .grid-stack-item-content`;\r\n let placeholder = `.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;\r\n Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n // resize handles offset (to match margin)\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`);\r\n }\r\n\r\n // now update the height specific fields\r\n maxH = maxH || this._styles._max;\r\n if (maxH > this._styles._max) {\r\n let getHeight = (rows: number): string => (cellHeight * rows) + cellHeightUnit;\r\n for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1\r\n let h: string = getHeight(i);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-y=\"${i-1}\"]`, `top: ${getHeight(i-1)}`); // start at 0\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-h=\"${i}\"]`, `height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-min-h=\"${i}\"]`, `min-height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-max-h=\"${i}\"]`, `max-height: ${h}`);\r\n }\r\n this._styles._max = maxH;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _updateContainerHeight(): GridStack {\r\n if (!this.engine || this.engine.batchMode) return this;\r\n let row = this.getRow() + this._extraDragRow; // checks for minRow already\r\n // check for css min height\r\n // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary\r\n // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.\r\n // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);\r\n // if (cssMinHeight > 0) {\r\n // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));\r\n // if (row < minRow) {\r\n // row = minRow;\r\n // }\r\n // }\r\n this.el.setAttribute('gs-current-row', String(row));\r\n if (row === 0) {\r\n this.el.style.removeProperty('height');\r\n return this;\r\n }\r\n let cellHeight = this.opts.cellHeight as number;\r\n let unit = this.opts.cellHeightUnit;\r\n if (!cellHeight) return this;\r\n this.el.style.height = row * cellHeight + unit;\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _prepareElement(el: GridItemHTMLElement, triggerAddEvent = false, node?: GridStackNode): GridStack {\r\n if (!node) {\r\n el.classList.add(this.opts.itemClass);\r\n node = this._readAttr(el);\r\n }\r\n el.gridstackNode = node;\r\n node.el = el;\r\n node.grid = this;\r\n let copy = {...node};\r\n node = this.engine.addNode(node, triggerAddEvent);\r\n // write node attr back in case there was collision or we have to fix bad values during addNode()\r\n if (!Utils.same(node, copy)) {\r\n this._writeAttr(el, node);\r\n }\r\n this._prepareDragDropByNode(node);\r\n return this;\r\n }\r\n\r\n /** @internal call to write position x,y,w,h attributes back to element */\r\n protected _writePosAttr(el: HTMLElement, n: GridStackPosition): GridStack {\r\n if (n.x !== undefined && n.x !== null) { el.setAttribute('gs-x', String(n.x)); }\r\n if (n.y !== undefined && n.y !== null) { el.setAttribute('gs-y', String(n.y)); }\r\n if (n.w) { el.setAttribute('gs-w', String(n.w)); }\r\n if (n.h) { el.setAttribute('gs-h', String(n.h)); }\r\n return this;\r\n }\r\n\r\n /** @internal call to write any default attributes back to element */\r\n protected _writeAttr(el: HTMLElement, node: GridStackWidget): GridStack {\r\n if (!node) return this;\r\n this._writePosAttr(el, node);\r\n\r\n let attrs /*: GridStackWidget but strings */ = { // remaining attributes\r\n autoPosition: 'gs-auto-position',\r\n minW: 'gs-min-w',\r\n minH: 'gs-min-h',\r\n maxW: 'gs-max-w',\r\n maxH: 'gs-max-h',\r\n noResize: 'gs-no-resize',\r\n noMove: 'gs-no-move',\r\n locked: 'gs-locked',\r\n id: 'gs-id',\r\n resizeHandles: 'gs-resize-handles'\r\n };\r\n for (const key in attrs) {\r\n if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway\r\n el.setAttribute(attrs[key], String(node[key]));\r\n } else {\r\n el.removeAttribute(attrs[key]);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal call to read any default attributes from element */\r\n protected _readAttr(el: HTMLElement): GridStackWidget {\r\n let node: GridStackNode = {};\r\n node.x = Utils.toNumber(el.getAttribute('gs-x'));\r\n node.y = Utils.toNumber(el.getAttribute('gs-y'));\r\n node.w = Utils.toNumber(el.getAttribute('gs-w'));\r\n node.h = Utils.toNumber(el.getAttribute('gs-h'));\r\n node.maxW = Utils.toNumber(el.getAttribute('gs-max-w'));\r\n node.minW = Utils.toNumber(el.getAttribute('gs-min-w'));\r\n node.maxH = Utils.toNumber(el.getAttribute('gs-max-h'));\r\n node.minH = Utils.toNumber(el.getAttribute('gs-min-h'));\r\n node.autoPosition = Utils.toBool(el.getAttribute('gs-auto-position'));\r\n node.noResize = Utils.toBool(el.getAttribute('gs-no-resize'));\r\n node.noMove = Utils.toBool(el.getAttribute('gs-no-move'));\r\n node.locked = Utils.toBool(el.getAttribute('gs-locked'));\r\n node.resizeHandles = el.getAttribute('gs-resize-handles');\r\n node.id = el.getAttribute('gs-id');\r\n\r\n // remove any key not found (null or false which is default)\r\n for (const key in node) {\r\n if (!node.hasOwnProperty(key)) return;\r\n if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)\r\n delete node[key];\r\n }\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /** @internal */\r\n protected _setStaticClass(): GridStack {\r\n let classes = ['grid-stack-static'];\r\n\r\n if (this.opts.staticGrid) {\r\n this.el.classList.add(...classes);\r\n this.el.setAttribute('gs-static', 'true');\r\n } else {\r\n this.el.classList.remove(...classes);\r\n this.el.removeAttribute('gs-static');\r\n\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off\r\n * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)\r\n */\r\n public onParentResize(): GridStack {\r\n if (!this.el || !this.el.clientWidth) return; // return if we're gone or no size yet (will get called again)\r\n let changedColumn = false;\r\n\r\n // see if we're nested and take our column count from our parent....\r\n if (this._autoColumn && this.opts._isNested) {\r\n if (this.opts.column !== this.opts._isNested.w) {\r\n changedColumn = true;\r\n this.column(this.opts._isNested.w, 'none');\r\n }\r\n } else {\r\n // else check for 1 column in/out behavior\r\n let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;\r\n if ((this.opts.column === 1) !== oneColumn) {\r\n changedColumn = true;\r\n if (this.opts.animate) { this.setAnimation(false); } // 1 <-> 12 is too radical, turn off animation\r\n this.column(oneColumn ? 1 : this._prevColumn);\r\n if (this.opts.animate) { this.setAnimation(true); }\r\n }\r\n }\r\n\r\n // make the cells content square again\r\n if (this._isAutoCellHeight) {\r\n if (!changedColumn && this.opts.cellHeightThrottle) {\r\n if (!this._cellHeightThrottle) {\r\n this._cellHeightThrottle = Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle);\r\n }\r\n this._cellHeightThrottle();\r\n } else {\r\n // immediate update if we've changed column count or have no threshold\r\n this.cellHeight();\r\n }\r\n }\r\n\r\n // finally update any nested grids\r\n this.engine.nodes.forEach(n => {\r\n if (n.subGrid) {(n.subGrid as GridStack).onParentResize()}\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /** add or remove the window size event handler */\r\n protected _updateWindowResizeEvent(forceRemove = false): GridStack {\r\n // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)\r\n const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested;\r\n\r\n if (!forceRemove && workTodo && !this._windowResizeBind) {\r\n this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later\r\n window.addEventListener('resize', this._windowResizeBind);\r\n } else if ((forceRemove || !workTodo) && this._windowResizeBind) {\r\n window.removeEventListener('resize', this._windowResizeBind);\r\n delete this._windowResizeBind; // remove link to us so we can free\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** @internal convert a potential selector into actual element */\r\n public static getElement(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement { return Utils.getElement(els) }\r\n /** @internal */\r\n public static getElements(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement[] { return Utils.getElements(els) }\r\n /** @internal */\r\n public static getGridElement(els: GridStackElement): GridHTMLElement { return GridStack.getElement(els) }\r\n /** @internal */\r\n public static getGridElements(els: string): GridHTMLElement[] { return Utils.getElements(els) }\r\n\r\n /** @internal initialize margin top/bottom/left/right and units */\r\n protected _initMargin(): GridStack {\r\n\r\n let data: HeightData;\r\n let margin = 0;\r\n\r\n // support passing multiple values like CSS (ex: '5px 10px 0 20px')\r\n let margins: string[] = [];\r\n if (typeof this.opts.margin === 'string') {\r\n margins = this.opts.margin.split(' ')\r\n }\r\n if (margins.length === 2) { // top/bot, left/right like CSS\r\n this.opts.marginTop = this.opts.marginBottom = margins[0];\r\n this.opts.marginLeft = this.opts.marginRight = margins[1];\r\n } else if (margins.length === 4) { // Clockwise like CSS\r\n this.opts.marginTop = margins[0];\r\n this.opts.marginRight = margins[1];\r\n this.opts.marginBottom = margins[2];\r\n this.opts.marginLeft = margins[3];\r\n } else {\r\n data = Utils.parseHeight(this.opts.margin);\r\n this.opts.marginUnit = data.unit;\r\n margin = this.opts.margin = data.h;\r\n }\r\n\r\n // see if top/bottom/left/right need to be set as well\r\n if (this.opts.marginTop === undefined) {\r\n this.opts.marginTop = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginTop);\r\n this.opts.marginTop = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginBottom === undefined) {\r\n this.opts.marginBottom = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginBottom);\r\n this.opts.marginBottom = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginRight === undefined) {\r\n this.opts.marginRight = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginRight);\r\n this.opts.marginRight = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginLeft === undefined) {\r\n this.opts.marginLeft = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginLeft);\r\n this.opts.marginLeft = data.h;\r\n delete this.opts.margin;\r\n }\r\n this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...\r\n if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {\r\n this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()\r\n }\r\n return this;\r\n }\r\n\r\n static GDRev = '6.0.1-dev';\r\n\r\n /*\r\n * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid\r\n * so we don't incur the load unless needed.\r\n * NOTE: had to make those methods public in order to define them else as\r\n * GridStack.prototype._setupAcceptWidget = function()\r\n * maybe there is a better way ????\r\n */\r\n /* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n /**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n * @param dragIn string selector (ex: '.sidebar .grid-stack-item')\r\n * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}\r\n **/\r\n public static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void { /* implemented in dd-gridstack.ts */ }\r\n\r\n /**\r\n * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids.\r\n * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\n public movable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\n public resizable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\n public disable(): GridStack { return this }\r\n /**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\n public enable(): GridStack { return this }\r\n /**\r\n * Enables/disables widget moving. No-op for static grids.\r\n */\r\n public enableMove(doEnable: boolean): GridStack { return this }\r\n /**\r\n * Enables/disables widget resizing. No-op for static grids.\r\n */\r\n public enableResize(doEnable: boolean): GridStack { return this }\r\n\r\n /** @internal removes any drag&drop present (called during destroy) */\r\n public _removeDD(el: GridItemHTMLElement): GridStack { return this }\r\n /** @internal called to add drag over support to support widgets */\r\n public _setupAcceptWidget(): GridStack { return this }\r\n /** @internal called to setup a trash drop zone if the user specifies it */\r\n public _setupRemoveDrop(): GridStack { return this }\r\n /** @internal prepares the element for drag&drop **/\r\n public _prepareDragDropByNode(node: GridStackNode): GridStack { return this }\r\n /** @internal handles actual drag/resize start **/\r\n public _onStartMoving(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal handles actual drag/resize **/\r\n public _dragOrResize(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal called when a node leaves our area (mouse out or shape outside) **/\r\n public _leave(el: GridItemHTMLElement, helper?: GridItemHTMLElement): void { return }\r\n // legacy method removed\r\n public commit(): GridStack { obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }\r\n}\r\n\r\n/*\r\n * and include D&D by default, which override some methods here\r\n * TODO: while we can generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)\r\n * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts\r\n */\r\nimport { DDGridStack } from './dd-gridstack';\r\nimport { isTouch } from './dd-touch';\r\nexport * from './dd-gridstack';\r\n","/**\r\n * utils.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types';\r\n\r\nexport interface HeightData {\r\n h: number;\r\n unit: string;\r\n}\r\n\r\n/** checks for obsolete method names */\r\n// eslint-disable-next-line\r\nexport function obsolete(self, f, oldName: string, newName: string, rev: string): (...args: any[]) => any {\r\n let wrapper = (...args) => {\r\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\r\n 'with `' + newName + '`. It will be **removed** in a future release');\r\n return f.apply(self, args);\r\n }\r\n wrapper.prototype = f.prototype;\r\n return wrapper;\r\n}\r\n\r\n/** checks for obsolete grid options (can be used for any fields, but msg is about options) */\r\nexport function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void {\r\n if (opts[oldName] !== undefined) {\r\n opts[newName] = opts[oldName];\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/** checks for obsolete grid options which are gone */\r\nexport function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void {\r\n if (opts[oldName] !== undefined) {\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\r\n }\r\n}\r\n\r\n/** checks for obsolete Jquery element attributes */\r\nexport function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void {\r\n let oldAttr = el.getAttribute(oldName);\r\n if (oldAttr !== null) {\r\n el.setAttribute(newName, oldAttr);\r\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods\r\n */\r\nexport class Utils {\r\n\r\n /** convert a potential selector into actual list of html elements */\r\n static getElements(els: GridStackElement): HTMLElement[] {\r\n if (typeof els === 'string') {\r\n let list = document.querySelectorAll(els);\r\n if (!list.length && els[0] !== '.' && els[0] !== '#') {\r\n list = document.querySelectorAll('.' + els);\r\n if (!list.length) { list = document.querySelectorAll('#' + els) }\r\n }\r\n return Array.from(list) as HTMLElement[];\r\n }\r\n return [els];\r\n }\r\n\r\n /** convert a potential selector into actual single element */\r\n static getElement(els: GridStackElement): HTMLElement {\r\n if (typeof els === 'string') {\r\n if (!els.length) return null;\r\n if (els[0] === '#') {\r\n return document.getElementById(els.substring(1));\r\n }\r\n if (els[0] === '.' || els[0] === '[') {\r\n return document.querySelector(els);\r\n }\r\n\r\n // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS\r\n if(!isNaN(+els[0])) { // start with digit\r\n return document.getElementById(els);\r\n }\r\n\r\n // finally try string, then id then class\r\n let el = document.querySelector(els);\r\n if (!el) { el = document.getElementById(els) }\r\n if (!el) { el = document.querySelector('.' + els) }\r\n return el as HTMLElement;\r\n }\r\n return els;\r\n }\r\n\r\n /** returns true if a and b overlap */\r\n static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w);\r\n }\r\n\r\n /** returns true if a and b touch edges or corners */\r\n static isTouching(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return Utils.isIntercepted(a, {x: b.x-0.5, y: b.y-0.5, w: b.w+1, h: b.h+1})\r\n }\r\n /**\r\n * Sorts array of nodes\r\n * @param nodes array to sort\r\n * @param dir 1 for asc, -1 for desc (optional)\r\n * @param width width of the grid. If undefined the width will be calculated automatically (optional).\r\n **/\r\n static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[] {\r\n column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12;\r\n if (dir === -1)\r\n return nodes.sort((a, b) => (b.x + b.y * column)-(a.x + a.y * column));\r\n else\r\n return nodes.sort((b, a) => (b.x + b.y * column)-(a.x + a.y * column));\r\n }\r\n\r\n /**\r\n * creates a style sheet with style id under given parent\r\n * @param id will set the 'gs-style-id' attribute to that id\r\n * @param parent to insert the stylesheet as first child,\r\n * if none supplied it will be appended to the document head instead.\r\n */\r\n static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet {\r\n let style: HTMLStyleElement = document.createElement('style');\r\n style.setAttribute('type', 'text/css');\r\n style.setAttribute('gs-style-id', id);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if ((style as any).styleSheet) { // TODO: only CSSImportRule have that and different beast ??\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (style as any).styleSheet.cssText = '';\r\n } else {\r\n style.appendChild(document.createTextNode('')); // WebKit hack\r\n }\r\n if (!parent) {\r\n // default to head\r\n parent = document.getElementsByTagName('head')[0];\r\n parent.appendChild(style);\r\n } else {\r\n parent.insertBefore(style, parent.firstChild);\r\n }\r\n return style.sheet as CSSStyleSheet;\r\n }\r\n\r\n /** removed the given stylesheet id */\r\n static removeStylesheet(id: string): void {\r\n let el = document.querySelector('STYLE[gs-style-id=' + id + ']');\r\n if (el && el.parentNode) el.remove();\r\n }\r\n\r\n /** inserts a CSS rule */\r\n static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void {\r\n if (typeof sheet.addRule === 'function') {\r\n sheet.addRule(selector, rules);\r\n } else if (typeof sheet.insertRule === 'function') {\r\n sheet.insertRule(`${selector}{${rules}}`);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n static toBool(v: unknown): boolean {\r\n if (typeof v === 'boolean') {\r\n return v;\r\n }\r\n if (typeof v === 'string') {\r\n v = v.toLowerCase();\r\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\r\n }\r\n return Boolean(v);\r\n }\r\n\r\n static toNumber(value: null | string): number {\r\n return (value === null || value.length === 0) ? undefined : Number(value);\r\n }\r\n\r\n static parseHeight(val: numberOrString): HeightData {\r\n let h: number;\r\n let unit = 'px';\r\n if (typeof val === 'string') {\r\n let match = val.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\r\n if (!match) {\r\n throw new Error('Invalid height');\r\n }\r\n unit = match[2] || 'px';\r\n h = parseFloat(match[1]);\r\n } else {\r\n h = val;\r\n }\r\n return { h, unit };\r\n }\r\n\r\n /** copies unset fields in target to use the given default sources values */\r\n // eslint-disable-next-line\r\n static defaults(target, ...sources): {} {\r\n\r\n sources.forEach(source => {\r\n for (const key in source) {\r\n if (!source.hasOwnProperty(key)) return;\r\n if (target[key] === null || target[key] === undefined) {\r\n target[key] = source[key];\r\n } else if (typeof source[key] === 'object' && typeof target[key] === 'object') {\r\n // property is an object, recursively add it's field over... #1373\r\n this.defaults(target[key], source[key]);\r\n }\r\n }\r\n });\r\n\r\n return target;\r\n }\r\n\r\n /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */\r\n static same(a: unknown, b: unknown): boolean {\r\n if (typeof a !== 'object') return a == b;\r\n if (typeof a !== typeof b) return false;\r\n // else we have object, check just 1 level deep for being same things...\r\n if (Object.keys(a).length !== Object.keys(b).length) return false;\r\n for (const key in a) {\r\n if (a[key] !== b[key]) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /** copies over b size & position (GridStackPosition), and possibly min/max as well */\r\n static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax = false): GridStackWidget {\r\n a.x = b.x;\r\n a.y = b.y;\r\n a.w = b.w;\r\n a.h = b.h;\r\n if (doMinMax) {\r\n if (b.minW) a.minW = b.minW;\r\n if (b.minH) a.minH = b.minH;\r\n if (b.maxW) a.maxW = b.maxW;\r\n if (b.maxH) a.maxH = b.maxH;\r\n }\r\n return a;\r\n }\r\n\r\n /** true if a and b has same size & position */\r\n static samePos(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\r\n }\r\n\r\n /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */\r\n static removeInternalAndSame(a: unknown, b: unknown):void {\r\n if (typeof a !== 'object' || typeof b !== 'object') return;\r\n for (let key in a) {\r\n let val = a[key];\r\n if (key[0] === '_' || val === b[key]) {\r\n delete a[key]\r\n } else if (val && typeof val === 'object' && b[key] !== undefined) {\r\n for (let i in val) {\r\n if (val[i] === b[key][i] || i[0] === '_') { delete val[i] }\r\n }\r\n if (!Object.keys(val).length) { delete a[key] }\r\n }\r\n }\r\n }\r\n\r\n /** return the closest parent (or itself) matching the given class */\r\n static closestByClass(el: HTMLElement, name: string): HTMLElement {\r\n while (el) {\r\n if (el.classList.contains(name)) return el;\r\n el = el.parentElement\r\n }\r\n return null;\r\n }\r\n\r\n /** delay calling the given function for given delay, preventing new calls from happening while waiting */\r\n static throttle(func: () => void, delay: number): () => void {\r\n let isWaiting = false;\r\n return (...args) => {\r\n if (!isWaiting) {\r\n isWaiting = true;\r\n setTimeout(() => { func(...args); isWaiting = false; }, delay);\r\n }\r\n }\r\n }\r\n\r\n static removePositioningStyles(el: HTMLElement): void {\r\n let style = el.style;\r\n if (style.position) {\r\n style.removeProperty('position');\r\n }\r\n if (style.left) {\r\n style.removeProperty('left');\r\n }\r\n if (style.top) {\r\n style.removeProperty('top');\r\n }\r\n if (style.width) {\r\n style.removeProperty('width');\r\n }\r\n if (style.height) {\r\n style.removeProperty('height');\r\n }\r\n }\r\n\r\n /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */\r\n static getScrollElement(el?: HTMLElement): HTMLElement {\r\n if (!el) return document.scrollingElement as HTMLElement || document.documentElement; // IE support\r\n const style = getComputedStyle(el);\r\n const overflowRegex = /(auto|scroll)/;\r\n\r\n if (overflowRegex.test(style.overflow + style.overflowY)) {\r\n return el;\r\n } else {\r\n return this.getScrollElement(el.parentElement);\r\n }\r\n }\r\n\r\n /** @internal */\r\n static updateScrollPosition(el: HTMLElement, position: {top: number}, distance: number): void {\r\n // is widget in view?\r\n let rect = el.getBoundingClientRect();\r\n let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\r\n if (rect.top < 0 ||\r\n rect.bottom > innerHeightOrClientHeight\r\n ) {\r\n // set scrollTop of first parent that scrolls\r\n // if parent is larger than el, set as low as possible\r\n // to get entire widget on screen\r\n let offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\r\n let offsetDiffUp = rect.top;\r\n let scrollEl = this.getScrollElement(el);\r\n if (scrollEl !== null) {\r\n let prevScroll = scrollEl.scrollTop;\r\n if (rect.top < 0 && distance < 0) {\r\n // moving up\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\r\n }\r\n } else if (distance > 0) {\r\n // moving down\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\r\n }\r\n }\r\n // move widget y by amount scrolled\r\n position.top += scrollEl.scrollTop - prevScroll;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal Function used to scroll the page.\r\n *\r\n * @param event `MouseEvent` that triggers the resize\r\n * @param el `HTMLElement` that's being resized\r\n * @param distance Distance from the V edges to start scrolling\r\n */\r\n static updateScrollResize(event: MouseEvent, el: HTMLElement, distance: number): void {\r\n const scrollEl = this.getScrollElement(el);\r\n const height = scrollEl.clientHeight;\r\n // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top\r\n // #1745 Special situation if scrollEl is document 'html': here browser spec states that\r\n // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;\r\n // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.\r\n const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top;\r\n const pointerPosY = event.clientY - offsetTop;\r\n const top = pointerPosY < distance;\r\n const bottom = pointerPosY > height - distance;\r\n\r\n if (top) {\r\n // This also can be done with a timeout to keep scrolling while the mouse is\r\n // in the scrolling zone. (will have smoother behavior)\r\n scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance});\r\n } else if (bottom) {\r\n scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY)});\r\n }\r\n }\r\n\r\n /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */\r\n static clone(obj: T): T {\r\n if (obj === null || obj === undefined || typeof(obj) !== 'object') {\r\n return obj;\r\n }\r\n // return Object.assign({}, obj);\r\n if (obj instanceof Array) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return [...obj] as any;\r\n }\r\n return {...obj};\r\n }\r\n\r\n /**\r\n * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.\r\n * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.\r\n */\r\n static cloneDeep(obj: T): T {\r\n // list of fields we will skip during cloneDeep (nested objects, other internal)\r\n const skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine'];\r\n // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ?\r\n const ret = Utils.clone(obj);\r\n for (const key in ret) {\r\n // NOTE: we don't support function/circular dependencies so skip those properties for now...\r\n if (ret.hasOwnProperty(key) && typeof(ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) {\r\n ret[key] = Utils.cloneDeep(obj[key]);\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /** deep clone the given HTML node, removing teh unique id field */\r\n public static cloneNode(el: HTMLElement): HTMLElement {\r\n const node = el.cloneNode(true) as HTMLElement;\r\n node.removeAttribute('id');\r\n return node;\r\n }\r\n\r\n public static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void {\r\n let parentNode: HTMLElement;\r\n if (typeof parent === 'string') {\r\n parentNode = document.querySelector(parent as string);\r\n } else {\r\n parentNode = parent as HTMLElement;\r\n }\r\n if (parentNode) {\r\n parentNode.appendChild(el);\r\n }\r\n }\r\n\r\n // public static setPositionRelative(el: HTMLElement): void {\r\n // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) {\r\n // el.style.position = \"relative\";\r\n // }\r\n // }\r\n\r\n public static addElStyles(el: HTMLElement, styles: { [prop: string]: string | string[] }): void {\r\n if (styles instanceof Object) {\r\n for (const s in styles) {\r\n if (styles.hasOwnProperty(s)) {\r\n if (Array.isArray(styles[s])) {\r\n // support fallback value\r\n (styles[s] as string[]).forEach(val => {\r\n el.style[s] = val;\r\n });\r\n } else {\r\n el.style[s] = styles[s];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public static initEvent(e: DragEvent | MouseEvent, info: { type: string; target?: EventTarget }): T {\r\n const evt = { type: info.type };\r\n const obj = {\r\n button: 0,\r\n which: 0,\r\n buttons: 1,\r\n bubbles: true,\r\n cancelable: true,\r\n target: info.target ? info.target : e.target\r\n };\r\n // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540\r\n if ((e as DragEvent).dataTransfer) {\r\n evt['dataTransfer'] = (e as DragEvent).dataTransfer; // workaround 'readonly' field.\r\n }\r\n ['altKey','ctrlKey','metaKey','shiftKey'].forEach(p => evt[p] = e[p]); // keys\r\n ['pageX','pageY','clientX','clientY','screenX','screenY'].forEach(p => evt[p] = e[p]); // point info\r\n return {...evt, ...obj} as unknown as T;\r\n }\r\n\r\n /** returns true if event is inside the given element rectangle */\r\n // Note: Safari Mac has null event.relatedTarget which causes #1684 so check if DragEvent is inside the coordinates instead\r\n // this.el.contains(event.relatedTarget as HTMLElement)\r\n // public static inside(e: MouseEvent, el: HTMLElement): boolean {\r\n // // srcElement, toElement, target: all set to placeholder when leaving simple grid, so we can't use that (Chrome)\r\n // let target: HTMLElement = e.relatedTarget || (e as any).fromElement;\r\n // if (!target) {\r\n // const { bottom, left, right, top } = el.getBoundingClientRect();\r\n // return (e.x < right && e.x > left && e.y < bottom && e.y > top);\r\n // }\r\n // return el.contains(target);\r\n // }\r\n}\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(324);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/es5/gridstack-engine.d.ts b/dist/es5/gridstack-engine.d.ts new file mode 100644 index 000000000..97e09d74b --- /dev/null +++ b/dist/es5/gridstack-engine.d.ts @@ -0,0 +1,96 @@ +/** + * gridstack-engine.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { GridStackNode, GridStackPosition, GridStackMoveOpts } from './types'; +/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */ +declare type OnChangeCB = (nodes: GridStackNode[]) => void; +/** options used during creation - similar to GridStackOptions */ +export interface GridStackEngineOptions { + column?: number; + maxRow?: number; + float?: boolean; + nodes?: GridStackNode[]; + onChange?: OnChangeCB; +} +/** + * Defines the GridStack engine that does most no DOM grid manipulation. + * See GridStack methods and vars for descriptions. + * + * NOTE: values should not be modified directly - call the main GridStack API instead + */ +export declare class GridStackEngine { + column: number; + maxRow: number; + nodes: GridStackNode[]; + addedNodes: GridStackNode[]; + removedNodes: GridStackNode[]; + batchMode: boolean; + constructor(opts?: GridStackEngineOptions); + batchUpdate(flag?: boolean): GridStackEngine; + protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean; + /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */ + collide(skip: GridStackNode, area?: GridStackNode, skip2?: GridStackNode): GridStackNode; + collideAll(skip: GridStackNode, area?: GridStackNode, skip2?: GridStackNode): GridStackNode[]; + /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */ + collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode; + /** called to cache the nodes pixel rectangles used for collision detection during drag */ + cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine; + /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */ + swap(a: GridStackNode, b: GridStackNode): boolean; + isAreaEmpty(x: number, y: number, w: number, h: number): boolean; + /** re-layout grid items to reclaim any empty space */ + compact(): GridStackEngine; + /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */ + set float(val: boolean); + /** float getter method */ + get float(): boolean; + /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */ + sortNodes(dir?: -1 | 1): GridStackEngine; + /** + * given a random node, makes sure it's coordinates/values are valid in the current grid + * @param node to adjust + * @param resizing if out of bound, resize down or move into the grid to fit ? + */ + prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode; + /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */ + nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode; + /** returns a list of modified nodes from their original values */ + getDirtyNodes(verify?: boolean): GridStackNode[]; + /** call to add the given node to our list, fixing collision and re-packing */ + addNode(node: GridStackNode, triggerAddEvent?: boolean): GridStackNode; + removeNode(node: GridStackNode, removeDOM?: boolean, triggerEvent?: boolean): GridStackEngine; + removeAll(removeDOM?: boolean): GridStackEngine; + /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move. + * In more complicated cases (maxRow) it will attempt at moving the item and fixing + * others in a clone first, then apply those changes if still within specs. */ + moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean; + /** return true if can fit in grid height constrain only (always true if no maxRow) */ + willItFit(node: GridStackNode): boolean; + /** true if x,y or w,h are different after clamping to min/max */ + changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean; + /** return true if the passed in node was actually moved (checks for no-op and locked) */ + moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean; + getRow(): number; + beginUpdate(node: GridStackNode): GridStackEngine; + endUpdate(): GridStackEngine; + /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout), + * returning a list of widgets for serialization */ + save(saveElement?: boolean): GridStackNode[]; + /** + * call to cache the given layout internally to the given location so we can restore back when column changes size + * @param nodes list of nodes + * @param column corresponding column index to save it under + * @param clear if true, will force other caches to be removed (default false) + */ + cacheLayout(nodes: GridStackNode[], column: number, clear?: boolean): GridStackEngine; + /** + * call to cache the given node layout internally to the given location so we can restore back when column changes size + * @param node single node to cache + * @param column corresponding column index to save it under + */ + cacheOneLayout(n: GridStackNode, column: number): GridStackEngine; + /** called to remove all internal values but the _id */ + cleanupNode(node: GridStackNode): GridStackEngine; +} +export {}; diff --git a/dist/es5/gridstack-engine.js b/dist/es5/gridstack-engine.js new file mode 100644 index 000000000..e20c6fdd4 --- /dev/null +++ b/dist/es5/gridstack-engine.js @@ -0,0 +1,945 @@ +"use strict"; +/** + * gridstack-engine.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GridStackEngine = void 0; +var utils_1 = require("./utils"); +/** + * Defines the GridStack engine that does most no DOM grid manipulation. + * See GridStack methods and vars for descriptions. + * + * NOTE: values should not be modified directly - call the main GridStack API instead + */ +var GridStackEngine = /** @class */ (function () { + function GridStackEngine(opts) { + if (opts === void 0) { opts = {}; } + this.addedNodes = []; + this.removedNodes = []; + this.column = opts.column || 12; + this.maxRow = opts.maxRow; + this._float = opts.float; + this.nodes = opts.nodes || []; + this.onChange = opts.onChange; + } + GridStackEngine.prototype.batchUpdate = function (flag) { + if (flag === void 0) { flag = true; } + if (!!this.batchMode === flag) + return this; + this.batchMode = flag; + if (flag) { + this._prevFloat = this._float; + this._float = true; // let things go anywhere for now... will restore and possibly reposition later + this.saveInitial(); // since begin update (which is called multiple times) won't do this + } + else { + this._float = this._prevFloat; + delete this._prevFloat; + this._packNodes()._notify(); + } + return this; + }; + // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip + GridStackEngine.prototype._useEntireRowArea = function (node, nn) { + return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y); + }; + /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found. + * return true if we moved. */ + GridStackEngine.prototype._fixCollisions = function (node, nn, collide, opt) { + if (nn === void 0) { nn = node; } + if (opt === void 0) { opt = {}; } + this.sortNodes(-1); // from last to first, so recursive collision move items in the right order + collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none... + if (!collide) + return false; + // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size + if (node._moving && !opt.nested && !this.float) { + if (this.swap(node, collide)) + return true; + } + // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid) + var area = nn; + if (this._useEntireRowArea(node, nn)) { + area = { x: 0, w: this.column, y: nn.y, h: nn.h }; + collide = this.collide(node, area, opt.skip); // force new hit + } + var didMove = false; + var newOpt = { nested: true, pack: false }; + while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each + var moved = void 0; + // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide, + // but remember that skip down so we only do this once (and push others otherwise). + if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float && + // can take space we had, or before where we're going + (!this.collide(collide, __assign(__assign({}, collide), { y: node.y }), node) || !this.collide(collide, __assign(__assign({}, collide), { y: nn.y - collide.h }), node))) { + node._skipDown = (node._skipDown || nn.y > node.y); + moved = this.moveNode(node, __assign(__assign(__assign({}, nn), { y: collide.y + collide.h }), newOpt)); + if (collide.locked && moved) { + utils_1.Utils.copyPos(nn, node); // moving after lock become our new desired location + } + else if (!collide.locked && moved && opt.pack) { + // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way + this._packNodes(); + nn.y = collide.y + collide.h; + utils_1.Utils.copyPos(node, nn); + } + didMove = didMove || moved; + } + else { + // move collide down *after* where we will be, ignoring where we are now (don't collide with us) + moved = this.moveNode(collide, __assign(__assign(__assign({}, collide), { y: nn.y + nn.h, skip: node }), newOpt)); + } + if (!moved) { + return didMove; + } // break inf loop if we couldn't move after all (ex: maxRow, fixed) + collide = undefined; + } + return didMove; + }; + /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */ + GridStackEngine.prototype.collide = function (skip, area, skip2) { + if (area === void 0) { area = skip; } + return this.nodes.find(function (n) { return n !== skip && n !== skip2 && utils_1.Utils.isIntercepted(n, area); }); + }; + GridStackEngine.prototype.collideAll = function (skip, area, skip2) { + if (area === void 0) { area = skip; } + return this.nodes.filter(function (n) { return n !== skip && n !== skip2 && utils_1.Utils.isIntercepted(n, area); }); + }; + /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */ + GridStackEngine.prototype.collideCoverage = function (node, o, collides) { + if (!o.rect || !node._rect) + return; + var r0 = node._rect; // where started + var r = __assign({}, o.rect); // where we are + // update dragged rect to show where it's coming from (above or below, etc...) + if (r.y > r0.y) { + r.h += r.y - r0.y; + r.y = r0.y; + } + else { + r.h += r0.y - r.y; + } + if (r.x > r0.x) { + r.w += r.x - r0.x; + r.x = r0.x; + } + else { + r.w += r0.x - r.x; + } + var collide; + collides.forEach(function (n) { + if (n.locked || !n._rect) + return; + var r2 = n._rect; // overlapping target + var yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50% + // depending on which side we started from, compute the overlap % of coverage + // (ex: from above/below we only compute the max horizontal line coverage) + if (r0.y < r2.y) { // from above + yOver = ((r.y + r.h) - r2.y) / r2.h; + } + else if (r0.y + r0.h > r2.y + r2.h) { // from below + yOver = ((r2.y + r2.h) - r.y) / r2.h; + } + if (r0.x < r2.x) { // from the left + xOver = ((r.x + r.w) - r2.x) / r2.w; + } + else if (r0.x + r0.w > r2.x + r2.w) { // from the right + xOver = ((r2.x + r2.w) - r.x) / r2.w; + } + var over = Math.min(xOver, yOver); + if (over > overMax) { + overMax = over; + collide = n; + } + }); + return collide; + }; + /** called to cache the nodes pixel rectangles used for collision detection during drag */ + GridStackEngine.prototype.cacheRects = function (w, h, top, right, bottom, left) { + this.nodes.forEach(function (n) { + return n._rect = { + y: n.y * h + top, + x: n.x * w + left, + w: n.w * w - left - right, + h: n.h * h - top - bottom + }; + }); + return this; + }; + /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */ + GridStackEngine.prototype.swap = function (a, b) { + if (!b || b.locked || !a || a.locked) + return false; + function _doSwap() { + var x = b.x, y = b.y; + b.x = a.x; + b.y = a.y; // b -> a position + if (a.h != b.h) { + a.x = x; + a.y = b.y + b.h; // a -> goes after b + } + else if (a.w != b.w) { + a.x = b.x + b.w; + a.y = y; // a -> goes after b + } + else { + a.x = x; + a.y = y; // a -> old b position + } + a._dirty = b._dirty = true; + return true; + } + var touching; // remember if we called it (vs undefined) + // same size and same row or column, and touching + if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = utils_1.Utils.isTouching(a, b))) + return _doSwap(); + if (touching === false) + return; // IFF ran test and fail, bail out + // check for taking same columns (but different height) and touching + if (a.w === b.w && a.x === b.x && (touching || (touching = utils_1.Utils.isTouching(a, b)))) { + if (b.y < a.y) { + var t = a; + a = b; + b = t; + } // swap a <-> b vars so a is first + return _doSwap(); + } + if (touching === false) + return; + // check if taking same row (but different width) and touching + if (a.h === b.h && a.y === b.y && (touching || (touching = utils_1.Utils.isTouching(a, b)))) { + if (b.x < a.x) { + var t = a; + a = b; + b = t; + } // swap a <-> b vars so a is first + return _doSwap(); + } + return false; + }; + GridStackEngine.prototype.isAreaEmpty = function (x, y, w, h) { + var nn = { x: x || 0, y: y || 0, w: w || 1, h: h || 1 }; + return !this.collide(nn); + }; + /** re-layout grid items to reclaim any empty space */ + GridStackEngine.prototype.compact = function () { + var _this = this; + if (this.nodes.length === 0) + return this; + this.batchUpdate() + .sortNodes(); + var copyNodes = this.nodes; + this.nodes = []; // pretend we have no nodes to conflict layout to start with... + copyNodes.forEach(function (node) { + if (!node.locked) { + node.autoPosition = true; + } + _this.addNode(node, false); // 'false' for add event trigger + node._dirty = true; // will force attr update + }); + return this.batchUpdate(false); + }; + Object.defineProperty(GridStackEngine.prototype, "float", { + /** float getter method */ + get: function () { return this._float || false; }, + /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */ + set: function (val) { + if (this._float === val) + return; + this._float = val || false; + if (!val) { + this._packNodes()._notify(); + } + }, + enumerable: false, + configurable: true + }); + /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */ + GridStackEngine.prototype.sortNodes = function (dir) { + this.nodes = utils_1.Utils.sort(this.nodes, dir, this.column); + return this; + }; + /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */ + GridStackEngine.prototype._packNodes = function () { + var _this = this; + if (this.batchMode) { + return this; + } + this.sortNodes(); // first to last + if (this.float) { + // restore original Y pos + this.nodes.forEach(function (n) { + if (n._updating || n._orig === undefined || n.y === n._orig.y) + return; + var newY = n.y; + while (newY > n._orig.y) { + --newY; + var collide = _this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h }); + if (!collide) { + n._dirty = true; + n.y = newY; + } + } + }); + } + else { + // top gravity pack + this.nodes.forEach(function (n, i) { + if (n.locked) + return; + while (n.y > 0) { + var newY = i === 0 ? 0 : n.y - 1; + var canBeMoved = i === 0 || !_this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h }); + if (!canBeMoved) + break; + // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions + // and move items back. The user 'change' CB should detect changes from the original + // starting position instead. + n._dirty = (n.y !== newY); + n.y = newY; + } + }); + } + return this; + }; + /** + * given a random node, makes sure it's coordinates/values are valid in the current grid + * @param node to adjust + * @param resizing if out of bound, resize down or move into the grid to fit ? + */ + GridStackEngine.prototype.prepareNode = function (node, resizing) { + node = node || {}; + node._id = node._id || GridStackEngine._idSeq++; + // if we're missing position, have the grid position us automatically (before we set them to 0,0) + if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) { + node.autoPosition = true; + } + // assign defaults for missing required fields + var defaults = { x: 0, y: 0, w: 1, h: 1 }; + utils_1.Utils.defaults(node, defaults); + if (!node.autoPosition) { + delete node.autoPosition; + } + if (!node.noResize) { + delete node.noResize; + } + if (!node.noMove) { + delete node.noMove; + } + // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #) + if (typeof node.x == 'string') { + node.x = Number(node.x); + } + if (typeof node.y == 'string') { + node.y = Number(node.y); + } + if (typeof node.w == 'string') { + node.w = Number(node.w); + } + if (typeof node.h == 'string') { + node.h = Number(node.h); + } + if (isNaN(node.x)) { + node.x = defaults.x; + node.autoPosition = true; + } + if (isNaN(node.y)) { + node.y = defaults.y; + node.autoPosition = true; + } + if (isNaN(node.w)) { + node.w = defaults.w; + } + if (isNaN(node.h)) { + node.h = defaults.h; + } + return this.nodeBoundFix(node, resizing); + }; + /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */ + GridStackEngine.prototype.nodeBoundFix = function (node, resizing) { + var before = node._orig || utils_1.Utils.copyPos({}, node); + if (node.maxW) { + node.w = Math.min(node.w, node.maxW); + } + if (node.maxH) { + node.h = Math.min(node.h, node.maxH); + } + if (node.minW && node.minW <= this.column) { + node.w = Math.max(node.w, node.minW); + } + if (node.minH) { + node.h = Math.max(node.h, node.minH); + } + if (node.w > this.column) { + // if user loaded a larger than allowed widget for current # of columns, + // remember it's full width so we can restore back (1 -> 12 column) #1655 + // IFF we're not in the middle of column resizing! + if (this.column < 12 && !this._inColumnResize) { + node.w = Math.min(12, node.w); + this.cacheOneLayout(node, 12); + } + node.w = this.column; + } + else if (node.w < 1) { + node.w = 1; + } + if (this.maxRow && node.h > this.maxRow) { + node.h = this.maxRow; + } + else if (node.h < 1) { + node.h = 1; + } + if (node.x < 0) { + node.x = 0; + } + if (node.y < 0) { + node.y = 0; + } + if (node.x + node.w > this.column) { + if (resizing) { + node.w = this.column - node.x; + } + else { + node.x = this.column - node.w; + } + } + if (this.maxRow && node.y + node.h > this.maxRow) { + if (resizing) { + node.h = this.maxRow - node.y; + } + else { + node.y = this.maxRow - node.h; + } + } + if (!utils_1.Utils.samePos(node, before)) { + node._dirty = true; + } + return node; + }; + /** returns a list of modified nodes from their original values */ + GridStackEngine.prototype.getDirtyNodes = function (verify) { + // compare original x,y,w,h instead as _dirty can be a temporary state + if (verify) { + return this.nodes.filter(function (n) { return n._dirty && !utils_1.Utils.samePos(n, n._orig); }); + } + return this.nodes.filter(function (n) { return n._dirty; }); + }; + /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */ + GridStackEngine.prototype._notify = function (removedNodes) { + if (this.batchMode || !this.onChange) + return this; + var dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes()); + this.onChange(dirtyNodes); + return this; + }; + /** @internal remove dirty and last tried info */ + GridStackEngine.prototype.cleanNodes = function () { + if (this.batchMode) + return this; + this.nodes.forEach(function (n) { + delete n._dirty; + delete n._lastTried; + }); + return this; + }; + /** @internal called to save initial position/size to track real dirty state. + * Note: should be called right after we call change event (so next API is can detect changes) + * as well as right before we start move/resize/enter (so we can restore items to prev values) */ + GridStackEngine.prototype.saveInitial = function () { + this.nodes.forEach(function (n) { + n._orig = utils_1.Utils.copyPos({}, n); + delete n._dirty; + }); + this._hasLocked = this.nodes.some(function (n) { return n.locked; }); + return this; + }; + /** @internal restore all the nodes back to initial values (called when we leave) */ + GridStackEngine.prototype.restoreInitial = function () { + this.nodes.forEach(function (n) { + if (utils_1.Utils.samePos(n, n._orig)) + return; + utils_1.Utils.copyPos(n, n._orig); + n._dirty = true; + }); + this._notify(); + return this; + }; + /** call to add the given node to our list, fixing collision and re-packing */ + GridStackEngine.prototype.addNode = function (node, triggerAddEvent) { + if (triggerAddEvent === void 0) { triggerAddEvent = false; } + var dup = this.nodes.find(function (n) { return n._id === node._id; }); + if (dup) + return dup; // prevent inserting twice! return it instead. + // skip prepareNode if we're in middle of column resize (not new) but do check for bounds! + node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node); + delete node._temporaryRemoved; + delete node._removeDOM; + if (node.autoPosition) { + this.sortNodes(); + var _loop_1 = function (i) { + var x = i % this_1.column; + var y = Math.floor(i / this_1.column); + if (x + node.w > this_1.column) { + return "continue"; + } + var box = { x: x, y: y, w: node.w, h: node.h }; + if (!this_1.nodes.find(function (n) { return utils_1.Utils.isIntercepted(box, n); })) { + node.x = x; + node.y = y; + delete node.autoPosition; // found our slot + return "break"; + } + }; + var this_1 = this; + for (var i = 0;; ++i) { + var state_1 = _loop_1(i); + if (state_1 === "break") + break; + } + } + this.nodes.push(node); + if (triggerAddEvent) { + this.addedNodes.push(node); + } + this._fixCollisions(node); + if (!this.batchMode) { + this._packNodes()._notify(); + } + return node; + }; + GridStackEngine.prototype.removeNode = function (node, removeDOM, triggerEvent) { + if (removeDOM === void 0) { removeDOM = true; } + if (triggerEvent === void 0) { triggerEvent = false; } + if (!this.nodes.find(function (n) { return n === node; })) { + // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`) + return this; + } + if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag) + this.removedNodes.push(node); + } + if (removeDOM) + node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info) + // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times. + this.nodes = this.nodes.filter(function (n) { return n !== node; }); + return this._packNodes() + ._notify([node]); + }; + GridStackEngine.prototype.removeAll = function (removeDOM) { + if (removeDOM === void 0) { removeDOM = true; } + delete this._layouts; + if (this.nodes.length === 0) + return this; + removeDOM && this.nodes.forEach(function (n) { return n._removeDOM = true; }); // let CB remove actual HTML (used to set _id to null, but then we loose layout info) + this.removedNodes = this.nodes; + this.nodes = []; + return this._notify(this.removedNodes); + }; + /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move. + * In more complicated cases (maxRow) it will attempt at moving the item and fixing + * others in a clone first, then apply those changes if still within specs. */ + GridStackEngine.prototype.moveNodeCheck = function (node, o) { + var _this = this; + // if (node.locked) return false; + if (!this.changedPosConstrain(node, o)) + return false; + o.pack = true; + // simpler case: move item directly... + if (!this.maxRow) { + return this.moveNode(node, o); + } + // complex case: create a clone with NO maxRow (will check for out of bounds at the end) + var clonedNode; + var clone = new GridStackEngine({ + column: this.column, + float: this.float, + nodes: this.nodes.map(function (n) { + if (n === node) { + clonedNode = __assign({}, n); + return clonedNode; + } + return __assign({}, n); + }) + }); + if (!clonedNode) + return false; + // make sure we are still valid size + var canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow; + // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing + if (!canMove && !o.resizing) { + var collide = this.collide(node, o); + if (collide && this.swap(node, collide)) { + this._notify(); + return true; + } + } + if (!canMove) + return false; + // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over! + // Note: we can't use the list directly as elements and other parts point to actual node, so copy content + clone.nodes.filter(function (n) { return n._dirty; }).forEach(function (c) { + var n = _this.nodes.find(function (a) { return a._id === c._id; }); + if (!n) + return; + utils_1.Utils.copyPos(n, c); + n._dirty = true; + }); + this._notify(); + return true; + }; + /** return true if can fit in grid height constrain only (always true if no maxRow) */ + GridStackEngine.prototype.willItFit = function (node) { + delete node._willFitPos; + if (!this.maxRow) + return true; + // create a clone with NO maxRow and check if still within size + var clone = new GridStackEngine({ + column: this.column, + float: this.float, + nodes: this.nodes.map(function (n) { return __assign({}, n); }) + }); + var n = __assign({}, node); // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687 + this.cleanupNode(n); + delete n.el; + delete n._id; + delete n.content; + delete n.grid; + clone.addNode(n); + if (clone.getRow() <= this.maxRow) { + node._willFitPos = utils_1.Utils.copyPos({}, n); + return true; + } + return false; + }; + /** true if x,y or w,h are different after clamping to min/max */ + GridStackEngine.prototype.changedPosConstrain = function (node, p) { + // first make sure w,h are set for caller + p.w = p.w || node.w; + p.h = p.h || node.h; + if (node.x !== p.x || node.y !== p.y) + return true; + // check constrained w,h + if (node.maxW) { + p.w = Math.min(p.w, node.maxW); + } + if (node.maxH) { + p.h = Math.min(p.h, node.maxH); + } + if (node.minW) { + p.w = Math.max(p.w, node.minW); + } + if (node.minH) { + p.h = Math.max(p.h, node.minH); + } + return (node.w !== p.w || node.h !== p.h); + }; + /** return true if the passed in node was actually moved (checks for no-op and locked) */ + GridStackEngine.prototype.moveNode = function (node, o) { + if (!node || /*node.locked ||*/ !o) + return false; + if (o.pack === undefined) + o.pack = true; + // constrain the passed in values and check if we're still changing our node + if (typeof o.x !== 'number') { + o.x = node.x; + } + if (typeof o.y !== 'number') { + o.y = node.y; + } + if (typeof o.w !== 'number') { + o.w = node.w; + } + if (typeof o.h !== 'number') { + o.h = node.h; + } + var resizing = (node.w !== o.w || node.h !== o.h); + var nn = utils_1.Utils.copyPos({}, node, true); // get min/max out first, then opt positions next + utils_1.Utils.copyPos(nn, o); + nn = this.nodeBoundFix(nn, resizing); + utils_1.Utils.copyPos(o, nn); + if (utils_1.Utils.samePos(node, o)) + return false; + var prevPos = utils_1.Utils.copyPos({}, node); + // check if we will need to fix collision at our new location + var collides = this.collideAll(node, nn, o.skip); + var needToMove = true; + if (collides.length) { + // now check to make sure we actually collided over 50% surface area while dragging + var collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0]; + if (collide) { + needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved... + } + else { + needToMove = false; // we didn't cover >50% for a move, skip... + } + } + // now move (to the original ask vs the collision version which might differ) and repack things + if (needToMove) { + node._dirty = true; + utils_1.Utils.copyPos(node, nn); + } + if (o.pack) { + this._packNodes() + ._notify(); + } + return !utils_1.Utils.samePos(node, prevPos); // pack might have moved things back + }; + GridStackEngine.prototype.getRow = function () { + return this.nodes.reduce(function (row, n) { return Math.max(row, n.y + n.h); }, 0); + }; + GridStackEngine.prototype.beginUpdate = function (node) { + if (!node._updating) { + node._updating = true; + delete node._skipDown; + if (!this.batchMode) + this.saveInitial(); + } + return this; + }; + GridStackEngine.prototype.endUpdate = function () { + var n = this.nodes.find(function (n) { return n._updating; }); + if (n) { + delete n._updating; + delete n._skipDown; + } + return this; + }; + /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout), + * returning a list of widgets for serialization */ + GridStackEngine.prototype.save = function (saveElement) { + var _a; + if (saveElement === void 0) { saveElement = true; } + // use the highest layout for any saved info so we can have full detail on reload #1849 + var len = (_a = this._layouts) === null || _a === void 0 ? void 0 : _a.length; + var layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null; + var list = []; + this.sortNodes(); + this.nodes.forEach(function (n) { + var wl = layout === null || layout === void 0 ? void 0 : layout.find(function (l) { return l._id === n._id; }); + var w = __assign({}, n); + // use layout info instead if set + if (wl) { + w.x = wl.x; + w.y = wl.y; + w.w = wl.w; + } + // delete internals + for (var key in w) { + if (key[0] === '_' || w[key] === null || w[key] === undefined) + delete w[key]; + } + delete w.grid; + if (!saveElement) + delete w.el; + // delete default values (will be re-created on read) + if (!w.autoPosition) + delete w.autoPosition; + if (!w.noResize) + delete w.noResize; + if (!w.noMove) + delete w.noMove; + if (!w.locked) + delete w.locked; + list.push(w); + }); + return list; + }; + /** @internal called whenever a node is added or moved - updates the cached layouts */ + GridStackEngine.prototype.layoutsNodesChange = function (nodes) { + var _this = this; + if (!this._layouts || this._inColumnResize) + return this; + // remove smaller layouts - we will re-generate those on the fly... larger ones need to update + this._layouts.forEach(function (layout, column) { + if (!layout || column === _this.column) + return _this; + if (column < _this.column) { + _this._layouts[column] = undefined; + } + else { + // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better. + // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785 + var ratio_1 = column / _this.column; + nodes.forEach(function (node) { + if (!node._orig) + return; // didn't change (newly added ?) + var n = layout.find(function (l) { return l._id === node._id; }); + if (!n) + return; // no cache for new nodes. Will use those values. + // Y changed, push down same amount + // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode) + if (node.y !== node._orig.y) { + n.y += (node.y - node._orig.y); + } + // X changed, scale from new position + if (node.x !== node._orig.x) { + n.x = Math.round(node.x * ratio_1); + } + // width changed, scale from new width + if (node.w !== node._orig.w) { + n.w = Math.round(node.w * ratio_1); + } + // ...height always carries over from cache + }); + } + }); + return this; + }; + /** + * @internal Called to scale the widget width & position up/down based on the column change. + * Note we store previous layouts (especially original ones) to make it possible to go + * from say 12 -> 1 -> 12 and get back to where we were. + * + * @param prevColumn previous number of columns + * @param column new column number + * @param nodes different sorted list (ex: DOM order) instead of current list + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + GridStackEngine.prototype.updateNodeWidths = function (prevColumn, column, nodes, layout) { + var _this = this; + var _a; + if (layout === void 0) { layout = 'moveScale'; } + if (!this.nodes.length || !column || prevColumn === column) + return this; + // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data + this.cacheLayout(this.nodes, prevColumn); + this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision + var newNodes = []; + // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout + var domOrder = false; + if (column === 1 && (nodes === null || nodes === void 0 ? void 0 : nodes.length)) { + domOrder = true; + var top_1 = 0; + nodes.forEach(function (n) { + n.x = 0; + n.w = 1; + n.y = Math.max(n.y, top_1); + top_1 = n.y + n.h; + }); + newNodes = nodes; + nodes = []; + } + else { + nodes = utils_1.Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision) + } + // see if we have cached previous layout IFF we are going up in size (restore) otherwise always + // generate next size down from where we are (looks more natural as you gradually size down). + var cacheNodes = []; + if (column > prevColumn) { + cacheNodes = this._layouts[column] || []; + // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate + // by pretending we came from that larger column by assigning those values as starting point + var lastIndex = this._layouts.length - 1; + if (!cacheNodes.length && prevColumn !== lastIndex && ((_a = this._layouts[lastIndex]) === null || _a === void 0 ? void 0 : _a.length)) { + prevColumn = lastIndex; + this._layouts[lastIndex].forEach(function (cacheNode) { + var n = nodes.find(function (n) { return n._id === cacheNode._id; }); + if (n) { + // still current, use cache info positions + n.x = cacheNode.x; + n.y = cacheNode.y; + n.w = cacheNode.w; + } + }); + } + } + // if we found cache re-use those nodes that are still current + cacheNodes.forEach(function (cacheNode) { + var j = nodes.findIndex(function (n) { return n._id === cacheNode._id; }); + if (j !== -1) { + // still current, use cache info positions + nodes[j].x = cacheNode.x; + nodes[j].y = cacheNode.y; + nodes[j].w = cacheNode.w; + newNodes.push(nodes[j]); + nodes.splice(j, 1); + } + }); + // ...and add any extra non-cached ones + if (nodes.length) { + if (typeof layout === 'function') { + layout(column, prevColumn, newNodes, nodes); + } + else if (!domOrder) { + var ratio_2 = column / prevColumn; + var move_1 = (layout === 'move' || layout === 'moveScale'); + var scale_1 = (layout === 'scale' || layout === 'moveScale'); + nodes.forEach(function (node) { + // NOTE: x + w could be outside of the grid, but addNode() below will handle that + node.x = (column === 1 ? 0 : (move_1 ? Math.round(node.x * ratio_2) : Math.min(node.x, column - 1))); + node.w = ((column === 1 || prevColumn === 1) ? 1 : + scale_1 ? (Math.round(node.w * ratio_2) || 1) : (Math.min(node.w, column))); + newNodes.push(node); + }); + nodes = []; + } + } + // finally re-layout them in reverse order (to get correct placement) + newNodes = utils_1.Utils.sort(newNodes, -1, column); + this._inColumnResize = true; // prevent cache update + this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout + newNodes.forEach(function (node) { + _this.addNode(node, false); // 'false' for add event trigger + delete node._orig; // make sure the commit doesn't try to restore things back to original + }); + this.batchUpdate(false); + delete this._inColumnResize; + return this; + }; + /** + * call to cache the given layout internally to the given location so we can restore back when column changes size + * @param nodes list of nodes + * @param column corresponding column index to save it under + * @param clear if true, will force other caches to be removed (default false) + */ + GridStackEngine.prototype.cacheLayout = function (nodes, column, clear) { + if (clear === void 0) { clear = false; } + var copy = []; + nodes.forEach(function (n, i) { + n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set + copy[i] = { x: n.x, y: n.y, w: n.w, _id: n._id }; // only thing we change is x,y,w and id to find it back + }); + this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick + this._layouts[column] = copy; + return this; + }; + /** + * call to cache the given node layout internally to the given location so we can restore back when column changes size + * @param node single node to cache + * @param column corresponding column index to save it under + */ + GridStackEngine.prototype.cacheOneLayout = function (n, column) { + n._id = n._id || GridStackEngine._idSeq++; + var layout = { x: n.x, y: n.y, w: n.w, _id: n._id }; + this._layouts = this._layouts || []; + this._layouts[column] = this._layouts[column] || []; + var index = this._layouts[column].findIndex(function (l) { return l._id === n._id; }); + index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout; + return this; + }; + /** called to remove all internal values but the _id */ + GridStackEngine.prototype.cleanupNode = function (node) { + for (var prop in node) { + if (prop[0] === '_' && prop !== '_id') + delete node[prop]; + } + return this; + }; + /** @internal unique global internal _id counter NOT starting at 0 */ + GridStackEngine._idSeq = 1; + return GridStackEngine; +}()); +exports.GridStackEngine = GridStackEngine; +//# sourceMappingURL=gridstack-engine.js.map \ No newline at end of file diff --git a/dist/es5/gridstack-engine.js.map b/dist/es5/gridstack-engine.js.map new file mode 100644 index 000000000..3af939900 --- /dev/null +++ b/dist/es5/gridstack-engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gridstack-engine.js","sourceRoot":"","sources":["../../src/gridstack-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gridstack-engine.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { Utils } from './utils';\nimport { GridStackNode, ColumnOptions, GridStackPosition, GridStackMoveOpts } from './types';\n\n/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */\ntype OnChangeCB = (nodes: GridStackNode[]) => void;\n\n/** options used during creation - similar to GridStackOptions */\nexport interface GridStackEngineOptions {\n column?: number;\n maxRow?: number;\n float?: boolean;\n nodes?: GridStackNode[];\n onChange?: OnChangeCB;\n}\n\n/**\n * Defines the GridStack engine that does most no DOM grid manipulation.\n * See GridStack methods and vars for descriptions.\n *\n * NOTE: values should not be modified directly - call the main GridStack API instead\n */\nexport class GridStackEngine {\n public column: number;\n public maxRow: number;\n public nodes: GridStackNode[];\n public addedNodes: GridStackNode[] = [];\n public removedNodes: GridStackNode[] = [];\n public batchMode: boolean;\n /** @internal callback to update the DOM attributes */\n protected onChange: OnChangeCB;\n /** @internal */\n protected _float: boolean;\n /** @internal */\n protected _prevFloat: boolean;\n /** @internal cached layouts of difference column count so we can restore ack (eg 12 -> 1 -> 12) */\n protected _layouts?: GridStackNode[][]; // maps column # to array of values nodes\n /** @internal true while we are resizing widgets during column resize to skip certain parts */\n protected _inColumnResize: boolean;\n /** @internal true if we have some items locked */\n protected _hasLocked: boolean;\n /** @internal unique global internal _id counter NOT starting at 0 */\n protected static _idSeq = 1;\n\n public constructor(opts: GridStackEngineOptions = {}) {\n this.column = opts.column || 12;\n this.maxRow = opts.maxRow;\n this._float = opts.float;\n this.nodes = opts.nodes || [];\n this.onChange = opts.onChange;\n }\n\n public batchUpdate(flag = true): GridStackEngine {\n if (!!this.batchMode === flag) return this;\n this.batchMode = flag;\n if (flag) {\n this._prevFloat = this._float;\n this._float = true; // let things go anywhere for now... will restore and possibly reposition later\n this.saveInitial(); // since begin update (which is called multiple times) won't do this\n } else {\n this._float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes()._notify();\n }\n return this;\n }\n\n // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip\n protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean {\n return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y);\n }\n\n /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.\n * return true if we moved. */\n protected _fixCollisions(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {}): boolean {\n this.sortNodes(-1); // from last to first, so recursive collision move items in the right order\n\n collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none...\n if (!collide) return false;\n\n // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size\n if (node._moving && !opt.nested && !this.float) {\n if (this.swap(node, collide)) return true;\n }\n\n // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)\n let area = nn;\n if (this._useEntireRowArea(node, nn)) {\n area = {x: 0, w: this.column, y: nn.y, h: nn.h};\n collide = this.collide(node, area, opt.skip); // force new hit\n }\n\n let didMove = false;\n let newOpt: GridStackMoveOpts = {nested: true, pack: false};\n while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each\n let moved: boolean;\n // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,\n // but remember that skip down so we only do this once (and push others otherwise).\n if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&\n // can take space we had, or before where we're going\n (!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {\n node._skipDown = (node._skipDown || nn.y > node.y);\n moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});\n if (collide.locked && moved) {\n Utils.copyPos(nn, node); // moving after lock become our new desired location\n } else if (!collide.locked && moved && opt.pack) {\n // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way\n this._packNodes();\n nn.y = collide.y + collide.h;\n Utils.copyPos(node, nn);\n }\n didMove = didMove || moved;\n } else {\n // move collide down *after* where we will be, ignoring where we are now (don't collide with us)\n moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt});\n }\n if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)\n collide = undefined;\n }\n return didMove;\n }\n\n /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */\n public collide(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode {\n return this.nodes.find(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n public collideAll(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode[] {\n return this.nodes.filter(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n\n /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */\n public collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode {\n if (!o.rect || !node._rect) return;\n let r0 = node._rect; // where started\n let r = {...o.rect}; // where we are\n\n // update dragged rect to show where it's coming from (above or below, etc...)\n if (r.y > r0.y) {\n r.h += r.y - r0.y;\n r.y = r0.y;\n } else {\n r.h += r0.y - r.y;\n }\n if (r.x > r0.x) {\n r.w += r.x - r0.x;\n r.x = r0.x;\n } else {\n r.w += r0.x - r.x;\n }\n\n let collide: GridStackNode;\n collides.forEach(n => {\n if (n.locked || !n._rect) return;\n let r2 = n._rect; // overlapping target\n let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50%\n // depending on which side we started from, compute the overlap % of coverage\n // (ex: from above/below we only compute the max horizontal line coverage)\n if (r0.y < r2.y) { // from above\n yOver = ((r.y + r.h) - r2.y) / r2.h;\n } else if (r0.y+r0.h > r2.y+r2.h) { // from below\n yOver = ((r2.y + r2.h) - r.y) / r2.h;\n }\n if (r0.x < r2.x) { // from the left\n xOver = ((r.x + r.w) - r2.x) / r2.w;\n } else if (r0.x+r0.w > r2.x+r2.w) { // from the right\n xOver = ((r2.x + r2.w) - r.x) / r2.w;\n }\n let over = Math.min(xOver, yOver);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n return collide;\n }\n\n /** called to cache the nodes pixel rectangles used for collision detection during drag */\n public cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine\n {\n this.nodes.forEach(n =>\n n._rect = {\n y: n.y * h + top,\n x: n.x * w + left,\n w: n.w * w - left - right,\n h: n.h * h - top - bottom\n }\n );\n return this;\n }\n\n /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */\n public swap(a: GridStackNode, b: GridStackNode): boolean {\n if (!b || b.locked || !a || a.locked) return false;\n\n function _doSwap(): true { // assumes a is before b IFF they have different height (put after rather than exact swap)\n let x = b.x, y = b.y;\n b.x = a.x; b.y = a.y; // b -> a position\n if (a.h != b.h) {\n a.x = x; a.y = b.y + b.h; // a -> goes after b\n } else if (a.w != b.w) {\n a.x = b.x + b.w; a.y = y; // a -> goes after b\n } else {\n a.x = x; a.y = y; // a -> old b position\n }\n a._dirty = b._dirty = true;\n return true;\n }\n let touching: boolean; // remember if we called it (vs undefined)\n\n // same size and same row or column, and touching\n if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = Utils.isTouching(a, b)))\n return _doSwap();\n if (touching === false) return; // IFF ran test and fail, bail out\n\n // check for taking same columns (but different height) and touching\n if (a.w === b.w && a.x === b.x && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.y < a.y) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n if (touching === false) return;\n\n // check if taking same row (but different width) and touching\n if (a.h === b.h && a.y === b.y && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.x < a.x) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n return false;\n }\n\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\n let nn: GridStackNode = {x: x || 0, y: y || 0, w: w || 1, h: h || 1};\n return !this.collide(nn);\n }\n\n /** re-layout grid items to reclaim any empty space */\n public compact(): GridStackEngine {\n if (this.nodes.length === 0) return this;\n this.batchUpdate()\n .sortNodes();\n let copyNodes = this.nodes;\n this.nodes = []; // pretend we have no nodes to conflict layout to start with...\n copyNodes.forEach(node => {\n if (!node.locked) {\n node.autoPosition = true;\n }\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // will force attr update\n });\n return this.batchUpdate(false);\n }\n\n /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */\n public set float(val: boolean) {\n if (this._float === val) return;\n this._float = val || false;\n if (!val) {\n this._packNodes()._notify();\n }\n }\n\n /** float getter method */\n public get float(): boolean { return this._float || false; }\n\n /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */\n public sortNodes(dir?: -1 | 1): GridStackEngine {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n return this;\n }\n\n /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */\n protected _packNodes(): GridStackEngine {\n if (this.batchMode) { return this; }\n this.sortNodes(); // first to last\n\n if (this.float) {\n // restore original Y pos\n this.nodes.forEach(n => {\n if (n._updating || n._orig === undefined || n.y === n._orig.y) return;\n let newY = n.y;\n while (newY > n._orig.y) {\n --newY;\n let collide = this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!collide) {\n n._dirty = true;\n n.y = newY;\n }\n }\n });\n } else {\n // top gravity pack\n this.nodes.forEach((n, i) => {\n if (n.locked) return;\n while (n.y > 0) {\n let newY = i === 0 ? 0 : n.y - 1;\n let canBeMoved = i === 0 || !this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!canBeMoved) break;\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n });\n }\n return this;\n }\n\n /**\n * given a random node, makes sure it's coordinates/values are valid in the current grid\n * @param node to adjust\n * @param resizing if out of bound, resize down or move into the grid to fit ?\n */\n public prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode {\n node = node || {};\n node._id = node._id || GridStackEngine._idSeq++;\n\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n\n // assign defaults for missing required fields\n let defaults: GridStackNode = { x: 0, y: 0, w: 1, h: 1};\n Utils.defaults(node, defaults);\n\n if (!node.autoPosition) { delete node.autoPosition; }\n if (!node.noResize) { delete node.noResize; }\n if (!node.noMove) { delete node.noMove; }\n\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (typeof node.x == 'string') { node.x = Number(node.x); }\n if (typeof node.y == 'string') { node.y = Number(node.y); }\n if (typeof node.w == 'string') { node.w = Number(node.w); }\n if (typeof node.h == 'string') { node.h = Number(node.h); }\n if (isNaN(node.x)) { node.x = defaults.x; node.autoPosition = true; }\n if (isNaN(node.y)) { node.y = defaults.y; node.autoPosition = true; }\n if (isNaN(node.w)) { node.w = defaults.w; }\n if (isNaN(node.h)) { node.h = defaults.h; }\n\n return this.nodeBoundFix(node, resizing);\n }\n\n /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */\n public nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode {\n\n let before = node._orig || Utils.copyPos({}, node);\n\n if (node.maxW) { node.w = Math.min(node.w, node.maxW); }\n if (node.maxH) { node.h = Math.min(node.h, node.maxH); }\n if (node.minW && node.minW <= this.column) { node.w = Math.max(node.w, node.minW); }\n if (node.minH) { node.h = Math.max(node.h, node.minH); }\n\n if (node.w > this.column) {\n // if user loaded a larger than allowed widget for current # of columns,\n // remember it's full width so we can restore back (1 -> 12 column) #1655\n // IFF we're not in the middle of column resizing!\n if (this.column < 12 && !this._inColumnResize) {\n node.w = Math.min(12, node.w);\n this.cacheOneLayout(node, 12);\n }\n node.w = this.column;\n } else if (node.w < 1) {\n node.w = 1;\n }\n\n if (this.maxRow && node.h > this.maxRow) {\n node.h = this.maxRow;\n } else if (node.h < 1) {\n node.h = 1;\n }\n\n if (node.x < 0) {\n node.x = 0;\n }\n if (node.y < 0) {\n node.y = 0;\n }\n\n if (node.x + node.w > this.column) {\n if (resizing) {\n node.w = this.column - node.x;\n } else {\n node.x = this.column - node.w;\n }\n }\n if (this.maxRow && node.y + node.h > this.maxRow) {\n if (resizing) {\n node.h = this.maxRow - node.y;\n } else {\n node.y = this.maxRow - node.h;\n }\n }\n\n if (!Utils.samePos(node, before)) {\n node._dirty = true;\n }\n\n return node;\n }\n\n /** returns a list of modified nodes from their original values */\n public getDirtyNodes(verify?: boolean): GridStackNode[] {\n // compare original x,y,w,h instead as _dirty can be a temporary state\n if (verify) {\n return this.nodes.filter(n => n._dirty && !Utils.samePos(n, n._orig));\n }\n return this.nodes.filter(n => n._dirty);\n }\n\n /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */\n protected _notify(removedNodes?: GridStackNode[]): GridStackEngine {\n if (this.batchMode || !this.onChange) return this;\n let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes());\n this.onChange(dirtyNodes);\n return this;\n }\n\n /** @internal remove dirty and last tried info */\n public cleanNodes(): GridStackEngine {\n if (this.batchMode) return this;\n this.nodes.forEach(n => {\n delete n._dirty;\n delete n._lastTried;\n });\n return this;\n }\n\n /** @internal called to save initial position/size to track real dirty state.\n * Note: should be called right after we call change event (so next API is can detect changes)\n * as well as right before we start move/resize/enter (so we can restore items to prev values) */\n public saveInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n n._orig = Utils.copyPos({}, n);\n delete n._dirty;\n });\n this._hasLocked = this.nodes.some(n => n.locked);\n return this;\n }\n\n /** @internal restore all the nodes back to initial values (called when we leave) */\n public restoreInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n if (Utils.samePos(n, n._orig)) return;\n Utils.copyPos(n, n._orig);\n n._dirty = true;\n });\n this._notify();\n return this;\n }\n\n /** call to add the given node to our list, fixing collision and re-packing */\n public addNode(node: GridStackNode, triggerAddEvent = false): GridStackNode {\n let dup = this.nodes.find(n => n._id === node._id);\n if (dup) return dup; // prevent inserting twice! return it instead.\n\n // skip prepareNode if we're in middle of column resize (not new) but do check for bounds!\n node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);\n delete node._temporaryRemoved;\n delete node._removeDOM;\n\n if (node.autoPosition) {\n this.sortNodes();\n\n for (let i = 0;; ++i) {\n let x = i % this.column;\n let y = Math.floor(i / this.column);\n if (x + node.w > this.column) {\n continue;\n }\n let box = {x, y, w: node.w, h: node.h};\n if (!this.nodes.find(n => Utils.isIntercepted(box, n))) {\n node.x = x;\n node.y = y;\n delete node.autoPosition; // found our slot\n break;\n }\n }\n }\n\n this.nodes.push(node);\n if (triggerAddEvent) { this.addedNodes.push(node); }\n\n this._fixCollisions(node);\n if (!this.batchMode) { this._packNodes()._notify(); }\n return node;\n }\n\n public removeNode(node: GridStackNode, removeDOM = true, triggerEvent = false): GridStackEngine {\n if (!this.nodes.find(n => n === node)) {\n // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)\n return this;\n }\n if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag)\n this.removedNodes.push(node);\n }\n if (removeDOM) node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.\n this.nodes = this.nodes.filter(n => n !== node);\n return this._packNodes()\n ._notify([node]);\n }\n\n public removeAll(removeDOM = true): GridStackEngine {\n delete this._layouts;\n if (this.nodes.length === 0) return this;\n removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n this.removedNodes = this.nodes;\n this.nodes = [];\n return this._notify(this.removedNodes);\n }\n\n /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.\n * In more complicated cases (maxRow) it will attempt at moving the item and fixing\n * others in a clone first, then apply those changes if still within specs. */\n public moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean {\n // if (node.locked) return false;\n if (!this.changedPosConstrain(node, o)) return false;\n o.pack = true;\n\n // simpler case: move item directly...\n if (!this.maxRow) {\n return this.moveNode(node, o);\n }\n\n // complex case: create a clone with NO maxRow (will check for out of bounds at the end)\n let clonedNode: GridStackNode;\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {\n if (n === node) {\n clonedNode = {...n};\n return clonedNode;\n }\n return {...n};\n })\n });\n if (!clonedNode) return false;\n\n // make sure we are still valid size\n let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow;\n // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing\n if (!canMove && !o.resizing) {\n let collide = this.collide(node, o);\n if (collide && this.swap(node, collide)) {\n this._notify();\n return true;\n }\n }\n if (!canMove) return false;\n\n // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over!\n // Note: we can't use the list directly as elements and other parts point to actual node, so copy content\n clone.nodes.filter(n => n._dirty).forEach(c => {\n let n = this.nodes.find(a => a._id === c._id);\n if (!n) return;\n Utils.copyPos(n, c);\n n._dirty = true;\n });\n this._notify();\n return true;\n }\n\n /** return true if can fit in grid height constrain only (always true if no maxRow) */\n public willItFit(node: GridStackNode): boolean {\n delete node._willFitPos;\n if (!this.maxRow) return true;\n // create a clone with NO maxRow and check if still within size\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {return {...n}})\n });\n let n = {...node}; // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687\n this.cleanupNode(n);\n delete n.el; delete n._id; delete n.content; delete n.grid;\n clone.addNode(n);\n if (clone.getRow() <= this.maxRow) {\n node._willFitPos = Utils.copyPos({}, n);\n return true;\n }\n return false;\n }\n\n /** true if x,y or w,h are different after clamping to min/max */\n public changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean {\n // first make sure w,h are set for caller\n p.w = p.w || node.w;\n p.h = p.h || node.h;\n if (node.x !== p.x || node.y !== p.y) return true;\n // check constrained w,h\n if (node.maxW) { p.w = Math.min(p.w, node.maxW); }\n if (node.maxH) { p.h = Math.min(p.h, node.maxH); }\n if (node.minW) { p.w = Math.max(p.w, node.minW); }\n if (node.minH) { p.h = Math.max(p.h, node.minH); }\n return (node.w !== p.w || node.h !== p.h);\n }\n\n /** return true if the passed in node was actually moved (checks for no-op and locked) */\n public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {\n if (!node || /*node.locked ||*/ !o) return false;\n if (o.pack === undefined) o.pack = true;\n\n // constrain the passed in values and check if we're still changing our node\n if (typeof o.x !== 'number') { o.x = node.x; }\n if (typeof o.y !== 'number') { o.y = node.y; }\n if (typeof o.w !== 'number') { o.w = node.w; }\n if (typeof o.h !== 'number') { o.h = node.h; }\n let resizing = (node.w !== o.w || node.h !== o.h);\n let nn: GridStackNode = Utils.copyPos({}, node, true); // get min/max out first, then opt positions next\n Utils.copyPos(nn, o);\n nn = this.nodeBoundFix(nn, resizing);\n Utils.copyPos(o, nn);\n\n if (Utils.samePos(node, o)) return false;\n let prevPos: GridStackPosition = Utils.copyPos({}, node);\n\n // check if we will need to fix collision at our new location\n let collides = this.collideAll(node, nn, o.skip);\n let needToMove = true;\n if (collides.length) {\n // now check to make sure we actually collided over 50% surface area while dragging\n let collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0];\n if (collide) {\n needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved...\n } else {\n needToMove = false; // we didn't cover >50% for a move, skip...\n }\n }\n\n // now move (to the original ask vs the collision version which might differ) and repack things\n if (needToMove) {\n node._dirty = true;\n Utils.copyPos(node, nn);\n }\n if (o.pack) {\n this._packNodes()\n ._notify();\n }\n return !Utils.samePos(node, prevPos); // pack might have moved things back\n }\n\n public getRow(): number {\n return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0);\n }\n\n public beginUpdate(node: GridStackNode): GridStackEngine {\n if (!node._updating) {\n node._updating = true;\n delete node._skipDown;\n if (!this.batchMode) this.saveInitial();\n }\n return this;\n }\n\n public endUpdate(): GridStackEngine {\n let n = this.nodes.find(n => n._updating);\n if (n) {\n delete n._updating;\n delete n._skipDown;\n }\n return this;\n }\n\n /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout),\n * returning a list of widgets for serialization */\n public save(saveElement = true): GridStackNode[] {\n // use the highest layout for any saved info so we can have full detail on reload #1849\n let len = this._layouts?.length;\n let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null;\n let list: GridStackNode[] = [];\n this.sortNodes();\n this.nodes.forEach(n => {\n let wl = layout?.find(l => l._id === n._id);\n let w: GridStackNode = {...n};\n // use layout info instead if set\n if (wl) { w.x = wl.x; w.y = wl.y; w.w = wl.w; }\n // delete internals\n for (let key in w) { if (key[0] === '_' || w[key] === null || w[key] === undefined ) delete w[key]; }\n delete w.grid;\n if (!saveElement) delete w.el;\n // delete default values (will be re-created on read)\n if (!w.autoPosition) delete w.autoPosition;\n if (!w.noResize) delete w.noResize;\n if (!w.noMove) delete w.noMove;\n if (!w.locked) delete w.locked;\n list.push(w);\n });\n return list;\n }\n\n /** @internal called whenever a node is added or moved - updates the cached layouts */\n public layoutsNodesChange(nodes: GridStackNode[]): GridStackEngine {\n if (!this._layouts || this._inColumnResize) return this;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach((layout, column) => {\n if (!layout || column === this.column) return this;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785\n let ratio = column / this.column;\n nodes.forEach(node => {\n if (!node._orig) return; // didn't change (newly added ?)\n let n = layout.find(l => l._id === node._id);\n if (!n) return; // no cache for new nodes. Will use those values.\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._orig.y) {\n n.y += (node.y - node._orig.y);\n }\n // X changed, scale from new position\n if (node.x !== node._orig.x) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.w !== node._orig.w) {\n n.w = Math.round(node.w * ratio);\n }\n // ...height always carries over from cache\n });\n }\n });\n return this;\n }\n\n /**\n * @internal Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * @param prevColumn previous number of columns\n * @param column new column number\n * @param nodes different sorted list (ex: DOM order) instead of current list\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n public updateNodeWidths(prevColumn: number, column: number, nodes: GridStackNode[], layout: ColumnOptions = 'moveScale'): GridStackEngine {\n if (!this.nodes.length || !column || prevColumn === column) return this;\n\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n this.cacheLayout(this.nodes, prevColumn);\n this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision\n let newNodes: GridStackNode[] = [];\n\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n let domOrder = false;\n if (column === 1 && nodes?.length) {\n domOrder = true;\n let top = 0;\n nodes.forEach(n => {\n n.x = 0;\n n.w = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.h;\n });\n newNodes = nodes;\n nodes = [];\n } else {\n nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n\n // see if we have cached previous layout IFF we are going up in size (restore) otherwise always\n // generate next size down from where we are (looks more natural as you gradually size down).\n let cacheNodes: GridStackNode[] = [];\n if (column > prevColumn) {\n cacheNodes = this._layouts[column] || [];\n // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate\n // by pretending we came from that larger column by assigning those values as starting point\n let lastIndex = this._layouts.length - 1;\n if (!cacheNodes.length && prevColumn !== lastIndex && this._layouts[lastIndex]?.length) {\n prevColumn = lastIndex;\n this._layouts[lastIndex].forEach(cacheNode => {\n let n = nodes.find(n => n._id === cacheNode._id);\n if (n) {\n // still current, use cache info positions\n n.x = cacheNode.x;\n n.y = cacheNode.y;\n n.w = cacheNode.w;\n }\n });\n }\n }\n\n // if we found cache re-use those nodes that are still current\n cacheNodes.forEach(cacheNode => {\n let j = nodes.findIndex(n => n._id === cacheNode._id);\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].w = cacheNode.w;\n newNodes.push(nodes[j]);\n nodes.splice(j, 1);\n }\n });\n // ...and add any extra non-cached ones\n if (nodes.length) {\n if (typeof layout === 'function') {\n layout(column, prevColumn, newNodes, nodes);\n } else if (!domOrder) {\n let ratio = column / prevColumn;\n let move = (layout === 'move' || layout === 'moveScale');\n let scale = (layout === 'scale' || layout === 'moveScale');\n nodes.forEach(node => {\n // NOTE: x + w could be outside of the grid, but addNode() below will handle that\n node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));\n node.w = ((column === 1 || prevColumn === 1) ? 1 :\n scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));\n newNodes.push(node);\n });\n nodes = [];\n }\n }\n\n // finally re-layout them in reverse order (to get correct placement)\n newNodes = Utils.sort(newNodes, -1, column);\n this._inColumnResize = true; // prevent cache update\n this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout\n newNodes.forEach(node => {\n this.addNode(node, false); // 'false' for add event trigger\n delete node._orig; // make sure the commit doesn't try to restore things back to original\n });\n this.batchUpdate(false);\n delete this._inColumnResize;\n return this;\n }\n\n /**\n * call to cache the given layout internally to the given location so we can restore back when column changes size\n * @param nodes list of nodes\n * @param column corresponding column index to save it under\n * @param clear if true, will force other caches to be removed (default false)\n */\n public cacheLayout(nodes: GridStackNode[], column: number, clear = false): GridStackEngine {\n let copy: GridStackNode[] = [];\n nodes.forEach((n, i) => {\n n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set\n copy[i] = {x: n.x, y: n.y, w: n.w, _id: n._id} // only thing we change is x,y,w and id to find it back\n });\n this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick\n this._layouts[column] = copy;\n return this;\n }\n\n /**\n * call to cache the given node layout internally to the given location so we can restore back when column changes size\n * @param node single node to cache\n * @param column corresponding column index to save it under\n */\n public cacheOneLayout(n: GridStackNode, column: number): GridStackEngine {\n n._id = n._id || GridStackEngine._idSeq++;\n let layout: GridStackNode = {x: n.x, y: n.y, w: n.w, _id: n._id}\n this._layouts = this._layouts || [];\n this._layouts[column] = this._layouts[column] || [];\n let index = this._layouts[column].findIndex(l => l._id === n._id);\n index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout;\n return this;\n }\n\n\n /** called to remove all internal values but the _id */\n public cleanupNode(node: GridStackNode): GridStackEngine {\n for (let prop in node) {\n if (prop[0] === '_' && prop !== '_id') delete node[prop];\n }\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/es5/gridstack-poly.js b/dist/es5/gridstack-poly.js new file mode 100644 index 000000000..1b4b4d728 --- /dev/null +++ b/dist/es5/gridstack-poly.js @@ -0,0 +1,356 @@ +/** + * gridstack-poly.ts 6.0.1-dev used for IE and older browser support (not supported in v2-v4.3.1, but again in v4.4) + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ + +/* eslint-disable prefer-rest-params */ +/* eslint-disable no-var */ + +// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent +(function () { + if (typeof window.CustomEvent === "function") { + return false; + } + + function CustomEvent (event, params) { + params = params || {bubbles: false, cancelable: false, detail: null}; + var evt = document.createEvent('CustomEvent'); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; + } + + window.CustomEvent = CustomEvent; +})(); + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN +Number.isNaN = Number.isNaN || function isNaN(input) { + return typeof input === 'number' && input !== input; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find +if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + value: function (predicate) { + // 1. Let O be ? ToObject(this value). + if (this == null) { + throw TypeError('"this" is null or not defined'); + } + + var o = Object(this); + + // 2. Let len be ? ToLength(? Get(O, "length")). + var len = o.length >>> 0; + + // 3. If IsCallable(predicate) is false, throw a TypeError exception. + if (typeof predicate !== 'function') { + throw TypeError('predicate must be a function'); + } + + // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. + var thisArg = arguments[1]; + + // 5. Let k be 0. + var k = 0; + + // 6. Repeat, while k < len + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kValue be ? Get(O, Pk). + // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // d. If testResult is true, return kValue. + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return kValue; + } + // e. Increase k by 1. + k++; + } + + // 7. Return undefined. + return undefined; + }, + configurable: true, + writable: true + }); +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex +if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + value: function(predicate) { + // 1. Let O be ? ToObject(this value). + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this); + + // 2. Let len be ? ToLength(? Get(O, "length")). + var len = o.length >>> 0; + + // 3. If IsCallable(predicate) is false, throw a TypeError exception. + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + + // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. + var thisArg = arguments[1]; + + // 5. Let k be 0. + var k = 0; + + // 6. Repeat, while k < len + while (k < len) { + // a. Let Pk be ! ToString(k). + // b. Let kValue be ? Get(O, Pk). + // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). + // d. If testResult is true, return k. + var kValue = o[k]; + if (predicate.call(thisArg, kValue, k, o)) { + return k; + } + // e. Increase k by 1. + k++; + } + + // 7. Return -1. + return -1; + }, + configurable: true, + writable: true + }); +} + +// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/append()/append().md +(function (arr) { + arr.forEach(function (item) { + if (item.hasOwnProperty('append')) { + return; + } + Object.defineProperty(item, 'append', { + configurable: true, + enumerable: true, + writable: true, + value: function append() { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.appendChild(docFrag); + } + }); + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); + +// from: https://github.com/jserz/js_piece/blob/master/DOM/Element/prepend()/prepend().md +(function (arr) { + arr.forEach(function (item) { + item.prepend = item.prepend || function () { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.insertBefore(docFrag, this.firstChild); + }; + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); + +// Production steps of ECMA-262, Edition 5, 15.4.4.1-dev8 +// Reference: http://es5.github.io/#x15.4.4.1-dev8 + +if (!Array.prototype['forEach']) { + + Array.prototype.forEach = function(callback, thisArg) { + + if (this == null) { throw new TypeError('Array.prototype.forEach called on null or undefined'); } + + var T, k; + // 1. Let O be the result of calling toObject() passing the + // |this| value as the argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get() internal + // method of O with the argument "length". + // 3. Let len be toUint32(lenValue). + var len = O.length >>> 0; + + // 4. If isCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== "function") { throw new TypeError(callback + ' is not a function'); } + + // 5. If thisArg was supplied, let T be thisArg; else let + // T be undefined. + if (arguments.length > 1) { T = thisArg; } + + // 6. Let k be 0 + k = 0; + + // 7. Repeat, while k < len + while (k < len) { + + var kValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty + // internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal + // method of O with argument Pk. + kValue = O[k]; + + // ii. Call the Call internal method of callback with T as + // the this value and argument list containing kValue, k, and O. + callback.call(T, kValue, k, O); + } + // d. Increase k by 1. + k++; + } + // 8. return undefined + }; +} + +// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent +(function(){ + try{ + new window.CustomEvent('T'); + }catch(e){ + var CustomEvent = function(event, params){ + params = params || { bubbles: false, cancelable: false, detail: undefined }; + + var evt = document.createEvent('CustomEvent'); + + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + + return evt; + }; + + CustomEvent.prototype = window.Event.prototype; + + window.CustomEvent = CustomEvent; + } +})(); + +// https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md +(function (arr) { + arr.forEach(function (item) { + if (item.hasOwnProperty('remove')) { + return; + } + Object.defineProperty(item, 'remove', { + configurable: true, + enumerable: true, + writable: true, + value: function remove() { + this.parentNode.removeChild(this); + } + }); + }); +})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); + +// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches +if (!Element.prototype.matches) { + Element.prototype.matches = + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector || + function(s) { + var matches = (this.document || this.ownerDocument).querySelectorAll(s), + i = matches.length; + while (--i >= 0 && matches.item(i) !== this) {} + return i > -1; + }; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from +// Production steps of ECMA-262, Edition 6, 22.1.2.1 +if (!Array.from) { + Array.from = (function () { + var toStr = Object.prototype.toString; + var isCallable = function (fn) { + return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; + }; + var toInteger = function (value) { + var number = Number(value); + if (isNaN(number)) { return 0; } + if (number === 0 || !isFinite(number)) { return number; } + return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); + }; + var maxSafeInteger = Math.pow(2, 53) - 1; + var toLength = function (value) { + var len = toInteger(value); + return Math.min(Math.max(len, 0), maxSafeInteger); + }; + + // The length property of the from method is 1. + return function from(arrayLike/*, mapFn, thisArg */) { + // 1. Let C be the this value. + var C = this; + + // 2. Let items be ToObject(arrayLike). + var items = Object(arrayLike); + + // 3. ReturnIfAbrupt(items). + if (arrayLike == null) { + throw new TypeError("Array.from requires an array-like object - not null or undefined"); + } + + // 4. If mapfn is undefined, then let mapping be false. + var mapFn = arguments.length > 1 ? arguments[1] : void undefined; + var T; + if (typeof mapFn !== 'undefined') { + // 5. else + // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. + if (!isCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); + } + + // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (arguments.length > 2) { + T = arguments[2]; + } + } + + // 10. Let lenValue be Get(items, "length"). + // 11. Let len be ToLength(lenValue). + var len = toLength(items.length); + + // 13. If IsConstructor(C) is true, then + // 13. a. Let A be the result of calling the [[Construct]] internal method + // of C with an argument list containing the single item len. + // 14. a. Else, Let A be ArrayCreate(len). + var A = isCallable(C) ? Object(new C(len)) : new Array(len); + + // 16. Let k be 0. + var k = 0; + // 17. Repeat, while k < len… (also steps a - h) + var kValue; + while (k < len) { + kValue = items[k]; + if (mapFn) { + A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); + } else { + A[k] = kValue; + } + k += 1; + } + // 18. Let putStatus be Put(A, "length", len, true). + A.length = len; + // 20. Return A. + return A; + }; + }()); +} \ No newline at end of file diff --git a/dist/es5/gridstack.d.ts b/dist/es5/gridstack.d.ts new file mode 100644 index 000000000..eb4f06035 --- /dev/null +++ b/dist/es5/gridstack.d.ts @@ -0,0 +1,352 @@ +/*! + * GridStack 6.0.1-dev + * https://gridstackjs.com/ + * + * Copyright (c) 2021-2022 Alain Dumesny + * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE + */ +import { GridStackEngine } from './gridstack-engine'; +import { Utils } from './utils'; +import { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback, GridStackOptions, GridStackWidget, numberOrString, DDDragInOpt } from './types'; +export * from './types'; +export * from './utils'; +export * from './gridstack-engine'; +export interface GridHTMLElement extends HTMLElement { + gridstack?: GridStack; +} +/** list of possible events, or space separated list of them */ +export declare type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' | 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string; +/** Defines the coordinates of an object */ +export interface MousePosition { + top: number; + left: number; +} +/** Defines the position of a cell inside the grid*/ +export interface CellPosition { + x: number; + y: number; +} +/** + * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid. + * Note: your grid elements MUST have the following classes for the CSS layout to work: + * @example + *
+ *
+ *
Item 1
+ *
+ *
+ */ +export declare class GridStack { + /** + * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will + * simply return the existing instance (ignore any passed options). There is also an initAll() version that support + * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON. + * @param options grid options (optional) + * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector) + * + * @example + * let grid = GridStack.init(); + * + * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later + * let grid = document.querySelector('.grid-stack').gridstack; + */ + static init(options?: GridStackOptions, elOrString?: GridStackElement): GridStack; + /** + * Will initialize a list of elements (given a selector) and return an array of grids. + * @param options grid options (optional) + * @param selector elements selector to convert to grids (default to '.grid-stack' class selector) + * + * @example + * let grids = GridStack.initAll(); + * grids.forEach(...) + */ + static initAll(options?: GridStackOptions, selector?: string): GridStack[]; + /** + * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then + * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from + * JSON serialized data, including options. + * @param parent HTML element parent to the grid + * @param opt grids options used to initialize the grid, and list of children + */ + static addGrid(parent: HTMLElement, opt?: GridStackOptions): GridStack; + /** call this method to register your engine instead of the default one. + * See instead `GridStackOptions.engineClass` if you only need to + * replace just one instance. + */ + static registerEngine(engineClass: typeof GridStackEngine): void; + /** scoping so users can call GridStack.Utils.sort() for example */ + static Utils: typeof Utils; + /** scoping so users can call new GridStack.Engine(12) for example */ + static Engine: typeof GridStackEngine; + /** the HTML element tied to this grid after it's been initialized */ + el: GridHTMLElement; + /** engine used to implement non DOM grid functionality */ + engine: GridStackEngine; + /** grid options - public for classes to access, but use methods to modify! */ + opts: GridStackOptions; + protected static engineClass: typeof GridStackEngine; + /** + * Construct a grid item from the given element and options + * @param el + * @param opts + */ + constructor(el: GridHTMLElement, opts?: GridStackOptions); + change(): void; + /** + * add a new widget and returns it. + * + * Widget will be always placed even if result height is more than actual grid height. + * You need to use `willItFit()` before calling addWidget for additional check. + * See also `makeWidget()`. + * + * @example + * let grid = GridStack.init(); + * grid.addWidget({w: 3, content: 'hello'}); + * grid.addWidget('
hello
', {w: 3}); + * + * @param el GridStackWidget (which can have content string as well), html element, or string definition to add + * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget + */ + addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement; + /** + /** + * saves the current layout returning a list of widgets for serialization which might include any nested grids. + * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will + * be removed. + * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() + * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead. + * @returns list of widgets or full grid option, including .children list of widgets + */ + save(saveContent?: boolean, saveGridOpt?: boolean): GridStackWidget[] | GridStackOptions; + /** + * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there. + * + * @param layout list of widgets definition to update/create + * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving + * the user control of insertion. + * + * @example + * see http://gridstackjs.com/demo/serialization.html + **/ + load(layout: GridStackWidget[], addAndRemove?: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement)): GridStack; + /** + * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient) + * and get a single event callback. You will see no changes until `batchUpdate(false)` is called. + */ + batchUpdate(flag?: boolean): GridStack; + /** + * Gets current cell height. + */ + getCellHeight(forcePixel?: boolean): number; + /** + * Update current cell height - see `GridStackOptions.cellHeight` for format. + * This method rebuilds an internal CSS style sheet. + * Note: You can expect performance issues if call this method too often. + * + * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin), + * if pass 0 the CSS will be generated by the application instead. + * @param update (Optional) if false, styles will not be updated + * + * @example + * grid.cellHeight(100); // same as 100px + * grid.cellHeight('70px'); + * grid.cellHeight(grid.cellWidth() * 1.2); + */ + cellHeight(val?: numberOrString, update?: boolean): GridStack; + /** Gets current cell width. */ + cellWidth(): number; + /** return our expected width (or parent) for 1 column check */ + protected _widthOrContainer(): number; + /** re-layout grid items to reclaim any empty space */ + compact(): GridStack; + /** + * set the number of columns in the grid. Will update existing widgets to conform to new number of columns, + * as well as cache the original layout so you can revert back to previous positions without loss. + * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11], + * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns) + * @param column - Integer > 0 (default 12). + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + column(column: number, layout?: ColumnOptions): GridStack; + /** + * get the number of columns in the grid (default 12) + */ + getColumn(): number; + /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */ + getGridItems(): GridItemHTMLElement[]; + /** + * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members. + * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`). + */ + destroy(removeDOM?: boolean): GridStack; + /** + * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) + */ + float(val: boolean): GridStack; + /** + * get the current float mode + */ + getFloat(): boolean; + /** + * Get the position of the cell under a pixel on screen. + * @param position the position of the pixel to resolve in + * absolute coordinates, as an object with top and left properties + * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false). + * Useful when grid is within `position: relative` element + * + * Returns an object with properties `x` and `y` i.e. the column and row in the grid. + */ + getCellFromPixel(position: MousePosition, useDocRelative?: boolean): CellPosition; + /** returns the current number of rows, which will be at least `minRow` if set */ + getRow(): number; + /** + * Checks if specified area is empty. + * @param x the position x. + * @param y the position y. + * @param w the width of to check + * @param h the height of to check + */ + isAreaEmpty(x: number, y: number, w: number, h: number): boolean; + /** + * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets. + * If you want gridstack to add the elements for you, use `addWidget()` instead. + * Makes the given element a widget and returns it. + * @param els widget or single selector to convert. + * + * @example + * let grid = GridStack.init(); + * grid.el.appendChild('
'); + * grid.makeWidget('#gsi-1'); + */ + makeWidget(els: GridStackElement): GridItemHTMLElement; + /** + * Event handler that extracts our CustomEvent data out automatically for receiving custom + * notifications (see doc for supported events) + * @param name of the event (see possible values) or list of names space separated + * @param callback function called with event and optional second/third param + * (see README documentation for each signature). + * + * @example + * grid.on('added', function(e, items) { log('added ', items)} ); + * or + * grid.on('added removed change', function(e, items) { log(e.type, items)} ); + * + * Note: in some cases it is the same as calling native handler and parsing the event. + * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} ); + * + */ + on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack; + /** + * unsubscribe from the 'on' event below + * @param name of the event (see possible values) + */ + off(name: GridStackEvent): GridStack; + /** + * Removes widget from the grid. + * @param el widget or selector to modify + * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true). + * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true). + */ + removeWidget(els: GridStackElement, removeDOM?: boolean, triggerEvent?: boolean): GridStack; + /** + * Removes all widgets from the grid. + * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`). + */ + removeAll(removeDOM?: boolean): GridStack; + /** + * Toggle the grid animation state. Toggles the `grid-stack-animate` class. + * @param doAnimate if true the grid will animate. + */ + setAnimation(doAnimate: boolean): GridStack; + /** + * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on. + * Also toggle the grid-stack-static class. + * @param val if true the grid become static. + */ + setStatic(val: boolean, updateClass?: boolean): GridStack; + /** + * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed. + * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted) + * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated. + */ + update(els: GridStackElement, opt: GridStackWidget): GridStack; + /** + * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number). + * @param value margin value + */ + margin(value: numberOrString): GridStack; + /** returns current margin number value (undefined if 4 sides don't match) */ + getMargin(): number; + /** + * Returns true if the height of the grid will be less than the vertical + * constraint. Always returns true if grid doesn't have height constraint. + * @param node contains x,y,w,h,auto-position options + * + * @example + * if (grid.willItFit(newWidget)) { + * grid.addWidget(newWidget); + * } else { + * alert('Not enough free space to place the widget'); + * } + */ + willItFit(node: GridStackWidget): boolean; + /** + * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off + * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square) + */ + onParentResize(): GridStack; + /** add or remove the window size event handler */ + protected _updateWindowResizeEvent(forceRemove?: boolean): GridStack; + static GDRev: string; + /** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + * @param dragIn string selector (ex: '.sidebar .grid-stack-item') + * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'} + **/ + static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void; + /** + * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids. + * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ + movable(els: GridStackElement, val: boolean): GridStack; + /** + * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ + resizable(els: GridStackElement, val: boolean): GridStack; + /** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ + disable(): GridStack; + /** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ + enable(): GridStack; + /** + * Enables/disables widget moving. No-op for static grids. + */ + enableMove(doEnable: boolean): GridStack; + /** + * Enables/disables widget resizing. No-op for static grids. + */ + enableResize(doEnable: boolean): GridStack; + commit(): GridStack; +} +export * from './dd-gridstack'; diff --git a/dist/es5/gridstack.js b/dist/es5/gridstack.js new file mode 100644 index 000000000..73419081a --- /dev/null +++ b/dist/es5/gridstack.js @@ -0,0 +1,1549 @@ +"use strict"; +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); +}; +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GridStack = void 0; +/*! + * GridStack 6.0.1-dev + * https://gridstackjs.com/ + * + * Copyright (c) 2021-2022 Alain Dumesny + * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE + */ +var gridstack_engine_1 = require("./gridstack-engine"); +var utils_1 = require("./utils"); +// export all dependent file as well to make it easier for users to just import the main file +__exportStar(require("./types"), exports); +__exportStar(require("./utils"), exports); +__exportStar(require("./gridstack-engine"), exports); +// default values for grid options - used during init and when saving out +var GridDefaults = { + column: 12, + minRow: 0, + maxRow: 0, + itemClass: 'grid-stack-item', + placeholderClass: 'grid-stack-placeholder', + placeholderText: '', + handle: '.grid-stack-item-content', + handleClass: null, + styleInHead: false, + cellHeight: 'auto', + cellHeightThrottle: 100, + margin: 10, + auto: true, + oneColumnSize: 768, + float: false, + staticGrid: false, + animate: true, + alwaysShowResizeHandle: 'mobile', + resizable: { + handles: 'se' + }, + draggable: { + handle: '.grid-stack-item-content', + appendTo: 'body' + }, + disableDrag: false, + disableResize: false, + rtl: 'auto', + removable: false, + removableOptions: { + accept: '.grid-stack-item' + }, + marginUnit: 'px', + cellHeightUnit: 'px', + disableOneColumnMode: false, + oneColumnModeDomSort: false, +}; +/** + * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid. + * Note: your grid elements MUST have the following classes for the CSS layout to work: + * @example + *
+ *
+ *
Item 1
+ *
+ *
+ */ +var GridStack = /** @class */ (function () { + /** + * Construct a grid item from the given element and options + * @param el + * @param opts + */ + function GridStack(el, opts) { + var _this = this; + if (opts === void 0) { opts = {}; } + /** @internal */ + this._gsEventHandler = {}; + /** @internal extra row added when dragging at the bottom of the grid */ + this._extraDragRow = 0; + this.el = el; // exposed HTML element to the user + opts = opts || {}; // handles null/undefined/0 + // if row property exists, replace minRow and maxRow instead + if (opts.row) { + opts.minRow = opts.maxRow = opts.row; + delete opts.row; + } + var rowAttr = utils_1.Utils.toNumber(el.getAttribute('gs-row')); + // flag only valid in sub-grids (handled by parent, not here) + if (opts.column === 'auto') { + delete opts.column; + } + // 'minWidth' legacy support in 5.1 + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + var anyOpts = opts; + if (anyOpts.minWidth !== undefined) { + opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth; + delete anyOpts.minWidth; + } + // save original setting so we can restore on save + if (opts.alwaysShowResizeHandle !== undefined) { + opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle; + } + // elements DOM attributes override any passed options (like CSS style) - merge the two together + var defaults = __assign(__assign({}, utils_1.Utils.cloneDeep(GridDefaults)), { column: utils_1.Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column, minRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow, maxRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow, staticGrid: utils_1.Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid, _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0), draggable: { + handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle, + }, removableOptions: { + accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept, + } }); + if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead + defaults.animate = utils_1.Utils.toBool(el.getAttribute('gs-animate')); + } + this.opts = utils_1.Utils.defaults(opts, defaults); + opts = null; // make sure we use this.opts instead + this._initMargin(); // part of settings defaults... + // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column) + if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) { + this._prevColumn = this.getColumn(); + this.opts.column = 1; + } + if (this.opts.rtl === 'auto') { + this.opts.rtl = (el.style.direction === 'rtl'); + } + if (this.opts.rtl) { + this.el.classList.add('grid-stack-rtl'); + } + // check if we're been nested, and if so update our style and keep pointer around (used during save) + var parentGridItemEl = utils_1.Utils.closestByClass(this.el, GridDefaults.itemClass); + if (parentGridItemEl && parentGridItemEl.gridstackNode) { + this.opts._isNested = parentGridItemEl.gridstackNode; + this.opts._isNested.subGrid = this; + parentGridItemEl.classList.add('grid-stack-nested'); + this.el.classList.add('grid-stack-nested'); + } + this._isAutoCellHeight = (this.opts.cellHeight === 'auto'); + if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') { + // make the cell content square initially (will use resize/column event to keep it square) + this.cellHeight(undefined, false); + } + else { + // append unit if any are set + if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) { + this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit; + delete this.opts.cellHeightUnit; + } + this.cellHeight(this.opts.cellHeight, false); + } + // see if we need to adjust auto-hide + if (this.opts.alwaysShowResizeHandle === 'mobile') { + this.opts.alwaysShowResizeHandle = dd_touch_1.isTouch; + } + this.el.classList.add(this.opts._styleSheetClass); + this._setStaticClass(); + var engineClass = this.opts.engineClass || GridStack.engineClass || gridstack_engine_1.GridStackEngine; + this.engine = new engineClass({ + column: this.getColumn(), + float: this.opts.float, + maxRow: this.opts.maxRow, + onChange: function (cbNodes) { + var maxH = 0; + _this.engine.nodes.forEach(function (n) { maxH = Math.max(maxH, n.y + n.h); }); + cbNodes.forEach(function (n) { + var el = n.el; + if (!el) + return; + if (n._removeDOM) { + if (el) + el.remove(); + delete n._removeDOM; + } + else { + _this._writePosAttr(el, n); + } + }); + _this._updateStyles(false, maxH); // false = don't recreate, just append if need be + } + }); + if (this.opts.auto) { + this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check... + var elements_1 = []; + this.getGridItems().forEach(function (el) { + var x = parseInt(el.getAttribute('gs-x')); + var y = parseInt(el.getAttribute('gs-y')); + elements_1.push({ + el: el, + // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order + i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * _this.getColumn() + }); + }); + elements_1.sort(function (a, b) { return a.i - b.i; }).forEach(function (e) { return _this._prepareElement(e.el); }); + this.batchUpdate(false); + } + this.setAnimation(this.opts.animate); + this._updateStyles(); + if (this.opts.column != 12) { + this.el.classList.add('grid-stack-' + this.opts.column); + } + // legacy support to appear 'per grid` options when really global. + if (this.opts.dragIn) + GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions); + delete this.opts.dragIn; + delete this.opts.dragInOptions; + this._setupRemoveDrop(); + this._setupAcceptWidget(); + this._updateWindowResizeEvent(); + } + /** + * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will + * simply return the existing instance (ignore any passed options). There is also an initAll() version that support + * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON. + * @param options grid options (optional) + * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector) + * + * @example + * let grid = GridStack.init(); + * + * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later + * let grid = document.querySelector('.grid-stack').gridstack; + */ + GridStack.init = function (options, elOrString) { + if (options === void 0) { options = {}; } + if (elOrString === void 0) { elOrString = '.grid-stack'; } + var el = GridStack.getGridElement(elOrString); + if (!el) { + if (typeof elOrString === 'string') { + console.error('GridStack.initAll() no grid was found with selector "' + elOrString + '" - element missing or wrong selector ?' + + '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'); + } + else { + console.error('GridStack.init() no grid element was passed.'); + } + return null; + } + if (!el.gridstack) { + el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options)); + } + return el.gridstack; + }; + /** + * Will initialize a list of elements (given a selector) and return an array of grids. + * @param options grid options (optional) + * @param selector elements selector to convert to grids (default to '.grid-stack' class selector) + * + * @example + * let grids = GridStack.initAll(); + * grids.forEach(...) + */ + GridStack.initAll = function (options, selector) { + if (options === void 0) { options = {}; } + if (selector === void 0) { selector = '.grid-stack'; } + var grids = []; + GridStack.getGridElements(selector).forEach(function (el) { + if (!el.gridstack) { + el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options)); + delete options.dragIn; + delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid) + } + grids.push(el.gridstack); + }); + if (grids.length === 0) { + console.error('GridStack.initAll() no grid was found with selector "' + selector + '" - element missing or wrong selector ?' + + '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'); + } + return grids; + }; + /** + * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then + * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from + * JSON serialized data, including options. + * @param parent HTML element parent to the grid + * @param opt grids options used to initialize the grid, and list of children + */ + GridStack.addGrid = function (parent, opt) { + if (opt === void 0) { opt = {}; } + if (!parent) + return null; + // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead + var el = parent; + if (!parent.classList.contains('grid-stack')) { + var doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = "
"; + el = doc.body.children[0]; + parent.appendChild(el); + } + // create grid class and load any children + var grid = GridStack.init(opt, el); + if (grid.opts.children) { + var children = grid.opts.children; + delete grid.opts.children; + grid.load(children); + } + return grid; + }; + /** call this method to register your engine instead of the default one. + * See instead `GridStackOptions.engineClass` if you only need to + * replace just one instance. + */ + GridStack.registerEngine = function (engineClass) { + GridStack.engineClass = engineClass; + }; + Object.defineProperty(GridStack.prototype, "placeholder", { + /** @internal create placeholder DIV as needed */ + get: function () { + if (!this._placeholder) { + var placeholderChild = document.createElement('div'); // child so padding match item-content + placeholderChild.className = 'placeholder-content'; + if (this.opts.placeholderText) { + placeholderChild.innerHTML = this.opts.placeholderText; + } + this._placeholder = document.createElement('div'); + this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass); + this.placeholder.appendChild(placeholderChild); + } + return this._placeholder; + }, + enumerable: false, + configurable: true + }); + GridStack.prototype.change = function () { + this._triggerChangeEvent(); + }; + /** + * add a new widget and returns it. + * + * Widget will be always placed even if result height is more than actual grid height. + * You need to use `willItFit()` before calling addWidget for additional check. + * See also `makeWidget()`. + * + * @example + * let grid = GridStack.init(); + * grid.addWidget({w: 3, content: 'hello'}); + * grid.addWidget('
hello
', {w: 3}); + * + * @param el GridStackWidget (which can have content string as well), html element, or string definition to add + * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget + */ + GridStack.prototype.addWidget = function (els, options) { + // support legacy call for now ? + if (arguments.length > 2) { + console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + var a = arguments, i = 1, opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++], + minW: a[i++], maxW: a[i++], minH: a[i++], maxH: a[i++], id: a[i++] }; + return this.addWidget(els, opt); + } + function isGridStackWidget(w) { + return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false; + } + var el; + if (typeof els === 'string') { + var doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = els; + el = doc.body.children[0]; + } + else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) { + var content = els ? els.content || '' : ''; + options = els; + var doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = "
" + content + "
"; + el = doc.body.children[0]; + } + else { + el = els; + } + // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos + // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node. + // So make sure we load any DOM attributes that are not specified in passed in options (which override) + var domAttr = this._readAttr(el); + options = utils_1.Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it + utils_1.Utils.defaults(options, domAttr); + var node = this.engine.prepareNode(options); + this._writeAttr(el, options); + if (this._insertNotAppend) { + this.el.prepend(el); + } + else { + this.el.appendChild(el); + } + // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id + this._prepareElement(el, true, options); + this._updateContainerHeight(); + // check if nested grid definition is present + if (node.subGrid && !node.subGrid.el) { // see if there is a sub-grid to create too + // if column special case it set, remember that flag and set default + var autoColumn = void 0; + var ops = node.subGrid; + if (ops.column === 'auto') { + ops.column = node.w; + ops.disableOneColumnMode = true; // driven by parent + autoColumn = true; + } + var content = node.el.querySelector('.grid-stack-item-content'); + node.subGrid = GridStack.addGrid(content, node.subGrid); + if (autoColumn) { + node.subGrid._autoColumn = true; + } + } + this._triggerAddEvent(); + this._triggerChangeEvent(); + return el; + }; + /** + /** + * saves the current layout returning a list of widgets for serialization which might include any nested grids. + * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will + * be removed. + * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() + * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead. + * @returns list of widgets or full grid option, including .children list of widgets + */ + GridStack.prototype.save = function (saveContent, saveGridOpt) { + if (saveContent === void 0) { saveContent = true; } + if (saveGridOpt === void 0) { saveGridOpt = false; } + // return copied nodes we can modify at will... + var list = this.engine.save(saveContent); + // check for HTML content and nested grids + list.forEach(function (n) { + if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content + var sub = n.el.querySelector('.grid-stack-item-content'); + n.content = sub ? sub.innerHTML : undefined; + if (!n.content) + delete n.content; + } + else { + if (!saveContent) { + delete n.content; + } + // check for nested grid + if (n.subGrid) { + n.subGrid = n.subGrid.save(saveContent, true); + } + } + delete n.el; + }); + // check if save entire grid options (needed for recursive) + children... + if (saveGridOpt) { + var o = utils_1.Utils.cloneDeep(this.opts); + // delete default values that will be recreated on launch + if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) { + o.margin = o.marginTop; + delete o.marginTop; + delete o.marginRight; + delete o.marginBottom; + delete o.marginLeft; + } + if (o.rtl === (this.el.style.direction === 'rtl')) { + o.rtl = 'auto'; + } + if (this._isAutoCellHeight) { + o.cellHeight = 'auto'; + } + if (this._autoColumn) { + o.column = 'auto'; + delete o.disableOneColumnMode; + } + var origShow = o._alwaysShowResizeHandle; + delete o._alwaysShowResizeHandle; + if (origShow !== undefined) { + o.alwaysShowResizeHandle = origShow; + } + else { + delete o.alwaysShowResizeHandle; + } + utils_1.Utils.removeInternalAndSame(o, GridDefaults); + o.children = list; + return o; + } + return list; + }; + /** + * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there. + * + * @param layout list of widgets definition to update/create + * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving + * the user control of insertion. + * + * @example + * see http://gridstackjs.com/demo/serialization.html + **/ + GridStack.prototype.load = function (layout, addAndRemove) { + var _this = this; + if (addAndRemove === void 0) { addAndRemove = true; } + var items = GridStack.Utils.sort(__spreadArrays(layout), -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort + this._insertNotAppend = true; // since create in reverse order... + // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save + // the original wanted layout so we can scale back up correctly #1471 + if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(function (n) { return (n.x + n.w) > _this.opts.column; })) { + this._ignoreLayoutsNodeChange = true; // skip layout update + this.engine.cacheLayout(items, this._prevColumn, true); + } + var removed = []; + this.batchUpdate(); + // see if any items are missing from new layout and need to be removed first + if (addAndRemove) { + var copyNodes = __spreadArrays(this.engine.nodes); // don't loop through array you modify + copyNodes.forEach(function (n) { + var item = items.find(function (w) { return n.id === w.id; }); + if (!item) { + if (typeof (addAndRemove) === 'function') { + addAndRemove(_this, n, false); + } + else { + removed.push(n); // batch keep track + _this.removeWidget(n.el, true, false); + } + } + }); + } + // now add/update the widgets + items.forEach(function (w) { + var item = (w.id || w.id === 0) ? _this.engine.nodes.find(function (n) { return n.id === w.id; }) : undefined; + if (item) { + _this.update(item.el, w); + if (w.subGrid && w.subGrid.children) { // update any sub grid as well + var sub = item.el.querySelector('.grid-stack'); + if (sub && sub.gridstack) { + sub.gridstack.load(w.subGrid.children); // TODO: support updating grid options ? + _this._insertNotAppend = true; // got reset by above call + } + } + } + else if (addAndRemove) { + if (typeof (addAndRemove) === 'function') { + w = addAndRemove(_this, w, true).gridstackNode; + } + else { + w = _this.addWidget(w).gridstackNode; + } + } + }); + this.engine.removedNodes = removed; + this.batchUpdate(false); + // after commit, clear that flag + delete this._ignoreLayoutsNodeChange; + delete this._insertNotAppend; + return this; + }; + /** + * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient) + * and get a single event callback. You will see no changes until `batchUpdate(false)` is called. + */ + GridStack.prototype.batchUpdate = function (flag) { + if (flag === void 0) { flag = true; } + this.engine.batchUpdate(flag); + if (!flag) { + this._triggerRemoveEvent(); + this._triggerAddEvent(); + this._triggerChangeEvent(); + } + return this; + }; + /** + * Gets current cell height. + */ + GridStack.prototype.getCellHeight = function (forcePixel) { + if (forcePixel === void 0) { forcePixel = false; } + if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' && + (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) { + return this.opts.cellHeight; + } + // else get first cell height + var el = this.el.querySelector('.' + this.opts.itemClass); + if (el) { + var height = utils_1.Utils.toNumber(el.getAttribute('gs-h')); + return Math.round(el.offsetHeight / height); + } + // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain) + var rows = parseInt(this.el.getAttribute('gs-current-row')); + return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight; + }; + /** + * Update current cell height - see `GridStackOptions.cellHeight` for format. + * This method rebuilds an internal CSS style sheet. + * Note: You can expect performance issues if call this method too often. + * + * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin), + * if pass 0 the CSS will be generated by the application instead. + * @param update (Optional) if false, styles will not be updated + * + * @example + * grid.cellHeight(100); // same as 100px + * grid.cellHeight('70px'); + * grid.cellHeight(grid.cellWidth() * 1.2); + */ + GridStack.prototype.cellHeight = function (val, update) { + if (update === void 0) { update = true; } + // if not called internally, check if we're changing mode + if (update && val !== undefined) { + if (this._isAutoCellHeight !== (val === 'auto')) { + this._isAutoCellHeight = (val === 'auto'); + this._updateWindowResizeEvent(); + } + } + if (val === 'initial' || val === 'auto') { + val = undefined; + } + // make item content be square + if (val === undefined) { + var marginDiff = -this.opts.marginRight - this.opts.marginLeft + + this.opts.marginTop + this.opts.marginBottom; + val = this.cellWidth() + marginDiff; + } + var data = utils_1.Utils.parseHeight(val); + if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) { + return this; + } + this.opts.cellHeightUnit = data.unit; + this.opts.cellHeight = data.h; + if (update) { + this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows + } + return this; + }; + /** Gets current cell width. */ + GridStack.prototype.cellWidth = function () { + return this._widthOrContainer() / this.getColumn(); + }; + /** return our expected width (or parent) for 1 column check */ + GridStack.prototype._widthOrContainer = function () { + // use `offsetWidth` or `clientWidth` (no scrollbar) ? + // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively + return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth); + }; + /** re-layout grid items to reclaim any empty space */ + GridStack.prototype.compact = function () { + this.engine.compact(); + this._triggerChangeEvent(); + return this; + }; + /** + * set the number of columns in the grid. Will update existing widgets to conform to new number of columns, + * as well as cache the original layout so you can revert back to previous positions without loss. + * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11], + * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns) + * @param column - Integer > 0 (default 12). + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + GridStack.prototype.column = function (column, layout) { + if (layout === void 0) { layout = 'moveScale'; } + if (column < 1 || this.opts.column === column) + return this; + var oldColumn = this.getColumn(); + // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on) + // then remember the original columns so we can restore. + if (column === 1) { + this._prevColumn = oldColumn; + } + else { + delete this._prevColumn; + } + this.el.classList.remove('grid-stack-' + oldColumn); + this.el.classList.add('grid-stack-' + column); + this.opts.column = this.engine.column = column; + // update the items now - see if the dom order nodes should be passed instead (else default to current list) + var domNodes; + if (column === 1 && this.opts.oneColumnModeDomSort) { + domNodes = []; + this.getGridItems().forEach(function (el) { + if (el.gridstackNode) { + domNodes.push(el.gridstackNode); + } + }); + if (!domNodes.length) { + domNodes = undefined; + } + } + this.engine.updateNodeWidths(oldColumn, column, domNodes, layout); + if (this._isAutoCellHeight) + this.cellHeight(); + // and trigger our event last... + this._ignoreLayoutsNodeChange = true; // skip layout update + this._triggerChangeEvent(); + delete this._ignoreLayoutsNodeChange; + return this; + }; + /** + * get the number of columns in the grid (default 12) + */ + GridStack.prototype.getColumn = function () { + return this.opts.column; + }; + /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */ + GridStack.prototype.getGridItems = function () { + var _this = this; + return Array.from(this.el.children) + .filter(function (el) { return el.matches('.' + _this.opts.itemClass) && !el.matches('.' + _this.opts.placeholderClass); }); + }; + /** + * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members. + * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`). + */ + GridStack.prototype.destroy = function (removeDOM) { + if (removeDOM === void 0) { removeDOM = true; } + if (!this.el) + return; // prevent multiple calls + this._updateWindowResizeEvent(true); + this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away) + this.setAnimation(false); + if (!removeDOM) { + this.removeAll(removeDOM); + this.el.classList.remove(this.opts._styleSheetClass); + } + else { + this.el.parentNode.removeChild(this.el); + } + this._removeStylesheet(); + this.el.removeAttribute('gs-current-row'); + delete this.opts._isNested; + delete this.opts; + delete this._placeholder; + delete this.engine; + delete this.el.gridstack; // remove circular dependency that would prevent a freeing + delete this.el; + return this; + }; + /** + * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) + */ + GridStack.prototype.float = function (val) { + if (this.opts.float !== val) { + this.opts.float = this.engine.float = val; + this._triggerChangeEvent(); + } + return this; + }; + /** + * get the current float mode + */ + GridStack.prototype.getFloat = function () { + return this.engine.float; + }; + /** + * Get the position of the cell under a pixel on screen. + * @param position the position of the pixel to resolve in + * absolute coordinates, as an object with top and left properties + * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false). + * Useful when grid is within `position: relative` element + * + * Returns an object with properties `x` and `y` i.e. the column and row in the grid. + */ + GridStack.prototype.getCellFromPixel = function (position, useDocRelative) { + if (useDocRelative === void 0) { useDocRelative = false; } + var box = this.el.getBoundingClientRect(); + // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`) + var containerPos; + if (useDocRelative) { + containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left }; + // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`) + } + else { + containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft }; + // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`) + } + var relativeLeft = position.left - containerPos.left; + var relativeTop = position.top - containerPos.top; + var columnWidth = (box.width / this.getColumn()); + var rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row'))); + return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) }; + }; + /** returns the current number of rows, which will be at least `minRow` if set */ + GridStack.prototype.getRow = function () { + return Math.max(this.engine.getRow(), this.opts.minRow); + }; + /** + * Checks if specified area is empty. + * @param x the position x. + * @param y the position y. + * @param w the width of to check + * @param h the height of to check + */ + GridStack.prototype.isAreaEmpty = function (x, y, w, h) { + return this.engine.isAreaEmpty(x, y, w, h); + }; + /** + * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets. + * If you want gridstack to add the elements for you, use `addWidget()` instead. + * Makes the given element a widget and returns it. + * @param els widget or single selector to convert. + * + * @example + * let grid = GridStack.init(); + * grid.el.appendChild('
'); + * grid.makeWidget('#gsi-1'); + */ + GridStack.prototype.makeWidget = function (els) { + var el = GridStack.getElement(els); + this._prepareElement(el, true); + this._updateContainerHeight(); + this._triggerAddEvent(); + this._triggerChangeEvent(); + return el; + }; + /** + * Event handler that extracts our CustomEvent data out automatically for receiving custom + * notifications (see doc for supported events) + * @param name of the event (see possible values) or list of names space separated + * @param callback function called with event and optional second/third param + * (see README documentation for each signature). + * + * @example + * grid.on('added', function(e, items) { log('added ', items)} ); + * or + * grid.on('added removed change', function(e, items) { log(e.type, items)} ); + * + * Note: in some cases it is the same as calling native handler and parsing the event. + * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} ); + * + */ + GridStack.prototype.on = function (name, callback) { + var _this = this; + // check for array of names being passed instead + if (name.indexOf(' ') !== -1) { + var names = name.split(' '); + names.forEach(function (name) { return _this.on(name, callback); }); + return this; + } + if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') { + // native CustomEvent handlers - cash the generic handlers so we can easily remove + var noData = (name === 'enable' || name === 'disable'); + if (noData) { + this._gsEventHandler[name] = function (event) { return callback(event); }; + } + else { + this._gsEventHandler[name] = function (event) { return callback(event, event.detail); }; + } + this.el.addEventListener(name, this._gsEventHandler[name]); + } + else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') { + // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself. + // do same for start event to make it easier... + this._gsEventHandler[name] = callback; + } + else { + console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.'); + } + return this; + }; + /** + * unsubscribe from the 'on' event below + * @param name of the event (see possible values) + */ + GridStack.prototype.off = function (name) { + var _this = this; + // check for array of names being passed instead + if (name.indexOf(' ') !== -1) { + var names = name.split(' '); + names.forEach(function (name) { return _this.off(name); }); + return this; + } + if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') { + // remove native CustomEvent handlers + if (this._gsEventHandler[name]) { + this.el.removeEventListener(name, this._gsEventHandler[name]); + } + } + delete this._gsEventHandler[name]; + return this; + }; + /** + * Removes widget from the grid. + * @param el widget or selector to modify + * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true). + * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true). + */ + GridStack.prototype.removeWidget = function (els, removeDOM, triggerEvent) { + var _this = this; + if (removeDOM === void 0) { removeDOM = true; } + if (triggerEvent === void 0) { triggerEvent = true; } + GridStack.getElements(els).forEach(function (el) { + if (el.parentElement !== _this.el) + return; // not our child! + var node = el.gridstackNode; + // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272 + if (!node) { + node = _this.engine.nodes.find(function (n) { return el === n.el; }); + } + if (!node) + return; + // remove our DOM data (circular link) and drag&drop permanently + delete el.gridstackNode; + _this._removeDD(el); + _this.engine.removeNode(node, removeDOM, triggerEvent); + if (removeDOM && el.parentElement) { + el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM + } + }); + if (triggerEvent) { + this._triggerRemoveEvent(); + this._triggerChangeEvent(); + } + return this; + }; + /** + * Removes all widgets from the grid. + * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`). + */ + GridStack.prototype.removeAll = function (removeDOM) { + var _this = this; + if (removeDOM === void 0) { removeDOM = true; } + // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently + this.engine.nodes.forEach(function (n) { + delete n.el.gridstackNode; + _this._removeDD(n.el); + }); + this.engine.removeAll(removeDOM); + this._triggerRemoveEvent(); + return this; + }; + /** + * Toggle the grid animation state. Toggles the `grid-stack-animate` class. + * @param doAnimate if true the grid will animate. + */ + GridStack.prototype.setAnimation = function (doAnimate) { + if (doAnimate) { + this.el.classList.add('grid-stack-animate'); + } + else { + this.el.classList.remove('grid-stack-animate'); + } + return this; + }; + /** + * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on. + * Also toggle the grid-stack-static class. + * @param val if true the grid become static. + */ + GridStack.prototype.setStatic = function (val, updateClass) { + var _this = this; + if (updateClass === void 0) { updateClass = true; } + if (this.opts.staticGrid === val) + return this; + this.opts.staticGrid = val; + this._setupRemoveDrop(); + this._setupAcceptWidget(); + this.engine.nodes.forEach(function (n) { return _this._prepareDragDropByNode(n); }); // either delete or init Drag&drop + if (updateClass) { + this._setStaticClass(); + } + return this; + }; + /** + * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed. + * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted) + * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated. + */ + GridStack.prototype.update = function (els, opt) { + var _this = this; + // support legacy call for now ? + if (arguments.length > 2) { + console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + var a = arguments, i = 1; + opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] }; + return this.update(els, opt); + } + GridStack.getElements(els).forEach(function (el) { + if (!el || !el.gridstackNode) + return; + var n = el.gridstackNode; + var w = utils_1.Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items + delete w.autoPosition; + // move/resize widget if anything changed + var keys = ['x', 'y', 'w', 'h']; + var m; + if (keys.some(function (k) { return w[k] !== undefined && w[k] !== n[k]; })) { + m = {}; + keys.forEach(function (k) { + m[k] = (w[k] !== undefined) ? w[k] : n[k]; + delete w[k]; + }); + } + // for a move as well IFF there is any min/max fields set + if (!m && (w.minW || w.minH || w.maxW || w.maxH)) { + m = {}; // will use node position but validate values + } + // check for content changing + if (w.content) { + var sub = el.querySelector('.grid-stack-item-content'); + if (sub && sub.innerHTML !== w.content) { + sub.innerHTML = w.content; + } + delete w.content; + } + // any remaining fields are assigned, but check for dragging changes, resize constrain + var changed = false; + var ddChanged = false; + for (var key in w) { + if (key[0] !== '_' && n[key] !== w[key]) { + n[key] = w[key]; + changed = true; + ddChanged = ddChanged || (!_this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked')); + } + } + // finally move the widget + if (m) { + _this.engine.cleanNodes() + .beginUpdate(n) + .moveNode(n, m); + _this._updateContainerHeight(); + _this._triggerChangeEvent(); + _this.engine.endUpdate(); + } + if (changed) { // move will only update x,y,w,h so update the rest too + _this._writeAttr(el, n); + } + if (ddChanged) { + _this._prepareDragDropByNode(n); + } + }); + return this; + }; + /** + * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number). + * @param value margin value + */ + GridStack.prototype.margin = function (value) { + var isMultiValue = (typeof value === 'string' && value.split(' ').length > 1); + // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle) + if (!isMultiValue) { + var data = utils_1.Utils.parseHeight(value); + if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) + return; + } + // re-use existing margin handling + this.opts.margin = value; + this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined; + this._initMargin(); + this._updateStyles(true); // true = force re-create + return this; + }; + /** returns current margin number value (undefined if 4 sides don't match) */ + GridStack.prototype.getMargin = function () { return this.opts.margin; }; + /** + * Returns true if the height of the grid will be less than the vertical + * constraint. Always returns true if grid doesn't have height constraint. + * @param node contains x,y,w,h,auto-position options + * + * @example + * if (grid.willItFit(newWidget)) { + * grid.addWidget(newWidget); + * } else { + * alert('Not enough free space to place the widget'); + * } + */ + GridStack.prototype.willItFit = function (node) { + // support legacy call for now + if (arguments.length > 1) { + console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + var a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] }; + return this.willItFit(w); + } + return this.engine.willItFit(node); + }; + /** @internal */ + GridStack.prototype._triggerChangeEvent = function () { + if (this.engine.batchMode) + return this; + var elements = this.engine.getDirtyNodes(true); // verify they really changed + if (elements && elements.length) { + if (!this._ignoreLayoutsNodeChange) { + this.engine.layoutsNodesChange(elements); + } + this._triggerEvent('change', elements); + } + this.engine.saveInitial(); // we called, now reset initial values & dirty flags + return this; + }; + /** @internal */ + GridStack.prototype._triggerAddEvent = function () { + if (this.engine.batchMode) + return this; + if (this.engine.addedNodes && this.engine.addedNodes.length > 0) { + if (!this._ignoreLayoutsNodeChange) { + this.engine.layoutsNodesChange(this.engine.addedNodes); + } + // prevent added nodes from also triggering 'change' event (which is called next) + this.engine.addedNodes.forEach(function (n) { delete n._dirty; }); + this._triggerEvent('added', this.engine.addedNodes); + this.engine.addedNodes = []; + } + return this; + }; + /** @internal */ + GridStack.prototype._triggerRemoveEvent = function () { + if (this.engine.batchMode) + return this; + if (this.engine.removedNodes && this.engine.removedNodes.length > 0) { + this._triggerEvent('removed', this.engine.removedNodes); + this.engine.removedNodes = []; + } + return this; + }; + /** @internal */ + GridStack.prototype._triggerEvent = function (name, data) { + var event = data ? new CustomEvent(name, { bubbles: false, detail: data }) : new Event(name); + this.el.dispatchEvent(event); + return this; + }; + /** @internal called to delete the current dynamic style sheet used for our layout */ + GridStack.prototype._removeStylesheet = function () { + if (this._styles) { + utils_1.Utils.removeStylesheet(this._styles._id); + delete this._styles; + } + return this; + }; + /** @internal updated/create the CSS styles for row based layout and initial margin setting */ + GridStack.prototype._updateStyles = function (forceUpdate, maxH) { + if (forceUpdate === void 0) { forceUpdate = false; } + // call to delete existing one if we change cellHeight / margin + if (forceUpdate) { + this._removeStylesheet(); + } + this._updateContainerHeight(); + // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ?? + if (this.opts.cellHeight === 0) { + return this; + } + var cellHeight = this.opts.cellHeight; + var cellHeightUnit = this.opts.cellHeightUnit; + var prefix = "." + this.opts._styleSheetClass + " > ." + this.opts.itemClass; + // create one as needed + if (!this._styles) { + var id = 'gridstack-style-' + (Math.random() * 100000).toFixed(); + // insert style to parent (instead of 'head' by default) to support WebComponent + var styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode; + this._styles = utils_1.Utils.createStylesheet(id, styleLocation); + if (!this._styles) + return this; + this._styles._id = id; + this._styles._max = 0; + // these are done once only + utils_1.Utils.addCSSRule(this._styles, prefix, "min-height: " + cellHeight + cellHeightUnit); + // content margins + var top_1 = this.opts.marginTop + this.opts.marginUnit; + var bottom = this.opts.marginBottom + this.opts.marginUnit; + var right = this.opts.marginRight + this.opts.marginUnit; + var left = this.opts.marginLeft + this.opts.marginUnit; + var content = prefix + " > .grid-stack-item-content"; + var placeholder = "." + this.opts._styleSheetClass + " > .grid-stack-placeholder > .placeholder-content"; + utils_1.Utils.addCSSRule(this._styles, content, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";"); + utils_1.Utils.addCSSRule(this._styles, placeholder, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";"); + // resize handles offset (to match margin) + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-ne", "right: " + right); + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-e", "right: " + right); + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-se", "right: " + right + "; bottom: " + bottom); + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-nw", "left: " + left); + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-w", "left: " + left); + utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-sw", "left: " + left + "; bottom: " + bottom); + } + // now update the height specific fields + maxH = maxH || this._styles._max; + if (maxH > this._styles._max) { + var getHeight = function (rows) { return (cellHeight * rows) + cellHeightUnit; }; + for (var i = this._styles._max + 1; i <= maxH; i++) { // start at 1 + var h = getHeight(i); + utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-y=\"" + (i - 1) + "\"]", "top: " + getHeight(i - 1)); // start at 0 + utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-h=\"" + i + "\"]", "height: " + h); + utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-min-h=\"" + i + "\"]", "min-height: " + h); + utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-max-h=\"" + i + "\"]", "max-height: " + h); + } + this._styles._max = maxH; + } + return this; + }; + /** @internal */ + GridStack.prototype._updateContainerHeight = function () { + if (!this.engine || this.engine.batchMode) + return this; + var row = this.getRow() + this._extraDragRow; // checks for minRow already + // check for css min height + // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary + // rows as the CSS will make us bigger than our set height if needed... not sure why we had this. + // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']); + // if (cssMinHeight > 0) { + // let minRow = Math.round(cssMinHeight / this.getCellHeight(true)); + // if (row < minRow) { + // row = minRow; + // } + // } + this.el.setAttribute('gs-current-row', String(row)); + if (row === 0) { + this.el.style.removeProperty('height'); + return this; + } + var cellHeight = this.opts.cellHeight; + var unit = this.opts.cellHeightUnit; + if (!cellHeight) + return this; + this.el.style.height = row * cellHeight + unit; + return this; + }; + /** @internal */ + GridStack.prototype._prepareElement = function (el, triggerAddEvent, node) { + if (triggerAddEvent === void 0) { triggerAddEvent = false; } + if (!node) { + el.classList.add(this.opts.itemClass); + node = this._readAttr(el); + } + el.gridstackNode = node; + node.el = el; + node.grid = this; + var copy = __assign({}, node); + node = this.engine.addNode(node, triggerAddEvent); + // write node attr back in case there was collision or we have to fix bad values during addNode() + if (!utils_1.Utils.same(node, copy)) { + this._writeAttr(el, node); + } + this._prepareDragDropByNode(node); + return this; + }; + /** @internal call to write position x,y,w,h attributes back to element */ + GridStack.prototype._writePosAttr = function (el, n) { + if (n.x !== undefined && n.x !== null) { + el.setAttribute('gs-x', String(n.x)); + } + if (n.y !== undefined && n.y !== null) { + el.setAttribute('gs-y', String(n.y)); + } + if (n.w) { + el.setAttribute('gs-w', String(n.w)); + } + if (n.h) { + el.setAttribute('gs-h', String(n.h)); + } + return this; + }; + /** @internal call to write any default attributes back to element */ + GridStack.prototype._writeAttr = function (el, node) { + if (!node) + return this; + this._writePosAttr(el, node); + var attrs /*: GridStackWidget but strings */ = { + autoPosition: 'gs-auto-position', + minW: 'gs-min-w', + minH: 'gs-min-h', + maxW: 'gs-max-w', + maxH: 'gs-max-h', + noResize: 'gs-no-resize', + noMove: 'gs-no-move', + locked: 'gs-locked', + id: 'gs-id', + resizeHandles: 'gs-resize-handles' + }; + for (var key in attrs) { + if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway + el.setAttribute(attrs[key], String(node[key])); + } + else { + el.removeAttribute(attrs[key]); + } + } + return this; + }; + /** @internal call to read any default attributes from element */ + GridStack.prototype._readAttr = function (el) { + var node = {}; + node.x = utils_1.Utils.toNumber(el.getAttribute('gs-x')); + node.y = utils_1.Utils.toNumber(el.getAttribute('gs-y')); + node.w = utils_1.Utils.toNumber(el.getAttribute('gs-w')); + node.h = utils_1.Utils.toNumber(el.getAttribute('gs-h')); + node.maxW = utils_1.Utils.toNumber(el.getAttribute('gs-max-w')); + node.minW = utils_1.Utils.toNumber(el.getAttribute('gs-min-w')); + node.maxH = utils_1.Utils.toNumber(el.getAttribute('gs-max-h')); + node.minH = utils_1.Utils.toNumber(el.getAttribute('gs-min-h')); + node.autoPosition = utils_1.Utils.toBool(el.getAttribute('gs-auto-position')); + node.noResize = utils_1.Utils.toBool(el.getAttribute('gs-no-resize')); + node.noMove = utils_1.Utils.toBool(el.getAttribute('gs-no-move')); + node.locked = utils_1.Utils.toBool(el.getAttribute('gs-locked')); + node.resizeHandles = el.getAttribute('gs-resize-handles'); + node.id = el.getAttribute('gs-id'); + // remove any key not found (null or false which is default) + for (var key in node) { + if (!node.hasOwnProperty(key)) + return; + if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really) + delete node[key]; + } + } + return node; + }; + /** @internal */ + GridStack.prototype._setStaticClass = function () { + var _a, _b; + var classes = ['grid-stack-static']; + if (this.opts.staticGrid) { + (_a = this.el.classList).add.apply(_a, classes); + this.el.setAttribute('gs-static', 'true'); + } + else { + (_b = this.el.classList).remove.apply(_b, classes); + this.el.removeAttribute('gs-static'); + } + return this; + }; + /** + * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off + * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square) + */ + GridStack.prototype.onParentResize = function () { + var _this = this; + if (!this.el || !this.el.clientWidth) + return; // return if we're gone or no size yet (will get called again) + var changedColumn = false; + // see if we're nested and take our column count from our parent.... + if (this._autoColumn && this.opts._isNested) { + if (this.opts.column !== this.opts._isNested.w) { + changedColumn = true; + this.column(this.opts._isNested.w, 'none'); + } + } + else { + // else check for 1 column in/out behavior + var oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize; + if ((this.opts.column === 1) !== oneColumn) { + changedColumn = true; + if (this.opts.animate) { + this.setAnimation(false); + } // 1 <-> 12 is too radical, turn off animation + this.column(oneColumn ? 1 : this._prevColumn); + if (this.opts.animate) { + this.setAnimation(true); + } + } + } + // make the cells content square again + if (this._isAutoCellHeight) { + if (!changedColumn && this.opts.cellHeightThrottle) { + if (!this._cellHeightThrottle) { + this._cellHeightThrottle = utils_1.Utils.throttle(function () { return _this.cellHeight(); }, this.opts.cellHeightThrottle); + } + this._cellHeightThrottle(); + } + else { + // immediate update if we've changed column count or have no threshold + this.cellHeight(); + } + } + // finally update any nested grids + this.engine.nodes.forEach(function (n) { + if (n.subGrid) { + n.subGrid.onParentResize(); + } + }); + return this; + }; + /** add or remove the window size event handler */ + GridStack.prototype._updateWindowResizeEvent = function (forceRemove) { + if (forceRemove === void 0) { forceRemove = false; } + // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work) + var workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested; + if (!forceRemove && workTodo && !this._windowResizeBind) { + this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later + window.addEventListener('resize', this._windowResizeBind); + } + else if ((forceRemove || !workTodo) && this._windowResizeBind) { + window.removeEventListener('resize', this._windowResizeBind); + delete this._windowResizeBind; // remove link to us so we can free + } + return this; + }; + /** @internal convert a potential selector into actual element */ + GridStack.getElement = function (els) { + if (els === void 0) { els = '.grid-stack-item'; } + return utils_1.Utils.getElement(els); + }; + /** @internal */ + GridStack.getElements = function (els) { + if (els === void 0) { els = '.grid-stack-item'; } + return utils_1.Utils.getElements(els); + }; + /** @internal */ + GridStack.getGridElement = function (els) { return GridStack.getElement(els); }; + /** @internal */ + GridStack.getGridElements = function (els) { return utils_1.Utils.getElements(els); }; + /** @internal initialize margin top/bottom/left/right and units */ + GridStack.prototype._initMargin = function () { + var data; + var margin = 0; + // support passing multiple values like CSS (ex: '5px 10px 0 20px') + var margins = []; + if (typeof this.opts.margin === 'string') { + margins = this.opts.margin.split(' '); + } + if (margins.length === 2) { // top/bot, left/right like CSS + this.opts.marginTop = this.opts.marginBottom = margins[0]; + this.opts.marginLeft = this.opts.marginRight = margins[1]; + } + else if (margins.length === 4) { // Clockwise like CSS + this.opts.marginTop = margins[0]; + this.opts.marginRight = margins[1]; + this.opts.marginBottom = margins[2]; + this.opts.marginLeft = margins[3]; + } + else { + data = utils_1.Utils.parseHeight(this.opts.margin); + this.opts.marginUnit = data.unit; + margin = this.opts.margin = data.h; + } + // see if top/bottom/left/right need to be set as well + if (this.opts.marginTop === undefined) { + this.opts.marginTop = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginTop); + this.opts.marginTop = data.h; + delete this.opts.margin; + } + if (this.opts.marginBottom === undefined) { + this.opts.marginBottom = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginBottom); + this.opts.marginBottom = data.h; + delete this.opts.margin; + } + if (this.opts.marginRight === undefined) { + this.opts.marginRight = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginRight); + this.opts.marginRight = data.h; + delete this.opts.margin; + } + if (this.opts.marginLeft === undefined) { + this.opts.marginLeft = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginLeft); + this.opts.marginLeft = data.h; + delete this.opts.margin; + } + this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead... + if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) { + this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin() + } + return this; + }; + /* + * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid + * so we don't incur the load unless needed. + * NOTE: had to make those methods public in order to define them else as + * GridStack.prototype._setupAcceptWidget = function() + * maybe there is a better way ???? + */ + /* eslint-disable @typescript-eslint/no-unused-vars */ + /** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + * @param dragIn string selector (ex: '.sidebar .grid-stack-item') + * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'} + **/ + GridStack.setupDragIn = function (dragIn, dragInOptions) { }; + /** + * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids. + * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ + GridStack.prototype.movable = function (els, val) { return this; }; + /** + * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ + GridStack.prototype.resizable = function (els, val) { return this; }; + /** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ + GridStack.prototype.disable = function () { return this; }; + /** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ + GridStack.prototype.enable = function () { return this; }; + /** + * Enables/disables widget moving. No-op for static grids. + */ + GridStack.prototype.enableMove = function (doEnable) { return this; }; + /** + * Enables/disables widget resizing. No-op for static grids. + */ + GridStack.prototype.enableResize = function (doEnable) { return this; }; + /** @internal removes any drag&drop present (called during destroy) */ + GridStack.prototype._removeDD = function (el) { return this; }; + /** @internal called to add drag over support to support widgets */ + GridStack.prototype._setupAcceptWidget = function () { return this; }; + /** @internal called to setup a trash drop zone if the user specifies it */ + GridStack.prototype._setupRemoveDrop = function () { return this; }; + /** @internal prepares the element for drag&drop **/ + GridStack.prototype._prepareDragDropByNode = function (node) { return this; }; + /** @internal handles actual drag/resize start **/ + GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) { return; }; + /** @internal handles actual drag/resize **/ + GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) { return; }; + /** @internal called when a node leaves our area (mouse out or shape outside) **/ + GridStack.prototype._leave = function (el, helper) { return; }; + // legacy method removed + GridStack.prototype.commit = function () { utils_1.obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }; + /** scoping so users can call GridStack.Utils.sort() for example */ + GridStack.Utils = utils_1.Utils; + /** scoping so users can call new GridStack.Engine(12) for example */ + GridStack.Engine = gridstack_engine_1.GridStackEngine; + GridStack.GDRev = '6.0.1-dev'; + return GridStack; +}()); +exports.GridStack = GridStack; +var dd_touch_1 = require("./dd-touch"); +__exportStar(require("./dd-gridstack"), exports); +//# sourceMappingURL=gridstack.js.map \ No newline at end of file diff --git a/dist/es5/gridstack.js.map b/dist/es5/gridstack.js.map new file mode 100644 index 000000000..dc4f1bb19 --- /dev/null +++ b/dist/es5/gridstack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gridstack.js","sourceRoot":"","sources":["../../src/gridstack.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\r\n * GridStack 6.0.1-dev\r\n * https://gridstackjs.com/\r\n *\r\n * Copyright (c) 2021-2022 Alain Dumesny\r\n * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE\r\n */\r\nimport { GridStackEngine } from './gridstack-engine';\r\nimport { Utils, HeightData, obsolete } from './utils';\r\nimport { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback,\r\n GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\n\r\n// export all dependent file as well to make it easier for users to just import the main file\r\nexport * from './types';\r\nexport * from './utils';\r\nexport * from './gridstack-engine';\r\n\r\nexport interface GridHTMLElement extends HTMLElement {\r\n gridstack?: GridStack; // grid's parent DOM element points back to grid class\r\n}\r\n/** list of possible events, or space separated list of them */\r\nexport type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' |\r\n 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string;\r\n\r\n/** Defines the coordinates of an object */\r\nexport interface MousePosition {\r\n top: number;\r\n left: number;\r\n}\r\n\r\n/** Defines the position of a cell inside the grid*/\r\nexport interface CellPosition {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface GridCSSStyleSheet extends CSSStyleSheet {\r\n _id?: string; // random id we will use to style us\r\n _max?: number; // internal tracker of the max # of rows we created\\\r\n}\r\n\r\n// default values for grid options - used during init and when saving out\r\nconst GridDefaults: GridStackOptions = {\r\n column: 12,\r\n minRow: 0,\r\n maxRow: 0,\r\n itemClass: 'grid-stack-item',\r\n placeholderClass: 'grid-stack-placeholder',\r\n placeholderText: '',\r\n handle: '.grid-stack-item-content',\r\n handleClass: null,\r\n styleInHead: false,\r\n cellHeight: 'auto',\r\n cellHeightThrottle: 100,\r\n margin: 10,\r\n auto: true,\r\n oneColumnSize: 768,\r\n float: false,\r\n staticGrid: false,\r\n animate: true,\r\n alwaysShowResizeHandle: 'mobile',\r\n resizable: {\r\n handles: 'se'\r\n },\r\n draggable: {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body'\r\n },\r\n disableDrag: false,\r\n disableResize: false,\r\n rtl: 'auto',\r\n removable: false,\r\n removableOptions: {\r\n accept: '.grid-stack-item'\r\n },\r\n marginUnit: 'px',\r\n cellHeightUnit: 'px',\r\n disableOneColumnMode: false,\r\n oneColumnModeDomSort: false,\r\n};\r\n\r\n/**\r\n * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.\r\n * Note: your grid elements MUST have the following classes for the CSS layout to work:\r\n * @example\r\n *
\r\n *
\r\n *
Item 1
\r\n *
\r\n *
\r\n */\r\nexport class GridStack {\r\n\r\n /**\r\n * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will\r\n * simply return the existing instance (ignore any passed options). There is also an initAll() version that support\r\n * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.\r\n * @param options grid options (optional)\r\n * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n *\r\n * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later\r\n * let grid = document.querySelector('.grid-stack').gridstack;\r\n */\r\n public static init(options: GridStackOptions = {}, elOrString: GridStackElement = '.grid-stack'): GridStack {\r\n let el = GridStack.getGridElement(elOrString);\r\n if (!el) {\r\n if (typeof elOrString === 'string') {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + elOrString + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n } else {\r\n console.error('GridStack.init() no grid element was passed.');\r\n }\r\n return null;\r\n }\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n }\r\n return el.gridstack\r\n }\r\n\r\n /**\r\n * Will initialize a list of elements (given a selector) and return an array of grids.\r\n * @param options grid options (optional)\r\n * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grids = GridStack.initAll();\r\n * grids.forEach(...)\r\n */\r\n public static initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[] {\r\n let grids: GridStack[] = [];\r\n GridStack.getGridElements(selector).forEach(el => {\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n delete options.dragIn; delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)\r\n }\r\n grids.push(el.gridstack);\r\n });\r\n if (grids.length === 0) {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + selector + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n }\r\n return grids;\r\n }\r\n\r\n /**\r\n * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then\r\n * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from\r\n * JSON serialized data, including options.\r\n * @param parent HTML element parent to the grid\r\n * @param opt grids options used to initialize the grid, and list of children\r\n */\r\n public static addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack {\r\n if (!parent) return null;\r\n\r\n // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead\r\n let el = parent;\r\n if (!parent.classList.contains('grid-stack')) {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n parent.appendChild(el);\r\n }\r\n\r\n // create grid class and load any children\r\n let grid = GridStack.init(opt, el);\r\n if (grid.opts.children) {\r\n let children = grid.opts.children;\r\n delete grid.opts.children;\r\n grid.load(children);\r\n }\r\n return grid;\r\n }\r\n\r\n /** call this method to register your engine instead of the default one.\r\n * See instead `GridStackOptions.engineClass` if you only need to\r\n * replace just one instance.\r\n */\r\n static registerEngine(engineClass: typeof GridStackEngine) {\r\n GridStack.engineClass = engineClass;\r\n }\r\n\r\n /** scoping so users can call GridStack.Utils.sort() for example */\r\n public static Utils = Utils;\r\n\r\n /** scoping so users can call new GridStack.Engine(12) for example */\r\n public static Engine = GridStackEngine;\r\n\r\n /** the HTML element tied to this grid after it's been initialized */\r\n public el: GridHTMLElement;\r\n\r\n /** engine used to implement non DOM grid functionality */\r\n public engine: GridStackEngine;\r\n\r\n /** grid options - public for classes to access, but use methods to modify! */\r\n public opts: GridStackOptions;\r\n\r\n protected static engineClass: typeof GridStackEngine;\r\n\r\n /** @internal create placeholder DIV as needed */\r\n public get placeholder(): HTMLElement {\r\n if (!this._placeholder) {\r\n let placeholderChild = document.createElement('div'); // child so padding match item-content\r\n placeholderChild.className = 'placeholder-content';\r\n if (this.opts.placeholderText) {\r\n placeholderChild.innerHTML = this.opts.placeholderText;\r\n }\r\n this._placeholder = document.createElement('div');\r\n this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass);\r\n this.placeholder.appendChild(placeholderChild);\r\n }\r\n return this._placeholder;\r\n }\r\n /** @internal */\r\n protected _placeholder: HTMLElement;\r\n /** @internal */\r\n protected _prevColumn: number;\r\n /** @internal */\r\n protected _ignoreLayoutsNodeChange: boolean;\r\n /** @internal */\r\n public _gsEventHandler = {};\r\n /** @internal */\r\n protected _styles: GridCSSStyleSheet;\r\n /** @internal flag to keep cells square during resize */\r\n protected _isAutoCellHeight: boolean;\r\n /** @internal track event binding to window resize so we can remove */\r\n protected _windowResizeBind: () => void;\r\n /** @internal limit auto cell resizing method */\r\n protected _cellHeightThrottle: () => void;\r\n /** @internal true when loading items to insert first rather than append */\r\n protected _insertNotAppend: boolean;\r\n /** @internal extra row added when dragging at the bottom of the grid */\r\n protected _extraDragRow = 0;\r\n /** @internal true if nested grid should get column count from our width */\r\n protected _autoColumn?: boolean;\r\n\r\n /**\r\n * Construct a grid item from the given element and options\r\n * @param el\r\n * @param opts\r\n */\r\n public constructor(el: GridHTMLElement, opts: GridStackOptions = {}) {\r\n this.el = el; // exposed HTML element to the user\r\n opts = opts || {}; // handles null/undefined/0\r\n\r\n // if row property exists, replace minRow and maxRow instead\r\n if (opts.row) {\r\n opts.minRow = opts.maxRow = opts.row;\r\n delete opts.row;\r\n }\r\n let rowAttr = Utils.toNumber(el.getAttribute('gs-row'));\r\n\r\n // flag only valid in sub-grids (handled by parent, not here)\r\n if (opts.column === 'auto') {\r\n delete opts.column;\r\n }\r\n // 'minWidth' legacy support in 5.1\r\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\r\n let anyOpts = opts as any;\r\n if (anyOpts.minWidth !== undefined) {\r\n opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;\r\n delete anyOpts.minWidth;\r\n }\r\n // save original setting so we can restore on save\r\n if (opts.alwaysShowResizeHandle !== undefined) {\r\n (opts as any)._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;\r\n }\r\n\r\n // elements DOM attributes override any passed options (like CSS style) - merge the two together\r\n let defaults: GridStackOptions = {...Utils.cloneDeep(GridDefaults),\r\n column: Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column,\r\n minRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow,\r\n maxRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow,\r\n staticGrid: Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid,\r\n _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0),\r\n draggable: {\r\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle,\r\n },\r\n removableOptions: {\r\n accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept,\r\n },\r\n };\r\n if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead\r\n defaults.animate = Utils.toBool(el.getAttribute('gs-animate'))\r\n }\r\n\r\n this.opts = Utils.defaults(opts, defaults);\r\n opts = null; // make sure we use this.opts instead\r\n this._initMargin(); // part of settings defaults...\r\n\r\n // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)\r\n if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {\r\n this._prevColumn = this.getColumn();\r\n this.opts.column = 1;\r\n }\r\n\r\n if (this.opts.rtl === 'auto') {\r\n this.opts.rtl = (el.style.direction === 'rtl');\r\n }\r\n if (this.opts.rtl) {\r\n this.el.classList.add('grid-stack-rtl');\r\n }\r\n\r\n // check if we're been nested, and if so update our style and keep pointer around (used during save)\r\n let parentGridItemEl = Utils.closestByClass(this.el, GridDefaults.itemClass) as GridItemHTMLElement;\r\n if (parentGridItemEl && parentGridItemEl.gridstackNode) {\r\n this.opts._isNested = parentGridItemEl.gridstackNode;\r\n this.opts._isNested.subGrid = this;\r\n parentGridItemEl.classList.add('grid-stack-nested');\r\n this.el.classList.add('grid-stack-nested');\r\n }\r\n\r\n this._isAutoCellHeight = (this.opts.cellHeight === 'auto');\r\n if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {\r\n // make the cell content square initially (will use resize/column event to keep it square)\r\n this.cellHeight(undefined, false);\r\n } else {\r\n // append unit if any are set\r\n if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) {\r\n this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;\r\n delete this.opts.cellHeightUnit;\r\n }\r\n this.cellHeight(this.opts.cellHeight, false);\r\n }\r\n\r\n // see if we need to adjust auto-hide\r\n if (this.opts.alwaysShowResizeHandle === 'mobile') {\r\n this.opts.alwaysShowResizeHandle = isTouch;\r\n }\r\n\r\n this.el.classList.add(this.opts._styleSheetClass);\r\n\r\n this._setStaticClass();\r\n\r\n let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;\r\n this.engine = new engineClass({\r\n column: this.getColumn(),\r\n float: this.opts.float,\r\n maxRow: this.opts.maxRow,\r\n onChange: (cbNodes) => {\r\n let maxH = 0;\r\n this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) });\r\n cbNodes.forEach(n => {\r\n let el = n.el;\r\n if (!el) return;\r\n if (n._removeDOM) {\r\n if (el) el.remove();\r\n delete n._removeDOM;\r\n } else {\r\n this._writePosAttr(el, n);\r\n }\r\n });\r\n this._updateStyles(false, maxH); // false = don't recreate, just append if need be\r\n }\r\n });\r\n\r\n if (this.opts.auto) {\r\n this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...\r\n let elements: {el: HTMLElement; i: number}[] = [];\r\n this.getGridItems().forEach(el => { // get dom elements (not nodes yet)\r\n let x = parseInt(el.getAttribute('gs-x'));\r\n let y = parseInt(el.getAttribute('gs-y'));\r\n elements.push({\r\n el,\r\n // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order\r\n i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * this.getColumn()\r\n });\r\n });\r\n elements.sort((a, b) => a.i - b.i).forEach(e => this._prepareElement(e.el));\r\n this.batchUpdate(false);\r\n }\r\n\r\n this.setAnimation(this.opts.animate);\r\n\r\n this._updateStyles();\r\n if (this.opts.column != 12) {\r\n this.el.classList.add('grid-stack-' + this.opts.column);\r\n }\r\n\r\n // legacy support to appear 'per grid` options when really global.\r\n if (this.opts.dragIn) GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);\r\n delete this.opts.dragIn;\r\n delete this.opts.dragInOptions;\r\n\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this._updateWindowResizeEvent();\r\n }\r\n\r\n public change() {\r\n this._triggerChangeEvent();\r\n }\r\n\r\n /**\r\n * add a new widget and returns it.\r\n *\r\n * Widget will be always placed even if result height is more than actual grid height.\r\n * You need to use `willItFit()` before calling addWidget for additional check.\r\n * See also `makeWidget()`.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.addWidget({w: 3, content: 'hello'});\r\n * grid.addWidget('
hello
', {w: 3});\r\n *\r\n * @param el GridStackWidget (which can have content string as well), html element, or string definition to add\r\n * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget\r\n */\r\n public addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1,\r\n opt: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++],\r\n minW:a[i++], maxW:a[i++], minH:a[i++], maxH:a[i++], id:a[i++] };\r\n return this.addWidget(els, opt);\r\n }\r\n\r\n function isGridStackWidget(w: GridStackWidget): w is GridStackWidget { // https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0\r\n return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;\r\n }\r\n\r\n let el: HTMLElement;\r\n if (typeof els === 'string') {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = els;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {\r\n let content = els ? (els as GridStackWidget).content || '' : '';\r\n options = els;\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
${content}
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else {\r\n el = els as HTMLElement;\r\n }\r\n\r\n // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos\r\n // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node.\r\n // So make sure we load any DOM attributes that are not specified in passed in options (which override)\r\n let domAttr = this._readAttr(el);\r\n options = Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it\r\n Utils.defaults(options, domAttr);\r\n let node = this.engine.prepareNode(options);\r\n this._writeAttr(el, options);\r\n\r\n if (this._insertNotAppend) {\r\n this.el.prepend(el);\r\n } else {\r\n this.el.appendChild(el);\r\n }\r\n\r\n // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id\r\n this._prepareElement(el, true, options);\r\n this._updateContainerHeight();\r\n\r\n // check if nested grid definition is present\r\n if (node.subGrid && !(node.subGrid as GridStack).el) { // see if there is a sub-grid to create too\r\n // if column special case it set, remember that flag and set default\r\n let autoColumn: boolean;\r\n let ops = node.subGrid as GridStackOptions;\r\n if (ops.column === 'auto') {\r\n ops.column = node.w;\r\n ops.disableOneColumnMode = true; // driven by parent\r\n autoColumn = true;\r\n }\r\n let content = node.el.querySelector('.grid-stack-item-content') as HTMLElement;\r\n node.subGrid = GridStack.addGrid(content, node.subGrid as GridStackOptions);\r\n if (autoColumn) { node.subGrid._autoColumn = true; }\r\n }\r\n\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n /**\r\n * saves the current layout returning a list of widgets for serialization which might include any nested grids.\r\n * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will\r\n * be removed.\r\n * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()\r\n * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.\r\n * @returns list of widgets or full grid option, including .children list of widgets\r\n */\r\n public save(saveContent = true, saveGridOpt = false): GridStackWidget[] | GridStackOptions {\r\n // return copied nodes we can modify at will...\r\n let list = this.engine.save(saveContent);\r\n\r\n // check for HTML content and nested grids\r\n list.forEach(n => {\r\n if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content\r\n let sub = n.el.querySelector('.grid-stack-item-content');\r\n n.content = sub ? sub.innerHTML : undefined;\r\n if (!n.content) delete n.content;\r\n } else {\r\n if (!saveContent) { delete n.content; }\r\n // check for nested grid\r\n if (n.subGrid) {\r\n n.subGrid = (n.subGrid as GridStack).save(saveContent, true) as GridStackOptions;\r\n }\r\n }\r\n delete n.el;\r\n });\r\n\r\n // check if save entire grid options (needed for recursive) + children...\r\n if (saveGridOpt) {\r\n let o: GridStackOptions = Utils.cloneDeep(this.opts);\r\n // delete default values that will be recreated on launch\r\n if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {\r\n o.margin = o.marginTop;\r\n delete o.marginTop; delete o.marginRight; delete o.marginBottom; delete o.marginLeft;\r\n }\r\n if (o.rtl === (this.el.style.direction === 'rtl')) { o.rtl = 'auto' }\r\n if (this._isAutoCellHeight) {\r\n o.cellHeight = 'auto'\r\n }\r\n if (this._autoColumn) {\r\n o.column = 'auto';\r\n delete o.disableOneColumnMode;\r\n }\r\n const origShow = (o as any)._alwaysShowResizeHandle;\r\n delete (o as any)._alwaysShowResizeHandle;\r\n if (origShow !== undefined) {\r\n o.alwaysShowResizeHandle = origShow;\r\n } else {\r\n delete o.alwaysShowResizeHandle;\r\n }\r\n Utils.removeInternalAndSame(o, GridDefaults);\r\n o.children = list;\r\n return o;\r\n }\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.\r\n *\r\n * @param layout list of widgets definition to update/create\r\n * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving\r\n * the user control of insertion.\r\n *\r\n * @example\r\n * see http://gridstackjs.com/demo/serialization.html\r\n **/\r\n public load(layout: GridStackWidget[], addAndRemove: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement) = true): GridStack {\r\n let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort\r\n this._insertNotAppend = true; // since create in reverse order...\r\n\r\n // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save\r\n // the original wanted layout so we can scale back up correctly #1471\r\n if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) {\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this.engine.cacheLayout(items, this._prevColumn, true);\r\n }\r\n\r\n let removed: GridStackNode[] = [];\r\n this.batchUpdate();\r\n\r\n // see if any items are missing from new layout and need to be removed first\r\n if (addAndRemove) {\r\n let copyNodes = [...this.engine.nodes]; // don't loop through array you modify\r\n copyNodes.forEach(n => {\r\n let item = items.find(w => n.id === w.id);\r\n if (!item) {\r\n if (typeof(addAndRemove) === 'function') {\r\n addAndRemove(this, n, false);\r\n } else {\r\n removed.push(n); // batch keep track\r\n this.removeWidget(n.el, true, false);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // now add/update the widgets\r\n items.forEach(w => {\r\n let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined;\r\n if (item) {\r\n this.update(item.el, w);\r\n if (w.subGrid && (w.subGrid as GridStackOptions).children) { // update any sub grid as well\r\n let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;\r\n if (sub && sub.gridstack) {\r\n sub.gridstack.load((w.subGrid as GridStackOptions).children); // TODO: support updating grid options ?\r\n this._insertNotAppend = true; // got reset by above call\r\n }\r\n }\r\n } else if (addAndRemove) {\r\n if (typeof(addAndRemove) === 'function') {\r\n w = addAndRemove(this, w, true).gridstackNode;\r\n } else {\r\n w = this.addWidget(w).gridstackNode;\r\n }\r\n }\r\n });\r\n\r\n this.engine.removedNodes = removed;\r\n this.batchUpdate(false);\r\n\r\n // after commit, clear that flag\r\n delete this._ignoreLayoutsNodeChange;\r\n delete this._insertNotAppend;\r\n return this;\r\n }\r\n\r\n /**\r\n * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)\r\n * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.\r\n */\r\n public batchUpdate(flag = true): GridStack {\r\n this.engine.batchUpdate(flag);\r\n if (!flag) {\r\n this._triggerRemoveEvent();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets current cell height.\r\n */\r\n public getCellHeight(forcePixel = false): number {\r\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&\r\n (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {\r\n return this.opts.cellHeight as number;\r\n }\r\n // else get first cell height\r\n let el = this.el.querySelector('.' + this.opts.itemClass) as HTMLElement;\r\n if (el) {\r\n let height = Utils.toNumber(el.getAttribute('gs-h'));\r\n return Math.round(el.offsetHeight / height);\r\n }\r\n // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)\r\n let rows = parseInt(this.el.getAttribute('gs-current-row'));\r\n return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight as number;\r\n }\r\n\r\n /**\r\n * Update current cell height - see `GridStackOptions.cellHeight` for format.\r\n * This method rebuilds an internal CSS style sheet.\r\n * Note: You can expect performance issues if call this method too often.\r\n *\r\n * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),\r\n * if pass 0 the CSS will be generated by the application instead.\r\n * @param update (Optional) if false, styles will not be updated\r\n *\r\n * @example\r\n * grid.cellHeight(100); // same as 100px\r\n * grid.cellHeight('70px');\r\n * grid.cellHeight(grid.cellWidth() * 1.2);\r\n */\r\n public cellHeight(val?: numberOrString, update = true): GridStack {\r\n\r\n // if not called internally, check if we're changing mode\r\n if (update && val !== undefined) {\r\n if (this._isAutoCellHeight !== (val === 'auto')) {\r\n this._isAutoCellHeight = (val === 'auto');\r\n this._updateWindowResizeEvent();\r\n }\r\n }\r\n if (val === 'initial' || val === 'auto') { val = undefined; }\r\n\r\n // make item content be square\r\n if (val === undefined) {\r\n let marginDiff = - (this.opts.marginRight as number) - (this.opts.marginLeft as number)\r\n + (this.opts.marginTop as number) + (this.opts.marginBottom as number);\r\n val = this.cellWidth() + marginDiff;\r\n }\r\n\r\n let data = Utils.parseHeight(val);\r\n if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {\r\n return this;\r\n }\r\n this.opts.cellHeightUnit = data.unit;\r\n this.opts.cellHeight = data.h;\r\n\r\n if (update) {\r\n this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows\r\n }\r\n return this;\r\n }\r\n\r\n /** Gets current cell width. */\r\n public cellWidth(): number {\r\n return this._widthOrContainer() / this.getColumn();\r\n }\r\n /** return our expected width (or parent) for 1 column check */\r\n protected _widthOrContainer(): number {\r\n // use `offsetWidth` or `clientWidth` (no scrollbar) ?\r\n // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);\r\n }\r\n\r\n /** re-layout grid items to reclaim any empty space */\r\n public compact(): GridStack {\r\n this.engine.compact();\r\n this._triggerChangeEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,\r\n * as well as cache the original layout so you can revert back to previous positions without loss.\r\n * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],\r\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\r\n * @param column - Integer > 0 (default 12).\r\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\r\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\r\n */\r\n public column(column: number, layout: ColumnOptions = 'moveScale'): GridStack {\r\n if (column < 1 || this.opts.column === column) return this;\r\n let oldColumn = this.getColumn();\r\n\r\n // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)\r\n // then remember the original columns so we can restore.\r\n if (column === 1) {\r\n this._prevColumn = oldColumn;\r\n } else {\r\n delete this._prevColumn;\r\n }\r\n\r\n this.el.classList.remove('grid-stack-' + oldColumn);\r\n this.el.classList.add('grid-stack-' + column);\r\n this.opts.column = this.engine.column = column;\r\n\r\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\r\n let domNodes: GridStackNode[];\r\n if (column === 1 && this.opts.oneColumnModeDomSort) {\r\n domNodes = [];\r\n this.getGridItems().forEach(el => { // get dom elements in order\r\n if (el.gridstackNode) { domNodes.push(el.gridstackNode); }\r\n });\r\n if (!domNodes.length) { domNodes = undefined; }\r\n }\r\n this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);\r\n if (this._isAutoCellHeight) this.cellHeight();\r\n\r\n // and trigger our event last...\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this._triggerChangeEvent();\r\n delete this._ignoreLayoutsNodeChange;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * get the number of columns in the grid (default 12)\r\n */\r\n public getColumn(): number {\r\n return this.opts.column as number;\r\n }\r\n\r\n /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */\r\n public getGridItems(): GridItemHTMLElement[] {\r\n return Array.from(this.el.children)\r\n .filter((el: HTMLElement) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass)) as GridItemHTMLElement[];\r\n }\r\n\r\n /**\r\n * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.\r\n * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).\r\n */\r\n public destroy(removeDOM = true): GridStack {\r\n if (!this.el) return; // prevent multiple calls\r\n this._updateWindowResizeEvent(true);\r\n this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)\r\n this.setAnimation(false);\r\n if (!removeDOM) {\r\n this.removeAll(removeDOM);\r\n this.el.classList.remove(this.opts._styleSheetClass);\r\n } else {\r\n this.el.parentNode.removeChild(this.el);\r\n }\r\n this._removeStylesheet();\r\n this.el.removeAttribute('gs-current-row');\r\n delete this.opts._isNested;\r\n delete this.opts;\r\n delete this._placeholder;\r\n delete this.engine;\r\n delete this.el.gridstack; // remove circular dependency that would prevent a freeing\r\n delete this.el;\r\n return this;\r\n }\r\n\r\n /**\r\n * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)\r\n */\r\n public float(val: boolean): GridStack {\r\n if (this.opts.float !== val) {\r\n this.opts.float = this.engine.float = val;\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get the current float mode\r\n */\r\n public getFloat(): boolean {\r\n return this.engine.float;\r\n }\r\n\r\n /**\r\n * Get the position of the cell under a pixel on screen.\r\n * @param position the position of the pixel to resolve in\r\n * absolute coordinates, as an object with top and left properties\r\n * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).\r\n * Useful when grid is within `position: relative` element\r\n *\r\n * Returns an object with properties `x` and `y` i.e. the column and row in the grid.\r\n */\r\n public getCellFromPixel(position: MousePosition, useDocRelative = false): CellPosition {\r\n let box = this.el.getBoundingClientRect();\r\n // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)\r\n let containerPos: {top: number, left: number};\r\n if (useDocRelative) {\r\n containerPos = {top: box.top + document.documentElement.scrollTop, left: box.left};\r\n // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)\r\n } else {\r\n containerPos = {top: this.el.offsetTop, left: this.el.offsetLeft}\r\n // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)\r\n }\r\n let relativeLeft = position.left - containerPos.left;\r\n let relativeTop = position.top - containerPos.top;\r\n\r\n let columnWidth = (box.width / this.getColumn());\r\n let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));\r\n\r\n return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)};\r\n }\r\n\r\n /** returns the current number of rows, which will be at least `minRow` if set */\r\n public getRow(): number {\r\n return Math.max(this.engine.getRow(), this.opts.minRow);\r\n }\r\n\r\n /**\r\n * Checks if specified area is empty.\r\n * @param x the position x.\r\n * @param y the position y.\r\n * @param w the width of to check\r\n * @param h the height of to check\r\n */\r\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\r\n return this.engine.isAreaEmpty(x, y, w, h);\r\n }\r\n\r\n /**\r\n * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.\r\n * If you want gridstack to add the elements for you, use `addWidget()` instead.\r\n * Makes the given element a widget and returns it.\r\n * @param els widget or single selector to convert.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.el.appendChild('
');\r\n * grid.makeWidget('#gsi-1');\r\n */\r\n public makeWidget(els: GridStackElement): GridItemHTMLElement {\r\n let el = GridStack.getElement(els);\r\n this._prepareElement(el, true);\r\n this._updateContainerHeight();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n return el;\r\n }\r\n\r\n /**\r\n * Event handler that extracts our CustomEvent data out automatically for receiving custom\r\n * notifications (see doc for supported events)\r\n * @param name of the event (see possible values) or list of names space separated\r\n * @param callback function called with event and optional second/third param\r\n * (see README documentation for each signature).\r\n *\r\n * @example\r\n * grid.on('added', function(e, items) { log('added ', items)} );\r\n * or\r\n * grid.on('added removed change', function(e, items) { log(e.type, items)} );\r\n *\r\n * Note: in some cases it is the same as calling native handler and parsing the event.\r\n * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );\r\n *\r\n */\r\n public on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.on(name, callback));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // native CustomEvent handlers - cash the generic handlers so we can easily remove\r\n let noData = (name === 'enable' || name === 'disable');\r\n if (noData) {\r\n this._gsEventHandler[name] = (event: Event) => callback(event);\r\n } else {\r\n this._gsEventHandler[name] = (event: CustomEvent) => callback(event, event.detail);\r\n }\r\n this.el.addEventListener(name, this._gsEventHandler[name]);\r\n } else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {\r\n // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.\r\n // do same for start event to make it easier...\r\n this._gsEventHandler[name] = callback;\r\n } else {\r\n console.log('GridStack.on(' + name + ') event not supported, but you can still use $(\".grid-stack\").on(...) while jquery-ui is still used internally.');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * unsubscribe from the 'on' event below\r\n * @param name of the event (see possible values)\r\n */\r\n public off(name: GridStackEvent): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.off(name));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // remove native CustomEvent handlers\r\n if (this._gsEventHandler[name]) {\r\n this.el.removeEventListener(name, this._gsEventHandler[name]);\r\n }\r\n }\r\n delete this._gsEventHandler[name];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes widget from the grid.\r\n * @param el widget or selector to modify\r\n * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).\r\n * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).\r\n */\r\n public removeWidget(els: GridStackElement, removeDOM = true, triggerEvent = true): GridStack {\r\n GridStack.getElements(els).forEach(el => {\r\n if (el.parentElement !== this.el) return; // not our child!\r\n let node = el.gridstackNode;\r\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\r\n if (!node) {\r\n node = this.engine.nodes.find(n => el === n.el);\r\n }\r\n if (!node) return;\r\n\r\n // remove our DOM data (circular link) and drag&drop permanently\r\n delete el.gridstackNode;\r\n this._removeDD(el);\r\n\r\n this.engine.removeNode(node, removeDOM, triggerEvent);\r\n\r\n if (removeDOM && el.parentElement) {\r\n el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM\r\n }\r\n });\r\n if (triggerEvent) {\r\n this._triggerRemoveEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all widgets from the grid.\r\n * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).\r\n */\r\n public removeAll(removeDOM = true): GridStack {\r\n // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently\r\n this.engine.nodes.forEach(n => {\r\n delete n.el.gridstackNode;\r\n this._removeDD(n.el);\r\n });\r\n this.engine.removeAll(removeDOM);\r\n this._triggerRemoveEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid animation state. Toggles the `grid-stack-animate` class.\r\n * @param doAnimate if true the grid will animate.\r\n */\r\n public setAnimation(doAnimate: boolean): GridStack {\r\n if (doAnimate) {\r\n this.el.classList.add('grid-stack-animate');\r\n } else {\r\n this.el.classList.remove('grid-stack-animate');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.\r\n * Also toggle the grid-stack-static class.\r\n * @param val if true the grid become static.\r\n */\r\n public setStatic(val: boolean, updateClass = true): GridStack {\r\n if (this.opts.staticGrid === val) return this;\r\n this.opts.staticGrid = val;\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this.engine.nodes.forEach(n => this._prepareDragDropByNode(n)); // either delete or init Drag&drop\r\n if (updateClass) { this._setStaticClass(); }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed.\r\n * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)\r\n * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.\r\n */\r\n public update(els: GridStackElement, opt: GridStackWidget): GridStack {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1;\r\n opt = { x:a[i++], y:a[i++], w:a[i++], h:a[i++] };\r\n return this.update(els, opt);\r\n }\r\n\r\n GridStack.getElements(els).forEach(el => {\r\n if (!el || !el.gridstackNode) return;\r\n let n = el.gridstackNode;\r\n let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items\r\n delete w.autoPosition;\r\n\r\n // move/resize widget if anything changed\r\n let keys = ['x', 'y', 'w', 'h'];\r\n let m: GridStackWidget;\r\n if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) {\r\n m = {};\r\n keys.forEach(k => {\r\n m[k] = (w[k] !== undefined) ? w[k] : n[k];\r\n delete w[k];\r\n });\r\n }\r\n // for a move as well IFF there is any min/max fields set\r\n if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {\r\n m = {}; // will use node position but validate values\r\n }\r\n\r\n // check for content changing\r\n if (w.content) {\r\n let sub = el.querySelector('.grid-stack-item-content');\r\n if (sub && sub.innerHTML !== w.content) {\r\n sub.innerHTML = w.content;\r\n }\r\n delete w.content;\r\n }\r\n\r\n // any remaining fields are assigned, but check for dragging changes, resize constrain\r\n let changed = false;\r\n let ddChanged = false;\r\n for (const key in w) {\r\n if (key[0] !== '_' && n[key] !== w[key]) {\r\n n[key] = w[key];\r\n changed = true;\r\n ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));\r\n }\r\n }\r\n\r\n // finally move the widget\r\n if (m) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(n)\r\n .moveNode(n, m);\r\n this._updateContainerHeight();\r\n this._triggerChangeEvent();\r\n this.engine.endUpdate();\r\n }\r\n if (changed) { // move will only update x,y,w,h so update the rest too\r\n this._writeAttr(el, n);\r\n }\r\n if (ddChanged) {\r\n this._prepareDragDropByNode(n);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number).\r\n * @param value margin value\r\n */\r\n public margin(value: numberOrString): GridStack {\r\n let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);\r\n // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)\r\n if (!isMultiValue) {\r\n let data = Utils.parseHeight(value);\r\n if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) return;\r\n }\r\n // re-use existing margin handling\r\n this.opts.margin = value;\r\n this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;\r\n this._initMargin();\r\n\r\n this._updateStyles(true); // true = force re-create\r\n\r\n return this;\r\n }\r\n\r\n /** returns current margin number value (undefined if 4 sides don't match) */\r\n public getMargin(): number { return this.opts.margin as number; }\r\n\r\n /**\r\n * Returns true if the height of the grid will be less than the vertical\r\n * constraint. Always returns true if grid doesn't have height constraint.\r\n * @param node contains x,y,w,h,auto-position options\r\n *\r\n * @example\r\n * if (grid.willItFit(newWidget)) {\r\n * grid.addWidget(newWidget);\r\n * } else {\r\n * alert('Not enough free space to place the widget');\r\n * }\r\n */\r\n public willItFit(node: GridStackWidget): boolean {\r\n // support legacy call for now\r\n if (arguments.length > 1) {\r\n console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 0,\r\n w: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++] };\r\n return this.willItFit(w);\r\n }\r\n return this.engine.willItFit(node);\r\n }\r\n\r\n /** @internal */\r\n protected _triggerChangeEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n let elements = this.engine.getDirtyNodes(true); // verify they really changed\r\n if (elements && elements.length) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(elements);\r\n }\r\n this._triggerEvent('change', elements);\r\n }\r\n this.engine.saveInitial(); // we called, now reset initial values & dirty flags\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerAddEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(this.engine.addedNodes);\r\n }\r\n // prevent added nodes from also triggering 'change' event (which is called next)\r\n this.engine.addedNodes.forEach(n => { delete n._dirty; });\r\n this._triggerEvent('added', this.engine.addedNodes);\r\n this.engine.addedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n public _triggerRemoveEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {\r\n this._triggerEvent('removed', this.engine.removedNodes);\r\n this.engine.removedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerEvent(name: string, data?: GridStackNode[]): GridStack {\r\n let event = data ? new CustomEvent(name, {bubbles: false, detail: data}) : new Event(name);\r\n this.el.dispatchEvent(event);\r\n return this;\r\n }\r\n\r\n /** @internal called to delete the current dynamic style sheet used for our layout */\r\n protected _removeStylesheet(): GridStack {\r\n\r\n if (this._styles) {\r\n Utils.removeStylesheet(this._styles._id);\r\n delete this._styles;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal updated/create the CSS styles for row based layout and initial margin setting */\r\n protected _updateStyles(forceUpdate = false, maxH?: number): GridStack {\r\n // call to delete existing one if we change cellHeight / margin\r\n if (forceUpdate) {\r\n this._removeStylesheet();\r\n }\r\n\r\n this._updateContainerHeight();\r\n\r\n // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??\r\n if (this.opts.cellHeight === 0) {\r\n return this;\r\n }\r\n\r\n let cellHeight = this.opts.cellHeight as number;\r\n let cellHeightUnit = this.opts.cellHeightUnit;\r\n let prefix = `.${this.opts._styleSheetClass} > .${this.opts.itemClass}`;\r\n\r\n // create one as needed\r\n if (!this._styles) {\r\n let id = 'gridstack-style-' + (Math.random() * 100000).toFixed();\r\n // insert style to parent (instead of 'head' by default) to support WebComponent\r\n let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement;\r\n this._styles = Utils.createStylesheet(id, styleLocation);\r\n if (!this._styles) return this;\r\n this._styles._id = id;\r\n this._styles._max = 0;\r\n\r\n // these are done once only\r\n Utils.addCSSRule(this._styles, prefix, `min-height: ${cellHeight}${cellHeightUnit}`);\r\n // content margins\r\n let top: string = this.opts.marginTop + this.opts.marginUnit;\r\n let bottom: string = this.opts.marginBottom + this.opts.marginUnit;\r\n let right: string = this.opts.marginRight + this.opts.marginUnit;\r\n let left: string = this.opts.marginLeft + this.opts.marginUnit;\r\n let content = `${prefix} > .grid-stack-item-content`;\r\n let placeholder = `.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;\r\n Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n // resize handles offset (to match margin)\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`);\r\n }\r\n\r\n // now update the height specific fields\r\n maxH = maxH || this._styles._max;\r\n if (maxH > this._styles._max) {\r\n let getHeight = (rows: number): string => (cellHeight * rows) + cellHeightUnit;\r\n for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1\r\n let h: string = getHeight(i);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-y=\"${i-1}\"]`, `top: ${getHeight(i-1)}`); // start at 0\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-h=\"${i}\"]`, `height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-min-h=\"${i}\"]`, `min-height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-max-h=\"${i}\"]`, `max-height: ${h}`);\r\n }\r\n this._styles._max = maxH;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _updateContainerHeight(): GridStack {\r\n if (!this.engine || this.engine.batchMode) return this;\r\n let row = this.getRow() + this._extraDragRow; // checks for minRow already\r\n // check for css min height\r\n // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary\r\n // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.\r\n // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);\r\n // if (cssMinHeight > 0) {\r\n // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));\r\n // if (row < minRow) {\r\n // row = minRow;\r\n // }\r\n // }\r\n this.el.setAttribute('gs-current-row', String(row));\r\n if (row === 0) {\r\n this.el.style.removeProperty('height');\r\n return this;\r\n }\r\n let cellHeight = this.opts.cellHeight as number;\r\n let unit = this.opts.cellHeightUnit;\r\n if (!cellHeight) return this;\r\n this.el.style.height = row * cellHeight + unit;\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _prepareElement(el: GridItemHTMLElement, triggerAddEvent = false, node?: GridStackNode): GridStack {\r\n if (!node) {\r\n el.classList.add(this.opts.itemClass);\r\n node = this._readAttr(el);\r\n }\r\n el.gridstackNode = node;\r\n node.el = el;\r\n node.grid = this;\r\n let copy = {...node};\r\n node = this.engine.addNode(node, triggerAddEvent);\r\n // write node attr back in case there was collision or we have to fix bad values during addNode()\r\n if (!Utils.same(node, copy)) {\r\n this._writeAttr(el, node);\r\n }\r\n this._prepareDragDropByNode(node);\r\n return this;\r\n }\r\n\r\n /** @internal call to write position x,y,w,h attributes back to element */\r\n protected _writePosAttr(el: HTMLElement, n: GridStackPosition): GridStack {\r\n if (n.x !== undefined && n.x !== null) { el.setAttribute('gs-x', String(n.x)); }\r\n if (n.y !== undefined && n.y !== null) { el.setAttribute('gs-y', String(n.y)); }\r\n if (n.w) { el.setAttribute('gs-w', String(n.w)); }\r\n if (n.h) { el.setAttribute('gs-h', String(n.h)); }\r\n return this;\r\n }\r\n\r\n /** @internal call to write any default attributes back to element */\r\n protected _writeAttr(el: HTMLElement, node: GridStackWidget): GridStack {\r\n if (!node) return this;\r\n this._writePosAttr(el, node);\r\n\r\n let attrs /*: GridStackWidget but strings */ = { // remaining attributes\r\n autoPosition: 'gs-auto-position',\r\n minW: 'gs-min-w',\r\n minH: 'gs-min-h',\r\n maxW: 'gs-max-w',\r\n maxH: 'gs-max-h',\r\n noResize: 'gs-no-resize',\r\n noMove: 'gs-no-move',\r\n locked: 'gs-locked',\r\n id: 'gs-id',\r\n resizeHandles: 'gs-resize-handles'\r\n };\r\n for (const key in attrs) {\r\n if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway\r\n el.setAttribute(attrs[key], String(node[key]));\r\n } else {\r\n el.removeAttribute(attrs[key]);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal call to read any default attributes from element */\r\n protected _readAttr(el: HTMLElement): GridStackWidget {\r\n let node: GridStackNode = {};\r\n node.x = Utils.toNumber(el.getAttribute('gs-x'));\r\n node.y = Utils.toNumber(el.getAttribute('gs-y'));\r\n node.w = Utils.toNumber(el.getAttribute('gs-w'));\r\n node.h = Utils.toNumber(el.getAttribute('gs-h'));\r\n node.maxW = Utils.toNumber(el.getAttribute('gs-max-w'));\r\n node.minW = Utils.toNumber(el.getAttribute('gs-min-w'));\r\n node.maxH = Utils.toNumber(el.getAttribute('gs-max-h'));\r\n node.minH = Utils.toNumber(el.getAttribute('gs-min-h'));\r\n node.autoPosition = Utils.toBool(el.getAttribute('gs-auto-position'));\r\n node.noResize = Utils.toBool(el.getAttribute('gs-no-resize'));\r\n node.noMove = Utils.toBool(el.getAttribute('gs-no-move'));\r\n node.locked = Utils.toBool(el.getAttribute('gs-locked'));\r\n node.resizeHandles = el.getAttribute('gs-resize-handles');\r\n node.id = el.getAttribute('gs-id');\r\n\r\n // remove any key not found (null or false which is default)\r\n for (const key in node) {\r\n if (!node.hasOwnProperty(key)) return;\r\n if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)\r\n delete node[key];\r\n }\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /** @internal */\r\n protected _setStaticClass(): GridStack {\r\n let classes = ['grid-stack-static'];\r\n\r\n if (this.opts.staticGrid) {\r\n this.el.classList.add(...classes);\r\n this.el.setAttribute('gs-static', 'true');\r\n } else {\r\n this.el.classList.remove(...classes);\r\n this.el.removeAttribute('gs-static');\r\n\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off\r\n * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)\r\n */\r\n public onParentResize(): GridStack {\r\n if (!this.el || !this.el.clientWidth) return; // return if we're gone or no size yet (will get called again)\r\n let changedColumn = false;\r\n\r\n // see if we're nested and take our column count from our parent....\r\n if (this._autoColumn && this.opts._isNested) {\r\n if (this.opts.column !== this.opts._isNested.w) {\r\n changedColumn = true;\r\n this.column(this.opts._isNested.w, 'none');\r\n }\r\n } else {\r\n // else check for 1 column in/out behavior\r\n let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;\r\n if ((this.opts.column === 1) !== oneColumn) {\r\n changedColumn = true;\r\n if (this.opts.animate) { this.setAnimation(false); } // 1 <-> 12 is too radical, turn off animation\r\n this.column(oneColumn ? 1 : this._prevColumn);\r\n if (this.opts.animate) { this.setAnimation(true); }\r\n }\r\n }\r\n\r\n // make the cells content square again\r\n if (this._isAutoCellHeight) {\r\n if (!changedColumn && this.opts.cellHeightThrottle) {\r\n if (!this._cellHeightThrottle) {\r\n this._cellHeightThrottle = Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle);\r\n }\r\n this._cellHeightThrottle();\r\n } else {\r\n // immediate update if we've changed column count or have no threshold\r\n this.cellHeight();\r\n }\r\n }\r\n\r\n // finally update any nested grids\r\n this.engine.nodes.forEach(n => {\r\n if (n.subGrid) {(n.subGrid as GridStack).onParentResize()}\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /** add or remove the window size event handler */\r\n protected _updateWindowResizeEvent(forceRemove = false): GridStack {\r\n // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)\r\n const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested;\r\n\r\n if (!forceRemove && workTodo && !this._windowResizeBind) {\r\n this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later\r\n window.addEventListener('resize', this._windowResizeBind);\r\n } else if ((forceRemove || !workTodo) && this._windowResizeBind) {\r\n window.removeEventListener('resize', this._windowResizeBind);\r\n delete this._windowResizeBind; // remove link to us so we can free\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** @internal convert a potential selector into actual element */\r\n public static getElement(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement { return Utils.getElement(els) }\r\n /** @internal */\r\n public static getElements(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement[] { return Utils.getElements(els) }\r\n /** @internal */\r\n public static getGridElement(els: GridStackElement): GridHTMLElement { return GridStack.getElement(els) }\r\n /** @internal */\r\n public static getGridElements(els: string): GridHTMLElement[] { return Utils.getElements(els) }\r\n\r\n /** @internal initialize margin top/bottom/left/right and units */\r\n protected _initMargin(): GridStack {\r\n\r\n let data: HeightData;\r\n let margin = 0;\r\n\r\n // support passing multiple values like CSS (ex: '5px 10px 0 20px')\r\n let margins: string[] = [];\r\n if (typeof this.opts.margin === 'string') {\r\n margins = this.opts.margin.split(' ')\r\n }\r\n if (margins.length === 2) { // top/bot, left/right like CSS\r\n this.opts.marginTop = this.opts.marginBottom = margins[0];\r\n this.opts.marginLeft = this.opts.marginRight = margins[1];\r\n } else if (margins.length === 4) { // Clockwise like CSS\r\n this.opts.marginTop = margins[0];\r\n this.opts.marginRight = margins[1];\r\n this.opts.marginBottom = margins[2];\r\n this.opts.marginLeft = margins[3];\r\n } else {\r\n data = Utils.parseHeight(this.opts.margin);\r\n this.opts.marginUnit = data.unit;\r\n margin = this.opts.margin = data.h;\r\n }\r\n\r\n // see if top/bottom/left/right need to be set as well\r\n if (this.opts.marginTop === undefined) {\r\n this.opts.marginTop = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginTop);\r\n this.opts.marginTop = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginBottom === undefined) {\r\n this.opts.marginBottom = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginBottom);\r\n this.opts.marginBottom = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginRight === undefined) {\r\n this.opts.marginRight = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginRight);\r\n this.opts.marginRight = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginLeft === undefined) {\r\n this.opts.marginLeft = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginLeft);\r\n this.opts.marginLeft = data.h;\r\n delete this.opts.margin;\r\n }\r\n this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...\r\n if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {\r\n this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()\r\n }\r\n return this;\r\n }\r\n\r\n static GDRev = '6.0.1-dev';\r\n\r\n /*\r\n * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid\r\n * so we don't incur the load unless needed.\r\n * NOTE: had to make those methods public in order to define them else as\r\n * GridStack.prototype._setupAcceptWidget = function()\r\n * maybe there is a better way ????\r\n */\r\n /* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n /**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n * @param dragIn string selector (ex: '.sidebar .grid-stack-item')\r\n * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}\r\n **/\r\n public static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void { /* implemented in dd-gridstack.ts */ }\r\n\r\n /**\r\n * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids.\r\n * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\n public movable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\n public resizable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\n public disable(): GridStack { return this }\r\n /**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\n public enable(): GridStack { return this }\r\n /**\r\n * Enables/disables widget moving. No-op for static grids.\r\n */\r\n public enableMove(doEnable: boolean): GridStack { return this }\r\n /**\r\n * Enables/disables widget resizing. No-op for static grids.\r\n */\r\n public enableResize(doEnable: boolean): GridStack { return this }\r\n\r\n /** @internal removes any drag&drop present (called during destroy) */\r\n public _removeDD(el: GridItemHTMLElement): GridStack { return this }\r\n /** @internal called to add drag over support to support widgets */\r\n public _setupAcceptWidget(): GridStack { return this }\r\n /** @internal called to setup a trash drop zone if the user specifies it */\r\n public _setupRemoveDrop(): GridStack { return this }\r\n /** @internal prepares the element for drag&drop **/\r\n public _prepareDragDropByNode(node: GridStackNode): GridStack { return this }\r\n /** @internal handles actual drag/resize start **/\r\n public _onStartMoving(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal handles actual drag/resize **/\r\n public _dragOrResize(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal called when a node leaves our area (mouse out or shape outside) **/\r\n public _leave(el: GridItemHTMLElement, helper?: GridItemHTMLElement): void { return }\r\n // legacy method removed\r\n public commit(): GridStack { obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }\r\n}\r\n\r\n/*\r\n * and include D&D by default, which override some methods here\r\n * TODO: while we can generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)\r\n * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts\r\n */\r\nimport { DDGridStack } from './dd-gridstack';\r\nimport { isTouch } from './dd-touch';\r\nexport * from './dd-gridstack';\r\n"]} \ No newline at end of file diff --git a/dist/es5/types.d.ts b/dist/es5/types.d.ts new file mode 100644 index 000000000..e7f857d37 --- /dev/null +++ b/dist/es5/types.d.ts @@ -0,0 +1,262 @@ +/** + * types.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridStack } from './gridstack'; +import { GridStackEngine } from './gridstack-engine'; +/** different layout options when changing # of columns, + * including a custom function that takes new/old column count, and array of new/old positions + * Note: new list may be partially already filled if we have a cache of the layout at that size and new items were added later. + */ +export declare type ColumnOptions = 'moveScale' | 'move' | 'scale' | 'none' | ((column: number, oldColumn: number, nodes: GridStackNode[], oldNodes: GridStackNode[]) => void); +export declare type numberOrString = number | string; +export interface GridItemHTMLElement extends HTMLElement { + /** pointer to grid node instance */ + gridstackNode?: GridStackNode; +} +export declare type GridStackElement = string | HTMLElement | GridItemHTMLElement; +export declare type GridStackEventHandlerCallback = (event: Event, arg2?: GridItemHTMLElement | GridStackNode | GridStackNode[], newNode?: GridStackNode) => void; +/** + * Defines the options for a Grid + */ +export interface GridStackOptions { + /** + * accept widgets dragged from other grids or from outside (default: `false`). Can be: + * `true` (uses `'.grid-stack-item'` class filter) or `false`, + * string for explicit class name, + * function returning a boolean. See [example](http://gridstack.github.io/gridstack.js/demo/two.html) + */ + acceptWidgets?: boolean | string | ((element: Element) => boolean); + /** possible values (default: `mobile`) - does not apply to non-resizable widgets + * `false` the resizing handles are only shown while hovering over a widget + * `true` the resizing handles are always shown + * 'mobile' if running on a mobile device, default to `true` (since there is no hovering per say), else `false`. + * this uses this condition on browser agent check: + `alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent )` + See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html) */ + alwaysShowResizeHandle?: true | false | 'mobile'; + /** turns animation on (default?: true) */ + animate?: boolean; + /** if false gridstack will not initialize existing items (default?: true) */ + auto?: boolean; + /** + * one cell height (default?: 'auto'). Can be: + * an integer (px) + * a string (ex: '100px', '10em', '10rem'). Note: % doesn't right - see demo/cell-height.html + * 0, in which case the library will not generate styles for rows. Everything must be defined in your own CSS files. + * 'auto' - height will be calculated for square cells (width / column) and updated live as you resize the window - also see `cellHeightThrottle` + * 'initial' - similar to 'auto' (start at square cells) but stay that size during window resizing. + */ + cellHeight?: numberOrString; + /** throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100). + * A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event! + * */ + cellHeightThrottle?: number; + /** (internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem') */ + cellHeightUnit?: string; + /** list of children item to create when calling load() or addGrid() */ + children?: GridStackWidget[]; + /** number of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns. + * Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside + * items always to same. flag is not supported for regular non-nested grids. + */ + column?: number | 'auto'; + /** additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance. + Note: only used by addGrid(), else your element should have the needed class */ + class?: string; + /** disallows dragging of widgets (default?: false) */ + disableDrag?: boolean; + /** disables the onColumnMode when the grid width is less than oneColumnSize (default?: false) */ + disableOneColumnMode?: boolean; + /** disallows resizing of widgets (default?: false). */ + disableResize?: boolean; + /** allows to override UI draggable options. (default?: { handle?: '.grid-stack-item-content', appendTo?: 'body' }) */ + draggable?: DDDragOpt; + /** allows to drag external items using this selector - see dragInOptions. (default: undefined) */ + dragIn?: string; + /** allows to drag external items using these options. See `GridStack.setupDragIn()` instead (not per grid really). + * (default?: { handle: '.grid-stack-item-content', appendTo: 'body' }) + * helper can be 'clone' or your own function (set what the drag/dropped item will be instead) + */ + dragInOptions?: DDDragInOpt; + /** let user drag nested grid items out of a parent or not (default true - not supported yet) */ + /** the type of engine to create (so you can subclass) default to GridStackEngine */ + engineClass?: typeof GridStackEngine; + /** enable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html) */ + float?: boolean; + /** draggable handle selector (default?: '.grid-stack-item-content') */ + handle?: string; + /** draggable handle class (e.g. 'grid-stack-item-content'). If set 'handle' is ignored (default?: null) */ + handleClass?: string; + /** id used to debug grid instance, not currently stored in DOM attributes */ + id?: numberOrString; + /** additional widget class (default?: 'grid-stack-item') */ + itemClass?: string; + /** + * gap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below + * an integer (px) + * a string with possible units (ex: '2em', '20px', '2rem') + * string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS). + * Note: all sides must have same units (last one wins, default px) + */ + margin?: numberOrString; + /** OLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side. */ + marginTop?: numberOrString; + marginRight?: numberOrString; + marginBottom?: numberOrString; + marginLeft?: numberOrString; + /** (internal) unit for margin (default? 'px') set when `margin` is set as string with unit (ex: 2rem') */ + marginUnit?: string; + /** maximum rows amount. Default? is 0 which means no maximum rows */ + maxRow?: number; + /** minimum rows amount. Default is `0`. You can also do this with `min-height` CSS attribute + * on the grid div in pixels, which will round to the closest row. + */ + minRow?: number; + /** minimal width before grid will be shown in one column mode (default?: 768) */ + oneColumnSize?: number; + /** + * set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column + * layouts during sorting. This enables you to have custom 1 column layout that differ from the rest. (default?: false) + */ + oneColumnModeDomSort?: boolean; + /** class for placeholder (default?: 'grid-stack-placeholder') */ + placeholderClass?: string; + /** placeholder default content (default?: '') */ + placeholderText?: string; + /** allows to override UI resizable options. (default?: { handles: 'se' }) */ + resizable?: DDResizeOpt; + /** + * if true widgets could be removed by dragging outside of the grid. It could also be a selector string (ex: ".trash"), + * in this case widgets will be removed by dropping them there (default?: false) + * See example (http://gridstack.github.io/gridstack.js/demo/two.html) + */ + removable?: boolean | string; + /** allows to override UI removable options. (default?: { accept: '.grid-stack-item' }) */ + removableOptions?: DDRemoveOpt; + /** fix grid number of rows. This is a shortcut of writing `minRow:N, maxRow:N`. (default `0` no constrain) */ + row?: number; + /** + * if true turns grid to RTL. Possible values are true, false, 'auto' (default?: 'auto') + * See [example](http://gridstack.github.io/gridstack.js/demo/rtl.html) + */ + rtl?: boolean | 'auto'; + /** + * makes grid static (default?: false). If `true` widgets are not movable/resizable. + * You don't even need draggable/resizable. A CSS class + * 'grid-stack-static' is also added to the element. + */ + staticGrid?: boolean; + /** if `true` will add style element to `` otherwise will add it to element's parent node (default `false`). */ + styleInHead?: boolean; +} +/** options used during GridStackEngine.moveNode() */ +export interface GridStackMoveOpts extends GridStackPosition { + /** node to skip collision */ + skip?: GridStackNode; + /** do we pack (default true) */ + pack?: boolean; + /** true if we are calling this recursively to prevent simple swap or coverage collision - default false*/ + nested?: boolean; + /** vars to calculate other cells coordinates */ + cellWidth?: number; + cellHeight?: number; + marginTop?: number; + marginBottom?: number; + marginLeft?: number; + marginRight?: number; + /** position in pixels of the currently dragged items (for overlap check) */ + rect?: GridStackPosition; + /** true if we're live resizing */ + resizing?: boolean; +} +export interface GridStackPosition { + /** widget position x (default?: 0) */ + x?: number; + /** widget position y (default?: 0) */ + y?: number; + /** widget dimension width (default?: 1) */ + w?: number; + /** widget dimension height (default?: 1) */ + h?: number; +} +/** + * GridStack Widget creation options + */ +export interface GridStackWidget extends GridStackPosition { + /** if true then x, y parameters will be ignored and widget will be places on the first available position (default?: false) */ + autoPosition?: boolean; + /** minimum width allowed during resize/creation (default?: undefined = un-constrained) */ + minW?: number; + /** maximum width allowed during resize/creation (default?: undefined = un-constrained) */ + maxW?: number; + /** minimum height allowed during resize/creation (default?: undefined = un-constrained) */ + minH?: number; + /** maximum height allowed during resize/creation (default?: undefined = un-constrained) */ + maxH?: number; + /** prevent resizing (default?: undefined = un-constrained) */ + noResize?: boolean; + /** prevents moving (default?: undefined = un-constrained) */ + noMove?: boolean; + /** prevents being moved by others during their (default?: undefined = un-constrained) */ + locked?: boolean; + /** widgets can have their own custom resize handles. For example 'e,w' will make that particular widget only resize east and west. See `resizable: {handles: string}` option */ + resizeHandles?: string; + /** value for `gs-id` stored on the widget (default?: undefined) */ + id?: numberOrString; + /** html to append inside as content */ + content?: string; + /** optional nested grid options and list of children, which then turns into actual instance at runtime */ + subGrid?: GridStackOptions | GridStack; +} +/** Drag&Drop resize options */ +export interface DDResizeOpt { + /** do resize handle hide by default until mouse over ? - default: true on desktop, false on mobile*/ + autoHide?: boolean; + /** + * sides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east) + * Note: it is not recommended to resize from the top sides as weird side effect may occur. + */ + handles?: string; +} +/** Drag&Drop remove options */ +export interface DDRemoveOpt { + /** class that can be removed (default?: '.' + opts.itemClass) */ + accept?: string; +} +/** Drag&Drop dragging options */ +export interface DDDragOpt { + /** class selector of items that can be dragged. default to '.grid-stack-item-content' */ + handle?: string; + /** default to 'body' */ + appendTo?: string; +} +export interface DDDragInOpt extends DDDragOpt { + /** used when dragging item from the outside, and canceling (ex: 'invalid' or your own method)*/ + /** helper function when dropping (ex: 'clone' or your own method) */ + helper?: string | ((event: Event) => HTMLElement); +} +export interface Size { + width: number; + height: number; +} +export interface Position { + top: number; + left: number; +} +export interface Rect extends Size, Position { +} +/** data that is passed during drag and resizing callbacks */ +export interface DDUIData { + position?: Position; + size?: Size; +} +/** + * internal descriptions describing the items in the grid + */ +export interface GridStackNode extends GridStackWidget { + /** pointer back to HTML element */ + el?: GridItemHTMLElement; + /** pointer back to Grid instance */ + grid?: GridStack; +} diff --git a/dist/es5/types.js b/dist/es5/types.js new file mode 100644 index 000000000..86d8af4a8 --- /dev/null +++ b/dist/es5/types.js @@ -0,0 +1,7 @@ +"use strict"; +/** + * types.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/es5/types.js.map b/dist/es5/types.js.map new file mode 100644 index 000000000..7ec6e77d3 --- /dev/null +++ b/dist/es5/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\r\n * types.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStack } from './gridstack';\r\nimport { GridStackEngine } from './gridstack-engine';\r\n\r\n\r\n/** different layout options when changing # of columns,\r\n * including a custom function that takes new/old column count, and array of new/old positions\r\n * Note: new list may be partially already filled if we have a cache of the layout at that size and new items were added later.\r\n */\r\nexport type ColumnOptions = 'moveScale' | 'move' | 'scale' | 'none' |\r\n ((column: number, oldColumn: number, nodes: GridStackNode[], oldNodes: GridStackNode[]) => void);\r\n\r\nexport type numberOrString = number | string;\r\nexport interface GridItemHTMLElement extends HTMLElement {\r\n /** pointer to grid node instance */\r\n gridstackNode?: GridStackNode;\r\n /** @internal */\r\n _gridstackNodeOrig?: GridStackNode;\r\n}\r\n\r\nexport type GridStackElement = string | HTMLElement | GridItemHTMLElement;\r\n\r\nexport type GridStackEventHandlerCallback = (event: Event, arg2?: GridItemHTMLElement | GridStackNode | GridStackNode[], newNode?: GridStackNode) => void;\r\n\r\n/**\r\n * Defines the options for a Grid\r\n */\r\nexport interface GridStackOptions {\r\n /**\r\n * accept widgets dragged from other grids or from outside (default: `false`). Can be:\r\n * `true` (uses `'.grid-stack-item'` class filter) or `false`,\r\n * string for explicit class name,\r\n * function returning a boolean. See [example](http://gridstack.github.io/gridstack.js/demo/two.html)\r\n */\r\n acceptWidgets?: boolean | string | ((element: Element) => boolean);\r\n\r\n /** possible values (default: `mobile`) - does not apply to non-resizable widgets\r\n * `false` the resizing handles are only shown while hovering over a widget\r\n * `true` the resizing handles are always shown\r\n * 'mobile' if running on a mobile device, default to `true` (since there is no hovering per say), else `false`.\r\n * this uses this condition on browser agent check:\r\n `alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent )`\r\n See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html) */\r\n alwaysShowResizeHandle?: true | false | 'mobile';\r\n\r\n /** turns animation on (default?: true) */\r\n animate?: boolean;\r\n\r\n /** if false gridstack will not initialize existing items (default?: true) */\r\n auto?: boolean;\r\n\r\n /**\r\n * one cell height (default?: 'auto'). Can be:\r\n * an integer (px)\r\n * a string (ex: '100px', '10em', '10rem'). Note: % doesn't right - see demo/cell-height.html\r\n * 0, in which case the library will not generate styles for rows. Everything must be defined in your own CSS files.\r\n * 'auto' - height will be calculated for square cells (width / column) and updated live as you resize the window - also see `cellHeightThrottle`\r\n * 'initial' - similar to 'auto' (start at square cells) but stay that size during window resizing.\r\n */\r\n cellHeight?: numberOrString;\r\n\r\n /** throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100).\r\n * A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event!\r\n * */\r\n cellHeightThrottle?: number;\r\n\r\n /** (internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem') */\r\n cellHeightUnit?: string;\r\n\r\n /** list of children item to create when calling load() or addGrid() */\r\n children?: GridStackWidget[];\r\n\r\n /** number of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns.\r\n * Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside\r\n * items always to same. flag is not supported for regular non-nested grids.\r\n */\r\n column?: number | 'auto';\r\n\r\n /** additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance.\r\n Note: only used by addGrid(), else your element should have the needed class */\r\n class?: string;\r\n\r\n /** disallows dragging of widgets (default?: false) */\r\n disableDrag?: boolean;\r\n\r\n /** disables the onColumnMode when the grid width is less than oneColumnSize (default?: false) */\r\n disableOneColumnMode?: boolean;\r\n\r\n /** disallows resizing of widgets (default?: false). */\r\n disableResize?: boolean;\r\n\r\n /** allows to override UI draggable options. (default?: { handle?: '.grid-stack-item-content', appendTo?: 'body' }) */\r\n draggable?: DDDragOpt;\r\n\r\n /** allows to drag external items using this selector - see dragInOptions. (default: undefined) */\r\n dragIn?: string;\r\n\r\n /** allows to drag external items using these options. See `GridStack.setupDragIn()` instead (not per grid really).\r\n * (default?: { handle: '.grid-stack-item-content', appendTo: 'body' })\r\n * helper can be 'clone' or your own function (set what the drag/dropped item will be instead)\r\n */\r\n dragInOptions?: DDDragInOpt;\r\n\r\n /** let user drag nested grid items out of a parent or not (default true - not supported yet) */\r\n //dragOut?: boolean;\r\n\r\n /** the type of engine to create (so you can subclass) default to GridStackEngine */\r\n engineClass?: typeof GridStackEngine;\r\n\r\n /** enable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html) */\r\n float?: boolean;\r\n\r\n /** draggable handle selector (default?: '.grid-stack-item-content') */\r\n handle?: string;\r\n\r\n /** draggable handle class (e.g. 'grid-stack-item-content'). If set 'handle' is ignored (default?: null) */\r\n handleClass?: string;\r\n\r\n /** id used to debug grid instance, not currently stored in DOM attributes */\r\n id?: numberOrString;\r\n\r\n /** additional widget class (default?: 'grid-stack-item') */\r\n itemClass?: string;\r\n\r\n /**\r\n * gap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below\r\n * an integer (px)\r\n * a string with possible units (ex: '2em', '20px', '2rem')\r\n * string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS).\r\n * Note: all sides must have same units (last one wins, default px)\r\n */\r\n margin?: numberOrString;\r\n\r\n /** OLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side. */\r\n marginTop?: numberOrString;\r\n marginRight?: numberOrString;\r\n marginBottom?: numberOrString;\r\n marginLeft?: numberOrString;\r\n\r\n /** (internal) unit for margin (default? 'px') set when `margin` is set as string with unit (ex: 2rem') */\r\n marginUnit?: string;\r\n\r\n /** maximum rows amount. Default? is 0 which means no maximum rows */\r\n maxRow?: number;\r\n\r\n /** minimum rows amount. Default is `0`. You can also do this with `min-height` CSS attribute\r\n * on the grid div in pixels, which will round to the closest row.\r\n */\r\n minRow?: number;\r\n\r\n /** minimal width before grid will be shown in one column mode (default?: 768) */\r\n oneColumnSize?: number;\r\n\r\n /**\r\n * set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column\r\n * layouts during sorting. This enables you to have custom 1 column layout that differ from the rest. (default?: false)\r\n */\r\n oneColumnModeDomSort?: boolean;\r\n\r\n /** class for placeholder (default?: 'grid-stack-placeholder') */\r\n placeholderClass?: string;\r\n\r\n /** placeholder default content (default?: '') */\r\n placeholderText?: string;\r\n\r\n /** allows to override UI resizable options. (default?: { handles: 'se' }) */\r\n resizable?: DDResizeOpt;\r\n\r\n /**\r\n * if true widgets could be removed by dragging outside of the grid. It could also be a selector string (ex: \".trash\"),\r\n * in this case widgets will be removed by dropping them there (default?: false)\r\n * See example (http://gridstack.github.io/gridstack.js/demo/two.html)\r\n */\r\n removable?: boolean | string;\r\n\r\n /** allows to override UI removable options. (default?: { accept: '.grid-stack-item' }) */\r\n removableOptions?: DDRemoveOpt;\r\n\r\n /** fix grid number of rows. This is a shortcut of writing `minRow:N, maxRow:N`. (default `0` no constrain) */\r\n row?: number;\r\n\r\n /**\r\n * if true turns grid to RTL. Possible values are true, false, 'auto' (default?: 'auto')\r\n * See [example](http://gridstack.github.io/gridstack.js/demo/rtl.html)\r\n */\r\n rtl?: boolean | 'auto';\r\n\r\n /**\r\n * makes grid static (default?: false). If `true` widgets are not movable/resizable.\r\n * You don't even need draggable/resizable. A CSS class\r\n * 'grid-stack-static' is also added to the element.\r\n */\r\n staticGrid?: boolean;\r\n\r\n /** if `true` will add style element to `` otherwise will add it to element's parent node (default `false`). */\r\n styleInHead?: boolean;\r\n\r\n /** @internal point to a parent grid item if we're nested */\r\n _isNested?: GridStackNode;\r\n /** @internal unique class name for our generated CSS style sheet */\r\n _styleSheetClass?: string;\r\n}\r\n\r\n/** options used during GridStackEngine.moveNode() */\r\nexport interface GridStackMoveOpts extends GridStackPosition {\r\n /** node to skip collision */\r\n skip?: GridStackNode;\r\n /** do we pack (default true) */\r\n pack?: boolean;\r\n /** true if we are calling this recursively to prevent simple swap or coverage collision - default false*/\r\n nested?: boolean;\r\n /** vars to calculate other cells coordinates */\r\n cellWidth?: number;\r\n cellHeight?: number;\r\n marginTop?: number;\r\n marginBottom?: number;\r\n marginLeft?: number;\r\n marginRight?: number;\r\n /** position in pixels of the currently dragged items (for overlap check) */\r\n rect?: GridStackPosition;\r\n /** true if we're live resizing */\r\n resizing?: boolean;\r\n}\r\n\r\nexport interface GridStackPosition {\r\n /** widget position x (default?: 0) */\r\n x?: number;\r\n /** widget position y (default?: 0) */\r\n y?: number;\r\n /** widget dimension width (default?: 1) */\r\n w?: number;\r\n /** widget dimension height (default?: 1) */\r\n h?: number;\r\n}\r\n\r\n/**\r\n * GridStack Widget creation options\r\n */\r\nexport interface GridStackWidget extends GridStackPosition {\r\n /** if true then x, y parameters will be ignored and widget will be places on the first available position (default?: false) */\r\n autoPosition?: boolean;\r\n /** minimum width allowed during resize/creation (default?: undefined = un-constrained) */\r\n minW?: number;\r\n /** maximum width allowed during resize/creation (default?: undefined = un-constrained) */\r\n maxW?: number;\r\n /** minimum height allowed during resize/creation (default?: undefined = un-constrained) */\r\n minH?: number;\r\n /** maximum height allowed during resize/creation (default?: undefined = un-constrained) */\r\n maxH?: number;\r\n /** prevent resizing (default?: undefined = un-constrained) */\r\n noResize?: boolean;\r\n /** prevents moving (default?: undefined = un-constrained) */\r\n noMove?: boolean;\r\n /** prevents being moved by others during their (default?: undefined = un-constrained) */\r\n locked?: boolean;\r\n /** widgets can have their own custom resize handles. For example 'e,w' will make that particular widget only resize east and west. See `resizable: {handles: string}` option */\r\n resizeHandles?: string;\r\n /** value for `gs-id` stored on the widget (default?: undefined) */\r\n id?: numberOrString;\r\n /** html to append inside as content */\r\n content?: string;\r\n /** optional nested grid options and list of children, which then turns into actual instance at runtime */\r\n subGrid?: GridStackOptions | GridStack;\r\n}\r\n\r\n/** Drag&Drop resize options */\r\nexport interface DDResizeOpt {\r\n /** do resize handle hide by default until mouse over ? - default: true on desktop, false on mobile*/\r\n autoHide?: boolean;\r\n /**\r\n * sides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east)\r\n * Note: it is not recommended to resize from the top sides as weird side effect may occur.\r\n */\r\n handles?: string;\r\n}\r\n\r\n/** Drag&Drop remove options */\r\nexport interface DDRemoveOpt {\r\n /** class that can be removed (default?: '.' + opts.itemClass) */\r\n accept?: string;\r\n}\r\n\r\n/** Drag&Drop dragging options */\r\nexport interface DDDragOpt {\r\n /** class selector of items that can be dragged. default to '.grid-stack-item-content' */\r\n handle?: string;\r\n /** default to 'body' */\r\n appendTo?: string;\r\n /** default to `true` */\r\n // scroll?: boolean;\r\n /** parent constraining where item can be dragged out from (default: null = no constrain) */\r\n // containment?: string;\r\n}\r\nexport interface DDDragInOpt extends DDDragOpt {\r\n /** used when dragging item from the outside, and canceling (ex: 'invalid' or your own method)*/\r\n // revert?: string | ((event: Event) => HTMLElement);\r\n /** helper function when dropping (ex: 'clone' or your own method) */\r\n helper?: string | ((event: Event) => HTMLElement);\r\n}\r\n\r\nexport interface Size {\r\n width: number;\r\n height: number;\r\n}\r\nexport interface Position {\r\n top: number;\r\n left: number;\r\n}\r\nexport interface Rect extends Size, Position {}\r\n\r\n/** data that is passed during drag and resizing callbacks */\r\nexport interface DDUIData {\r\n position?: Position;\r\n size?: Size;\r\n /* fields not used by GridStack but sent by jq ? leave in case we go back to them...\r\n originalPosition? : Position;\r\n offset?: Position;\r\n originalSize?: Size;\r\n element?: HTMLElement[];\r\n helper?: HTMLElement[];\r\n originalElement?: HTMLElement[];\r\n */\r\n}\r\n\r\n/**\r\n * internal descriptions describing the items in the grid\r\n */\r\nexport interface GridStackNode extends GridStackWidget {\r\n /** pointer back to HTML element */\r\n el?: GridItemHTMLElement;\r\n /** pointer back to Grid instance */\r\n grid?: GridStack;\r\n /** @internal internal id used to match when cloning engines or saving column layouts */\r\n _id?: number;\r\n /** @internal */\r\n _dirty?: boolean;\r\n /** @internal */\r\n _updating?: boolean;\r\n /** @internal true when over trash/another grid so we don't bother removing drag CSS style that would animate back to old position */\r\n _isAboutToRemove?: boolean;\r\n /** @internal true if item came from outside of the grid -> actual item need to be moved over */\r\n _isExternal?: boolean;\r\n /** @internal moving vs resizing */\r\n _moving?: boolean;\r\n /** @internal true if we jumped down past item below (one time jump so we don't have to totally pass it) */\r\n _skipDown?: boolean;\r\n /** @internal original values before a drag/size */\r\n _orig?: GridStackPosition;\r\n /** @internal position in pixels used during collision check */\r\n _rect?: GridStackPosition;\r\n /** @internal top/left pixel location before a drag so we can detect direction of move from last position*/\r\n _lastUiPosition?: Position;\r\n /** @internal set on the item being dragged/resized remember the last positions we've tried (but failed) so we don't try again during drag/resize */\r\n _lastTried?: GridStackPosition;\r\n /** @internal position willItFit() will use to position the item */\r\n _willFitPos?: GridStackPosition;\r\n /** @internal last drag Y pixel position used to incrementally update V scroll bar */\r\n _prevYPix?: number;\r\n /** @internal true if we've remove the item from ourself (dragging out) but might revert it back (release on nothing -> goes back) */\r\n _temporaryRemoved?: boolean;\r\n /** @internal true if we should remove DOM element on _notify() rather than clearing _id (old way) */\r\n _removeDOM?: boolean;\r\n /** @internal */\r\n _initDD?: boolean;\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/es5/utils.d.ts b/dist/es5/utils.d.ts new file mode 100644 index 000000000..be71753ad --- /dev/null +++ b/dist/es5/utils.d.ts @@ -0,0 +1,83 @@ +/** + * utils.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types'; +export interface HeightData { + h: number; + unit: string; +} +/** checks for obsolete method names */ +export declare function obsolete(self: any, f: any, oldName: string, newName: string, rev: string): (...args: any[]) => any; +/** checks for obsolete grid options (can be used for any fields, but msg is about options) */ +export declare function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void; +/** checks for obsolete grid options which are gone */ +export declare function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void; +/** checks for obsolete Jquery element attributes */ +export declare function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void; +/** + * Utility methods + */ +export declare class Utils { + /** convert a potential selector into actual list of html elements */ + static getElements(els: GridStackElement): HTMLElement[]; + /** convert a potential selector into actual single element */ + static getElement(els: GridStackElement): HTMLElement; + /** returns true if a and b overlap */ + static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean; + /** returns true if a and b touch edges or corners */ + static isTouching(a: GridStackPosition, b: GridStackPosition): boolean; + /** + * Sorts array of nodes + * @param nodes array to sort + * @param dir 1 for asc, -1 for desc (optional) + * @param width width of the grid. If undefined the width will be calculated automatically (optional). + **/ + static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[]; + /** + * creates a style sheet with style id under given parent + * @param id will set the 'gs-style-id' attribute to that id + * @param parent to insert the stylesheet as first child, + * if none supplied it will be appended to the document head instead. + */ + static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet; + /** removed the given stylesheet id */ + static removeStylesheet(id: string): void; + /** inserts a CSS rule */ + static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void; + static toBool(v: unknown): boolean; + static toNumber(value: null | string): number; + static parseHeight(val: numberOrString): HeightData; + /** copies unset fields in target to use the given default sources values */ + static defaults(target: any, ...sources: any[]): {}; + /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */ + static same(a: unknown, b: unknown): boolean; + /** copies over b size & position (GridStackPosition), and possibly min/max as well */ + static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax?: boolean): GridStackWidget; + /** true if a and b has same size & position */ + static samePos(a: GridStackPosition, b: GridStackPosition): boolean; + /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */ + static removeInternalAndSame(a: unknown, b: unknown): void; + /** return the closest parent (or itself) matching the given class */ + static closestByClass(el: HTMLElement, name: string): HTMLElement; + /** delay calling the given function for given delay, preventing new calls from happening while waiting */ + static throttle(func: () => void, delay: number): () => void; + static removePositioningStyles(el: HTMLElement): void; + /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */ + static clone(obj: T): T; + /** + * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY. + * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies. + */ + static cloneDeep(obj: T): T; + /** deep clone the given HTML node, removing teh unique id field */ + static cloneNode(el: HTMLElement): HTMLElement; + static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void; + static addElStyles(el: HTMLElement, styles: { + [prop: string]: string | string[]; + }): void; + static initEvent(e: DragEvent | MouseEvent, info: { + type: string; + target?: EventTarget; + }): T; +} diff --git a/dist/es5/utils.js b/dist/es5/utils.js new file mode 100644 index 000000000..adae2ad79 --- /dev/null +++ b/dist/es5/utils.js @@ -0,0 +1,506 @@ +"use strict"; +/** + * utils.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Utils = exports.obsoleteAttr = exports.obsoleteOptsDel = exports.obsoleteOpts = exports.obsolete = void 0; +/** checks for obsolete method names */ +// eslint-disable-next-line +function obsolete(self, f, oldName, newName, rev) { + var wrapper = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' + + 'with `' + newName + '`. It will be **removed** in a future release'); + return f.apply(self, args); + }; + wrapper.prototype = f.prototype; + return wrapper; +} +exports.obsolete = obsolete; +/** checks for obsolete grid options (can be used for any fields, but msg is about options) */ +function obsoleteOpts(opts, oldName, newName, rev) { + if (opts[oldName] !== undefined) { + opts[newName] = opts[oldName]; + console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' + + newName + '`. It will be **removed** in a future release'); + } +} +exports.obsoleteOpts = obsoleteOpts; +/** checks for obsolete grid options which are gone */ +function obsoleteOptsDel(opts, oldName, rev, info) { + if (opts[oldName] !== undefined) { + console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info); + } +} +exports.obsoleteOptsDel = obsoleteOptsDel; +/** checks for obsolete Jquery element attributes */ +function obsoleteAttr(el, oldName, newName, rev) { + var oldAttr = el.getAttribute(oldName); + if (oldAttr !== null) { + el.setAttribute(newName, oldAttr); + console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' + + newName + '`. It will be **removed** in a future release'); + } +} +exports.obsoleteAttr = obsoleteAttr; +/** + * Utility methods + */ +var Utils = /** @class */ (function () { + function Utils() { + } + /** convert a potential selector into actual list of html elements */ + Utils.getElements = function (els) { + if (typeof els === 'string') { + var list = document.querySelectorAll(els); + if (!list.length && els[0] !== '.' && els[0] !== '#') { + list = document.querySelectorAll('.' + els); + if (!list.length) { + list = document.querySelectorAll('#' + els); + } + } + return Array.from(list); + } + return [els]; + }; + /** convert a potential selector into actual single element */ + Utils.getElement = function (els) { + if (typeof els === 'string') { + if (!els.length) + return null; + if (els[0] === '#') { + return document.getElementById(els.substring(1)); + } + if (els[0] === '.' || els[0] === '[') { + return document.querySelector(els); + } + // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS + if (!isNaN(+els[0])) { // start with digit + return document.getElementById(els); + } + // finally try string, then id then class + var el = document.querySelector(els); + if (!el) { + el = document.getElementById(els); + } + if (!el) { + el = document.querySelector('.' + els); + } + return el; + } + return els; + }; + /** returns true if a and b overlap */ + Utils.isIntercepted = function (a, b) { + return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w); + }; + /** returns true if a and b touch edges or corners */ + Utils.isTouching = function (a, b) { + return Utils.isIntercepted(a, { x: b.x - 0.5, y: b.y - 0.5, w: b.w + 1, h: b.h + 1 }); + }; + /** + * Sorts array of nodes + * @param nodes array to sort + * @param dir 1 for asc, -1 for desc (optional) + * @param width width of the grid. If undefined the width will be calculated automatically (optional). + **/ + Utils.sort = function (nodes, dir, column) { + column = column || nodes.reduce(function (col, n) { return Math.max(n.x + n.w, col); }, 0) || 12; + if (dir === -1) + return nodes.sort(function (a, b) { return (b.x + b.y * column) - (a.x + a.y * column); }); + else + return nodes.sort(function (b, a) { return (b.x + b.y * column) - (a.x + a.y * column); }); + }; + /** + * creates a style sheet with style id under given parent + * @param id will set the 'gs-style-id' attribute to that id + * @param parent to insert the stylesheet as first child, + * if none supplied it will be appended to the document head instead. + */ + Utils.createStylesheet = function (id, parent) { + var style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + style.setAttribute('gs-style-id', id); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (style.styleSheet) { // TODO: only CSSImportRule have that and different beast ?? + // eslint-disable-next-line @typescript-eslint/no-explicit-any + style.styleSheet.cssText = ''; + } + else { + style.appendChild(document.createTextNode('')); // WebKit hack + } + if (!parent) { + // default to head + parent = document.getElementsByTagName('head')[0]; + parent.appendChild(style); + } + else { + parent.insertBefore(style, parent.firstChild); + } + return style.sheet; + }; + /** removed the given stylesheet id */ + Utils.removeStylesheet = function (id) { + var el = document.querySelector('STYLE[gs-style-id=' + id + ']'); + if (el && el.parentNode) + el.remove(); + }; + /** inserts a CSS rule */ + Utils.addCSSRule = function (sheet, selector, rules) { + if (typeof sheet.addRule === 'function') { + sheet.addRule(selector, rules); + } + else if (typeof sheet.insertRule === 'function') { + sheet.insertRule(selector + "{" + rules + "}"); + } + }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Utils.toBool = function (v) { + if (typeof v === 'boolean') { + return v; + } + if (typeof v === 'string') { + v = v.toLowerCase(); + return !(v === '' || v === 'no' || v === 'false' || v === '0'); + } + return Boolean(v); + }; + Utils.toNumber = function (value) { + return (value === null || value.length === 0) ? undefined : Number(value); + }; + Utils.parseHeight = function (val) { + var h; + var unit = 'px'; + if (typeof val === 'string') { + var match = val.match(/^(-[0-9]+\.[0-9]+|[0-9]*\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/); + if (!match) { + throw new Error('Invalid height'); + } + unit = match[2] || 'px'; + h = parseFloat(match[1]); + } + else { + h = val; + } + return { h: h, unit: unit }; + }; + /** copies unset fields in target to use the given default sources values */ + // eslint-disable-next-line + Utils.defaults = function (target) { + var _this = this; + var sources = []; + for (var _i = 1; _i < arguments.length; _i++) { + sources[_i - 1] = arguments[_i]; + } + sources.forEach(function (source) { + for (var key in source) { + if (!source.hasOwnProperty(key)) + return; + if (target[key] === null || target[key] === undefined) { + target[key] = source[key]; + } + else if (typeof source[key] === 'object' && typeof target[key] === 'object') { + // property is an object, recursively add it's field over... #1373 + _this.defaults(target[key], source[key]); + } + } + }); + return target; + }; + /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */ + Utils.same = function (a, b) { + if (typeof a !== 'object') + return a == b; + if (typeof a !== typeof b) + return false; + // else we have object, check just 1 level deep for being same things... + if (Object.keys(a).length !== Object.keys(b).length) + return false; + for (var key in a) { + if (a[key] !== b[key]) + return false; + } + return true; + }; + /** copies over b size & position (GridStackPosition), and possibly min/max as well */ + Utils.copyPos = function (a, b, doMinMax) { + if (doMinMax === void 0) { doMinMax = false; } + a.x = b.x; + a.y = b.y; + a.w = b.w; + a.h = b.h; + if (doMinMax) { + if (b.minW) + a.minW = b.minW; + if (b.minH) + a.minH = b.minH; + if (b.maxW) + a.maxW = b.maxW; + if (b.maxH) + a.maxH = b.maxH; + } + return a; + }; + /** true if a and b has same size & position */ + Utils.samePos = function (a, b) { + return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h; + }; + /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */ + Utils.removeInternalAndSame = function (a, b) { + if (typeof a !== 'object' || typeof b !== 'object') + return; + for (var key in a) { + var val = a[key]; + if (key[0] === '_' || val === b[key]) { + delete a[key]; + } + else if (val && typeof val === 'object' && b[key] !== undefined) { + for (var i in val) { + if (val[i] === b[key][i] || i[0] === '_') { + delete val[i]; + } + } + if (!Object.keys(val).length) { + delete a[key]; + } + } + } + }; + /** return the closest parent (or itself) matching the given class */ + Utils.closestByClass = function (el, name) { + while (el) { + if (el.classList.contains(name)) + return el; + el = el.parentElement; + } + return null; + }; + /** delay calling the given function for given delay, preventing new calls from happening while waiting */ + Utils.throttle = function (func, delay) { + var isWaiting = false; + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (!isWaiting) { + isWaiting = true; + setTimeout(function () { func.apply(void 0, args); isWaiting = false; }, delay); + } + }; + }; + Utils.removePositioningStyles = function (el) { + var style = el.style; + if (style.position) { + style.removeProperty('position'); + } + if (style.left) { + style.removeProperty('left'); + } + if (style.top) { + style.removeProperty('top'); + } + if (style.width) { + style.removeProperty('width'); + } + if (style.height) { + style.removeProperty('height'); + } + }; + /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */ + Utils.getScrollElement = function (el) { + if (!el) + return document.scrollingElement || document.documentElement; // IE support + var style = getComputedStyle(el); + var overflowRegex = /(auto|scroll)/; + if (overflowRegex.test(style.overflow + style.overflowY)) { + return el; + } + else { + return this.getScrollElement(el.parentElement); + } + }; + /** @internal */ + Utils.updateScrollPosition = function (el, position, distance) { + // is widget in view? + var rect = el.getBoundingClientRect(); + var innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight); + if (rect.top < 0 || + rect.bottom > innerHeightOrClientHeight) { + // set scrollTop of first parent that scrolls + // if parent is larger than el, set as low as possible + // to get entire widget on screen + var offsetDiffDown = rect.bottom - innerHeightOrClientHeight; + var offsetDiffUp = rect.top; + var scrollEl = this.getScrollElement(el); + if (scrollEl !== null) { + var prevScroll = scrollEl.scrollTop; + if (rect.top < 0 && distance < 0) { + // moving up + if (el.offsetHeight > innerHeightOrClientHeight) { + scrollEl.scrollTop += distance; + } + else { + scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp; + } + } + else if (distance > 0) { + // moving down + if (el.offsetHeight > innerHeightOrClientHeight) { + scrollEl.scrollTop += distance; + } + else { + scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown; + } + } + // move widget y by amount scrolled + position.top += scrollEl.scrollTop - prevScroll; + } + } + }; + /** + * @internal Function used to scroll the page. + * + * @param event `MouseEvent` that triggers the resize + * @param el `HTMLElement` that's being resized + * @param distance Distance from the V edges to start scrolling + */ + Utils.updateScrollResize = function (event, el, distance) { + var scrollEl = this.getScrollElement(el); + var height = scrollEl.clientHeight; + // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top + // #1745 Special situation if scrollEl is document 'html': here browser spec states that + // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element; + // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself. + var offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top; + var pointerPosY = event.clientY - offsetTop; + var top = pointerPosY < distance; + var bottom = pointerPosY > height - distance; + if (top) { + // This also can be done with a timeout to keep scrolling while the mouse is + // in the scrolling zone. (will have smoother behavior) + scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance }); + } + else if (bottom) { + scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY) }); + } + }; + /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */ + Utils.clone = function (obj) { + if (obj === null || obj === undefined || typeof (obj) !== 'object') { + return obj; + } + // return Object.assign({}, obj); + if (obj instanceof Array) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return __spreadArrays(obj); + } + return __assign({}, obj); + }; + /** + * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY. + * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies. + */ + Utils.cloneDeep = function (obj) { + // list of fields we will skip during cloneDeep (nested objects, other internal) + var skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine']; + // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ? + var ret = Utils.clone(obj); + var _loop_1 = function (key) { + // NOTE: we don't support function/circular dependencies so skip those properties for now... + if (ret.hasOwnProperty(key) && typeof (ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(function (k) { return k === key; })) { + ret[key] = Utils.cloneDeep(obj[key]); + } + }; + for (var key in ret) { + _loop_1(key); + } + return ret; + }; + /** deep clone the given HTML node, removing teh unique id field */ + Utils.cloneNode = function (el) { + var node = el.cloneNode(true); + node.removeAttribute('id'); + return node; + }; + Utils.appendTo = function (el, parent) { + var parentNode; + if (typeof parent === 'string') { + parentNode = document.querySelector(parent); + } + else { + parentNode = parent; + } + if (parentNode) { + parentNode.appendChild(el); + } + }; + // public static setPositionRelative(el: HTMLElement): void { + // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) { + // el.style.position = "relative"; + // } + // } + Utils.addElStyles = function (el, styles) { + if (styles instanceof Object) { + var _loop_2 = function (s) { + if (styles.hasOwnProperty(s)) { + if (Array.isArray(styles[s])) { + // support fallback value + styles[s].forEach(function (val) { + el.style[s] = val; + }); + } + else { + el.style[s] = styles[s]; + } + } + }; + for (var s in styles) { + _loop_2(s); + } + } + }; + Utils.initEvent = function (e, info) { + var evt = { type: info.type }; + var obj = { + button: 0, + which: 0, + buttons: 1, + bubbles: true, + cancelable: true, + target: info.target ? info.target : e.target + }; + // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540 + if (e.dataTransfer) { + evt['dataTransfer'] = e.dataTransfer; // workaround 'readonly' field. + } + ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].forEach(function (p) { return evt[p] = e[p]; }); // keys + ['pageX', 'pageY', 'clientX', 'clientY', 'screenX', 'screenY'].forEach(function (p) { return evt[p] = e[p]; }); // point info + return __assign(__assign({}, evt), obj); + }; + return Utils; +}()); +exports.Utils = Utils; +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/es5/utils.js.map b/dist/es5/utils.js.map new file mode 100644 index 000000000..e9df9f6e8 --- /dev/null +++ b/dist/es5/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * utils.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types';\r\n\r\nexport interface HeightData {\r\n h: number;\r\n unit: string;\r\n}\r\n\r\n/** checks for obsolete method names */\r\n// eslint-disable-next-line\r\nexport function obsolete(self, f, oldName: string, newName: string, rev: string): (...args: any[]) => any {\r\n let wrapper = (...args) => {\r\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\r\n 'with `' + newName + '`. It will be **removed** in a future release');\r\n return f.apply(self, args);\r\n }\r\n wrapper.prototype = f.prototype;\r\n return wrapper;\r\n}\r\n\r\n/** checks for obsolete grid options (can be used for any fields, but msg is about options) */\r\nexport function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void {\r\n if (opts[oldName] !== undefined) {\r\n opts[newName] = opts[oldName];\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/** checks for obsolete grid options which are gone */\r\nexport function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void {\r\n if (opts[oldName] !== undefined) {\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\r\n }\r\n}\r\n\r\n/** checks for obsolete Jquery element attributes */\r\nexport function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void {\r\n let oldAttr = el.getAttribute(oldName);\r\n if (oldAttr !== null) {\r\n el.setAttribute(newName, oldAttr);\r\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods\r\n */\r\nexport class Utils {\r\n\r\n /** convert a potential selector into actual list of html elements */\r\n static getElements(els: GridStackElement): HTMLElement[] {\r\n if (typeof els === 'string') {\r\n let list = document.querySelectorAll(els);\r\n if (!list.length && els[0] !== '.' && els[0] !== '#') {\r\n list = document.querySelectorAll('.' + els);\r\n if (!list.length) { list = document.querySelectorAll('#' + els) }\r\n }\r\n return Array.from(list) as HTMLElement[];\r\n }\r\n return [els];\r\n }\r\n\r\n /** convert a potential selector into actual single element */\r\n static getElement(els: GridStackElement): HTMLElement {\r\n if (typeof els === 'string') {\r\n if (!els.length) return null;\r\n if (els[0] === '#') {\r\n return document.getElementById(els.substring(1));\r\n }\r\n if (els[0] === '.' || els[0] === '[') {\r\n return document.querySelector(els);\r\n }\r\n\r\n // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS\r\n if(!isNaN(+els[0])) { // start with digit\r\n return document.getElementById(els);\r\n }\r\n\r\n // finally try string, then id then class\r\n let el = document.querySelector(els);\r\n if (!el) { el = document.getElementById(els) }\r\n if (!el) { el = document.querySelector('.' + els) }\r\n return el as HTMLElement;\r\n }\r\n return els;\r\n }\r\n\r\n /** returns true if a and b overlap */\r\n static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w);\r\n }\r\n\r\n /** returns true if a and b touch edges or corners */\r\n static isTouching(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return Utils.isIntercepted(a, {x: b.x-0.5, y: b.y-0.5, w: b.w+1, h: b.h+1})\r\n }\r\n /**\r\n * Sorts array of nodes\r\n * @param nodes array to sort\r\n * @param dir 1 for asc, -1 for desc (optional)\r\n * @param width width of the grid. If undefined the width will be calculated automatically (optional).\r\n **/\r\n static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[] {\r\n column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12;\r\n if (dir === -1)\r\n return nodes.sort((a, b) => (b.x + b.y * column)-(a.x + a.y * column));\r\n else\r\n return nodes.sort((b, a) => (b.x + b.y * column)-(a.x + a.y * column));\r\n }\r\n\r\n /**\r\n * creates a style sheet with style id under given parent\r\n * @param id will set the 'gs-style-id' attribute to that id\r\n * @param parent to insert the stylesheet as first child,\r\n * if none supplied it will be appended to the document head instead.\r\n */\r\n static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet {\r\n let style: HTMLStyleElement = document.createElement('style');\r\n style.setAttribute('type', 'text/css');\r\n style.setAttribute('gs-style-id', id);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if ((style as any).styleSheet) { // TODO: only CSSImportRule have that and different beast ??\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (style as any).styleSheet.cssText = '';\r\n } else {\r\n style.appendChild(document.createTextNode('')); // WebKit hack\r\n }\r\n if (!parent) {\r\n // default to head\r\n parent = document.getElementsByTagName('head')[0];\r\n parent.appendChild(style);\r\n } else {\r\n parent.insertBefore(style, parent.firstChild);\r\n }\r\n return style.sheet as CSSStyleSheet;\r\n }\r\n\r\n /** removed the given stylesheet id */\r\n static removeStylesheet(id: string): void {\r\n let el = document.querySelector('STYLE[gs-style-id=' + id + ']');\r\n if (el && el.parentNode) el.remove();\r\n }\r\n\r\n /** inserts a CSS rule */\r\n static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void {\r\n if (typeof sheet.addRule === 'function') {\r\n sheet.addRule(selector, rules);\r\n } else if (typeof sheet.insertRule === 'function') {\r\n sheet.insertRule(`${selector}{${rules}}`);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n static toBool(v: unknown): boolean {\r\n if (typeof v === 'boolean') {\r\n return v;\r\n }\r\n if (typeof v === 'string') {\r\n v = v.toLowerCase();\r\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\r\n }\r\n return Boolean(v);\r\n }\r\n\r\n static toNumber(value: null | string): number {\r\n return (value === null || value.length === 0) ? undefined : Number(value);\r\n }\r\n\r\n static parseHeight(val: numberOrString): HeightData {\r\n let h: number;\r\n let unit = 'px';\r\n if (typeof val === 'string') {\r\n let match = val.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\r\n if (!match) {\r\n throw new Error('Invalid height');\r\n }\r\n unit = match[2] || 'px';\r\n h = parseFloat(match[1]);\r\n } else {\r\n h = val;\r\n }\r\n return { h, unit };\r\n }\r\n\r\n /** copies unset fields in target to use the given default sources values */\r\n // eslint-disable-next-line\r\n static defaults(target, ...sources): {} {\r\n\r\n sources.forEach(source => {\r\n for (const key in source) {\r\n if (!source.hasOwnProperty(key)) return;\r\n if (target[key] === null || target[key] === undefined) {\r\n target[key] = source[key];\r\n } else if (typeof source[key] === 'object' && typeof target[key] === 'object') {\r\n // property is an object, recursively add it's field over... #1373\r\n this.defaults(target[key], source[key]);\r\n }\r\n }\r\n });\r\n\r\n return target;\r\n }\r\n\r\n /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */\r\n static same(a: unknown, b: unknown): boolean {\r\n if (typeof a !== 'object') return a == b;\r\n if (typeof a !== typeof b) return false;\r\n // else we have object, check just 1 level deep for being same things...\r\n if (Object.keys(a).length !== Object.keys(b).length) return false;\r\n for (const key in a) {\r\n if (a[key] !== b[key]) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /** copies over b size & position (GridStackPosition), and possibly min/max as well */\r\n static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax = false): GridStackWidget {\r\n a.x = b.x;\r\n a.y = b.y;\r\n a.w = b.w;\r\n a.h = b.h;\r\n if (doMinMax) {\r\n if (b.minW) a.minW = b.minW;\r\n if (b.minH) a.minH = b.minH;\r\n if (b.maxW) a.maxW = b.maxW;\r\n if (b.maxH) a.maxH = b.maxH;\r\n }\r\n return a;\r\n }\r\n\r\n /** true if a and b has same size & position */\r\n static samePos(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\r\n }\r\n\r\n /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */\r\n static removeInternalAndSame(a: unknown, b: unknown):void {\r\n if (typeof a !== 'object' || typeof b !== 'object') return;\r\n for (let key in a) {\r\n let val = a[key];\r\n if (key[0] === '_' || val === b[key]) {\r\n delete a[key]\r\n } else if (val && typeof val === 'object' && b[key] !== undefined) {\r\n for (let i in val) {\r\n if (val[i] === b[key][i] || i[0] === '_') { delete val[i] }\r\n }\r\n if (!Object.keys(val).length) { delete a[key] }\r\n }\r\n }\r\n }\r\n\r\n /** return the closest parent (or itself) matching the given class */\r\n static closestByClass(el: HTMLElement, name: string): HTMLElement {\r\n while (el) {\r\n if (el.classList.contains(name)) return el;\r\n el = el.parentElement\r\n }\r\n return null;\r\n }\r\n\r\n /** delay calling the given function for given delay, preventing new calls from happening while waiting */\r\n static throttle(func: () => void, delay: number): () => void {\r\n let isWaiting = false;\r\n return (...args) => {\r\n if (!isWaiting) {\r\n isWaiting = true;\r\n setTimeout(() => { func(...args); isWaiting = false; }, delay);\r\n }\r\n }\r\n }\r\n\r\n static removePositioningStyles(el: HTMLElement): void {\r\n let style = el.style;\r\n if (style.position) {\r\n style.removeProperty('position');\r\n }\r\n if (style.left) {\r\n style.removeProperty('left');\r\n }\r\n if (style.top) {\r\n style.removeProperty('top');\r\n }\r\n if (style.width) {\r\n style.removeProperty('width');\r\n }\r\n if (style.height) {\r\n style.removeProperty('height');\r\n }\r\n }\r\n\r\n /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */\r\n static getScrollElement(el?: HTMLElement): HTMLElement {\r\n if (!el) return document.scrollingElement as HTMLElement || document.documentElement; // IE support\r\n const style = getComputedStyle(el);\r\n const overflowRegex = /(auto|scroll)/;\r\n\r\n if (overflowRegex.test(style.overflow + style.overflowY)) {\r\n return el;\r\n } else {\r\n return this.getScrollElement(el.parentElement);\r\n }\r\n }\r\n\r\n /** @internal */\r\n static updateScrollPosition(el: HTMLElement, position: {top: number}, distance: number): void {\r\n // is widget in view?\r\n let rect = el.getBoundingClientRect();\r\n let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\r\n if (rect.top < 0 ||\r\n rect.bottom > innerHeightOrClientHeight\r\n ) {\r\n // set scrollTop of first parent that scrolls\r\n // if parent is larger than el, set as low as possible\r\n // to get entire widget on screen\r\n let offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\r\n let offsetDiffUp = rect.top;\r\n let scrollEl = this.getScrollElement(el);\r\n if (scrollEl !== null) {\r\n let prevScroll = scrollEl.scrollTop;\r\n if (rect.top < 0 && distance < 0) {\r\n // moving up\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\r\n }\r\n } else if (distance > 0) {\r\n // moving down\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\r\n }\r\n }\r\n // move widget y by amount scrolled\r\n position.top += scrollEl.scrollTop - prevScroll;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal Function used to scroll the page.\r\n *\r\n * @param event `MouseEvent` that triggers the resize\r\n * @param el `HTMLElement` that's being resized\r\n * @param distance Distance from the V edges to start scrolling\r\n */\r\n static updateScrollResize(event: MouseEvent, el: HTMLElement, distance: number): void {\r\n const scrollEl = this.getScrollElement(el);\r\n const height = scrollEl.clientHeight;\r\n // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top\r\n // #1745 Special situation if scrollEl is document 'html': here browser spec states that\r\n // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;\r\n // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.\r\n const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top;\r\n const pointerPosY = event.clientY - offsetTop;\r\n const top = pointerPosY < distance;\r\n const bottom = pointerPosY > height - distance;\r\n\r\n if (top) {\r\n // This also can be done with a timeout to keep scrolling while the mouse is\r\n // in the scrolling zone. (will have smoother behavior)\r\n scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance});\r\n } else if (bottom) {\r\n scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY)});\r\n }\r\n }\r\n\r\n /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */\r\n static clone(obj: T): T {\r\n if (obj === null || obj === undefined || typeof(obj) !== 'object') {\r\n return obj;\r\n }\r\n // return Object.assign({}, obj);\r\n if (obj instanceof Array) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return [...obj] as any;\r\n }\r\n return {...obj};\r\n }\r\n\r\n /**\r\n * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.\r\n * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.\r\n */\r\n static cloneDeep(obj: T): T {\r\n // list of fields we will skip during cloneDeep (nested objects, other internal)\r\n const skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine'];\r\n // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ?\r\n const ret = Utils.clone(obj);\r\n for (const key in ret) {\r\n // NOTE: we don't support function/circular dependencies so skip those properties for now...\r\n if (ret.hasOwnProperty(key) && typeof(ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) {\r\n ret[key] = Utils.cloneDeep(obj[key]);\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /** deep clone the given HTML node, removing teh unique id field */\r\n public static cloneNode(el: HTMLElement): HTMLElement {\r\n const node = el.cloneNode(true) as HTMLElement;\r\n node.removeAttribute('id');\r\n return node;\r\n }\r\n\r\n public static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void {\r\n let parentNode: HTMLElement;\r\n if (typeof parent === 'string') {\r\n parentNode = document.querySelector(parent as string);\r\n } else {\r\n parentNode = parent as HTMLElement;\r\n }\r\n if (parentNode) {\r\n parentNode.appendChild(el);\r\n }\r\n }\r\n\r\n // public static setPositionRelative(el: HTMLElement): void {\r\n // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) {\r\n // el.style.position = \"relative\";\r\n // }\r\n // }\r\n\r\n public static addElStyles(el: HTMLElement, styles: { [prop: string]: string | string[] }): void {\r\n if (styles instanceof Object) {\r\n for (const s in styles) {\r\n if (styles.hasOwnProperty(s)) {\r\n if (Array.isArray(styles[s])) {\r\n // support fallback value\r\n (styles[s] as string[]).forEach(val => {\r\n el.style[s] = val;\r\n });\r\n } else {\r\n el.style[s] = styles[s];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public static initEvent(e: DragEvent | MouseEvent, info: { type: string; target?: EventTarget }): T {\r\n const evt = { type: info.type };\r\n const obj = {\r\n button: 0,\r\n which: 0,\r\n buttons: 1,\r\n bubbles: true,\r\n cancelable: true,\r\n target: info.target ? info.target : e.target\r\n };\r\n // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540\r\n if ((e as DragEvent).dataTransfer) {\r\n evt['dataTransfer'] = (e as DragEvent).dataTransfer; // workaround 'readonly' field.\r\n }\r\n ['altKey','ctrlKey','metaKey','shiftKey'].forEach(p => evt[p] = e[p]); // keys\r\n ['pageX','pageY','clientX','clientY','screenX','screenY'].forEach(p => evt[p] = e[p]); // point info\r\n return {...evt, ...obj} as unknown as T;\r\n }\r\n\r\n /** returns true if event is inside the given element rectangle */\r\n // Note: Safari Mac has null event.relatedTarget which causes #1684 so check if DragEvent is inside the coordinates instead\r\n // this.el.contains(event.relatedTarget as HTMLElement)\r\n // public static inside(e: MouseEvent, el: HTMLElement): boolean {\r\n // // srcElement, toElement, target: all set to placeholder when leaving simple grid, so we can't use that (Chrome)\r\n // let target: HTMLElement = e.relatedTarget || (e as any).fromElement;\r\n // if (!target) {\r\n // const { bottom, left, right, top } = el.getBoundingClientRect();\r\n // return (e.x < right && e.x > left && e.y < bottom && e.y > top);\r\n // }\r\n // return el.contains(target);\r\n // }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/gridstack-all.js b/dist/gridstack-all.js new file mode 100644 index 000000000..c7505ad1f --- /dev/null +++ b/dist/gridstack-all.js @@ -0,0 +1,3 @@ +/*! For license information please see gridstack-all.js.LICENSE.txt */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.GridStack=e():t.GridStack=e()}(self,(function(){return(()=>{"use strict";var t={427:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDBaseImplement=void 0,e.DDBaseImplement=class{constructor(){this._eventRegister={}}get disabled(){return this._disabled}on(t,e){this._eventRegister[t]=e}off(t){delete this._eventRegister[t]}enable(){this._disabled=!1}disable(){this._disabled=!0}destroy(){delete this._eventRegister}triggerEvent(t,e){if(!this.disabled&&this._eventRegister&&this._eventRegister[t])return this._eventRegister[t](e)}}},186:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDDraggable=void 0;const s=i(939),o=i(593),n=i(427),r=i(635);class l extends n.DDBaseImplement{constructor(t,e={}){super(),this.el=t,this.option=e;let i=e.handle.substring(1);this.dragEl=t.classList.contains(i)?t:t.querySelector(e.handle)||t,this._mouseDown=this._mouseDown.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseUp=this._mouseUp.bind(this),this.enable()}on(t,e){super.on(t,e)}off(t){super.off(t)}enable(){!1!==this.disabled&&(super.enable(),this.dragEl.addEventListener("mousedown",this._mouseDown),r.isTouch&&(this.dragEl.addEventListener("touchstart",r.touchstart),this.dragEl.addEventListener("pointerdown",r.pointerdown)),this.el.classList.remove("ui-draggable-disabled"),this.el.classList.add("ui-draggable"))}disable(t=!1){!0!==this.disabled&&(super.disable(),this.dragEl.removeEventListener("mousedown",this._mouseDown),r.isTouch&&(this.dragEl.removeEventListener("touchstart",r.touchstart),this.dragEl.removeEventListener("pointerdown",r.pointerdown)),this.el.classList.remove("ui-draggable"),t||this.el.classList.add("ui-draggable-disabled"))}destroy(){this.dragging&&this._mouseUp(this.mouseDownEvent),this.disable(!0),delete this.el,delete this.helper,delete this.option,super.destroy()}updateOption(t){return Object.keys(t).forEach((e=>this.option[e]=t[e])),this}_mouseDown(t){if(s.DDManager.mouseHandled)return;if(0!==t.button)return!0;let e=this.option.handle.substring(1),i=t.target;for(;i&&!i.classList.contains(e);)i=i.parentElement;return i?(this.mouseDownEvent=t,delete this.dragging,delete s.DDManager.dragElement,delete s.DDManager.dropElement,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),r.isTouch&&(this.dragEl.addEventListener("touchmove",r.touchmove),this.dragEl.addEventListener("touchend",r.touchend)),t.preventDefault(),s.DDManager.mouseHandled=!0,!0):void 0}_mouseMove(t){var e;let i=this.mouseDownEvent;if(this.dragging){this._dragFollow(t);const e=o.Utils.initEvent(t,{target:this.el,type:"drag"});this.option.drag&&this.option.drag(e,this.ui()),this.triggerEvent("drag",e)}else if(Math.abs(t.x-i.x)+Math.abs(t.y-i.y)>3){this.dragging=!0,s.DDManager.dragElement=this;let i=null===(e=this.el.gridstackNode)||void 0===e?void 0:e.grid;i?s.DDManager.dropElement=i.el.ddElement.ddDroppable:delete s.DDManager.dropElement,this.helper=this._createHelper(t),this._setupHelperContainmentStyle(),this.dragOffset=this._getDragOffset(t,this.el,this.helperContainment);const n=o.Utils.initEvent(t,{target:this.el,type:"dragstart"});this._setupHelperStyle(t),this.option.start&&this.option.start(n,this.ui()),this.triggerEvent("dragstart",n)}return t.preventDefault(),!0}_mouseUp(t){var e;if(document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),r.isTouch&&(this.dragEl.removeEventListener("touchmove",r.touchmove,!0),this.dragEl.removeEventListener("touchend",r.touchend,!0)),this.dragging){delete this.dragging,(null===(e=s.DDManager.dropElement)||void 0===e?void 0:e.el)===this.el.parentElement&&delete s.DDManager.dropElement,this.helperContainment.style.position=this.parentOriginStylePosition||null,this.helper===this.el?this._removeHelperStyle():this.helper.remove();const i=o.Utils.initEvent(t,{target:this.el,type:"dragstop"});this.option.stop&&this.option.stop(i),this.triggerEvent("dragstop",i),s.DDManager.dropElement&&s.DDManager.dropElement.drop(t)}delete this.helper,delete this.mouseDownEvent,delete s.DDManager.dragElement,delete s.DDManager.dropElement,delete s.DDManager.mouseHandled,t.preventDefault()}_createHelper(t){let e=this.el;return"function"==typeof this.option.helper?e=this.option.helper(t):"clone"===this.option.helper&&(e=o.Utils.cloneNode(this.el)),document.body.contains(e)||o.Utils.appendTo(e,"parent"===this.option.appendTo?this.el.parentNode:this.option.appendTo),e===this.el&&(this.dragElementOriginStyle=l.originStyleProp.map((t=>this.el.style[t]))),e}_setupHelperStyle(t){this.helper.classList.add("ui-draggable-dragging");const e=this.helper.style;return e.pointerEvents="none",e["min-width"]=0,e.width=this.dragOffset.width+"px",e.height=this.dragOffset.height+"px",e.willChange="left, top",e.position="fixed",this._dragFollow(t),e.transition="none",setTimeout((()=>{this.helper&&(e.transition=null)}),0),this}_removeHelperStyle(){var t;this.helper.classList.remove("ui-draggable-dragging");let e=null===(t=this.helper)||void 0===t?void 0:t.gridstackNode;if(this.dragElementOriginStyle&&(!e||!e._isAboutToRemove)){let t=this.helper,e=this.dragElementOriginStyle.transition||null;t.style.transition=this.dragElementOriginStyle.transition="none",l.originStyleProp.forEach((e=>t.style[e]=this.dragElementOriginStyle[e]||null)),setTimeout((()=>t.style.transition=e),50)}return delete this.dragElementOriginStyle,this}_dragFollow(t){const e=this.helper.style,i=this.dragOffset;e.left=t.clientX+i.offsetLeft-0+"px",e.top=t.clientY+i.offsetTop-0+"px"}_setupHelperContainmentStyle(){return this.helperContainment=this.helper.parentElement,"fixed"!==this.helper.style.position&&(this.parentOriginStylePosition=this.helperContainment.style.position,window.getComputedStyle(this.helperContainment).position.match(/static/)&&(this.helperContainment.style.position="relative")),this}_getDragOffset(t,e,i){let s=0,n=0;if(i){const t=document.createElement("div");o.Utils.addElStyles(t,{opacity:"0",position:"fixed",top:"0px",left:"0px",width:"1px",height:"1px",zIndex:"-999999"}),i.appendChild(t);const e=t.getBoundingClientRect();i.removeChild(t),s=e.left,n=e.top}const r=e.getBoundingClientRect();return{left:r.left,top:r.top,offsetLeft:-t.clientX+r.left-s,offsetTop:-t.clientY+r.top-n,width:r.width,height:r.height}}ui(){const t=this.el.parentElement.getBoundingClientRect(),e=this.helper.getBoundingClientRect();return{position:{top:e.top-t.top,left:e.left-t.left}}}}e.DDDraggable=l,l.originStyleProp=["transition","pointerEvents","position","left","top"]},225:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDDroppable=void 0;const s=i(939),o=i(427),n=i(593),r=i(635);class l extends o.DDBaseImplement{constructor(t,e={}){super(),this.el=t,this.option=e,this._mouseEnter=this._mouseEnter.bind(this),this._mouseLeave=this._mouseLeave.bind(this),this.enable(),this._setupAccept()}on(t,e){super.on(t,e)}off(t){super.off(t)}enable(){!1!==this.disabled&&(super.enable(),this.el.classList.add("ui-droppable"),this.el.classList.remove("ui-droppable-disabled"),this.el.addEventListener("mouseenter",this._mouseEnter),this.el.addEventListener("mouseleave",this._mouseLeave),r.isTouch&&(this.el.addEventListener("pointerenter",r.pointerenter),this.el.addEventListener("pointerleave",r.pointerleave)))}disable(t=!1){!0!==this.disabled&&(super.disable(),this.el.classList.remove("ui-droppable"),t||this.el.classList.add("ui-droppable-disabled"),this.el.removeEventListener("mouseenter",this._mouseEnter),this.el.removeEventListener("mouseleave",this._mouseLeave),r.isTouch&&(this.el.removeEventListener("pointerenter",r.pointerenter),this.el.removeEventListener("pointerleave",r.pointerleave)))}destroy(){this.disable(!0),this.el.classList.remove("ui-droppable"),this.el.classList.remove("ui-droppable-disabled"),super.destroy()}updateOption(t){return Object.keys(t).forEach((e=>this.option[e]=t[e])),this._setupAccept(),this}_mouseEnter(t){if(!s.DDManager.dragElement)return;if(!this._canDrop())return;t.preventDefault(),t.stopPropagation(),s.DDManager.dropElement&&s.DDManager.dropElement!==this&&s.DDManager.dropElement._mouseLeave(t),s.DDManager.dropElement=this;const e=n.Utils.initEvent(t,{target:this.el,type:"dropover"});this.option.over&&this.option.over(e,this._ui(s.DDManager.dragElement)),this.triggerEvent("dropover",e),this.el.classList.add("ui-droppable-over")}_mouseLeave(t){var e;if(!s.DDManager.dragElement||s.DDManager.dropElement!==this)return;t.preventDefault(),t.stopPropagation();const i=n.Utils.initEvent(t,{target:this.el,type:"dropout"});if(this.option.out&&this.option.out(i,this._ui(s.DDManager.dragElement)),this.triggerEvent("dropout",i),s.DDManager.dropElement===this){let i;delete s.DDManager.dropElement;let o=this.el.parentElement;for(;!i&&o;)i=null===(e=o.ddElement)||void 0===e?void 0:e.ddDroppable,o=o.parentElement;i&&i._mouseEnter(t)}}drop(t){t.preventDefault();const e=n.Utils.initEvent(t,{target:this.el,type:"drop"});this.option.drop&&this.option.drop(e,this._ui(s.DDManager.dragElement)),this.triggerEvent("drop",e)}_canDrop(){return s.DDManager.dragElement&&(!this.accept||this.accept(s.DDManager.dragElement.el))}_setupAccept(){return this.option.accept?("string"==typeof this.option.accept?this.accept=t=>t.matches(this.option.accept):this.accept=this.option.accept,this):this}_ui(t){return Object.assign({draggable:t.el},t.ui())}}e.DDDroppable=l},320:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDElement=void 0;const s=i(204),o=i(186),n=i(225);class r{constructor(t){this.el=t}static init(t){return t.ddElement||(t.ddElement=new r(t)),t.ddElement}on(t,e){return this.ddDraggable&&["drag","dragstart","dragstop"].indexOf(t)>-1?this.ddDraggable.on(t,e):this.ddDroppable&&["drop","dropover","dropout"].indexOf(t)>-1?this.ddDroppable.on(t,e):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(t)>-1&&this.ddResizable.on(t,e),this}off(t){return this.ddDraggable&&["drag","dragstart","dragstop"].indexOf(t)>-1?this.ddDraggable.off(t):this.ddDroppable&&["drop","dropover","dropout"].indexOf(t)>-1?this.ddDroppable.off(t):this.ddResizable&&["resizestart","resize","resizestop"].indexOf(t)>-1&&this.ddResizable.off(t),this}setupDraggable(t){return this.ddDraggable?this.ddDraggable.updateOption(t):this.ddDraggable=new o.DDDraggable(this.el,t),this}cleanDraggable(){return this.ddDraggable&&(this.ddDraggable.destroy(),delete this.ddDraggable),this}setupResizable(t){return this.ddResizable?this.ddResizable.updateOption(t):this.ddResizable=new s.DDResizable(this.el,t),this}cleanResizable(){return this.ddResizable&&(this.ddResizable.destroy(),delete this.ddResizable),this}setupDroppable(t){return this.ddDroppable?this.ddDroppable.updateOption(t):this.ddDroppable=new n.DDDroppable(this.el,t),this}cleanDroppable(){return this.ddDroppable&&(this.ddDroppable.destroy(),delete this.ddDroppable),this}}e.DDElement=r},958:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDGridStack=void 0;const s=i(270),o=i(593),n=i(939),r=i(320);class l{static get(){return a}resizable(t,e,i,s){return this._getDDElements(t).forEach((t=>{if("disable"===e||"enable"===e)t.ddResizable&&t.ddResizable[e]();else if("destroy"===e)t.ddResizable&&t.cleanResizable();else if("option"===e)t.setupResizable({[i]:s});else{const i=t.el.gridstackNode.grid;let s=t.el.getAttribute("gs-resize-handles")?t.el.getAttribute("gs-resize-handles"):i.opts.resizable.handles,o=!i.opts.alwaysShowResizeHandle,n=t.el.getAttribute("gs-fixed-aspect-ratio")?parseFloat(t.el.getAttribute("gs-fixed-aspect-ratio")):void 0;t.setupResizable(Object.assign(Object.assign(Object.assign({},i.opts.resizable),{handles:s,autoHide:o}),{start:e.start,stop:e.stop,resize:e.resize,fixedAspectRatio:n}))}})),this}draggable(t,e,i,s){return this._getDDElements(t).forEach((t=>{if("disable"===e||"enable"===e)t.ddDraggable&&t.ddDraggable[e]();else if("destroy"===e)t.ddDraggable&&t.cleanDraggable();else if("option"===e)t.setupDraggable({[i]:s});else{const i=t.el.gridstackNode.grid;t.setupDraggable(Object.assign(Object.assign({},i.opts.draggable),{start:e.start,stop:e.stop,drag:e.drag}))}})),this}dragIn(t,e){return this._getDDElements(t).forEach((t=>t.setupDraggable(e))),this}droppable(t,e,i,s){return"function"!=typeof e.accept||e._accept||(e._accept=e.accept,e.accept=t=>e._accept(t)),this._getDDElements(t).forEach((t=>{"disable"===e||"enable"===e?t.ddDroppable&&t.ddDroppable[e]():"destroy"===e?t.ddDroppable&&t.cleanDroppable():"option"===e?t.setupDroppable({[i]:s}):t.setupDroppable(e)})),this}isDroppable(t){return!(!(t&&t.ddElement&&t.ddElement.ddDroppable)||t.ddElement.ddDroppable.disabled)}isDraggable(t){return!(!(t&&t.ddElement&&t.ddElement.ddDraggable)||t.ddElement.ddDraggable.disabled)}isResizable(t){return!(!(t&&t.ddElement&&t.ddElement.ddResizable)||t.ddElement.ddResizable.disabled)}on(t,e,i){return this._getDDElements(t).forEach((t=>t.on(e,(t=>{i(t,n.DDManager.dragElement?n.DDManager.dragElement.el:t.target,n.DDManager.dragElement?n.DDManager.dragElement.helper:null)})))),this}off(t,e){return this._getDDElements(t).forEach((t=>t.off(e))),this}_getDDElements(t,e=!0){let i=o.Utils.getElements(t);if(!i.length)return[];let s=i.map((t=>t.ddElement||(e?r.DDElement.init(t):null)));return e||s.filter((t=>t)),s}}e.DDGridStack=l;const a=new l;function h(t,e){let i=t?t.gridstackNode:void 0;i&&i.grid&&(e?i._isAboutToRemove=!0:delete i._isAboutToRemove,e?t.classList.add("grid-stack-item-removing"):t.classList.remove("grid-stack-item-removing"))}s.GridStack.prototype._setupAcceptWidget=function(){if(this.opts.staticGrid||!this.opts.acceptWidgets&&!this.opts.removable)return a.droppable(this.el,"destroy"),this;let t,e,i=(i,s,n)=>{let r=s.gridstackNode;if(!r)return;n=n||s;let l=this.el.getBoundingClientRect(),{top:h,left:d}=n.getBoundingClientRect();d-=l.left,h-=l.top;let g={position:{top:h,left:d}};if(r._temporaryRemoved){if(r.x=Math.max(0,Math.round(d/e)),r.y=Math.max(0,Math.round(h/t)),delete r.autoPosition,this.engine.nodeBoundFix(r),!this.engine.willItFit(r)){if(r.autoPosition=!0,!this.engine.willItFit(r))return void a.off(s,"drag");r._willFitPos&&(o.Utils.copyPos(r,r._willFitPos),delete r._willFitPos)}this._onStartMoving(n,i,g,r,e,t)}else this._dragOrResize(n,i,g,r,e,t)};return a.droppable(this.el,{accept:t=>{let e=t.gridstackNode;if((null==e?void 0:e.grid)===this)return!0;if(!this.opts.acceptWidgets)return!1;if(null==e?void 0:e.subGrid)return!1;let i=!0;if("function"==typeof this.opts.acceptWidgets)i=this.opts.acceptWidgets(t);else{let e=!0===this.opts.acceptWidgets?".grid-stack-item":this.opts.acceptWidgets;i=t.matches(e)}if(i&&e&&this.opts.maxRow){let t={w:e.w,h:e.h,minW:e.minW,minH:e.minH};i=this.engine.willItFit(t)}return i}}).on(this.el,"dropover",((s,o,n)=>{let r=o.gridstackNode;if((null==r?void 0:r.grid)===this&&!r._temporaryRemoved)return!1;(null==r?void 0:r.grid)&&r.grid!==this&&!r._temporaryRemoved&&r.grid._leave(o,n),e=this.cellWidth(),t=this.getCellHeight(!0),r||(r=this._readAttr(o)),r.grid||(r._isExternal=!0,o.gridstackNode=r),n=n||o;let l=r.w||Math.round(n.offsetWidth/e)||1,d=r.h||Math.round(n.offsetHeight/t)||1;return r.grid&&r.grid!==this?(o._gridstackNodeOrig||(o._gridstackNodeOrig=r),o.gridstackNode=r=Object.assign(Object.assign({},r),{w:l,h:d,grid:this}),this.engine.cleanupNode(r).nodeBoundFix(r),r._initDD=r._isExternal=r._temporaryRemoved=!0):(r.w=l,r.h=d,r._temporaryRemoved=!0),h(r.el,!1),a.on(o,"drag",i),i(s,o,n),!1})).on(this.el,"dropout",((t,e,i)=>{let s=e.gridstackNode;return!!s&&(s.grid&&s.grid!==this||this._leave(e,i),!1)})).on(this.el,"drop",((t,e,i)=>{let s=e.gridstackNode;if((null==s?void 0:s.grid)===this&&!s._isExternal)return!1;let n=!!this.placeholder.parentElement;this.placeholder.remove();let r=e._gridstackNodeOrig;if(delete e._gridstackNodeOrig,n&&r&&r.grid&&r.grid!==this){let t=r.grid;t.engine.removedNodes.push(r),t._triggerRemoveEvent()}return!!s&&(n&&(this.engine.cleanupNode(s),s.grid=this),a.off(e,"drag"),i!==e?(i.remove(),e.gridstackNode=r,n&&(e=e.cloneNode(!0))):(e.remove(),this._removeDD(e)),!!n&&(e.gridstackNode=s,s.el=e,o.Utils.copyPos(s,this._readAttr(this.placeholder)),o.Utils.removePositioningStyles(e),this._writeAttr(e,s),this.el.appendChild(e),this._updateContainerHeight(),this.engine.addedNodes.push(s),this._triggerAddEvent(),this._triggerChangeEvent(),this.engine.endUpdate(),this._gsEventHandler.dropped&&this._gsEventHandler.dropped(Object.assign(Object.assign({},t),{type:"dropped"}),r&&r.grid?r:void 0,s),window.setTimeout((()=>{s.el&&s.el.parentElement?this._prepareDragDropByNode(s):this.engine.removeNode(s)})),!1))})),this},s.GridStack.prototype._setupRemoveDrop=function(){if(!this.opts.staticGrid&&"string"==typeof this.opts.removable){let t=document.querySelector(this.opts.removable);if(!t)return this;a.isDroppable(t)||a.droppable(t,this.opts.removableOptions).on(t,"dropover",((t,e)=>h(e,!0))).on(t,"dropout",((t,e)=>h(e,!1)))}return this},s.GridStack.setupDragIn=function(t,e){let i,s;t&&(i=t,s=Object.assign(Object.assign({},{handle:".grid-stack-item-content",appendTo:"body"}),e||{})),"string"==typeof i&&o.Utils.getElements(i).forEach((t=>{a.isDraggable(t)||a.dragIn(t,s)}))},s.GridStack.prototype._prepareDragDropByNode=function(t){let e=t.el;const i=t.noMove||this.opts.disableDrag,s=t.noResize||this.opts.disableResize;if(this.opts.staticGrid||i&&s)return t._initDD&&(this._removeDD(e),delete t._initDD),e.classList.add("ui-draggable-disabled","ui-resizable-disabled"),this;if(!t._initDD){let i,s,n=(o,n)=>{this._gsEventHandler[o.type]&&this._gsEventHandler[o.type](o,o.target),i=this.cellWidth(),s=this.getCellHeight(!0),this._onStartMoving(e,o,n,t,i,s)},r=(o,n)=>{this._dragOrResize(e,o,n,t,i,s)},l=i=>{this.placeholder.remove(),delete t._moving,delete t._lastTried;let s=i.target;if(s.gridstackNode&&s.gridstackNode.grid===this){if(t.el=s,t._isAboutToRemove){let o=e.gridstackNode.grid;o._gsEventHandler[i.type]&&o._gsEventHandler[i.type](i,s),this._removeDD(e),o.engine.removedNodes.push(t),o._triggerRemoveEvent(),delete e.gridstackNode,delete t.el,e.remove()}else o.Utils.removePositioningStyles(s),t._temporaryRemoved?(o.Utils.copyPos(t,t._orig),this._writePosAttr(s,t),this.engine.addNode(t)):this._writePosAttr(s,t),this._gsEventHandler[i.type]&&this._gsEventHandler[i.type](i,s);this._extraDragRow=0,this._updateContainerHeight(),this._triggerChangeEvent(),this.engine.endUpdate()}};a.draggable(e,{start:n,stop:l,drag:r}).resizable(e,{start:n,stop:l,resize:r}),t._initDD=!0}return a.draggable(e,i?"disable":"enable").resizable(e,s?"disable":"enable"),this},s.GridStack.prototype._onStartMoving=function(t,e,i,s,o,n){this.engine.cleanNodes().beginUpdate(s),this._writePosAttr(this.placeholder,s),this.el.appendChild(this.placeholder),s.el=this.placeholder,s._lastUiPosition=i.position,s._prevYPix=i.position.top,s._moving="dragstart"===e.type,delete s._lastTried,"dropover"===e.type&&s._temporaryRemoved&&(this.engine.addNode(s),s._moving=!0),this.engine.cacheRects(o,n,this.opts.marginTop,this.opts.marginRight,this.opts.marginBottom,this.opts.marginLeft),"resizestart"===e.type&&(a.resizable(t,"option","minWidth",o*(s.minW||1)).resizable(t,"option","minHeight",n*(s.minH||1)),s.maxW&&a.resizable(t,"option","maxWidth",o*s.maxW),s.maxH&&a.resizable(t,"option","maxHeight",n*s.maxH))},s.GridStack.prototype._leave=function(t,e){let i=t.gridstackNode;i&&(a.off(t,"drag"),i._temporaryRemoved||(i._temporaryRemoved=!0,this.engine.removeNode(i),i.el=i._isExternal&&e?e:t,!0===this.opts.removable&&h(t,!0),t._gridstackNodeOrig?(t.gridstackNode=t._gridstackNodeOrig,delete t._gridstackNodeOrig):i._isExternal&&(delete i.el,delete t.gridstackNode,this.engine.restoreInitial())))},s.GridStack.prototype._dragOrResize=function(t,e,i,s,n,r){let l,a=Object.assign({},s._orig),h=this.opts.marginLeft,d=this.opts.marginRight,g=this.opts.marginTop,p=this.opts.marginBottom,u=Math.round(.1*r),c=Math.round(.1*n);if(h=Math.min(h,c),d=Math.min(d,c),g=Math.min(g,u),p=Math.min(p,u),"drag"===e.type){if(s._temporaryRemoved)return;let e=i.position.top-s._prevYPix;s._prevYPix=i.position.top,o.Utils.updateScrollPosition(t,i.position,e);let l=i.position.left+(i.position.left>s._lastUiPosition.left?-d:h),u=i.position.top+(i.position.top>s._lastUiPosition.top?-p:g);a.x=Math.round(l/n),a.y=Math.round(u/r);let c=this._extraDragRow;if(this.engine.collide(s,a)){let t=this.getRow(),e=Math.max(0,a.y+s.h-t);this.opts.maxRow&&t+e>this.opts.maxRow&&(e=Math.max(0,this.opts.maxRow-t)),this._extraDragRow=e}else this._extraDragRow=0;if(this._extraDragRow!==c&&this._updateContainerHeight(),s.x===a.x&&s.y===a.y)return}else if("resize"===e.type){if(a.x<0)return;if(o.Utils.updateScrollResize(e,t,r),a.w=Math.round((i.size.width-h)/n),a.h=Math.round((i.size.height-g)/r),s.w===a.w&&s.h===a.h)return;if(s._lastTried&&s._lastTried.w===a.w&&s._lastTried.h===a.h)return;let d=i.position.left+h,p=i.position.top+g;a.x=Math.round(d/n),a.y=Math.round(p/r),l=!0}s._lastTried=a;let m={x:i.position.left+h,y:i.position.top+g,w:(i.size?i.size.width:s.w*n)-h-d,h:(i.size?i.size.height:s.h*r)-g-p};if(this.engine.moveNodeCheck(s,Object.assign(Object.assign({},a),{cellWidth:n,cellHeight:r,rect:m,resizing:l}))){s._lastUiPosition=i.position,this.engine.cacheRects(n,r,g,d,p,h),delete s._skipDown,l&&s.subGrid&&s.subGrid.onParentResize(),this._extraDragRow=0,this._updateContainerHeight();let t=e.target;this._writePosAttr(t,s),this._gsEventHandler[e.type]&&this._gsEventHandler[e.type](e,t)}},s.GridStack.prototype.movable=function(t,e){return this.opts.staticGrid||s.GridStack.getElements(t).forEach((t=>{let i=t.gridstackNode;i&&(e?delete i.noMove:i.noMove=!0,this._prepareDragDropByNode(i))})),this},s.GridStack.prototype.resizable=function(t,e){return this.opts.staticGrid||s.GridStack.getElements(t).forEach((t=>{let i=t.gridstackNode;i&&(e?delete i.noResize:i.noResize=!0,this._prepareDragDropByNode(i))})),this},s.GridStack.prototype.disable=function(){if(!this.opts.staticGrid)return this.enableMove(!1),this.enableResize(!1),this._triggerEvent("disable"),this},s.GridStack.prototype.enable=function(){if(!this.opts.staticGrid)return this.enableMove(!0),this.enableResize(!0),this._triggerEvent("enable"),this},s.GridStack.prototype.enableMove=function(t){return this.opts.staticGrid||(this.opts.disableDrag=!t,this.engine.nodes.forEach((e=>this.movable(e.el,t)))),this},s.GridStack.prototype.enableResize=function(t){return this.opts.staticGrid||(this.opts.disableResize=!t,this.engine.nodes.forEach((e=>this.resizable(e.el,t)))),this},s.GridStack.prototype._removeDD=function(t){return a.draggable(t,"destroy").resizable(t,"destroy"),t.gridstackNode&&delete t.gridstackNode._initDD,this}},939:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDManager=void 0,e.DDManager=class{}},41:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDResizableHandle=void 0;const s=i(635);class o{constructor(t,e,i){this.moving=!1,this.host=t,this.dir=e,this.option=i,this._mouseDown=this._mouseDown.bind(this),this._mouseMove=this._mouseMove.bind(this),this._mouseUp=this._mouseUp.bind(this),this._init()}_init(){const t=document.createElement("div");return t.classList.add("ui-resizable-handle"),t.classList.add(`${o.prefix}${this.dir}`),t.style.zIndex="100",t.style.userSelect="none",this.el=t,this.host.appendChild(this.el),this.el.addEventListener("mousedown",this._mouseDown),s.isTouch&&(this.el.addEventListener("touchstart",s.touchstart),this.el.addEventListener("pointerdown",s.pointerdown)),this}destroy(){return this.moving&&this._mouseUp(this.mouseDownEvent),this.el.removeEventListener("mousedown",this._mouseDown),s.isTouch&&(this.el.removeEventListener("touchstart",s.touchstart),this.el.removeEventListener("pointerdown",s.pointerdown)),this.host.removeChild(this.el),delete this.el,delete this.host,this}_mouseDown(t){this.mouseDownEvent=t,document.addEventListener("mousemove",this._mouseMove,!0),document.addEventListener("mouseup",this._mouseUp,!0),s.isTouch&&(this.el.addEventListener("touchmove",s.touchmove),this.el.addEventListener("touchend",s.touchend)),t.stopPropagation(),t.preventDefault()}_mouseMove(t){let e=this.mouseDownEvent;this.moving?this._triggerEvent("move",t):Math.abs(t.x-e.x)+Math.abs(t.y-e.y)>2&&(this.moving=!0,this._triggerEvent("start",this.mouseDownEvent),this._triggerEvent("move",t)),t.stopPropagation(),t.preventDefault()}_mouseUp(t){this.moving&&this._triggerEvent("stop",t),document.removeEventListener("mousemove",this._mouseMove,!0),document.removeEventListener("mouseup",this._mouseUp,!0),s.isTouch&&(this.el.removeEventListener("touchmove",s.touchmove),this.el.removeEventListener("touchend",s.touchend)),delete this.moving,delete this.mouseDownEvent,t.stopPropagation(),t.preventDefault()}_triggerEvent(t,e){return this.option[t]&&this.option[t](e),this}}e.DDResizableHandle=o,o.prefix="ui-resizable-"},204:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.DDResizable=void 0;const s=i(41),o=i(427),n=i(593),r=i(939);class l extends o.DDBaseImplement{constructor(t,e={}){super(),this._ui=()=>{const t=this.el.parentElement.getBoundingClientRect(),e={width:this.originalRect.width,height:this.originalRect.height+this.scrolled,left:this.originalRect.left,top:this.originalRect.top-this.scrolled},i=this.temporalRect||e;return{position:{left:i.left-t.left,top:i.top-t.top},size:{width:i.width,height:i.height}}},this.el=t,this.option=e,this._mouseOver=this._mouseOver.bind(this),this._mouseOut=this._mouseOut.bind(this),this.enable(),this._setupAutoHide(this.option.autoHide),this._setupHandlers()}on(t,e){super.on(t,e)}off(t){super.off(t)}enable(){super.enable(),this.el.classList.add("ui-resizable"),this.el.classList.remove("ui-resizable-disabled"),this._setupAutoHide(this.option.autoHide)}disable(){super.disable(),this.el.classList.add("ui-resizable-disabled"),this.el.classList.remove("ui-resizable"),this._setupAutoHide(!1)}destroy(){this._removeHandlers(),this._setupAutoHide(!1),this.el.classList.remove("ui-resizable"),delete this.el,super.destroy()}updateOption(t){let e=t.handles&&t.handles!==this.option.handles,i=t.autoHide&&t.autoHide!==this.option.autoHide;return Object.keys(t).forEach((e=>this.option[e]=t[e])),e&&(this._removeHandlers(),this._setupHandlers()),i&&this._setupAutoHide(this.option.autoHide),this}_setupAutoHide(t){return t?(this.el.classList.add("ui-resizable-autohide"),this.el.addEventListener("mouseover",this._mouseOver),this.el.addEventListener("mouseout",this._mouseOut)):(this.el.classList.remove("ui-resizable-autohide"),this.el.removeEventListener("mouseover",this._mouseOver),this.el.removeEventListener("mouseout",this._mouseOut),r.DDManager.overResizeElement===this&&delete r.DDManager.overResizeElement),this}_mouseOver(t){r.DDManager.overResizeElement||r.DDManager.dragElement||(r.DDManager.overResizeElement=this,this.el.classList.remove("ui-resizable-autohide"))}_mouseOut(t){r.DDManager.overResizeElement===this&&(delete r.DDManager.overResizeElement,this.el.classList.add("ui-resizable-autohide"))}_setupHandlers(){let t=this.option.handles||"e,s,se";return"all"===t&&(t="n,e,s,w,se,sw,ne,nw"),this.handlers=t.split(",").map((t=>t.trim())).map((t=>new s.DDResizableHandle(this.el,t,{start:t=>{this._resizeStart(t)},stop:t=>{this._resizeStop(t)},move:e=>{this._resizing(e,t)}}))),this}_resizeStart(t){this.originalRect=this.el.getBoundingClientRect(),this.scrollEl=n.Utils.getScrollElement(this.el),this.scrollY=this.scrollEl.scrollTop,this.scrolled=0,this.startEvent=t,this._setupHelper(),this._applyChange();const e=n.Utils.initEvent(t,{type:"resizestart",target:this.el});return this.option.start&&this.option.start(e,this._ui()),this.el.classList.add("ui-resizable-resizing"),this.triggerEvent("resizestart",e),this}_resizing(t,e){this.scrolled=this.scrollEl.scrollTop-this.scrollY,this.temporalRect=this._getChange(t,e,this.option.fixedAspectRatio),this._applyChange();const i=n.Utils.initEvent(t,{type:"resize",target:this.el});return this.option.resize&&this.option.resize(i,this._ui()),this.triggerEvent("resize",i),this}_resizeStop(t){const e=n.Utils.initEvent(t,{type:"resizestop",target:this.el});return this.option.stop&&this.option.stop(e),this.el.classList.remove("ui-resizable-resizing"),this.triggerEvent("resizestop",e),this._cleanHelper(),delete this.startEvent,delete this.originalRect,delete this.temporalRect,delete this.scrollY,delete this.scrolled,this}_setupHelper(){return this.elOriginStyleVal=l._originStyleProp.map((t=>this.el.style[t])),this.parentOriginStylePosition=this.el.parentElement.style.position,window.getComputedStyle(this.el.parentElement).position.match(/static/)&&(this.el.parentElement.style.position="relative"),this.el.style.position="absolute",this.el.style.opacity="0.8",this}_cleanHelper(){return l._originStyleProp.forEach(((t,e)=>{this.el.style[t]=this.elOriginStyleVal[e]||null})),this.el.parentElement.style.position=this.parentOriginStylePosition||null,this}_getChange(t,e,i){const s=void 0!==i&&0!=i&&!isNaN(i)&&isFinite(i),o=this.startEvent,n={width:this.originalRect.width,height:this.originalRect.height+(s?0:this.scrolled),left:this.originalRect.left,top:this.originalRect.top-(s?0:this.scrolled)},r=t.clientX-o.clientX,l=t.clientY-o.clientY;s?e.length>1?r>l?e.indexOf("e")>-1?(n.width+=r,n.height+=Math.round(r/i)):e.indexOf("w")>-1&&(n.width-=r,n.left+=r,n.height-=Math.round(r/i),n.top+=Math.round(r/i)):e.indexOf("s")>-1?(n.height+=l,n.width+=Math.round(l*i)):e.indexOf("n")>-1&&(n.height-=l,n.top+=l,n.width-=Math.round(l*i),n.left+=Math.round(l*i)):(e.indexOf("e")>-1?(n.width+=r,n.height+=Math.round(r/i)):e.indexOf("w")>-1&&(n.width-=r,n.left+=r,n.height-=Math.round(r/i),n.top+=Math.round(r/i)),e.indexOf("s")>-1?(n.height+=l,n.width+=Math.round(l*i)):e.indexOf("n")>-1&&(n.height-=l,n.top+=l,n.width-=Math.round(l*i),n.left+=Math.round(l*i))):(e.indexOf("e")>-1?n.width+=r:e.indexOf("w")>-1&&(n.width-=r,n.left+=r),e.indexOf("s")>-1?n.height+=l:e.indexOf("n")>-1&&(n.height-=l,n.top+=l));const a=this._constrainSize(n.width,n.height);return Math.round(n.width)!==Math.round(a.width)&&(e.indexOf("w")>-1&&(n.left+=n.width-a.width),n.width=a.width),Math.round(n.height)!==Math.round(a.height)&&(e.indexOf("n")>-1&&(n.top+=n.height-a.height),n.height=a.height),n}_constrainSize(t,e){const i=this.option.maxWidth||Number.MAX_SAFE_INTEGER,s=this.option.minWidth||t,o=this.option.maxHeight||Number.MAX_SAFE_INTEGER,n=this.option.minHeight||e;return{width:Math.min(i,Math.max(s,t)),height:Math.min(o,Math.max(n,e))}}_applyChange(){let t={left:0,top:0,width:0,height:0};if("absolute"===this.el.style.position){const e=this.el.parentElement,{left:i,top:s}=e.getBoundingClientRect();t={left:i,top:s,width:0,height:0}}return this.temporalRect?(Object.keys(this.temporalRect).forEach((e=>{const i=this.temporalRect[e];this.el.style[e]=i-t[e]+"px"})),this):this}_removeHandlers(){return this.handlers.forEach((t=>t.destroy())),delete this.handlers,this}}e.DDResizable=l,l._originStyleProp=["width","height","position","left","top","opacity","zIndex"]},635:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.pointerleave=e.pointerenter=e.pointerdown=e.touchend=e.touchmove=e.touchstart=e.isTouch=void 0;const s=i(939);e.isTouch="ontouchstart"in document||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0;class o{}function n(t,e){if(t.touches.length>1)return;t.cancelable&&t.preventDefault();const i=t.changedTouches[0],s=document.createEvent("MouseEvents");s.initMouseEvent(e,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),t.target.dispatchEvent(s)}function r(t,e){t.cancelable&&t.preventDefault();const i=document.createEvent("MouseEvents");i.initMouseEvent(e,!0,!0,window,1,t.screenX,t.screenY,t.clientX,t.clientY,!1,!1,!1,!1,0,null),t.target.dispatchEvent(i)}e.touchstart=function(t){o.touchHandled||(o.touchHandled=!0,n(t,"mousedown"))},e.touchmove=function(t){o.touchHandled&&n(t,"mousemove")},e.touchend=function(t){if(!o.touchHandled)return;o.pointerLeaveTimeout&&(window.clearTimeout(o.pointerLeaveTimeout),delete o.pointerLeaveTimeout);const e=!!s.DDManager.dragElement;n(t,"mouseup"),e||n(t,"click"),o.touchHandled=!1},e.pointerdown=function(t){t.target.releasePointerCapture(t.pointerId)},e.pointerenter=function(t){s.DDManager.dragElement&&r(t,"mouseenter")},e.pointerleave=function(t){s.DDManager.dragElement&&(o.pointerLeaveTimeout=window.setTimeout((()=>{delete o.pointerLeaveTimeout,r(t,"mouseleave")}),10))}},62:(t,e,i)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.GridStackEngine=void 0;const s=i(593);class o{constructor(t={}){this.addedNodes=[],this.removedNodes=[],this.column=t.column||12,this.maxRow=t.maxRow,this._float=t.float,this.nodes=t.nodes||[],this.onChange=t.onChange}batchUpdate(t=!0){return!!this.batchMode===t||(this.batchMode=t,t?(this._prevFloat=this._float,this._float=!0,this.saveInitial()):(this._float=this._prevFloat,delete this._prevFloat,this._packNodes()._notify())),this}_useEntireRowArea(t,e){return!this.float&&!this._hasLocked&&(!t._moving||t._skipDown||e.y<=t.y)}_fixCollisions(t,e=t,i,o={}){if(this.sortNodes(-1),!(i=i||this.collide(t,e)))return!1;if(t._moving&&!o.nested&&!this.float&&this.swap(t,i))return!0;let n=e;this._useEntireRowArea(t,e)&&(n={x:0,w:this.column,y:e.y,h:e.h},i=this.collide(t,n,o.skip));let r=!1,l={nested:!0,pack:!1};for(;i=i||this.collide(t,n,o.skip);){let n;if(i.locked||t._moving&&!t._skipDown&&e.y>t.y&&!this.float&&(!this.collide(i,Object.assign(Object.assign({},i),{y:t.y}),t)||!this.collide(i,Object.assign(Object.assign({},i),{y:e.y-i.h}),t))?(t._skipDown=t._skipDown||e.y>t.y,n=this.moveNode(t,Object.assign(Object.assign(Object.assign({},e),{y:i.y+i.h}),l)),i.locked&&n?s.Utils.copyPos(e,t):!i.locked&&n&&o.pack&&(this._packNodes(),e.y=i.y+i.h,s.Utils.copyPos(t,e)),r=r||n):n=this.moveNode(i,Object.assign(Object.assign(Object.assign({},i),{y:e.y+e.h,skip:t}),l)),!n)return r;i=void 0}return r}collide(t,e=t,i){return this.nodes.find((o=>o!==t&&o!==i&&s.Utils.isIntercepted(o,e)))}collideAll(t,e=t,i){return this.nodes.filter((o=>o!==t&&o!==i&&s.Utils.isIntercepted(o,e)))}collideCoverage(t,e,i){if(!e.rect||!t._rect)return;let s,o=t._rect,n=Object.assign({},e.rect);return n.y>o.y?(n.h+=n.y-o.y,n.y=o.y):n.h+=o.y-n.y,n.x>o.x?(n.w+=n.x-o.x,n.x=o.x):n.w+=o.x-n.x,i.forEach((t=>{if(t.locked||!t._rect)return;let e=t._rect,i=Number.MAX_VALUE,r=Number.MAX_VALUE,l=.5;o.ye.y+e.h&&(i=(e.y+e.h-n.y)/e.h),o.xe.x+e.w&&(r=(e.x+e.w-n.x)/e.w);let a=Math.min(r,i);a>l&&(l=a,s=t)})),s}cacheRects(t,e,i,s,o,n){return this.nodes.forEach((r=>r._rect={y:r.y*e+i,x:r.x*t+n,w:r.w*t-n-s,h:r.h*e-i-o})),this}swap(t,e){if(!e||e.locked||!t||t.locked)return!1;function i(){let i=e.x,s=e.y;return e.x=t.x,e.y=t.y,t.h!=e.h?(t.x=i,t.y=e.y+e.h):t.w!=e.w?(t.x=e.x+e.w,t.y=s):(t.x=i,t.y=s),t._dirty=e._dirty=!0,!0}let o;if(t.w===e.w&&t.h===e.h&&(t.x===e.x||t.y===e.y)&&(o=s.Utils.isTouching(t,e)))return i();if(!1!==o){if(t.w===e.w&&t.x===e.x&&(o||(o=s.Utils.isTouching(t,e)))){if(e.y{t.locked||(t.autoPosition=!0),this.addNode(t,!1),t._dirty=!0})),this.batchUpdate(!1)}set float(t){this._float!==t&&(this._float=t||!1,t||this._packNodes()._notify())}get float(){return this._float||!1}sortNodes(t){return this.nodes=s.Utils.sort(this.nodes,t,this.column),this}_packNodes(){return this.batchMode||(this.sortNodes(),this.float?this.nodes.forEach((t=>{if(t._updating||void 0===t._orig||t.y===t._orig.y)return;let e=t.y;for(;e>t._orig.y;)--e,this.collide(t,{x:t.x,y:e,w:t.w,h:t.h})||(t._dirty=!0,t.y=e)})):this.nodes.forEach(((t,e)=>{if(!t.locked)for(;t.y>0;){let i=0===e?0:t.y-1;if(0!==e&&this.collide(t,{x:t.x,y:i,w:t.w,h:t.h}))break;t._dirty=t.y!==i,t.y=i}}))),this}prepareNode(t,e){(t=t||{})._id=t._id||o._idSeq++,void 0!==t.x&&void 0!==t.y&&null!==t.x&&null!==t.y||(t.autoPosition=!0);let i={x:0,y:0,w:1,h:1};return s.Utils.defaults(t,i),t.autoPosition||delete t.autoPosition,t.noResize||delete t.noResize,t.noMove||delete t.noMove,"string"==typeof t.x&&(t.x=Number(t.x)),"string"==typeof t.y&&(t.y=Number(t.y)),"string"==typeof t.w&&(t.w=Number(t.w)),"string"==typeof t.h&&(t.h=Number(t.h)),isNaN(t.x)&&(t.x=i.x,t.autoPosition=!0),isNaN(t.y)&&(t.y=i.y,t.autoPosition=!0),isNaN(t.w)&&(t.w=i.w),isNaN(t.h)&&(t.h=i.h),this.nodeBoundFix(t,e)}nodeBoundFix(t,e){let i=t._orig||s.Utils.copyPos({},t);return t.maxW&&(t.w=Math.min(t.w,t.maxW)),t.maxH&&(t.h=Math.min(t.h,t.maxH)),t.minW&&t.minW<=this.column&&(t.w=Math.max(t.w,t.minW)),t.minH&&(t.h=Math.max(t.h,t.minH)),t.w>this.column?(this.column<12&&!this._inColumnResize&&(t.w=Math.min(12,t.w),this.cacheOneLayout(t,12)),t.w=this.column):t.w<1&&(t.w=1),this.maxRow&&t.h>this.maxRow?t.h=this.maxRow:t.h<1&&(t.h=1),t.x<0&&(t.x=0),t.y<0&&(t.y=0),t.x+t.w>this.column&&(e?t.w=this.column-t.x:t.x=this.column-t.w),this.maxRow&&t.y+t.h>this.maxRow&&(e?t.h=this.maxRow-t.y:t.y=this.maxRow-t.h),s.Utils.samePos(t,i)||(t._dirty=!0),t}getDirtyNodes(t){return t?this.nodes.filter((t=>t._dirty&&!s.Utils.samePos(t,t._orig))):this.nodes.filter((t=>t._dirty))}_notify(t){if(this.batchMode||!this.onChange)return this;let e=(t||[]).concat(this.getDirtyNodes());return this.onChange(e),this}cleanNodes(){return this.batchMode||this.nodes.forEach((t=>{delete t._dirty,delete t._lastTried})),this}saveInitial(){return this.nodes.forEach((t=>{t._orig=s.Utils.copyPos({},t),delete t._dirty})),this._hasLocked=this.nodes.some((t=>t.locked)),this}restoreInitial(){return this.nodes.forEach((t=>{s.Utils.samePos(t,t._orig)||(s.Utils.copyPos(t,t._orig),t._dirty=!0)})),this._notify(),this}addNode(t,e=!1){let i=this.nodes.find((e=>e._id===t._id));if(i)return i;if(delete(t=this._inColumnResize?this.nodeBoundFix(t):this.prepareNode(t))._temporaryRemoved,delete t._removeDOM,t.autoPosition){this.sortNodes();for(let e=0;;++e){let i=e%this.column,o=Math.floor(e/this.column);if(i+t.w>this.column)continue;let n={x:i,y:o,w:t.w,h:t.h};if(!this.nodes.find((t=>s.Utils.isIntercepted(n,t)))){t.x=i,t.y=o,delete t.autoPosition;break}}}return this.nodes.push(t),e&&this.addedNodes.push(t),this._fixCollisions(t),this.batchMode||this._packNodes()._notify(),t}removeNode(t,e=!0,i=!1){return this.nodes.find((e=>e===t))?(i&&this.removedNodes.push(t),e&&(t._removeDOM=!0),this.nodes=this.nodes.filter((e=>e!==t)),this._packNodes()._notify([t])):this}removeAll(t=!0){return delete this._layouts,0===this.nodes.length?this:(t&&this.nodes.forEach((t=>t._removeDOM=!0)),this.removedNodes=this.nodes,this.nodes=[],this._notify(this.removedNodes))}moveNodeCheck(t,e){if(!this.changedPosConstrain(t,e))return!1;if(e.pack=!0,!this.maxRow)return this.moveNode(t,e);let i,n=new o({column:this.column,float:this.float,nodes:this.nodes.map((e=>e===t?(i=Object.assign({},e),i):Object.assign({},e)))});if(!i)return!1;let r=n.moveNode(i,e)&&n.getRow()<=this.maxRow;if(!r&&!e.resizing){let i=this.collide(t,e);if(i&&this.swap(t,i))return this._notify(),!0}return!!r&&(n.nodes.filter((t=>t._dirty)).forEach((t=>{let e=this.nodes.find((e=>e._id===t._id));e&&(s.Utils.copyPos(e,t),e._dirty=!0)})),this._notify(),!0)}willItFit(t){if(delete t._willFitPos,!this.maxRow)return!0;let e=new o({column:this.column,float:this.float,nodes:this.nodes.map((t=>Object.assign({},t)))}),i=Object.assign({},t);return this.cleanupNode(i),delete i.el,delete i._id,delete i.content,delete i.grid,e.addNode(i),e.getRow()<=this.maxRow&&(t._willFitPos=s.Utils.copyPos({},i),!0)}changedPosConstrain(t,e){return e.w=e.w||t.w,e.h=e.h||t.h,t.x!==e.x||t.y!==e.y||(t.maxW&&(e.w=Math.min(e.w,t.maxW)),t.maxH&&(e.h=Math.min(e.h,t.maxH)),t.minW&&(e.w=Math.max(e.w,t.minW)),t.minH&&(e.h=Math.max(e.h,t.minH)),t.w!==e.w||t.h!==e.h)}moveNode(t,e){if(!t||!e)return!1;void 0===e.pack&&(e.pack=!0),"number"!=typeof e.x&&(e.x=t.x),"number"!=typeof e.y&&(e.y=t.y),"number"!=typeof e.w&&(e.w=t.w),"number"!=typeof e.h&&(e.h=t.h);let i=t.w!==e.w||t.h!==e.h,o=s.Utils.copyPos({},t,!0);if(s.Utils.copyPos(o,e),o=this.nodeBoundFix(o,i),s.Utils.copyPos(e,o),s.Utils.samePos(t,e))return!1;let n=s.Utils.copyPos({},t),r=this.collideAll(t,o,e.skip),l=!0;if(r.length){let i=t._moving&&!e.nested?this.collideCoverage(t,e,r):r[0];l=!!i&&!this._fixCollisions(t,o,i,e)}return l&&(t._dirty=!0,s.Utils.copyPos(t,o)),e.pack&&this._packNodes()._notify(),!s.Utils.samePos(t,n)}getRow(){return this.nodes.reduce(((t,e)=>Math.max(t,e.y+e.h)),0)}beginUpdate(t){return t._updating||(t._updating=!0,delete t._skipDown,this.batchMode||this.saveInitial()),this}endUpdate(){let t=this.nodes.find((t=>t._updating));return t&&(delete t._updating,delete t._skipDown),this}save(t=!0){var e;let i=null===(e=this._layouts)||void 0===e?void 0:e.length,s=i&&this.column!==i-1?this._layouts[i-1]:null,o=[];return this.sortNodes(),this.nodes.forEach((e=>{let i=null==s?void 0:s.find((t=>t._id===e._id)),n=Object.assign({},e);i&&(n.x=i.x,n.y=i.y,n.w=i.w);for(let t in n)"_"!==t[0]&&null!==n[t]&&void 0!==n[t]||delete n[t];delete n.grid,t||delete n.el,n.autoPosition||delete n.autoPosition,n.noResize||delete n.noResize,n.noMove||delete n.noMove,n.locked||delete n.locked,o.push(n)})),o}layoutsNodesChange(t){return!this._layouts||this._inColumnResize||this._layouts.forEach(((e,i)=>{if(!e||i===this.column)return this;if(i{if(!t._orig)return;let i=e.find((e=>e._id===t._id));i&&(t.y!==t._orig.y&&(i.y+=t.y-t._orig.y),t.x!==t._orig.x&&(i.x=Math.round(t.x*s)),t.w!==t._orig.w&&(i.w=Math.round(t.w*s)))}))}})),this}updateNodeWidths(t,e,i,o="moveScale"){var n;if(!this.nodes.length||!e||t===e)return this;this.cacheLayout(this.nodes,t),this.batchUpdate();let r=[],l=!1;if(1===e&&(null==i?void 0:i.length)){l=!0;let t=0;i.forEach((e=>{e.x=0,e.w=1,e.y=Math.max(e.y,t),t=e.y+e.h})),r=i,i=[]}else i=s.Utils.sort(this.nodes,-1,t);let a=[];if(e>t){a=this._layouts[e]||[];let s=this._layouts.length-1;!a.length&&t!==s&&(null===(n=this._layouts[s])||void 0===n?void 0:n.length)&&(t=s,this._layouts[s].forEach((t=>{let e=i.find((e=>e._id===t._id));e&&(e.x=t.x,e.y=t.y,e.w=t.w)})))}if(a.forEach((t=>{let e=i.findIndex((e=>e._id===t._id));-1!==e&&(i[e].x=t.x,i[e].y=t.y,i[e].w=t.w,r.push(i[e]),i.splice(e,1))})),i.length)if("function"==typeof o)o(e,t,r,i);else if(!l){let s=e/t,n="move"===o||"moveScale"===o,l="scale"===o||"moveScale"===o;i.forEach((i=>{i.x=1===e?0:n?Math.round(i.x*s):Math.min(i.x,e-1),i.w=1===e||1===t?1:l?Math.round(i.w*s)||1:Math.min(i.w,e),r.push(i)})),i=[]}return r=s.Utils.sort(r,-1,e),this._inColumnResize=!0,this.nodes=[],r.forEach((t=>{this.addNode(t,!1),delete t._orig})),this.batchUpdate(!1),delete this._inColumnResize,this}cacheLayout(t,e,i=!1){let s=[];return t.forEach(((t,e)=>{t._id=t._id||o._idSeq++,s[e]={x:t.x,y:t.y,w:t.w,_id:t._id}})),this._layouts=i?[]:this._layouts||[],this._layouts[e]=s,this}cacheOneLayout(t,e){t._id=t._id||o._idSeq++;let i={x:t.x,y:t.y,w:t.w,_id:t._id};this._layouts=this._layouts||[],this._layouts[e]=this._layouts[e]||[];let s=this._layouts[e].findIndex((e=>e._id===t._id));return-1===s?this._layouts[e].push(i):this._layouts[e][s]=i,this}cleanupNode(t){for(let e in t)"_"===e[0]&&"_id"!==e&&delete t[e];return this}}e.GridStackEngine=o,o._idSeq=1},270:function(t,e,i){var s=this&&this.__createBinding||(Object.create?function(t,e,i,s){void 0===s&&(s=i),Object.defineProperty(t,s,{enumerable:!0,get:function(){return e[i]}})}:function(t,e,i,s){void 0===s&&(s=i),t[s]=e[i]}),o=this&&this.__exportStar||function(t,e){for(var i in t)"default"===i||e.hasOwnProperty(i)||s(e,t,i)};Object.defineProperty(e,"__esModule",{value:!0}),e.GridStack=void 0;const n=i(62),r=i(593);o(i(699),e),o(i(593),e),o(i(62),e);const l={column:12,minRow:0,maxRow:0,itemClass:"grid-stack-item",placeholderClass:"grid-stack-placeholder",placeholderText:"",handle:".grid-stack-item-content",handleClass:null,styleInHead:!1,cellHeight:"auto",cellHeightThrottle:100,margin:10,auto:!0,oneColumnSize:768,float:!1,staticGrid:!1,animate:!0,alwaysShowResizeHandle:"mobile",resizable:{handles:"se"},draggable:{handle:".grid-stack-item-content",appendTo:"body"},disableDrag:!1,disableResize:!1,rtl:"auto",removable:!1,removableOptions:{accept:".grid-stack-item"},marginUnit:"px",cellHeightUnit:"px",disableOneColumnMode:!1,oneColumnModeDomSort:!1};class a{constructor(t,e={}){this._gsEventHandler={},this._extraDragRow=0,this.el=t,(e=e||{}).row&&(e.minRow=e.maxRow=e.row,delete e.row);let i=r.Utils.toNumber(t.getAttribute("gs-row"));"auto"===e.column&&delete e.column;let s=e;void 0!==s.minWidth&&(e.oneColumnSize=e.oneColumnSize||s.minWidth,delete s.minWidth),void 0!==e.alwaysShowResizeHandle&&(e._alwaysShowResizeHandle=e.alwaysShowResizeHandle);let o=Object.assign(Object.assign({},r.Utils.cloneDeep(l)),{column:r.Utils.toNumber(t.getAttribute("gs-column"))||l.column,minRow:i||r.Utils.toNumber(t.getAttribute("gs-min-row"))||l.minRow,maxRow:i||r.Utils.toNumber(t.getAttribute("gs-max-row"))||l.maxRow,staticGrid:r.Utils.toBool(t.getAttribute("gs-static"))||l.staticGrid,_styleSheetClass:"grid-stack-instance-"+(1e4*Math.random()).toFixed(0),draggable:{handle:(e.handleClass?"."+e.handleClass:e.handle?e.handle:"")||l.draggable.handle},removableOptions:{accept:e.itemClass?"."+e.itemClass:l.removableOptions.accept}});t.getAttribute("gs-animate")&&(o.animate=r.Utils.toBool(t.getAttribute("gs-animate"))),this.opts=r.Utils.defaults(e,o),e=null,this._initMargin(),1!==this.opts.column&&!this.opts.disableOneColumnMode&&this._widthOrContainer()<=this.opts.oneColumnSize&&(this._prevColumn=this.getColumn(),this.opts.column=1),"auto"===this.opts.rtl&&(this.opts.rtl="rtl"===t.style.direction),this.opts.rtl&&this.el.classList.add("grid-stack-rtl");let d=r.Utils.closestByClass(this.el,l.itemClass);d&&d.gridstackNode&&(this.opts._isNested=d.gridstackNode,this.opts._isNested.subGrid=this,d.classList.add("grid-stack-nested"),this.el.classList.add("grid-stack-nested")),this._isAutoCellHeight="auto"===this.opts.cellHeight,this._isAutoCellHeight||"initial"===this.opts.cellHeight?this.cellHeight(void 0,!1):("number"==typeof this.opts.cellHeight&&this.opts.cellHeightUnit&&this.opts.cellHeightUnit!==l.cellHeightUnit&&(this.opts.cellHeight=this.opts.cellHeight+this.opts.cellHeightUnit,delete this.opts.cellHeightUnit),this.cellHeight(this.opts.cellHeight,!1)),"mobile"===this.opts.alwaysShowResizeHandle&&(this.opts.alwaysShowResizeHandle=h.isTouch),this.el.classList.add(this.opts._styleSheetClass),this._setStaticClass();let g=this.opts.engineClass||a.engineClass||n.GridStackEngine;if(this.engine=new g({column:this.getColumn(),float:this.opts.float,maxRow:this.opts.maxRow,onChange:t=>{let e=0;this.engine.nodes.forEach((t=>{e=Math.max(e,t.y+t.h)})),t.forEach((t=>{let e=t.el;e&&(t._removeDOM?(e&&e.remove(),delete t._removeDOM):this._writePosAttr(e,t))})),this._updateStyles(!1,e)}}),this.opts.auto){this.batchUpdate();let t=[];this.getGridItems().forEach((e=>{let i=parseInt(e.getAttribute("gs-x")),s=parseInt(e.getAttribute("gs-y"));t.push({el:e,i:(Number.isNaN(i)?1e3:i)+(Number.isNaN(s)?1e3:s)*this.getColumn()})})),t.sort(((t,e)=>t.i-e.i)).forEach((t=>this._prepareElement(t.el))),this.batchUpdate(!1)}this.setAnimation(this.opts.animate),this._updateStyles(),12!=this.opts.column&&this.el.classList.add("grid-stack-"+this.opts.column),this.opts.dragIn&&a.setupDragIn(this.opts.dragIn,this.opts.dragInOptions),delete this.opts.dragIn,delete this.opts.dragInOptions,this._setupRemoveDrop(),this._setupAcceptWidget(),this._updateWindowResizeEvent()}static init(t={},e=".grid-stack"){let i=a.getGridElement(e);return i?(i.gridstack||(i.gridstack=new a(i,r.Utils.cloneDeep(t))),i.gridstack):("string"==typeof e?console.error('GridStack.initAll() no grid was found with selector "'+e+'" - element missing or wrong selector ?\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'):console.error("GridStack.init() no grid element was passed."),null)}static initAll(t={},e=".grid-stack"){let i=[];return a.getGridElements(e).forEach((e=>{e.gridstack||(e.gridstack=new a(e,r.Utils.cloneDeep(t)),delete t.dragIn,delete t.dragInOptions),i.push(e.gridstack)})),0===i.length&&console.error('GridStack.initAll() no grid was found with selector "'+e+'" - element missing or wrong selector ?\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'),i}static addGrid(t,e={}){if(!t)return null;let i=t;if(!t.classList.contains("grid-stack")){let s=document.implementation.createHTMLDocument("");s.body.innerHTML=`
`,i=s.body.children[0],t.appendChild(i)}let s=a.init(e,i);if(s.opts.children){let t=s.opts.children;delete s.opts.children,s.load(t)}return s}static registerEngine(t){a.engineClass=t}get placeholder(){if(!this._placeholder){let t=document.createElement("div");t.className="placeholder-content",this.opts.placeholderText&&(t.innerHTML=this.opts.placeholderText),this._placeholder=document.createElement("div"),this._placeholder.classList.add(this.opts.placeholderClass,l.itemClass,this.opts.itemClass),this.placeholder.appendChild(t)}return this._placeholder}change(){this._triggerChangeEvent()}addWidget(t,e){if(arguments.length>2){console.warn("gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon");let e=arguments,i=1,s={x:e[i++],y:e[i++],w:e[i++],h:e[i++],autoPosition:e[i++],minW:e[i++],maxW:e[i++],minH:e[i++],maxH:e[i++],id:e[i++]};return this.addWidget(t,s)}let i;if("string"==typeof t){let e=document.implementation.createHTMLDocument("");e.body.innerHTML=t,i=e.body.children[0]}else if(0===arguments.length||1===arguments.length&&(void 0!==(s=t).x||void 0!==s.y||void 0!==s.w||void 0!==s.h||void 0!==s.content)){let s=t&&t.content||"";e=t;let o=document.implementation.createHTMLDocument("");o.body.innerHTML=`
${s}
`,i=o.body.children[0]}else i=t;var s;let o=this._readAttr(i);e=r.Utils.cloneDeep(e)||{},r.Utils.defaults(e,o);let n=this.engine.prepareNode(e);if(this._writeAttr(i,e),this._insertNotAppend?this.el.prepend(i):this.el.appendChild(i),this._prepareElement(i,!0,e),this._updateContainerHeight(),n.subGrid&&!n.subGrid.el){let t,e=n.subGrid;"auto"===e.column&&(e.column=n.w,e.disableOneColumnMode=!0,t=!0);let i=n.el.querySelector(".grid-stack-item-content");n.subGrid=a.addGrid(i,n.subGrid),t&&(n.subGrid._autoColumn=!0)}return this._triggerAddEvent(),this._triggerChangeEvent(),i}save(t=!0,e=!1){let i=this.engine.save(t);if(i.forEach((e=>{if(t&&e.el&&!e.subGrid){let t=e.el.querySelector(".grid-stack-item-content");e.content=t?t.innerHTML:void 0,e.content||delete e.content}else t||delete e.content,e.subGrid&&(e.subGrid=e.subGrid.save(t,!0));delete e.el})),e){let t=r.Utils.cloneDeep(this.opts);t.marginBottom===t.marginTop&&t.marginRight===t.marginLeft&&t.marginTop===t.marginRight&&(t.margin=t.marginTop,delete t.marginTop,delete t.marginRight,delete t.marginBottom,delete t.marginLeft),t.rtl===("rtl"===this.el.style.direction)&&(t.rtl="auto"),this._isAutoCellHeight&&(t.cellHeight="auto"),this._autoColumn&&(t.column="auto",delete t.disableOneColumnMode);const e=t._alwaysShowResizeHandle;return delete t._alwaysShowResizeHandle,void 0!==e?t.alwaysShowResizeHandle=e:delete t.alwaysShowResizeHandle,r.Utils.removeInternalAndSame(t,l),t.children=i,t}return i}load(t,e=!0){let i=a.Utils.sort([...t],-1,this._prevColumn||this.getColumn());this._insertNotAppend=!0,this._prevColumn&&this._prevColumn!==this.opts.column&&i.some((t=>t.x+t.w>this.opts.column))&&(this._ignoreLayoutsNodeChange=!0,this.engine.cacheLayout(i,this._prevColumn,!0));let s=[];return this.batchUpdate(),e&&[...this.engine.nodes].forEach((t=>{i.find((e=>t.id===e.id))||("function"==typeof e?e(this,t,!1):(s.push(t),this.removeWidget(t.el,!0,!1)))})),i.forEach((t=>{let i=t.id||0===t.id?this.engine.nodes.find((e=>e.id===t.id)):void 0;if(i){if(this.update(i.el,t),t.subGrid&&t.subGrid.children){let e=i.el.querySelector(".grid-stack");e&&e.gridstack&&(e.gridstack.load(t.subGrid.children),this._insertNotAppend=!0)}}else e&&(t="function"==typeof e?e(this,t,!0).gridstackNode:this.addWidget(t).gridstackNode)})),this.engine.removedNodes=s,this.batchUpdate(!1),delete this._ignoreLayoutsNodeChange,delete this._insertNotAppend,this}batchUpdate(t=!0){return this.engine.batchUpdate(t),t||(this._triggerRemoveEvent(),this._triggerAddEvent(),this._triggerChangeEvent()),this}getCellHeight(t=!1){if(this.opts.cellHeight&&"auto"!==this.opts.cellHeight&&(!t||!this.opts.cellHeightUnit||"px"===this.opts.cellHeightUnit))return this.opts.cellHeight;let e=this.el.querySelector("."+this.opts.itemClass);if(e){let t=r.Utils.toNumber(e.getAttribute("gs-h"));return Math.round(e.offsetHeight/t)}let i=parseInt(this.el.getAttribute("gs-current-row"));return i?Math.round(this.el.getBoundingClientRect().height/i):this.opts.cellHeight}cellHeight(t,e=!0){if(e&&void 0!==t&&this._isAutoCellHeight!==("auto"===t)&&(this._isAutoCellHeight="auto"===t,this._updateWindowResizeEvent()),"initial"!==t&&"auto"!==t||(t=void 0),void 0===t){let e=-this.opts.marginRight-this.opts.marginLeft+this.opts.marginTop+this.opts.marginBottom;t=this.cellWidth()+e}let i=r.Utils.parseHeight(t);return this.opts.cellHeightUnit===i.unit&&this.opts.cellHeight===i.h||(this.opts.cellHeightUnit=i.unit,this.opts.cellHeight=i.h,e&&this._updateStyles(!0,this.getRow())),this}cellWidth(){return this._widthOrContainer()/this.getColumn()}_widthOrContainer(){return this.el.clientWidth||this.el.parentElement.clientWidth||window.innerWidth}compact(){return this.engine.compact(),this._triggerChangeEvent(),this}column(t,e="moveScale"){if(t<1||this.opts.column===t)return this;let i,s=this.getColumn();return 1===t?this._prevColumn=s:delete this._prevColumn,this.el.classList.remove("grid-stack-"+s),this.el.classList.add("grid-stack-"+t),this.opts.column=this.engine.column=t,1===t&&this.opts.oneColumnModeDomSort&&(i=[],this.getGridItems().forEach((t=>{t.gridstackNode&&i.push(t.gridstackNode)})),i.length||(i=void 0)),this.engine.updateNodeWidths(s,t,i,e),this._isAutoCellHeight&&this.cellHeight(),this._ignoreLayoutsNodeChange=!0,this._triggerChangeEvent(),delete this._ignoreLayoutsNodeChange,this}getColumn(){return this.opts.column}getGridItems(){return Array.from(this.el.children).filter((t=>t.matches("."+this.opts.itemClass)&&!t.matches("."+this.opts.placeholderClass)))}destroy(t=!0){if(this.el)return this._updateWindowResizeEvent(!0),this.setStatic(!0,!1),this.setAnimation(!1),t?this.el.parentNode.removeChild(this.el):(this.removeAll(t),this.el.classList.remove(this.opts._styleSheetClass)),this._removeStylesheet(),this.el.removeAttribute("gs-current-row"),delete this.opts._isNested,delete this.opts,delete this._placeholder,delete this.engine,delete this.el.gridstack,delete this.el,this}float(t){return this.opts.float!==t&&(this.opts.float=this.engine.float=t,this._triggerChangeEvent()),this}getFloat(){return this.engine.float}getCellFromPixel(t,e=!1){let i,s=this.el.getBoundingClientRect();i=e?{top:s.top+document.documentElement.scrollTop,left:s.left}:{top:this.el.offsetTop,left:this.el.offsetLeft};let o=t.left-i.left,n=t.top-i.top,r=s.width/this.getColumn(),l=s.height/parseInt(this.el.getAttribute("gs-current-row"));return{x:Math.floor(o/r),y:Math.floor(n/l)}}getRow(){return Math.max(this.engine.getRow(),this.opts.minRow)}isAreaEmpty(t,e,i,s){return this.engine.isAreaEmpty(t,e,i,s)}makeWidget(t){let e=a.getElement(t);return this._prepareElement(e,!0),this._updateContainerHeight(),this._triggerAddEvent(),this._triggerChangeEvent(),e}on(t,e){if(-1!==t.indexOf(" "))return t.split(" ").forEach((t=>this.on(t,e))),this;if("change"===t||"added"===t||"removed"===t||"enable"===t||"disable"===t){let i="enable"===t||"disable"===t;this._gsEventHandler[t]=i?t=>e(t):t=>e(t,t.detail),this.el.addEventListener(t,this._gsEventHandler[t])}else"drag"===t||"dragstart"===t||"dragstop"===t||"resizestart"===t||"resize"===t||"resizestop"===t||"dropped"===t?this._gsEventHandler[t]=e:console.log("GridStack.on("+t+') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');return this}off(t){return-1!==t.indexOf(" ")?(t.split(" ").forEach((t=>this.off(t))),this):("change"!==t&&"added"!==t&&"removed"!==t&&"enable"!==t&&"disable"!==t||this._gsEventHandler[t]&&this.el.removeEventListener(t,this._gsEventHandler[t]),delete this._gsEventHandler[t],this)}removeWidget(t,e=!0,i=!0){return a.getElements(t).forEach((t=>{if(t.parentElement!==this.el)return;let s=t.gridstackNode;s||(s=this.engine.nodes.find((e=>t===e.el))),s&&(delete t.gridstackNode,this._removeDD(t),this.engine.removeNode(s,e,i),e&&t.parentElement&&t.remove())})),i&&(this._triggerRemoveEvent(),this._triggerChangeEvent()),this}removeAll(t=!0){return this.engine.nodes.forEach((t=>{delete t.el.gridstackNode,this._removeDD(t.el)})),this.engine.removeAll(t),this._triggerRemoveEvent(),this}setAnimation(t){return t?this.el.classList.add("grid-stack-animate"):this.el.classList.remove("grid-stack-animate"),this}setStatic(t,e=!0){return this.opts.staticGrid===t||(this.opts.staticGrid=t,this._setupRemoveDrop(),this._setupAcceptWidget(),this.engine.nodes.forEach((t=>this._prepareDragDropByNode(t))),e&&this._setStaticClass()),this}update(t,e){if(arguments.length>2){console.warn("gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon");let i=arguments,s=1;return e={x:i[s++],y:i[s++],w:i[s++],h:i[s++]},this.update(t,e)}return a.getElements(t).forEach((t=>{if(!t||!t.gridstackNode)return;let i=t.gridstackNode,s=r.Utils.cloneDeep(e);delete s.autoPosition;let o,n=["x","y","w","h"];if(n.some((t=>void 0!==s[t]&&s[t]!==i[t]))&&(o={},n.forEach((t=>{o[t]=void 0!==s[t]?s[t]:i[t],delete s[t]}))),!o&&(s.minW||s.minH||s.maxW||s.maxH)&&(o={}),s.content){let e=t.querySelector(".grid-stack-item-content");e&&e.innerHTML!==s.content&&(e.innerHTML=s.content),delete s.content}let l=!1,a=!1;for(const t in s)"_"!==t[0]&&i[t]!==s[t]&&(i[t]=s[t],l=!0,a=a||!this.opts.staticGrid&&("noResize"===t||"noMove"===t||"locked"===t));o&&(this.engine.cleanNodes().beginUpdate(i).moveNode(i,o),this._updateContainerHeight(),this._triggerChangeEvent(),this.engine.endUpdate()),l&&this._writeAttr(t,i),a&&this._prepareDragDropByNode(i)})),this}margin(t){if(!("string"==typeof t&&t.split(" ").length>1)){let e=r.Utils.parseHeight(t);if(this.opts.marginUnit===e.unit&&this.opts.margin===e.h)return}return this.opts.margin=t,this.opts.marginTop=this.opts.marginBottom=this.opts.marginLeft=this.opts.marginRight=void 0,this._initMargin(),this._updateStyles(!0),this}getMargin(){return this.opts.margin}willItFit(t){if(arguments.length>1){console.warn("gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon");let t=arguments,e=0,i={x:t[e++],y:t[e++],w:t[e++],h:t[e++],autoPosition:t[e++]};return this.willItFit(i)}return this.engine.willItFit(t)}_triggerChangeEvent(){if(this.engine.batchMode)return this;let t=this.engine.getDirtyNodes(!0);return t&&t.length&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(t),this._triggerEvent("change",t)),this.engine.saveInitial(),this}_triggerAddEvent(){return this.engine.batchMode||this.engine.addedNodes&&this.engine.addedNodes.length>0&&(this._ignoreLayoutsNodeChange||this.engine.layoutsNodesChange(this.engine.addedNodes),this.engine.addedNodes.forEach((t=>{delete t._dirty})),this._triggerEvent("added",this.engine.addedNodes),this.engine.addedNodes=[]),this}_triggerRemoveEvent(){return this.engine.batchMode||this.engine.removedNodes&&this.engine.removedNodes.length>0&&(this._triggerEvent("removed",this.engine.removedNodes),this.engine.removedNodes=[]),this}_triggerEvent(t,e){let i=e?new CustomEvent(t,{bubbles:!1,detail:e}):new Event(t);return this.el.dispatchEvent(i),this}_removeStylesheet(){return this._styles&&(r.Utils.removeStylesheet(this._styles._id),delete this._styles),this}_updateStyles(t=!1,e){if(t&&this._removeStylesheet(),this._updateContainerHeight(),0===this.opts.cellHeight)return this;let i=this.opts.cellHeight,s=this.opts.cellHeightUnit,o=`.${this.opts._styleSheetClass} > .${this.opts.itemClass}`;if(!this._styles){let t="gridstack-style-"+(1e5*Math.random()).toFixed(),e=this.opts.styleInHead?void 0:this.el.parentNode;if(this._styles=r.Utils.createStylesheet(t,e),!this._styles)return this;this._styles._id=t,this._styles._max=0,r.Utils.addCSSRule(this._styles,o,`min-height: ${i}${s}`);let n=this.opts.marginTop+this.opts.marginUnit,l=this.opts.marginBottom+this.opts.marginUnit,a=this.opts.marginRight+this.opts.marginUnit,h=this.opts.marginLeft+this.opts.marginUnit,d=`${o} > .grid-stack-item-content`,g=`.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;r.Utils.addCSSRule(this._styles,d,`top: ${n}; right: ${a}; bottom: ${l}; left: ${h};`),r.Utils.addCSSRule(this._styles,g,`top: ${n}; right: ${a}; bottom: ${l}; left: ${h};`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-ne`,`right: ${a}`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-e`,`right: ${a}`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-se`,`right: ${a}; bottom: ${l}`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-nw`,`left: ${h}`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-w`,`left: ${h}`),r.Utils.addCSSRule(this._styles,`${o} > .ui-resizable-sw`,`left: ${h}; bottom: ${l}`)}if((e=e||this._styles._max)>this._styles._max){let t=t=>i*t+s;for(let i=this._styles._max+1;i<=e;i++){let e=t(i);r.Utils.addCSSRule(this._styles,`${o}[gs-y="${i-1}"]`,`top: ${t(i-1)}`),r.Utils.addCSSRule(this._styles,`${o}[gs-h="${i}"]`,`height: ${e}`),r.Utils.addCSSRule(this._styles,`${o}[gs-min-h="${i}"]`,`min-height: ${e}`),r.Utils.addCSSRule(this._styles,`${o}[gs-max-h="${i}"]`,`max-height: ${e}`)}this._styles._max=e}return this}_updateContainerHeight(){if(!this.engine||this.engine.batchMode)return this;let t=this.getRow()+this._extraDragRow;if(this.el.setAttribute("gs-current-row",String(t)),0===t)return this.el.style.removeProperty("height"),this;let e=this.opts.cellHeight,i=this.opts.cellHeightUnit;return e?(this.el.style.height=t*e+i,this):this}_prepareElement(t,e=!1,i){i||(t.classList.add(this.opts.itemClass),i=this._readAttr(t)),t.gridstackNode=i,i.el=t,i.grid=this;let s=Object.assign({},i);return i=this.engine.addNode(i,e),r.Utils.same(i,s)||this._writeAttr(t,i),this._prepareDragDropByNode(i),this}_writePosAttr(t,e){return void 0!==e.x&&null!==e.x&&t.setAttribute("gs-x",String(e.x)),void 0!==e.y&&null!==e.y&&t.setAttribute("gs-y",String(e.y)),e.w&&t.setAttribute("gs-w",String(e.w)),e.h&&t.setAttribute("gs-h",String(e.h)),this}_writeAttr(t,e){if(!e)return this;this._writePosAttr(t,e);let i={autoPosition:"gs-auto-position",minW:"gs-min-w",minH:"gs-min-h",maxW:"gs-max-w",maxH:"gs-max-h",noResize:"gs-no-resize",noMove:"gs-no-move",locked:"gs-locked",id:"gs-id",resizeHandles:"gs-resize-handles"};for(const s in i)e[s]?t.setAttribute(i[s],String(e[s])):t.removeAttribute(i[s]);return this}_readAttr(t){let e={};e.x=r.Utils.toNumber(t.getAttribute("gs-x")),e.y=r.Utils.toNumber(t.getAttribute("gs-y")),e.w=r.Utils.toNumber(t.getAttribute("gs-w")),e.h=r.Utils.toNumber(t.getAttribute("gs-h")),e.maxW=r.Utils.toNumber(t.getAttribute("gs-max-w")),e.minW=r.Utils.toNumber(t.getAttribute("gs-min-w")),e.maxH=r.Utils.toNumber(t.getAttribute("gs-max-h")),e.minH=r.Utils.toNumber(t.getAttribute("gs-min-h")),e.autoPosition=r.Utils.toBool(t.getAttribute("gs-auto-position")),e.noResize=r.Utils.toBool(t.getAttribute("gs-no-resize")),e.noMove=r.Utils.toBool(t.getAttribute("gs-no-move")),e.locked=r.Utils.toBool(t.getAttribute("gs-locked")),e.resizeHandles=t.getAttribute("gs-resize-handles"),e.id=t.getAttribute("gs-id");for(const t in e){if(!e.hasOwnProperty(t))return;e[t]||0===e[t]||delete e[t]}return e}_setStaticClass(){let t=["grid-stack-static"];return this.opts.staticGrid?(this.el.classList.add(...t),this.el.setAttribute("gs-static","true")):(this.el.classList.remove(...t),this.el.removeAttribute("gs-static")),this}onParentResize(){if(!this.el||!this.el.clientWidth)return;let t=!1;if(this._autoColumn&&this.opts._isNested)this.opts.column!==this.opts._isNested.w&&(t=!0,this.column(this.opts._isNested.w,"none"));else{let e=!this.opts.disableOneColumnMode&&this.el.clientWidth<=this.opts.oneColumnSize;1===this.opts.column!==e&&(t=!0,this.opts.animate&&this.setAnimation(!1),this.column(e?1:this._prevColumn),this.opts.animate&&this.setAnimation(!0))}return this._isAutoCellHeight&&(!t&&this.opts.cellHeightThrottle?(this._cellHeightThrottle||(this._cellHeightThrottle=r.Utils.throttle((()=>this.cellHeight()),this.opts.cellHeightThrottle)),this._cellHeightThrottle()):this.cellHeight()),this.engine.nodes.forEach((t=>{t.subGrid&&t.subGrid.onParentResize()})),this}_updateWindowResizeEvent(t=!1){const e=(this._isAutoCellHeight||!this.opts.disableOneColumnMode)&&!this.opts._isNested;return t||!e||this._windowResizeBind?!t&&e||!this._windowResizeBind||(window.removeEventListener("resize",this._windowResizeBind),delete this._windowResizeBind):(this._windowResizeBind=this.onParentResize.bind(this),window.addEventListener("resize",this._windowResizeBind)),this}static getElement(t=".grid-stack-item"){return r.Utils.getElement(t)}static getElements(t=".grid-stack-item"){return r.Utils.getElements(t)}static getGridElement(t){return a.getElement(t)}static getGridElements(t){return r.Utils.getElements(t)}_initMargin(){let t,e=0,i=[];return"string"==typeof this.opts.margin&&(i=this.opts.margin.split(" ")),2===i.length?(this.opts.marginTop=this.opts.marginBottom=i[0],this.opts.marginLeft=this.opts.marginRight=i[1]):4===i.length?(this.opts.marginTop=i[0],this.opts.marginRight=i[1],this.opts.marginBottom=i[2],this.opts.marginLeft=i[3]):(t=r.Utils.parseHeight(this.opts.margin),this.opts.marginUnit=t.unit,e=this.opts.margin=t.h),void 0===this.opts.marginTop?this.opts.marginTop=e:(t=r.Utils.parseHeight(this.opts.marginTop),this.opts.marginTop=t.h,delete this.opts.margin),void 0===this.opts.marginBottom?this.opts.marginBottom=e:(t=r.Utils.parseHeight(this.opts.marginBottom),this.opts.marginBottom=t.h,delete this.opts.margin),void 0===this.opts.marginRight?this.opts.marginRight=e:(t=r.Utils.parseHeight(this.opts.marginRight),this.opts.marginRight=t.h,delete this.opts.margin),void 0===this.opts.marginLeft?this.opts.marginLeft=e:(t=r.Utils.parseHeight(this.opts.marginLeft),this.opts.marginLeft=t.h,delete this.opts.margin),this.opts.marginUnit=t.unit,this.opts.marginTop===this.opts.marginBottom&&this.opts.marginLeft===this.opts.marginRight&&this.opts.marginTop===this.opts.marginRight&&(this.opts.margin=this.opts.marginTop),this}static setupDragIn(t,e){}movable(t,e){return this}resizable(t,e){return this}disable(){return this}enable(){return this}enableMove(t){return this}enableResize(t){return this}_removeDD(t){return this}_setupAcceptWidget(){return this}_setupRemoveDrop(){return this}_prepareDragDropByNode(t){return this}_onStartMoving(t,e,i,s,o,n){}_dragOrResize(t,e,i,s,o,n){}_leave(t,e){}commit(){return r.obsolete(this,this.batchUpdate(!1),"commit","batchUpdate","5.2"),this}}e.GridStack=a,a.Utils=r.Utils,a.Engine=n.GridStackEngine,a.GDRev="6.0.1-dev";const h=i(635);o(i(958),e)},699:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0})},593:(t,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.Utils=e.obsoleteAttr=e.obsoleteOptsDel=e.obsoleteOpts=e.obsolete=void 0,e.obsolete=function(t,e,i,s,o){let n=(...n)=>(console.warn("gridstack.js: Function `"+i+"` is deprecated in "+o+" and has been replaced with `"+s+"`. It will be **removed** in a future release"),e.apply(t,n));return n.prototype=e.prototype,n},e.obsoleteOpts=function(t,e,i,s){void 0!==t[e]&&(t[i]=t[e],console.warn("gridstack.js: Option `"+e+"` is deprecated in "+s+" and has been replaced with `"+i+"`. It will be **removed** in a future release"))},e.obsoleteOptsDel=function(t,e,i,s){void 0!==t[e]&&console.warn("gridstack.js: Option `"+e+"` is deprecated in "+i+s)},e.obsoleteAttr=function(t,e,i,s){let o=t.getAttribute(e);null!==o&&(t.setAttribute(i,o),console.warn("gridstack.js: attribute `"+e+"`="+o+" is deprecated on this object in "+s+" and has been replaced with `"+i+"`. It will be **removed** in a future release"))};class i{static getElements(t){if("string"==typeof t){let e=document.querySelectorAll(t);return e.length||"."===t[0]||"#"===t[0]||(e=document.querySelectorAll("."+t),e.length||(e=document.querySelectorAll("#"+t))),Array.from(e)}return[t]}static getElement(t){if("string"==typeof t){if(!t.length)return null;if("#"===t[0])return document.getElementById(t.substring(1));if("."===t[0]||"["===t[0])return document.querySelector(t);if(!isNaN(+t[0]))return document.getElementById(t);let e=document.querySelector(t);return e||(e=document.getElementById(t)),e||(e=document.querySelector("."+t)),e}return t}static isIntercepted(t,e){return!(t.y>=e.y+e.h||t.y+t.h<=e.y||t.x+t.w<=e.x||t.x>=e.x+e.w)}static isTouching(t,e){return i.isIntercepted(t,{x:e.x-.5,y:e.y-.5,w:e.w+1,h:e.h+1})}static sort(t,e,i){return i=i||t.reduce(((t,e)=>Math.max(e.x+e.w,t)),0)||12,-1===e?t.sort(((t,e)=>e.x+e.y*i-(t.x+t.y*i))):t.sort(((t,e)=>t.x+t.y*i-(e.x+e.y*i)))}static createStylesheet(t,e){let i=document.createElement("style");return i.setAttribute("type","text/css"),i.setAttribute("gs-style-id",t),i.styleSheet?i.styleSheet.cssText="":i.appendChild(document.createTextNode("")),e?e.insertBefore(i,e.firstChild):(e=document.getElementsByTagName("head")[0]).appendChild(i),i.sheet}static removeStylesheet(t){let e=document.querySelector("STYLE[gs-style-id="+t+"]");e&&e.parentNode&&e.remove()}static addCSSRule(t,e,i){"function"==typeof t.addRule?t.addRule(e,i):"function"==typeof t.insertRule&&t.insertRule(`${e}{${i}}`)}static toBool(t){return"boolean"==typeof t?t:"string"==typeof t?!(""===(t=t.toLowerCase())||"no"===t||"false"===t||"0"===t):Boolean(t)}static toNumber(t){return null===t||0===t.length?void 0:Number(t)}static parseHeight(t){let e,i="px";if("string"==typeof t){let s=t.match(/^(-[0-9]+\.[0-9]+|[0-9]*\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);if(!s)throw new Error("Invalid height");i=s[2]||"px",e=parseFloat(s[1])}else e=t;return{h:e,unit:i}}static defaults(t,...e){return e.forEach((e=>{for(const i in e){if(!e.hasOwnProperty(i))return;null===t[i]||void 0===t[i]?t[i]=e[i]:"object"==typeof e[i]&&"object"==typeof t[i]&&this.defaults(t[i],e[i])}})),t}static same(t,e){if("object"!=typeof t)return t==e;if(typeof t!=typeof e)return!1;if(Object.keys(t).length!==Object.keys(e).length)return!1;for(const i in t)if(t[i]!==e[i])return!1;return!0}static copyPos(t,e,i=!1){return t.x=e.x,t.y=e.y,t.w=e.w,t.h=e.h,i&&(e.minW&&(t.minW=e.minW),e.minH&&(t.minH=e.minH),e.maxW&&(t.maxW=e.maxW),e.maxH&&(t.maxH=e.maxH)),t}static samePos(t,e){return t&&e&&t.x===e.x&&t.y===e.y&&t.w===e.w&&t.h===e.h}static removeInternalAndSame(t,e){if("object"==typeof t&&"object"==typeof e)for(let i in t){let s=t[i];if("_"===i[0]||s===e[i])delete t[i];else if(s&&"object"==typeof s&&void 0!==e[i]){for(let t in s)s[t]!==e[i][t]&&"_"!==t[0]||delete s[t];Object.keys(s).length||delete t[i]}}}static closestByClass(t,e){for(;t;){if(t.classList.contains(e))return t;t=t.parentElement}return null}static throttle(t,e){let i=!1;return(...s)=>{i||(i=!0,setTimeout((()=>{t(...s),i=!1}),e))}}static removePositioningStyles(t){let e=t.style;e.position&&e.removeProperty("position"),e.left&&e.removeProperty("left"),e.top&&e.removeProperty("top"),e.width&&e.removeProperty("width"),e.height&&e.removeProperty("height")}static getScrollElement(t){if(!t)return document.scrollingElement||document.documentElement;const e=getComputedStyle(t);return/(auto|scroll)/.test(e.overflow+e.overflowY)?t:this.getScrollElement(t.parentElement)}static updateScrollPosition(t,e,i){let s=t.getBoundingClientRect(),o=window.innerHeight||document.documentElement.clientHeight;if(s.top<0||s.bottom>o){let n=s.bottom-o,r=s.top,l=this.getScrollElement(t);if(null!==l){let a=l.scrollTop;s.top<0&&i<0?t.offsetHeight>o?l.scrollTop+=i:l.scrollTop+=Math.abs(r)>Math.abs(i)?i:r:i>0&&(t.offsetHeight>o?l.scrollTop+=i:l.scrollTop+=n>i?i:n),e.top+=l.scrollTop-a}}}static updateScrollResize(t,e,i){const s=this.getScrollElement(e),o=s.clientHeight,n=s===this.getScrollElement()?0:s.getBoundingClientRect().top,r=t.clientY-n,l=r>o-i;rt===o))&&(s[o]=i.cloneDeep(t[o]));return s}static cloneNode(t){const e=t.cloneNode(!0);return e.removeAttribute("id"),e}static appendTo(t,e){let i;i="string"==typeof e?document.querySelector(e):e,i&&i.appendChild(t)}static addElStyles(t,e){if(e instanceof Object)for(const i in e)e.hasOwnProperty(i)&&(Array.isArray(e[i])?e[i].forEach((e=>{t.style[i]=e})):t.style[i]=e[i])}static initEvent(t,e){const i={type:e.type},s={button:0,which:0,buttons:1,bubbles:!0,cancelable:!0,target:e.target?e.target:t.target};return t.dataTransfer&&(i.dataTransfer=t.dataTransfer),["altKey","ctrlKey","metaKey","shiftKey"].forEach((e=>i[e]=t[e])),["pageX","pageY","clientX","clientY","screenX","screenY"].forEach((e=>i[e]=t[e])),Object.assign(Object.assign({},i),s)}}e.Utils=i}},e={},i=function i(s){var o=e[s];if(void 0!==o)return o.exports;var n=e[s]={exports:{}};return t[s].call(n.exports,n,n.exports,i),n.exports}(270);return i.GridStack})()})); +//# sourceMappingURL=gridstack-all.js.map \ No newline at end of file diff --git a/dist/gridstack-all.js.LICENSE.txt b/dist/gridstack-all.js.LICENSE.txt new file mode 100644 index 000000000..0694a2f1c --- /dev/null +++ b/dist/gridstack-all.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * GridStack 6.0.1-dev + * https://gridstackjs.com/ + * + * Copyright (c) 2021-2022 Alain Dumesny + * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE + */ diff --git a/dist/gridstack-all.js.map b/dist/gridstack-all.js.map new file mode 100644 index 000000000..701fdc718 --- /dev/null +++ b/dist/gridstack-all.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack://GridStack/webpack/universalModuleDefinition","webpack://GridStack/./src/dd-base-impl.ts","webpack://GridStack/./src/dd-draggable.ts","webpack://GridStack/./src/dd-droppable.ts","webpack://GridStack/./src/dd-element.ts","webpack://GridStack/./src/dd-gridstack.ts","webpack://GridStack/./src/dd-manager.ts","webpack://GridStack/./src/dd-resizable-handle.ts","webpack://GridStack/./src/dd-resizable.ts","webpack://GridStack/./src/dd-touch.ts","webpack://GridStack/./src/gridstack-engine.ts","webpack://GridStack/./src/gridstack.ts","webpack://GridStack/./src/utils.ts","webpack://GridStack/webpack/bootstrap","webpack://GridStack/webpack/startup"],"names":["root","factory","exports","module","define","amd","self","_eventRegister","disabled","this","_disabled","on","event","callback","off","enable","disable","destroy","triggerEvent","eventName","DDDraggable","DDBaseImplement","constructor","el","option","super","className","handle","substring","dragEl","classList","contains","querySelector","_mouseDown","bind","_mouseMove","_mouseUp","addEventListener","isTouch","touchstart","pointerdown","remove","add","forDestroy","removeEventListener","dragging","mouseDownEvent","helper","updateOption","opts","Object","keys","forEach","key","e","DDManager","mouseHandled","button","target","parentElement","dragElement","dropElement","document","touchmove","touchend","preventDefault","s","_dragFollow","ev","Utils","initEvent","type","drag","ui","Math","abs","x","y","grid","gridstackNode","ddElement","ddDroppable","_createHelper","_setupHelperContainmentStyle","dragOffset","_getDragOffset","helperContainment","_setupHelperStyle","start","style","position","parentOriginStylePosition","_removeHelperStyle","stop","drop","cloneNode","body","appendTo","parentNode","dragElementOriginStyle","originStyleProp","map","prop","pointerEvents","width","height","willChange","transition","setTimeout","node","_isAboutToRemove","offset","left","clientX","offsetLeft","top","clientY","offsetTop","window","getComputedStyle","match","parent","xformOffsetX","xformOffsetY","testEl","createElement","addElStyles","opacity","zIndex","appendChild","testElPosition","getBoundingClientRect","removeChild","targetOffset","containmentRect","DDDroppable","_mouseEnter","_mouseLeave","_setupAccept","pointerenter","pointerleave","_canDrop","stopPropagation","over","_ui","out","parentDrop","accept","matches","draggable","DDElement","static","ddDraggable","indexOf","ddResizable","setupDraggable","cleanDraggable","setupResizable","DDResizable","cleanResizable","setupDroppable","cleanDroppable","DDGridStack","dd","resizable","value","_getDDElements","dEl","handles","getAttribute","autoHide","alwaysShowResizeHandle","fixedAspectRatio","parseFloat","undefined","resize","dragIn","droppable","_accept","isDroppable","isDraggable","isResizable","name","els","create","hosts","getElements","length","list","init","filter","d","_itemRemoving","GridStack","prototype","_setupAcceptWidget","staticGrid","acceptWidgets","removable","cellHeight","cellWidth","onDrag","_temporaryRemoved","max","round","autoPosition","engine","nodeBoundFix","willItFit","_willFitPos","copyPos","_onStartMoving","_dragOrResize","subGrid","canAccept","selector","maxRow","n","w","h","minW","minH","_leave","getCellHeight","_readAttr","_isExternal","offsetWidth","offsetHeight","_gridstackNodeOrig","cleanupNode","_initDD","wasAdded","placeholder","origNode","oGrid","removedNodes","push","_triggerRemoveEvent","_removeDD","removePositioningStyles","_writeAttr","_updateContainerHeight","addedNodes","_triggerAddEvent","_triggerChangeEvent","endUpdate","_gsEventHandler","_prepareDragDropByNode","removeNode","_setupRemoveDrop","trashEl","removableOptions","setupDragIn","_dragIn","_dragInOptions","dragInOptions","noMove","disableDrag","noResize","disableResize","onStartMoving","dragOrResize","onEndMoving","_moving","_lastTried","gridToNotify","_orig","_writePosAttr","addNode","_extraDragRow","cleanNodes","beginUpdate","_lastUiPosition","_prevYPix","cacheRects","marginTop","marginRight","marginBottom","marginLeft","maxW","maxH","restoreInitial","resizing","p","mLeft","mRight","mTop","mBottom","mHeight","mWidth","min","distance","updateScrollPosition","prev","collide","row","getRow","extra","updateScrollResize","size","rect","moveNodeCheck","_skipDown","onParentResize","movable","val","enableMove","enableResize","_triggerEvent","doEnable","nodes","DDResizableHandle","host","direction","moving","dir","_init","prefix","userSelect","newRect","originalRect","scrolled","temporalRect","_mouseOver","_mouseOut","_setupAutoHide","_setupHandlers","_removeHandlers","updateHandles","updateAutoHide","auto","overResizeElement","handlerDirection","handlers","split","trim","_resizeStart","_resizeStop","move","_resizing","scrollEl","getScrollElement","scrollY","scrollTop","startEvent","_setupHelper","_applyChange","_getChange","_cleanHelper","elOriginStyleVal","_originStyleProp","i","fixedAspect","isNaN","isFinite","oEvent","offsetX","offsetY","constrain","_constrainSize","oWidth","oHeight","maxWidth","Number","MAX_SAFE_INTEGER","minWidth","maxHeight","minHeight","containmentEl","DocumentTouch","navigator","maxTouchPoints","msMaxTouchPoints","DDTouch","simulateMouseEvent","simulatedType","touches","cancelable","touch","changedTouches","simulatedEvent","createEvent","initMouseEvent","screenX","screenY","dispatchEvent","simulatePointerMouseEvent","touchHandled","pointerLeaveTimeout","clearTimeout","wasDragging","releasePointerCapture","pointerId","GridStackEngine","column","_float","float","onChange","batchUpdate","flag","batchMode","_prevFloat","saveInitial","_packNodes","_notify","_useEntireRowArea","nn","_hasLocked","_fixCollisions","opt","sortNodes","nested","swap","area","skip","didMove","newOpt","pack","moved","locked","moveNode","skip2","find","isIntercepted","collideAll","collideCoverage","o","collides","_rect","r0","r","r2","yOver","MAX_VALUE","xOver","overMax","right","bottom","a","b","_doSwap","_dirty","touching","isTouching","t","isAreaEmpty","compact","copyNodes","sort","_updating","newY","prepareNode","_id","_idSeq","defaults","before","_inColumnResize","cacheOneLayout","samePos","getDirtyNodes","verify","dirtyNodes","concat","some","triggerAddEvent","dup","_removeDOM","floor","box","removeDOM","removeAll","_layouts","changedPosConstrain","clonedNode","clone","canMove","c","content","prevPos","needToMove","reduce","save","saveElement","len","layout","wl","l","layoutsNodesChange","ratio","updateNodeWidths","prevColumn","cacheLayout","newNodes","domOrder","cacheNodes","lastIndex","cacheNode","j","findIndex","splice","scale","clear","copy","index","GridDefaults","minRow","itemClass","placeholderClass","placeholderText","handleClass","styleInHead","cellHeightThrottle","margin","oneColumnSize","animate","rtl","marginUnit","cellHeightUnit","disableOneColumnMode","oneColumnModeDomSort","rowAttr","toNumber","anyOpts","_alwaysShowResizeHandle","cloneDeep","toBool","_styleSheetClass","random","toFixed","_initMargin","_widthOrContainer","_prevColumn","getColumn","parentGridItemEl","closestByClass","_isNested","_isAutoCellHeight","_setStaticClass","engineClass","cbNodes","_updateStyles","elements","getGridItems","parseInt","_prepareElement","setAnimation","_updateWindowResizeEvent","options","elOrString","getGridElement","gridstack","console","error","grids","getGridElements","doc","implementation","createHTMLDocument","innerHTML","class","children","load","_placeholder","placeholderChild","change","addWidget","arguments","warn","id","domAttr","_insertNotAppend","prepend","autoColumn","ops","addGrid","_autoColumn","saveContent","saveGridOpt","sub","origShow","removeInternalAndSame","addAndRemove","items","_ignoreLayoutsNodeChange","removed","removeWidget","item","update","forcePixel","rows","marginDiff","data","parseHeight","unit","clientWidth","innerWidth","domNodes","oldColumn","Array","from","setStatic","_removeStylesheet","removeAttribute","getFloat","getCellFromPixel","useDocRelative","containerPos","documentElement","relativeLeft","relativeTop","columnWidth","rowHeight","makeWidget","getElement","noData","detail","log","doAnimate","updateClass","m","k","changed","ddChanged","getMargin","CustomEvent","bubbles","Event","_styles","removeStylesheet","forceUpdate","styleLocation","createStylesheet","_max","addCSSRule","getHeight","setAttribute","String","removeProperty","same","attrs","resizeHandles","hasOwnProperty","classes","changedColumn","oneColumn","_cellHeightThrottle","throttle","forceRemove","workTodo","_windowResizeBind","margins","commit","obsolete","Engine","GDRev","f","oldName","newName","rev","wrapper","args","apply","info","oldAttr","querySelectorAll","getElementById","col","styleSheet","cssText","createTextNode","insertBefore","firstChild","getElementsByTagName","sheet","rules","addRule","insertRule","v","toLowerCase","Boolean","Error","sources","source","doMinMax","func","delay","isWaiting","scrollingElement","test","overflow","overflowY","innerHeightOrClientHeight","innerHeight","clientHeight","offsetDiffDown","offsetDiffUp","prevScroll","pointerPosY","scrollBy","behavior","obj","skipFields","ret","styles","isArray","evt","which","buttons","dataTransfer","__webpack_module_cache__","__webpack_exports__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","call"],"mappings":"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","file":"gridstack-all.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"GridStack\"] = factory();\n\telse\n\t\troot[\"GridStack\"] = factory();\n})(self, function() {\nreturn ","/**\n * dd-base-impl.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nexport type EventCallback = (event: Event) => boolean|void;\nexport abstract class DDBaseImplement {\n /** returns the enable state, but you have to call enable()/disable() to change (as other things need to happen) */\n public get disabled(): boolean { return this._disabled; }\n\n /** @internal */\n protected _disabled: boolean; // initial state to differentiate from false\n /** @internal */\n protected _eventRegister: {\n [eventName: string]: EventCallback;\n } = {};\n\n public on(event: string, callback: EventCallback): void {\n this._eventRegister[event] = callback;\n }\n\n public off(event: string): void {\n delete this._eventRegister[event];\n }\n\n public enable(): void {\n this._disabled = false;\n }\n\n public disable(): void {\n this._disabled = true;\n }\n\n public destroy(): void {\n delete this._eventRegister;\n }\n\n public triggerEvent(eventName: string, event: Event): boolean|void {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\nexport interface HTMLElementExtendOpt {\n el: HTMLElement;\n option: T;\n updateOption(T): DDBaseImplement;\n}\n","/**\n * dd-draggable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\nimport { Utils } from './utils';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { GridItemHTMLElement, DDUIData } from './types';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, touchend, touchmove, touchstart, pointerdown } from './dd-touch';\n\n// TODO: merge with DDDragOpt ?\nexport interface DDDraggableOpt {\n appendTo?: string | HTMLElement;\n handle?: string;\n helper?: string | HTMLElement | ((event: Event) => HTMLElement);\n // containment?: string | HTMLElement; // TODO: not implemented yet\n // revert?: string | boolean | unknown; // TODO: not implemented yet\n // scroll?: boolean; // native support by HTML5 drag drop, can't be switch to off actually\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n drag?: (event: Event, ui: DDUIData) => void;\n}\n\ninterface DragOffset {\n left: number;\n top: number;\n width: number;\n height: number;\n offsetLeft: number;\n offsetTop: number;\n}\n\ntype DDDragEvent = 'drag' | 'dragstart' | 'dragstop';\n\n// let count = 0; // TEST\n\nexport class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt {\n public el: HTMLElement;\n public option: DDDraggableOpt;\n public helper: HTMLElement; // used by GridStackDDNative\n\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected dragOffset: DragOffset;\n /** @internal */\n protected dragElementOriginStyle: Array;\n /** @internal */\n protected dragEl: HTMLElement;\n /** @internal true while we are dragging an item around */\n protected dragging: boolean;\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected helperContainment: HTMLElement;\n /** @internal properties we change during dragging, and restore back */\n protected static originStyleProp = ['transition', 'pointerEvents', 'position', 'left', 'top'];\n\n constructor(el: HTMLElement, option: DDDraggableOpt = {}) {\n super();\n this.el = el;\n this.option = option;\n // get the element that is actually supposed to be dragged by\n let className = option.handle.substring(1);\n this.dragEl = el.classList.contains(className) ? el : el.querySelector(option.handle) || el;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n this.enable();\n }\n\n public on(event: DDDragEvent, callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: DDDragEvent): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.dragEl.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.addEventListener('touchstart', touchstart);\n this.dragEl.addEventListener('pointerdown', pointerdown);\n // this.dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n this.el.classList.remove('ui-draggable-disabled');\n this.el.classList.add('ui-draggable');\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.dragEl.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.dragEl.removeEventListener('touchstart', touchstart);\n this.dragEl.removeEventListener('pointerdown', pointerdown);\n }\n this.el.classList.remove('ui-draggable');\n if (!forDestroy) this.el.classList.add('ui-draggable-disabled');\n }\n\n public destroy(): void {\n if (this.dragging) this._mouseUp(this.mouseDownEvent);\n this.disable(true);\n delete this.el;\n delete this.helper;\n delete this.option;\n super.destroy();\n }\n\n public updateOption(opts: DDDraggableOpt): DDDraggable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n return this;\n }\n\n /** @internal call when mouse goes down before a dragstart happens */\n protected _mouseDown(e: MouseEvent): boolean {\n // don't let more than one widget handle mouseStart\n if (DDManager.mouseHandled) return;\n if (e.button !== 0) return true; // only left click\n\n // make sure we are clicking on a drag handle or child of it...\n // Note: we don't need to check that's handle is an immediate child, as mouseHandled will prevent parents from also handling it (lowest wins)\n let className = this.option.handle.substring(1);\n let el = e.target as HTMLElement;\n while (el && !el.classList.contains(className)) { el = el.parentElement; }\n if (!el) return;\n this.mouseDownEvent = e;\n delete this.dragging;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n // document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack\n document.addEventListener('mousemove', this._mouseMove, true); // true=capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.addEventListener('touchmove', touchmove);\n this.dragEl.addEventListener('touchend', touchend);\n }\n\n e.preventDefault();\n DDManager.mouseHandled = true;\n return true;\n }\n\n /** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */\n protected _mouseMove(e: DragEvent): boolean {\n // console.log(`${count++} move ${e.x},${e.y}`)\n let s = this.mouseDownEvent;\n\n if (this.dragging) {\n this._dragFollow(e);\n const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });\n if (this.option.drag) {\n this.option.drag(ev, this.ui());\n }\n this.triggerEvent('drag', ev);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {\n /**\n * don't start unless we've moved at least 3 pixels\n */\n this.dragging = true;\n DDManager.dragElement = this;\n // if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)\n let grid = (this.el as GridItemHTMLElement).gridstackNode?.grid;\n if (grid) {\n DDManager.dropElement = (grid.el as DDElementHost).ddElement.ddDroppable;\n } else {\n delete DDManager.dropElement;\n }\n this.helper = this._createHelper(e);\n this._setupHelperContainmentStyle();\n this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });\n\n this._setupHelperStyle(e);\n if (this.option.start) {\n this.option.start(ev, this.ui());\n }\n this.triggerEvent('dragstart', ev);\n }\n e.preventDefault();\n return true;\n }\n\n /** @internal call when the mouse gets released to drop the item at current location */\n protected _mouseUp(e: MouseEvent): void {\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.dragEl.removeEventListener('touchmove', touchmove, true);\n this.dragEl.removeEventListener('touchend', touchend, true);\n }\n if (this.dragging) {\n delete this.dragging;\n\n // reset the drop target if dragging over ourself (already parented, just moving during stop callback below)\n if (DDManager.dropElement?.el === this.el.parentElement) {\n delete DDManager.dropElement;\n }\n\n this.helperContainment.style.position = this.parentOriginStylePosition || null;\n if (this.helper === this.el) {\n this._removeHelperStyle();\n } else {\n this.helper.remove();\n }\n const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });\n if (this.option.stop) {\n this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!\n }\n this.triggerEvent('dragstop', ev);\n\n // call the droppable method to receive the item\n if (DDManager.dropElement) {\n DDManager.dropElement.drop(e);\n }\n }\n delete this.helper;\n delete this.mouseDownEvent;\n delete DDManager.dragElement;\n delete DDManager.dropElement;\n delete DDManager.mouseHandled;\n e.preventDefault();\n }\n\n /** @internal create a clone copy (or user defined method) of the original drag item if set */\n protected _createHelper(event: DragEvent): HTMLElement {\n let helper = this.el;\n if (typeof this.option.helper === 'function') {\n helper = this.option.helper(event);\n } else if (this.option.helper === 'clone') {\n helper = Utils.cloneNode(this.el);\n }\n if (!document.body.contains(helper)) {\n Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentNode : this.option.appendTo);\n }\n if (helper === this.el) {\n this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);\n }\n return helper;\n }\n\n /** @internal set the fix position of the dragged item */\n protected _setupHelperStyle(e: DragEvent): DDDraggable {\n this.helper.classList.add('ui-draggable-dragging');\n // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593\n const style = this.helper.style;\n style.pointerEvents = 'none'; // needed for over items to get enter/leave\n // style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (done in CSS as well)\n style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %)\n style.width = this.dragOffset.width + 'px';\n style.height = this.dragOffset.height + 'px';\n style.willChange = 'left, top';\n style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'\n this._dragFollow(e); // now position it\n style.transition = 'none'; // show up instantly\n setTimeout(() => {\n if (this.helper) {\n style.transition = null; // recover animation\n }\n }, 0);\n return this;\n }\n\n /** @internal restore back the original style before dragging */\n protected _removeHelperStyle(): DDDraggable {\n this.helper.classList.remove('ui-draggable-dragging');\n let node = (this.helper as GridItemHTMLElement)?.gridstackNode;\n // don't bother restoring styles if we're gonna remove anyway...\n if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) {\n let helper = this.helper;\n // don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'\n let transition = this.dragElementOriginStyle['transition'] || null;\n helper.style.transition = this.dragElementOriginStyle['transition'] = 'none';\n DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);\n setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)\n }\n delete this.dragElementOriginStyle;\n return this;\n }\n\n /** @internal updates the top/left position to follow the mouse */\n protected _dragFollow(e: DragEvent): void {\n let containmentRect = { left: 0, top: 0 };\n // if (this.helper.style.position === 'absolute') { // we use 'fixed'\n // const { left, top } = this.helperContainment.getBoundingClientRect();\n // containmentRect = { left, top };\n // }\n const style = this.helper.style;\n const offset = this.dragOffset;\n style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';\n style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';\n }\n\n /** @internal */\n protected _setupHelperContainmentStyle(): DDDraggable {\n this.helperContainment = this.helper.parentElement;\n if (this.helper.style.position !== 'fixed') {\n this.parentOriginStylePosition = this.helperContainment.style.position;\n if (window.getComputedStyle(this.helperContainment).position.match(/static/)) {\n this.helperContainment.style.position = 'relative';\n }\n }\n return this;\n }\n\n /** @internal */\n protected _getDragOffset(event: DragEvent, el: HTMLElement, parent: HTMLElement): DragOffset {\n\n // in case ancestor has transform/perspective css properties that change the viewpoint\n let xformOffsetX = 0;\n let xformOffsetY = 0;\n if (parent) {\n const testEl = document.createElement('div');\n Utils.addElStyles(testEl, {\n opacity: '0',\n position: 'fixed',\n top: 0 + 'px',\n left: 0 + 'px',\n width: '1px',\n height: '1px',\n zIndex: '-999999',\n });\n parent.appendChild(testEl);\n const testElPosition = testEl.getBoundingClientRect();\n parent.removeChild(testEl);\n xformOffsetX = testElPosition.left;\n xformOffsetY = testElPosition.top;\n // TODO: scale ?\n }\n\n const targetOffset = el.getBoundingClientRect();\n return {\n left: targetOffset.left,\n top: targetOffset.top,\n offsetLeft: - event.clientX + targetOffset.left - xformOffsetX,\n offsetTop: - event.clientY + targetOffset.top - xformOffsetY,\n width: targetOffset.width,\n height: targetOffset.height\n };\n }\n\n /** @internal TODO: set to public as called by DDDroppable! */\n public ui(): DDUIData {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const offset = this.helper.getBoundingClientRect();\n return {\n position: { //Current CSS position of the helper as { top, left } object\n top: offset.top - containmentRect.top,\n left: offset.left - containmentRect.left\n }\n /* not used by GridStack for now...\n helper: [this.helper], //The object arr representing the helper that's being dragged.\n offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.\n */\n };\n }\n}\n","/**\n * dd-droppable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDManager } from './dd-manager';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDElementHost } from './dd-element';\nimport { isTouch, pointerenter, pointerleave } from './dd-touch';\nimport { GridHTMLElement } from './gridstack';\n\nexport interface DDDroppableOpt {\n accept?: string | ((el: HTMLElement) => boolean);\n drop?: (event: DragEvent, ui) => void;\n over?: (event: DragEvent, ui) => void;\n out?: (event: DragEvent, ui) => void;\n}\n\n// let count = 0; // TEST\n\nexport class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n public accept: (el: HTMLElement) => boolean;\n public el: HTMLElement;\n public option: DDDroppableOpt;\n\n constructor(el: HTMLElement, opts: DDDroppableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseEnter = this._mouseEnter.bind(this);\n this._mouseLeave = this._mouseLeave.bind(this);\n this.enable();\n this._setupAccept();\n }\n\n public on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'drop' | 'dropover' | 'dropout'): void {\n super.off(event);\n }\n\n public enable(): void {\n if (this.disabled === false) return;\n super.enable();\n this.el.classList.add('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n this.el.addEventListener('mouseenter', this._mouseEnter);\n this.el.addEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.addEventListener('pointerenter', pointerenter);\n this.el.addEventListener('pointerleave', pointerleave);\n }\n }\n\n public disable(forDestroy = false): void {\n if (this.disabled === true) return;\n super.disable();\n this.el.classList.remove('ui-droppable');\n if (!forDestroy) this.el.classList.add('ui-droppable-disabled');\n this.el.removeEventListener('mouseenter', this._mouseEnter);\n this.el.removeEventListener('mouseleave', this._mouseLeave);\n if (isTouch) {\n this.el.removeEventListener('pointerenter', pointerenter);\n this.el.removeEventListener('pointerleave', pointerleave);\n }\n }\n\n public destroy(): void {\n this.disable(true);\n this.el.classList.remove('ui-droppable');\n this.el.classList.remove('ui-droppable-disabled');\n super.destroy();\n }\n\n public updateOption(opts: DDDroppableOpt): DDDroppable {\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n this._setupAccept();\n return this;\n }\n\n /** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */\n protected _mouseEnter(e: MouseEvent): void {\n // console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement) return;\n if (!this._canDrop()) return;\n e.preventDefault();\n e.stopPropagation();\n\n // make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do\n if (DDManager.dropElement && DDManager.dropElement !== this) {\n DDManager.dropElement._mouseLeave(e as DragEvent);\n }\n DDManager.dropElement = this;\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });\n if (this.option.over) {\n this.option.over(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropover', ev);\n this.el.classList.add('ui-droppable-over');\n // console.log('tracking'); // TEST\n }\n\n /** @internal called when the item is leaving our area, stop tracking if we had moving item */\n protected _mouseLeave(e: MouseEvent): void {\n // console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST\n if (!DDManager.dragElement || DDManager.dropElement !== this) return;\n e.preventDefault();\n e.stopPropagation();\n\n const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });\n if (this.option.out) {\n this.option.out(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('dropout', ev);\n\n if (DDManager.dropElement === this) {\n delete DDManager.dropElement;\n // console.log('not tracking'); // TEST\n\n // if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children\n let parentDrop: DDDroppable;\n let parent: DDElementHost = this.el.parentElement;\n while (!parentDrop && parent) {\n parentDrop = parent.ddElement?.ddDroppable;\n parent = parent.parentElement;\n }\n if (parentDrop) {\n parentDrop._mouseEnter(e);\n }\n }\n }\n\n /** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */\n public drop(e: MouseEvent): void {\n e.preventDefault();\n const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });\n if (this.option.drop) {\n this.option.drop(ev, this._ui(DDManager.dragElement))\n }\n this.triggerEvent('drop', ev);\n }\n\n /** @internal true if element matches the string/method accept option */\n protected _canDrop(): boolean {\n return DDManager.dragElement && (!this.accept || this.accept(DDManager.dragElement.el));\n }\n\n /** @internal */\n protected _setupAccept(): DDDroppable {\n if (!this.option.accept) return this;\n if (typeof this.option.accept === 'string') {\n this.accept = (el: HTMLElement) => el.matches(this.option.accept as string);\n } else {\n this.accept = this.option.accept;\n }\n return this;\n }\n\n /** @internal */\n protected _ui(drag: DDDraggable) {\n return {\n draggable: drag.el,\n ...drag.ui()\n };\n }\n}\n\n","/**\n * dd-elements.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizable, DDResizableOpt } from './dd-resizable';\nimport { GridItemHTMLElement } from './types';\nimport { DDDraggable, DDDraggableOpt } from './dd-draggable';\nimport { DDDroppable, DDDroppableOpt } from './dd-droppable';\n\nexport interface DDElementHost extends GridItemHTMLElement {\n ddElement?: DDElement;\n}\n\nexport class DDElement {\n\n static init(el: DDElementHost): DDElement {\n if (!el.ddElement) { el.ddElement = new DDElement(el); }\n return el.ddElement;\n }\n\n public el: DDElementHost;\n public ddDraggable?: DDDraggable;\n public ddDroppable?: DDDroppable;\n public ddResizable?: DDResizable;\n\n constructor(el: DDElementHost) {\n this.el = el;\n }\n\n public on(eventName: string, callback: (event: MouseEvent) => void): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.on(eventName as 'drag' | 'dragstart' | 'dragstop', callback);\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.on(eventName as 'drop' | 'dropover' | 'dropout', callback);\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.on(eventName as 'resizestart' | 'resize' | 'resizestop', callback);\n }\n return this;\n }\n\n public off(eventName: string): DDElement {\n if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {\n this.ddDraggable.off(eventName as 'drag' | 'dragstart' | 'dragstop');\n } else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {\n this.ddDroppable.off(eventName as 'drop' | 'dropover' | 'dropout');\n } else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {\n this.ddResizable.off(eventName as 'resizestart' | 'resize' | 'resizestop');\n }\n return this;\n }\n\n public setupDraggable(opts: DDDraggableOpt): DDElement {\n if (!this.ddDraggable) {\n this.ddDraggable = new DDDraggable(this.el, opts);\n } else {\n this.ddDraggable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDraggable(): DDElement {\n if (this.ddDraggable) {\n this.ddDraggable.destroy();\n delete this.ddDraggable;\n }\n return this;\n }\n\n public setupResizable(opts: DDResizableOpt): DDElement {\n if (!this.ddResizable) {\n this.ddResizable = new DDResizable(this.el, opts);\n } else {\n this.ddResizable.updateOption(opts);\n }\n return this;\n }\n\n public cleanResizable(): DDElement {\n if (this.ddResizable) {\n this.ddResizable.destroy();\n delete this.ddResizable;\n }\n return this;\n }\n\n public setupDroppable(opts: DDDroppableOpt): DDElement {\n if (!this.ddDroppable) {\n this.ddDroppable = new DDDroppable(this.el, opts);\n } else {\n this.ddDroppable.updateOption(opts);\n }\n return this;\n }\n\n public cleanDroppable(): DDElement {\n if (this.ddDroppable) {\n this.ddDroppable.destroy();\n delete this.ddDroppable;\n }\n return this;\n }\n}\n","/**\r\n * dd-gridstack.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\n/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { GridItemHTMLElement, GridStackNode, GridStackElement, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\nimport { GridStack } from './gridstack';\r\nimport { Utils } from './utils';\r\nimport { DDManager } from './dd-manager';\r\nimport { DDElement, DDElementHost } from './dd-element';\r\n\r\n/** Drag&Drop drop options */\r\nexport type DDDropOpt = {\r\n /** function or class type that this grid will accept as dropped items (see GridStackOptions.acceptWidgets) */\r\n accept?: (el: GridItemHTMLElement) => boolean;\r\n}\r\n\r\n/** drag&drop options currently called from the main code, but others can be passed in grid options */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nexport type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any;\r\nexport type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight';\r\nexport type DDValue = number | string;\r\n\r\n/** drag&drop events callbacks */\r\nexport type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void;\r\n\r\n// let count = 0; // TEST\r\n\r\n/**\r\n * HTML Native Mouse and Touch Events Drag and Drop functionality.\r\n */\r\nexport class DDGridStack {\r\n\r\n /** get the global (but static to this code) DD implementation */\r\n static get(): DDGridStack {\r\n return dd;\r\n }\r\n\r\n public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddResizable && dEl.cleanResizable();\r\n } else if (opts === 'option') {\r\n dEl.setupResizable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles;\r\n let autoHide = !grid.opts.alwaysShowResizeHandle;\r\n let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined;\r\n dEl.setupResizable({\r\n ...grid.opts.resizable,\r\n ...{ handles, autoHide },\r\n ...{\r\n start: opts.start,\r\n stop: opts.stop,\r\n resize: opts.resize,\r\n fixedAspectRatio: fixedAspectRatio\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()\r\n } else if (opts === 'destroy') {\r\n dEl.ddDraggable && dEl.cleanDraggable();\r\n } else if (opts === 'option') {\r\n dEl.setupDraggable({ [key]: value });\r\n } else {\r\n const grid = dEl.el.gridstackNode.grid;\r\n dEl.setupDraggable({\r\n ...grid.opts.draggable,\r\n ...{\r\n // containment: (grid.opts._isNested && !grid.opts.dragOut) ? grid.el.parentElement : (grid.opts.draggable.containment || null),\r\n start: opts.start,\r\n stop: opts.stop,\r\n drag: opts.drag\r\n }\r\n });\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n public dragIn(el: GridStackElement, opts: DDDragInOpt): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));\r\n return this;\r\n }\r\n\r\n public droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack {\r\n if (typeof opts.accept === 'function' && !opts._accept) {\r\n opts._accept = opts.accept;\r\n opts.accept = (el) => opts._accept(el);\r\n }\r\n this._getDDElements(el).forEach(dEl => {\r\n if (opts === 'disable' || opts === 'enable') {\r\n dEl.ddDroppable && dEl.ddDroppable[opts]();\r\n } else if (opts === 'destroy') {\r\n if (dEl.ddDroppable) { // error to call destroy if not there\r\n dEl.cleanDroppable();\r\n }\r\n } else if (opts === 'option') {\r\n dEl.setupDroppable({ [key]: value });\r\n } else {\r\n dEl.setupDroppable(opts);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /** true if element is droppable */\r\n public isDroppable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDroppable && !el.ddElement.ddDroppable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isDraggable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddDraggable && !el.ddElement.ddDraggable.disabled);\r\n }\r\n\r\n /** true if element is draggable */\r\n public isResizable(el: DDElementHost): boolean {\r\n return !!(el && el.ddElement && el.ddElement.ddResizable && !el.ddElement.ddResizable.disabled);\r\n }\r\n\r\n public on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack {\r\n this._getDDElements(el).forEach(dEl =>\r\n dEl.on(name, (event: Event) => {\r\n callback(\r\n event,\r\n DDManager.dragElement ? DDManager.dragElement.el : event.target as GridItemHTMLElement,\r\n DDManager.dragElement ? DDManager.dragElement.helper : null)\r\n })\r\n );\r\n return this;\r\n }\r\n\r\n public off(el: GridItemHTMLElement, name: string): DDGridStack {\r\n this._getDDElements(el).forEach(dEl => dEl.off(name));\r\n return this;\r\n }\r\n\r\n /** @internal returns a list of DD elements, creating them on the fly by default */\r\n protected _getDDElements(els: GridStackElement, create = true): DDElement[] {\r\n let hosts = Utils.getElements(els) as DDElementHost[];\r\n if (!hosts.length) return [];\r\n let list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null));\r\n if (!create) { list.filter(d => d); } // remove nulls\r\n return list;\r\n }\r\n}\r\n\r\n/** global instance */\r\nconst dd = new DDGridStack;\r\n\r\n/********************************************************************************\r\n * GridStack code that is doing drag&drop extracted here so main class is smaller\r\n * for static grid that don't do any of this work anyway. Saves about 31k (41k -> 72k)\r\n * https://www.typescriptlang.org/docs/handbook/declaration-merging.html\r\n * https://www.typescriptlang.org/docs/handbook/mixins.html\r\n ********************************************************************************/\r\n\r\n/** @internal called to add drag over to support widgets being added externally */\r\nGridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {\r\n\r\n // check if we need to disable things\r\n if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {\r\n dd.droppable(this.el, 'destroy');\r\n return this;\r\n }\r\n\r\n // vars shared across all methods\r\n let cellHeight: number, cellWidth: number;\r\n\r\n let onDrag = (event: DragEvent, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n helper = helper || el;\r\n let parent = this.el.getBoundingClientRect();\r\n let {top, left} = helper.getBoundingClientRect();\r\n left -= parent.left;\r\n top -= parent.top;\r\n let ui: DDUIData = {position: {top, left}};\r\n\r\n if (node._temporaryRemoved) {\r\n node.x = Math.max(0, Math.round(left / cellWidth));\r\n node.y = Math.max(0, Math.round(top / cellHeight));\r\n delete node.autoPosition;\r\n this.engine.nodeBoundFix(node);\r\n\r\n // don't accept *initial* location if doesn't fit #1419 (locked drop region, or can't grow), but maybe try if it will go somewhere\r\n if (!this.engine.willItFit(node)) {\r\n node.autoPosition = true; // ignore x,y and try for any slot...\r\n if (!this.engine.willItFit(node)) {\r\n dd.off(el, 'drag'); // stop calling us\r\n return; // full grid or can't grow\r\n }\r\n if (node._willFitPos) {\r\n // use the auto position instead #1687\r\n Utils.copyPos(node, node._willFitPos);\r\n delete node._willFitPos;\r\n }\r\n }\r\n\r\n // re-use the existing node dragging method\r\n this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);\r\n } else {\r\n // re-use the existing node dragging that does so much of the collision detection\r\n this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);\r\n }\r\n }\r\n\r\n dd.droppable(this.el, {\r\n accept: (el: GridItemHTMLElement) => {\r\n let node: GridStackNode = el.gridstackNode;\r\n // set accept drop to true on ourself (which we ignore) so we don't get \"can't drop\" icon in HTML5 mode while moving\r\n if (node?.grid === this) return true;\r\n if (!this.opts.acceptWidgets) return false;\r\n // prevent deeper nesting until rest of 992 can be fixed\r\n if (node?.subGrid) return false;\r\n // check for accept method or class matching\r\n let canAccept = true;\r\n if (typeof this.opts.acceptWidgets === 'function') {\r\n canAccept = this.opts.acceptWidgets(el);\r\n } else {\r\n let selector = (this.opts.acceptWidgets === true ? '.grid-stack-item' : this.opts.acceptWidgets as string);\r\n canAccept = el.matches(selector);\r\n }\r\n // finally check to make sure we actually have space left #1571\r\n if (canAccept && node && this.opts.maxRow) {\r\n let n = {w: node.w, h: node.h, minW: node.minW, minH: node.minH}; // only width/height matters and autoPosition\r\n canAccept = this.engine.willItFit(n);\r\n }\r\n return canAccept;\r\n }\r\n })\r\n /**\r\n * entering our grid area\r\n */\r\n .on(this.el, 'dropover', (event: Event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item\r\n if (node?.grid === this && !node._temporaryRemoved) {\r\n // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n }\r\n\r\n // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now\r\n if (node?.grid && node.grid !== this && !node._temporaryRemoved) {\r\n // console.log('dropover without leave'); // TEST\r\n let otherGrid = node.grid;\r\n otherGrid._leave(el, helper);\r\n }\r\n\r\n // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true);\r\n\r\n // load any element attributes if we don't have a node\r\n if (!node) {// @ts-ignore private read only on ourself\r\n node = this._readAttr(el);\r\n }\r\n if (!node.grid) {\r\n node._isExternal = true;\r\n el.gridstackNode = node;\r\n }\r\n\r\n // calculate the grid size based on element outer size\r\n helper = helper || el;\r\n let w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;\r\n let h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;\r\n\r\n // if the item came from another grid, make a copy and save the original info in case we go back there\r\n if (node.grid && node.grid !== this) {\r\n // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific\r\n // console.log('dropover cloning node'); // TEST\r\n if (!el._gridstackNodeOrig) el._gridstackNodeOrig = node; // shouldn't have multiple nested!\r\n el.gridstackNode = node = {...node, w, h, grid: this};\r\n this.engine.cleanupNode(node)\r\n .nodeBoundFix(node);\r\n // restore some internal fields we need after clearing them all\r\n node._initDD =\r\n node._isExternal = // DOM needs to be re-parented on a drop\r\n node._temporaryRemoved = true; // so it can be inserted onDrag below\r\n } else {\r\n node.w = w; node.h = h;\r\n node._temporaryRemoved = true; // so we can insert it\r\n }\r\n\r\n // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)\r\n _itemRemoving(node.el, false);\r\n\r\n dd.on(el, 'drag', onDrag);\r\n // make sure this is called at least once when going fast #1578\r\n onDrag(event as DragEvent, el, helper);\r\n return false; // prevent parent from receiving msg (which may be a grid as well)\r\n })\r\n /**\r\n * Leaving our grid area...\r\n */\r\n .on(this.el, 'dropout', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST\r\n let node = el.gridstackNode;\r\n if (!node) return false;\r\n // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)\r\n // so skip this one if we're not the active grid really..\r\n if (!node.grid || node.grid === this) {\r\n this._leave(el, helper);\r\n }\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n })\r\n /**\r\n * end - releasing the mouse\r\n */\r\n .on(this.el, 'drop', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => {\r\n let node = el.gridstackNode;\r\n // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead\r\n if (node?.grid === this && !node._isExternal) return false;\r\n\r\n let wasAdded = !!this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419\r\n this.placeholder.remove();\r\n\r\n // notify previous grid of removal\r\n // console.log('drop delete _gridstackNodeOrig') // TEST\r\n let origNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n if (wasAdded && origNode && origNode.grid && origNode.grid !== this) {\r\n let oGrid = origNode.grid;\r\n oGrid.engine.removedNodes.push(origNode);\r\n oGrid._triggerRemoveEvent();\r\n }\r\n\r\n if (!node) return false;\r\n\r\n // use existing placeholder node as it's already in our list with drop location\r\n if (wasAdded) {\r\n this.engine.cleanupNode(node); // removes all internal _xyz values\r\n node.grid = this;\r\n }\r\n dd.off(el, 'drag');\r\n // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)\r\n // as the helper will be nuked by jquery-ui otherwise\r\n if (helper !== el) {\r\n helper.remove();\r\n el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info\r\n if (wasAdded) {\r\n el = el.cloneNode(true) as GridItemHTMLElement;\r\n }\r\n } else {\r\n el.remove(); // reduce flicker as we change depth here, and size further down\r\n this._removeDD(el);\r\n }\r\n if (!wasAdded) return false;\r\n el.gridstackNode = node;\r\n node.el = el;\r\n // @ts-ignore\r\n Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578\r\n Utils.removePositioningStyles(el);// @ts-ignore\r\n this._writeAttr(el, node);\r\n this.el.appendChild(el);// @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)\r\n this._updateContainerHeight();\r\n this.engine.addedNodes.push(node);// @ts-ignore\r\n this._triggerAddEvent();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n if (this._gsEventHandler['dropped']) {\r\n this._gsEventHandler['dropped']({...event, type: 'dropped'}, origNode && origNode.grid ? origNode : undefined, node);\r\n }\r\n\r\n // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up\r\n window.setTimeout(() => {\r\n // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())\r\n if (node.el && node.el.parentElement) {\r\n this._prepareDragDropByNode(node);\r\n } else {\r\n this.engine.removeNode(node);\r\n }\r\n });\r\n\r\n return false; // prevent parent from receiving msg (which may be grid as well)\r\n });\r\n return this;\r\n}\r\n\r\n/** @internal mark item for removal */\r\nfunction _itemRemoving(el: GridItemHTMLElement, remove: boolean) {\r\n let node = el ? el.gridstackNode : undefined;\r\n if (!node || !node.grid) return;\r\n remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;\r\n remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');\r\n}\r\n\r\n/** @internal called to setup a trash drop zone if the user specifies it */\r\nGridStack.prototype._setupRemoveDrop = function(this: GridStack): GridStack {\r\n if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {\r\n let trashEl = document.querySelector(this.opts.removable) as HTMLElement;\r\n if (!trashEl) return this;\r\n // only register ONE drop-over/dropout callback for the 'trash', and it will\r\n // update the passed in item and parent grid because the 'trash' is a shared resource anyway,\r\n // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)\r\n if (!dd.isDroppable(trashEl)) {\r\n dd.droppable(trashEl, this.opts.removableOptions)\r\n .on(trashEl, 'dropover', (event, el) => _itemRemoving(el, true))\r\n .on(trashEl, 'dropout', (event, el) => _itemRemoving(el, false));\r\n }\r\n }\r\n return this;\r\n}\r\n\r\n/**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n **/\r\nGridStack.setupDragIn = function(this: GridStack, _dragIn?: string, _dragInOptions?: DDDragInOpt) {\r\n let dragIn: string;\r\n let dragInOptions: DDDragInOpt;\r\n const dragInDefaultOptions: DDDragInOpt = {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body',\r\n // revert: 'invalid',\r\n // scroll: false,\r\n };\r\n\r\n // cache in the passed in values (form grid init?) so they don't have to resend them each time\r\n if (_dragIn) {\r\n dragIn = _dragIn;\r\n dragInOptions = {...dragInDefaultOptions, ...(_dragInOptions || {})};\r\n }\r\n if (typeof dragIn !== 'string') return;\r\n Utils.getElements(dragIn).forEach(el => {\r\n if (!dd.isDraggable(el)) dd.dragIn(el, dragInOptions);\r\n });\r\n}\r\n\r\n/** @internal prepares the element for drag&drop **/\r\nGridStack.prototype._prepareDragDropByNode = function(this: GridStack, node: GridStackNode): GridStack {\r\n let el = node.el;\r\n const noMove = node.noMove || this.opts.disableDrag;\r\n const noResize = node.noResize || this.opts.disableResize;\r\n\r\n // check for disabled grid first\r\n if (this.opts.staticGrid || (noMove && noResize)) {\r\n if (node._initDD) {\r\n this._removeDD(el); // nukes everything instead of just disable, will add some styles back next\r\n delete node._initDD;\r\n }\r\n el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435\r\n return this;\r\n }\r\n\r\n if (!node._initDD) {\r\n // variables used/cashed between the 3 start/move/end methods, in addition to node passed above\r\n let cellWidth: number;\r\n let cellHeight: number;\r\n\r\n /** called when item starts moving/resizing */\r\n let onStartMoving = (event: Event, ui: DDUIData) => {\r\n // trigger any 'dragstart' / 'resizestart' manually\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, event.target);\r\n }\r\n cellWidth = this.cellWidth();\r\n cellHeight = this.getCellHeight(true); // force pixels for calculations\r\n\r\n this._onStartMoving(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when item is being dragged/resized */\r\n let dragOrResize = (event: Event, ui: DDUIData) => {\r\n this._dragOrResize(el, event, ui, node, cellWidth, cellHeight);\r\n }\r\n\r\n /** called when the item stops moving/resizing */\r\n let onEndMoving = (event: Event) => {\r\n this.placeholder.remove();\r\n delete node._moving;\r\n delete node._lastTried;\r\n\r\n // if the item has moved to another grid, we're done here\r\n let target: GridItemHTMLElement = event.target as GridItemHTMLElement;\r\n if (!target.gridstackNode || target.gridstackNode.grid !== this) return;\r\n\r\n node.el = target;\r\n\r\n if (node._isAboutToRemove) {\r\n let gridToNotify = el.gridstackNode.grid;\r\n if (gridToNotify._gsEventHandler[event.type]) {\r\n gridToNotify._gsEventHandler[event.type](event, target);\r\n }\r\n this._removeDD(el);\r\n gridToNotify.engine.removedNodes.push(node);\r\n gridToNotify._triggerRemoveEvent();\r\n // break circular links and remove DOM\r\n delete el.gridstackNode;\r\n delete node.el;\r\n el.remove();\r\n } else {\r\n Utils.removePositioningStyles(target);\r\n if (node._temporaryRemoved) {\r\n // got removed - restore item back to before dragging position\r\n Utils.copyPos(node, node._orig);// @ts-ignore\r\n this._writePosAttr(target, node);\r\n this.engine.addNode(node);\r\n } else {\r\n // move to new placeholder location\r\n this._writePosAttr(target, node);\r\n }\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n // @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();// @ts-ignore\r\n this._triggerChangeEvent();\r\n\r\n this.engine.endUpdate();\r\n }\r\n\r\n dd.draggable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n drag: dragOrResize\r\n }).resizable(el, {\r\n start: onStartMoving,\r\n stop: onEndMoving,\r\n resize: dragOrResize\r\n });\r\n node._initDD = true; // we've set DD support now\r\n }\r\n\r\n // finally fine tune move vs resize by disabling any part...\r\n dd.draggable(el, noMove ? 'disable' : 'enable')\r\n .resizable(el, noResize ? 'disable' : 'enable');\r\n\r\n return this;\r\n}\r\n\r\n/** @internal called when item is starting a drag/resize */\r\nGridStack.prototype._onStartMoving = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(node);\r\n // @ts-ignore\r\n this._writePosAttr(this.placeholder, node)\r\n this.el.appendChild(this.placeholder);\r\n // console.log('_onStartMoving placeholder') // TEST\r\n\r\n node.el = this.placeholder;\r\n node._lastUiPosition = ui.position;\r\n node._prevYPix = ui.position.top;\r\n node._moving = (event.type === 'dragstart'); // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)\r\n delete node._lastTried;\r\n\r\n if (event.type === 'dropover' && node._temporaryRemoved) {\r\n // console.log('engine.addNode x=' + node.x); // TEST\r\n this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved\r\n node._moving = true; // AFTER, mark as moving object (wanted fix location before)\r\n }\r\n\r\n // set the min/max resize info\r\n this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop as number, this.opts.marginRight as number, this.opts.marginBottom as number, this.opts.marginLeft as number);\r\n if (event.type === 'resizestart') {\r\n dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))\r\n .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));\r\n if (node.maxW) { dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW); }\r\n if (node.maxH) { dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH); }\r\n }\r\n}\r\n\r\n/** @internal called when item leaving our area by either cursor dropout event\r\n * or shape is outside our boundaries. remove it from us, and mark temporary if this was\r\n * our item to start with else restore prev node values from prev grid it came from.\r\n **/\r\nGridStack.prototype._leave = function(this: GridStack, el: GridItemHTMLElement, helper?: GridItemHTMLElement) {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n\r\n dd.off(el, 'drag'); // no need to track while being outside\r\n\r\n // this gets called when cursor leaves and shape is outside, so only do this once\r\n if (node._temporaryRemoved) return;\r\n node._temporaryRemoved = true;\r\n\r\n this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue\r\n node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged\r\n\r\n if (this.opts.removable === true) { // boolean vs a class string\r\n // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so\r\n _itemRemoving(el, true);\r\n }\r\n\r\n // finally if item originally came from another grid, but left us, restore things back to prev info\r\n if (el._gridstackNodeOrig) {\r\n // console.log('leave delete _gridstackNodeOrig') // TEST\r\n el.gridstackNode = el._gridstackNodeOrig;\r\n delete el._gridstackNodeOrig;\r\n } else if (node._isExternal) {\r\n // item came from outside (like a toolbar) so nuke any node info\r\n delete node.el;\r\n delete el.gridstackNode;\r\n // and restore all nodes back to original\r\n this.engine.restoreInitial();\r\n }\r\n}\r\n\r\n/** @internal called when item is being dragged/resized */\r\nGridStack.prototype._dragOrResize = function(this: GridStack, el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number) {\r\n let p = {...node._orig}; // could be undefined (_isExternal) which is ok (drag only set x,y and w,h will default to node value)\r\n let resizing: boolean;\r\n let mLeft = this.opts.marginLeft as number,\r\n mRight = this.opts.marginRight as number,\r\n mTop = this.opts.marginTop as number,\r\n mBottom = this.opts.marginBottom as number;\r\n\r\n // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855\r\n let mHeight = Math.round(cellHeight * 0.1),\r\n mWidth = Math.round(cellWidth * 0.1);\r\n mLeft = Math.min(mLeft, mWidth);\r\n mRight = Math.min(mRight, mWidth);\r\n mTop = Math.min(mTop, mHeight);\r\n mBottom = Math.min(mBottom, mHeight);\r\n\r\n if (event.type === 'drag') {\r\n if (node._temporaryRemoved) return; // handled by dropover\r\n let distance = ui.position.top - node._prevYPix;\r\n node._prevYPix = ui.position.top;\r\n Utils.updateScrollPosition(el, ui.position, distance);\r\n\r\n // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)\r\n let left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);\r\n let top = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n // @ts-ignore// if we're at the bottom hitting something else, grow the grid so cursor doesn't leave when trying to place below others\r\n let prev = this._extraDragRow;\r\n if (this.engine.collide(node, p)) {\r\n let row = this.getRow();\r\n let extra = Math.max(0, (p.y + node.h) - row);\r\n if (this.opts.maxRow && row + extra > this.opts.maxRow) {\r\n extra = Math.max(0, this.opts.maxRow - row);\r\n }// @ts-ignore\r\n this._extraDragRow = extra;// @ts-ignore\r\n } else this._extraDragRow = 0;// @ts-ignore\r\n if (this._extraDragRow !== prev) this._updateContainerHeight();\r\n\r\n if (node.x === p.x && node.y === p.y) return; // skip same\r\n // DON'T skip one we tried as we might have failed because of coverage <50% before\r\n // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;\r\n } else if (event.type === 'resize') {\r\n if (p.x < 0) return;\r\n // Scrolling page if needed\r\n Utils.updateScrollResize(event as MouseEvent, el, cellHeight);\r\n\r\n // get new size\r\n p.w = Math.round((ui.size.width - mLeft) / cellWidth);\r\n p.h = Math.round((ui.size.height - mTop) / cellHeight);\r\n if (node.w === p.w && node.h === p.h) return;\r\n if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h) return; // skip one we tried (but failed)\r\n\r\n // if we size on left/top side this might move us, so get possible new position as well\r\n let left = ui.position.left + mLeft;\r\n let top = ui.position.top + mTop;\r\n p.x = Math.round(left / cellWidth);\r\n p.y = Math.round(top / cellHeight);\r\n\r\n resizing = true;\r\n }\r\n\r\n node._lastTried = p; // set as last tried (will nuke if we go there)\r\n let rect: GridStackPosition = { // screen pix of the dragged box\r\n x: ui.position.left + mLeft,\r\n y: ui.position.top + mTop,\r\n w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,\r\n h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom\r\n };\r\n if (this.engine.moveNodeCheck(node, {...p, cellWidth, cellHeight, rect, resizing})) {\r\n node._lastUiPosition = ui.position;\r\n this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);\r\n delete node._skipDown;\r\n if (resizing && node.subGrid) { (node.subGrid as GridStack).onParentResize(); }// @ts-ignore\r\n this._extraDragRow = 0;// @ts-ignore\r\n this._updateContainerHeight();\r\n\r\n let target = event.target as GridItemHTMLElement;// @ts-ignore\r\n this._writePosAttr(target, node);\r\n if (this._gsEventHandler[event.type]) {\r\n this._gsEventHandler[event.type](event, target);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Enables/Disables moving.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\nGridStack.prototype.movable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noMove; else node.noMove = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Enables/Disables resizing.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\nGridStack.prototype.resizable = function(this: GridStack, els: GridStackElement, val: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't resize a static grid!\r\n GridStack.getElements(els).forEach(el => {\r\n let node = el.gridstackNode;\r\n if (!node) return;\r\n if (val) delete node.noResize; else node.noResize = true;\r\n this._prepareDragDropByNode(node); // init DD if need be, and adjust\r\n });\r\n return this;\r\n}\r\n\r\n/**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\nGridStack.prototype.disable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(false);\r\n this.enableResize(false);// @ts-ignore\r\n this._triggerEvent('disable');\r\n return this;\r\n}\r\n\r\n/**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\nGridStack.prototype.enable = function(this: GridStack): GridStack {\r\n if (this.opts.staticGrid) return;\r\n this.enableMove(true);\r\n this.enableResize(true);// @ts-ignore\r\n this._triggerEvent('enable');\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget moving. No-op for static grids. */\r\nGridStack.prototype.enableMove = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't move a static grid!\r\n this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.movable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** Enables/disables widget resizing. No-op for static grids. */\r\nGridStack.prototype.enableResize = function(this: GridStack, doEnable: boolean): GridStack {\r\n if (this.opts.staticGrid) return this; // can't size a static grid!\r\n this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658\r\n this.engine.nodes.forEach(n => this.resizable(n.el, doEnable));\r\n return this;\r\n}\r\n\r\n/** removes any drag&drop present (called during destroy) */\r\nGridStack.prototype._removeDD = function(this: GridStack, el: GridItemHTMLElement): GridStack {\r\n dd.draggable(el, 'destroy').resizable(el, 'destroy');\r\n if (el.gridstackNode) {\r\n delete el.gridstackNode._initDD; // reset our DD init flag\r\n }\r\n return this;\r\n}\r\n\r\n","/**\n * dd-manager.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDDraggable } from './dd-draggable';\nimport { DDDroppable } from './dd-droppable';\nimport { DDResizable } from './dd-resizable';\n\n/**\n * globals that are shared across Drag & Drop instances\n */\nexport class DDManager {\n /** true if a mouse down event was handled */\n public static mouseHandled: boolean;\n\n /** item being dragged */\n public static dragElement: DDDraggable;\n\n /** item we are currently over as drop target */\n public static dropElement: DDDroppable;\n\n /** current item we're over for resizing purpose (ignore nested grid resize handles) */\n public static overResizeElement: DDResizable;\n\n}\n","/**\n * dd-resizable-handle.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { isTouch, pointerdown, touchend, touchmove, touchstart } from './dd-touch';\n\nexport interface DDResizableHandleOpt {\n start?: (event) => void;\n move?: (event) => void;\n stop?: (event) => void;\n}\n\nexport class DDResizableHandle {\n /** @internal */\n protected el: HTMLElement;\n /** @internal */\n protected host: HTMLElement;\n /** @internal */\n protected option: DDResizableHandleOpt;\n /** @internal */\n protected dir: string;\n /** @internal true after we've moved enough pixels to start a resize */\n protected moving = false;\n /** @internal */\n protected mouseDownEvent: MouseEvent;\n /** @internal */\n protected static prefix = 'ui-resizable-';\n\n constructor(host: HTMLElement, direction: string, option: DDResizableHandleOpt) {\n this.host = host;\n this.dir = direction;\n this.option = option;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseDown = this._mouseDown.bind(this);\n this._mouseMove = this._mouseMove.bind(this);\n this._mouseUp = this._mouseUp.bind(this);\n\n this._init();\n }\n\n /** @internal */\n protected _init(): DDResizableHandle {\n const el = document.createElement('div');\n el.classList.add('ui-resizable-handle');\n el.classList.add(`${DDResizableHandle.prefix}${this.dir}`);\n el.style.zIndex = '100';\n el.style.userSelect = 'none';\n this.el = el;\n this.host.appendChild(this.el);\n this.el.addEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.addEventListener('touchstart', touchstart);\n this.el.addEventListener('pointerdown', pointerdown);\n // this.el.style.touchAction = 'none'; // not needed unlike pointerdown doc comment\n }\n return this;\n }\n\n /** call this when resize handle needs to be removed and cleaned up */\n public destroy(): DDResizableHandle {\n if (this.moving) this._mouseUp(this.mouseDownEvent);\n this.el.removeEventListener('mousedown', this._mouseDown);\n if (isTouch) {\n this.el.removeEventListener('touchstart', touchstart);\n this.el.removeEventListener('pointerdown', pointerdown);\n }\n this.host.removeChild(this.el);\n delete this.el;\n delete this.host;\n return this;\n }\n\n /** @internal called on mouse down on us: capture move on the entire document (mouse might not stay on us) until we release the mouse */\n protected _mouseDown(e: MouseEvent) {\n this.mouseDownEvent = e;\n document.addEventListener('mousemove', this._mouseMove, true); // capture, not bubble\n document.addEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.addEventListener('touchmove', touchmove);\n this.el.addEventListener('touchend', touchend);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseMove(e: MouseEvent) {\n let s = this.mouseDownEvent;\n if (this.moving) {\n this._triggerEvent('move', e);\n } else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 2) {\n // don't start unless we've moved at least 3 pixels\n this.moving = true;\n this._triggerEvent('start', this.mouseDownEvent);\n this._triggerEvent('move', e);\n }\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _mouseUp(e: MouseEvent) {\n if (this.moving) {\n this._triggerEvent('stop', e);\n }\n document.removeEventListener('mousemove', this._mouseMove, true);\n document.removeEventListener('mouseup', this._mouseUp, true);\n if (isTouch) {\n this.el.removeEventListener('touchmove', touchmove);\n this.el.removeEventListener('touchend', touchend);\n }\n delete this.moving;\n delete this.mouseDownEvent;\n e.stopPropagation();\n e.preventDefault();\n }\n\n /** @internal */\n protected _triggerEvent(name: string, event: MouseEvent): DDResizableHandle {\n if (this.option[name]) this.option[name](event);\n return this;\n }\n}\n","/**\n * dd-resizable.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { DDResizableHandle } from './dd-resizable-handle';\nimport { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';\nimport { Utils } from './utils';\nimport { DDUIData, Rect, Size } from './types';\nimport { DDManager } from './dd-manager';\n\n// import { GridItemHTMLElement } from './types'; let count = 0; // TEST\n\n// TODO: merge with DDDragOpt\nexport interface DDResizableOpt {\n autoHide?: boolean;\n handles?: string;\n maxHeight?: number;\n maxWidth?: number;\n minHeight?: number;\n minWidth?: number;\n fixedAspectRatio?: number;\n start?: (event: Event, ui: DDUIData) => void;\n stop?: (event: Event) => void;\n resize?: (event: Event, ui: DDUIData) => void;\n}\n\nexport class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt {\n\n // have to be public else complains for HTMLElementExtendOpt ?\n public el: HTMLElement;\n public option: DDResizableOpt;\n\n /** @internal */\n protected handlers: DDResizableHandle[];\n /** @internal */\n protected originalRect: Rect;\n /** @internal */\n protected temporalRect: Rect;\n /** @internal */\n protected scrollY: number;\n /** @internal */\n protected scrolled: number;\n /** @internal */\n protected scrollEl: HTMLElement;\n /** @internal */\n protected startEvent: MouseEvent;\n /** @internal value saved in the same order as _originStyleProp[] */\n protected elOriginStyleVal: string[];\n /** @internal */\n protected parentOriginStylePosition: string;\n /** @internal */\n protected static _originStyleProp = ['width', 'height', 'position', 'left', 'top', 'opacity', 'zIndex'];\n\n constructor(el: HTMLElement, opts: DDResizableOpt = {}) {\n super();\n this.el = el;\n this.option = opts;\n // create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)\n this._mouseOver = this._mouseOver.bind(this);\n this._mouseOut = this._mouseOut.bind(this);\n this.enable();\n this._setupAutoHide(this.option.autoHide);\n this._setupHandlers();\n }\n\n public on(event: 'resizestart' | 'resize' | 'resizestop', callback: (event: DragEvent) => void): void {\n super.on(event, callback);\n }\n\n public off(event: 'resizestart' | 'resize' | 'resizestop'): void {\n super.off(event);\n }\n\n public enable(): void {\n super.enable();\n this.el.classList.add('ui-resizable');\n this.el.classList.remove('ui-resizable-disabled');\n this._setupAutoHide(this.option.autoHide);\n }\n\n public disable(): void {\n super.disable();\n this.el.classList.add('ui-resizable-disabled');\n this.el.classList.remove('ui-resizable');\n this._setupAutoHide(false);\n }\n\n public destroy(): void {\n this._removeHandlers();\n this._setupAutoHide(false);\n this.el.classList.remove('ui-resizable');\n delete this.el;\n super.destroy();\n }\n\n public updateOption(opts: DDResizableOpt): DDResizable {\n let updateHandles = (opts.handles && opts.handles !== this.option.handles);\n let updateAutoHide = (opts.autoHide && opts.autoHide !== this.option.autoHide);\n Object.keys(opts).forEach(key => this.option[key] = opts[key]);\n if (updateHandles) {\n this._removeHandlers();\n this._setupHandlers();\n }\n if (updateAutoHide) {\n this._setupAutoHide(this.option.autoHide);\n }\n return this;\n }\n\n /** @internal turns auto hide on/off */\n protected _setupAutoHide(auto: boolean): DDResizable {\n if (auto) {\n this.el.classList.add('ui-resizable-autohide');\n // use mouseover and not mouseenter to get better performance and track for nested cases\n this.el.addEventListener('mouseover', this._mouseOver);\n this.el.addEventListener('mouseout', this._mouseOut);\n } else {\n this.el.classList.remove('ui-resizable-autohide');\n this.el.removeEventListener('mouseover', this._mouseOver);\n this.el.removeEventListener('mouseout', this._mouseOut);\n if (DDManager.overResizeElement === this) {\n delete DDManager.overResizeElement;\n } \n }\n return this;\n }\n\n /** @internal */\n protected _mouseOver(e: Event) {\n // console.log(`${count++} pre-enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n // already over a child, ignore. Ideally we just call e.stopPropagation() but see https://github.com/gridstack/gridstack.js/issues/2018\n if (DDManager.overResizeElement || DDManager.dragElement) return;\n DDManager.overResizeElement = this;\n // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.remove('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _mouseOut(e: Event) {\n // console.log(`${count++} pre-leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n if (DDManager.overResizeElement !== this) return;\n delete DDManager.overResizeElement;\n // console.log(`${count++} leave ${(this.el as GridItemHTMLElement).gridstackNode._id}`)\n this.el.classList.add('ui-resizable-autohide');\n }\n\n /** @internal */\n protected _setupHandlers(): DDResizable {\n let handlerDirection = this.option.handles || 'e,s,se';\n if (handlerDirection === 'all') {\n handlerDirection = 'n,e,s,w,se,sw,ne,nw';\n }\n this.handlers = handlerDirection.split(',')\n .map(dir => dir.trim())\n .map(dir => new DDResizableHandle(this.el, dir, {\n start: (event: MouseEvent) => {\n this._resizeStart(event);\n },\n stop: (event: MouseEvent) => {\n this._resizeStop(event);\n },\n move: (event: MouseEvent) => {\n this._resizing(event, dir);\n }\n }));\n return this;\n }\n\n /** @internal */\n protected _resizeStart(event: MouseEvent): DDResizable {\n this.originalRect = this.el.getBoundingClientRect();\n this.scrollEl = Utils.getScrollElement(this.el);\n this.scrollY = this.scrollEl.scrollTop;\n this.scrolled = 0;\n this.startEvent = event;\n this._setupHelper();\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el });\n if (this.option.start) {\n this.option.start(ev, this._ui());\n }\n this.el.classList.add('ui-resizable-resizing');\n this.triggerEvent('resizestart', ev);\n return this;\n }\n\n /** @internal */\n protected _resizing(event: MouseEvent, dir: string): DDResizable {\n this.scrolled = this.scrollEl.scrollTop - this.scrollY;\n this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio);\n this._applyChange();\n const ev = Utils.initEvent(event, { type: 'resize', target: this.el });\n if (this.option.resize) {\n this.option.resize(ev, this._ui());\n }\n this.triggerEvent('resize', ev);\n return this;\n }\n\n /** @internal */\n protected _resizeStop(event: MouseEvent): DDResizable {\n const ev = Utils.initEvent(event, { type: 'resizestop', target: this.el });\n if (this.option.stop) {\n this.option.stop(ev); // Note: ui() not used by gridstack so don't pass\n }\n this.el.classList.remove('ui-resizable-resizing');\n this.triggerEvent('resizestop', ev);\n this._cleanHelper();\n delete this.startEvent;\n delete this.originalRect;\n delete this.temporalRect;\n delete this.scrollY;\n delete this.scrolled;\n return this;\n }\n\n /** @internal */\n protected _setupHelper(): DDResizable {\n this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);\n this.parentOriginStylePosition = this.el.parentElement.style.position;\n if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) {\n this.el.parentElement.style.position = 'relative';\n }\n this.el.style.position = 'absolute';\n this.el.style.opacity = '0.8';\n return this;\n }\n\n /** @internal */\n protected _cleanHelper(): DDResizable {\n DDResizable._originStyleProp.forEach((prop, i) => {\n this.el.style[prop] = this.elOriginStyleVal[i] || null;\n });\n this.el.parentElement.style.position = this.parentOriginStylePosition || null;\n return this;\n }\n\n /** @internal */\n protected _getChange(event: MouseEvent, dir: string, fixedAspectRatio?: number): Rect {\n const fixedAspect = typeof(fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio);\n const oEvent = this.startEvent;\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled),\n left: this.originalRect.left,\n top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled)\n };\n\n const offsetX = event.clientX - oEvent.clientX;\n const offsetY = event.clientY - oEvent.clientY;\n\n if (fixedAspect)\n {\n // If the window is being resized using the corner\n if (dir.length > 1) {\n\n if (offsetX > offsetY) {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n } else {\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n \n\n\n } else {\n if (dir.indexOf('e') > -1) {\n newRect.width += offsetX;\n newRect.height += Math.round(offsetX / fixedAspectRatio);\n } else if (dir.indexOf('w') > -1) {\n newRect.width -= offsetX;\n newRect.left += offsetX;\n\n newRect.height -= Math.round(offsetX / fixedAspectRatio);\n newRect.top += Math.round(offsetX / fixedAspectRatio);\n }\n\n if (dir.indexOf('s') > -1) {\n newRect.height += offsetY;\n newRect.width += Math.round(offsetY * fixedAspectRatio);\n } else if (dir.indexOf('n') > -1) {\n newRect.height -= offsetY;\n newRect.top += offsetY;\n\n newRect.width -= Math.round(offsetY * fixedAspectRatio);\n newRect.left += Math.round(offsetY * fixedAspectRatio);\n }\n }\n }\n else\n {\n if (dir.indexOf('e') > -1) { // East\n newRect.width += offsetX;\n } else if (dir.indexOf('w') > -1) { // West\n newRect.width -= offsetX;\n newRect.left += offsetX;\n }\n\n if (dir.indexOf('s') > -1) { // South // HERE\n newRect.height += offsetY;\n } else if (dir.indexOf('n') > -1) { // North\n newRect.height -= offsetY;\n newRect.top += offsetY\n }\n }\n\n const constrain = this._constrainSize(newRect.width, newRect.height);\n if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors\n if (dir.indexOf('w') > -1) {\n newRect.left += newRect.width - constrain.width;\n }\n newRect.width = constrain.width;\n }\n if (Math.round(newRect.height) !== Math.round(constrain.height)) {\n if (dir.indexOf('n') > -1) {\n newRect.top += newRect.height - constrain.height;\n }\n newRect.height = constrain.height;\n }\n return newRect;\n }\n\n /** @internal constrain the size to the set min/max values */\n protected _constrainSize(oWidth: number, oHeight: number): Size {\n const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;\n const minWidth = this.option.minWidth || oWidth;\n const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;\n const minHeight = this.option.minHeight || oHeight;\n const width = Math.min(maxWidth, Math.max(minWidth, oWidth));\n const height = Math.min(maxHeight, Math.max(minHeight, oHeight));\n return { width, height };\n }\n\n /** @internal */\n protected _applyChange(): DDResizable {\n let containmentRect = { left: 0, top: 0, width: 0, height: 0 };\n if (this.el.style.position === 'absolute') {\n const containmentEl = this.el.parentElement;\n const { left, top } = containmentEl.getBoundingClientRect();\n containmentRect = { left, top, width: 0, height: 0 };\n }\n if (!this.temporalRect) return this;\n Object.keys(this.temporalRect).forEach(key => {\n const value = this.temporalRect[key];\n this.el.style[key] = value - containmentRect[key] + 'px';\n });\n return this;\n }\n\n /** @internal */\n protected _removeHandlers(): DDResizable {\n this.handlers.forEach(handle => handle.destroy());\n delete this.handlers;\n return this;\n }\n\n /** @internal */\n protected _ui = (): DDUIData => {\n const containmentEl = this.el.parentElement;\n const containmentRect = containmentEl.getBoundingClientRect();\n const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out.\n width: this.originalRect.width,\n height: this.originalRect.height + this.scrolled,\n left: this.originalRect.left,\n top: this.originalRect.top - this.scrolled\n };\n const rect = this.temporalRect || newRect;\n return {\n position: {\n left: rect.left - containmentRect.left,\n top: rect.top - containmentRect.top\n },\n size: {\n width: rect.width,\n height: rect.height\n }\n /* Gridstack ONLY needs position set above... keep around in case.\n element: [this.el], // The object representing the element to be resized\n helper: [], // TODO: not support yet - The object representing the helper that's being resized\n originalElement: [this.el],// we don't wrap here, so simplify as this.el //The object representing the original element before it is wrapped\n originalPosition: { // The position represented as { left, top } before the resizable is resized\n left: this.originalRect.left - containmentRect.left,\n top: this.originalRect.top - containmentRect.top\n },\n originalSize: { // The size represented as { width, height } before the resizable is resized\n width: this.originalRect.width,\n height: this.originalRect.height\n }\n */\n };\n }\n}\n","/**\n * touch.ts 6.0.1-dev\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\n */\n\nimport { DDManager } from './dd-manager';\n\n/**\n * Detect touch support - Windows Surface devices and other touch devices\n * should we use this instead ? (what we had for always showing resize handles)\n * /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n */\nexport const isTouch: boolean = ( 'ontouchstart' in document\n || 'ontouchstart' in window\n // || !!window.TouchEvent // true on Windows 10 Chrome desktop so don't use this\n || ((window as any).DocumentTouch && document instanceof (window as any).DocumentTouch)\n || navigator.maxTouchPoints > 0\n || (navigator as any).msMaxTouchPoints > 0\n);\n\n// interface TouchCoord {x: number, y: number};\n\nclass DDTouch {\n public static touchHandled: boolean;\n public static pointerLeaveTimeout: number;\n}\n\n/**\n* Get the x,y position of a touch event\n*/\n// function getTouchCoords(e: TouchEvent): TouchCoord {\n// return {\n// x: e.changedTouches[0].pageX,\n// y: e.changedTouches[0].pageY\n// };\n// }\n\n/**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} e A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulateMouseEvent(e: TouchEvent, simulatedType: string) {\n\n // Ignore multi-touch events\n if (e.touches.length > 1) return;\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const touch = e.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n/**\n * Simulate a mouse event based on a corresponding Pointer event\n * @param {Object} e A pointer event\n * @param {String} simulatedType The corresponding mouse event\n */\nfunction simulatePointerMouseEvent(e: PointerEvent, simulatedType: string) {\n\n // Prevent \"Ignored attempt to cancel a touchmove event with cancelable=false\" errors\n if (e.cancelable) e.preventDefault();\n\n const simulatedEvent = document.createEvent('MouseEvents');\n\n // Initialize the simulated mouse event using the touch event's coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n e.screenX, // screenX\n e.screenY, // screenY\n e.clientX, // clientX\n e.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n e.target.dispatchEvent(simulatedEvent);\n}\n\n\n/**\n * Handle the touchstart events\n * @param {Object} e The widget element's touchstart event\n */\nexport function touchstart(e: TouchEvent) {\n // Ignore the event if another widget is already being handled\n if (DDTouch.touchHandled) return; DDTouch.touchHandled = true;\n\n // Simulate the mouse events\n // simulateMouseEvent(e, 'mouseover');\n // simulateMouseEvent(e, 'mousemove');\n simulateMouseEvent(e, 'mousedown');\n}\n\n/**\n * Handle the touchmove events\n * @param {Object} e The document's touchmove event\n */\nexport function touchmove(e: TouchEvent) {\n // Ignore event if not handled by us\n if (!DDTouch.touchHandled) return;\n\n simulateMouseEvent(e, 'mousemove');\n}\n\n/**\n * Handle the touchend events\n * @param {Object} e The document's touchend event\n */\nexport function touchend(e: TouchEvent) {\n\n // Ignore event if not handled\n if (!DDTouch.touchHandled) return;\n\n // cancel delayed leave event when we release on ourself which happens BEFORE we get this!\n if (DDTouch.pointerLeaveTimeout) {\n window.clearTimeout(DDTouch.pointerLeaveTimeout);\n delete DDTouch.pointerLeaveTimeout;\n }\n\n const wasDragging = !!DDManager.dragElement;\n\n // Simulate the mouseup event\n simulateMouseEvent(e, 'mouseup');\n // simulateMouseEvent(event, 'mouseout');\n\n // If the touch interaction did not move, it should trigger a click\n if (!wasDragging) {\n simulateMouseEvent(e, 'click');\n }\n\n // Unset the flag to allow other widgets to inherit the touch event\n DDTouch.touchHandled = false;\n}\n\n/**\n * Note we don't get touchenter/touchleave (which are deprecated)\n * see https://stackoverflow.com/questions/27908339/js-touch-equivalent-for-mouseenter\n * so instead of PointerEvent to still get enter/leave and send the matching mouse event.\n */\nexport function pointerdown(e: PointerEvent) {\n (e.target as HTMLElement).releasePointerCapture(e.pointerId) // <- Important!\n}\n\nexport function pointerenter(e: PointerEvent) {\n // ignore the initial one we get on pointerdown on ourself\n if (!DDManager.dragElement) {\n // console.log('pointerenter ignored');\n return;\n }\n // console.log('pointerenter');\n simulatePointerMouseEvent(e, 'mouseenter');\n}\n\nexport function pointerleave(e: PointerEvent) {\n // ignore the leave on ourself we get before releasing the mouse over ourself\n // by delaying sending the event and having the up event cancel us\n if (!DDManager.dragElement) {\n // console.log('pointerleave ignored');\n return;\n }\n DDTouch.pointerLeaveTimeout = window.setTimeout(() => {\n delete DDTouch.pointerLeaveTimeout;\n // console.log('pointerleave delayed');\n simulatePointerMouseEvent(e, 'mouseleave');\n }, 10);\n}\n\n","/**\n * gridstack-engine.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { Utils } from './utils';\nimport { GridStackNode, ColumnOptions, GridStackPosition, GridStackMoveOpts } from './types';\n\n/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */\ntype OnChangeCB = (nodes: GridStackNode[]) => void;\n\n/** options used during creation - similar to GridStackOptions */\nexport interface GridStackEngineOptions {\n column?: number;\n maxRow?: number;\n float?: boolean;\n nodes?: GridStackNode[];\n onChange?: OnChangeCB;\n}\n\n/**\n * Defines the GridStack engine that does most no DOM grid manipulation.\n * See GridStack methods and vars for descriptions.\n *\n * NOTE: values should not be modified directly - call the main GridStack API instead\n */\nexport class GridStackEngine {\n public column: number;\n public maxRow: number;\n public nodes: GridStackNode[];\n public addedNodes: GridStackNode[] = [];\n public removedNodes: GridStackNode[] = [];\n public batchMode: boolean;\n /** @internal callback to update the DOM attributes */\n protected onChange: OnChangeCB;\n /** @internal */\n protected _float: boolean;\n /** @internal */\n protected _prevFloat: boolean;\n /** @internal cached layouts of difference column count so we can restore ack (eg 12 -> 1 -> 12) */\n protected _layouts?: GridStackNode[][]; // maps column # to array of values nodes\n /** @internal true while we are resizing widgets during column resize to skip certain parts */\n protected _inColumnResize: boolean;\n /** @internal true if we have some items locked */\n protected _hasLocked: boolean;\n /** @internal unique global internal _id counter NOT starting at 0 */\n protected static _idSeq = 1;\n\n public constructor(opts: GridStackEngineOptions = {}) {\n this.column = opts.column || 12;\n this.maxRow = opts.maxRow;\n this._float = opts.float;\n this.nodes = opts.nodes || [];\n this.onChange = opts.onChange;\n }\n\n public batchUpdate(flag = true): GridStackEngine {\n if (!!this.batchMode === flag) return this;\n this.batchMode = flag;\n if (flag) {\n this._prevFloat = this._float;\n this._float = true; // let things go anywhere for now... will restore and possibly reposition later\n this.saveInitial(); // since begin update (which is called multiple times) won't do this\n } else {\n this._float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes()._notify();\n }\n return this;\n }\n\n // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip\n protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean {\n return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y);\n }\n\n /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.\n * return true if we moved. */\n protected _fixCollisions(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {}): boolean {\n this.sortNodes(-1); // from last to first, so recursive collision move items in the right order\n\n collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none...\n if (!collide) return false;\n\n // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size\n if (node._moving && !opt.nested && !this.float) {\n if (this.swap(node, collide)) return true;\n }\n\n // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)\n let area = nn;\n if (this._useEntireRowArea(node, nn)) {\n area = {x: 0, w: this.column, y: nn.y, h: nn.h};\n collide = this.collide(node, area, opt.skip); // force new hit\n }\n\n let didMove = false;\n let newOpt: GridStackMoveOpts = {nested: true, pack: false};\n while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each\n let moved: boolean;\n // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,\n // but remember that skip down so we only do this once (and push others otherwise).\n if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&\n // can take space we had, or before where we're going\n (!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {\n node._skipDown = (node._skipDown || nn.y > node.y);\n moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});\n if (collide.locked && moved) {\n Utils.copyPos(nn, node); // moving after lock become our new desired location\n } else if (!collide.locked && moved && opt.pack) {\n // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way\n this._packNodes();\n nn.y = collide.y + collide.h;\n Utils.copyPos(node, nn);\n }\n didMove = didMove || moved;\n } else {\n // move collide down *after* where we will be, ignoring where we are now (don't collide with us)\n moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt});\n }\n if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)\n collide = undefined;\n }\n return didMove;\n }\n\n /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */\n public collide(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode {\n return this.nodes.find(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n public collideAll(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode[] {\n return this.nodes.filter(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n\n /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */\n public collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode {\n if (!o.rect || !node._rect) return;\n let r0 = node._rect; // where started\n let r = {...o.rect}; // where we are\n\n // update dragged rect to show where it's coming from (above or below, etc...)\n if (r.y > r0.y) {\n r.h += r.y - r0.y;\n r.y = r0.y;\n } else {\n r.h += r0.y - r.y;\n }\n if (r.x > r0.x) {\n r.w += r.x - r0.x;\n r.x = r0.x;\n } else {\n r.w += r0.x - r.x;\n }\n\n let collide: GridStackNode;\n collides.forEach(n => {\n if (n.locked || !n._rect) return;\n let r2 = n._rect; // overlapping target\n let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50%\n // depending on which side we started from, compute the overlap % of coverage\n // (ex: from above/below we only compute the max horizontal line coverage)\n if (r0.y < r2.y) { // from above\n yOver = ((r.y + r.h) - r2.y) / r2.h;\n } else if (r0.y+r0.h > r2.y+r2.h) { // from below\n yOver = ((r2.y + r2.h) - r.y) / r2.h;\n }\n if (r0.x < r2.x) { // from the left\n xOver = ((r.x + r.w) - r2.x) / r2.w;\n } else if (r0.x+r0.w > r2.x+r2.w) { // from the right\n xOver = ((r2.x + r2.w) - r.x) / r2.w;\n }\n let over = Math.min(xOver, yOver);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n return collide;\n }\n\n /** called to cache the nodes pixel rectangles used for collision detection during drag */\n public cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine\n {\n this.nodes.forEach(n =>\n n._rect = {\n y: n.y * h + top,\n x: n.x * w + left,\n w: n.w * w - left - right,\n h: n.h * h - top - bottom\n }\n );\n return this;\n }\n\n /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */\n public swap(a: GridStackNode, b: GridStackNode): boolean {\n if (!b || b.locked || !a || a.locked) return false;\n\n function _doSwap(): true { // assumes a is before b IFF they have different height (put after rather than exact swap)\n let x = b.x, y = b.y;\n b.x = a.x; b.y = a.y; // b -> a position\n if (a.h != b.h) {\n a.x = x; a.y = b.y + b.h; // a -> goes after b\n } else if (a.w != b.w) {\n a.x = b.x + b.w; a.y = y; // a -> goes after b\n } else {\n a.x = x; a.y = y; // a -> old b position\n }\n a._dirty = b._dirty = true;\n return true;\n }\n let touching: boolean; // remember if we called it (vs undefined)\n\n // same size and same row or column, and touching\n if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = Utils.isTouching(a, b)))\n return _doSwap();\n if (touching === false) return; // IFF ran test and fail, bail out\n\n // check for taking same columns (but different height) and touching\n if (a.w === b.w && a.x === b.x && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.y < a.y) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n if (touching === false) return;\n\n // check if taking same row (but different width) and touching\n if (a.h === b.h && a.y === b.y && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.x < a.x) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n return false;\n }\n\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\n let nn: GridStackNode = {x: x || 0, y: y || 0, w: w || 1, h: h || 1};\n return !this.collide(nn);\n }\n\n /** re-layout grid items to reclaim any empty space */\n public compact(): GridStackEngine {\n if (this.nodes.length === 0) return this;\n this.batchUpdate()\n .sortNodes();\n let copyNodes = this.nodes;\n this.nodes = []; // pretend we have no nodes to conflict layout to start with...\n copyNodes.forEach(node => {\n if (!node.locked) {\n node.autoPosition = true;\n }\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // will force attr update\n });\n return this.batchUpdate(false);\n }\n\n /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */\n public set float(val: boolean) {\n if (this._float === val) return;\n this._float = val || false;\n if (!val) {\n this._packNodes()._notify();\n }\n }\n\n /** float getter method */\n public get float(): boolean { return this._float || false; }\n\n /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */\n public sortNodes(dir?: -1 | 1): GridStackEngine {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n return this;\n }\n\n /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */\n protected _packNodes(): GridStackEngine {\n if (this.batchMode) { return this; }\n this.sortNodes(); // first to last\n\n if (this.float) {\n // restore original Y pos\n this.nodes.forEach(n => {\n if (n._updating || n._orig === undefined || n.y === n._orig.y) return;\n let newY = n.y;\n while (newY > n._orig.y) {\n --newY;\n let collide = this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!collide) {\n n._dirty = true;\n n.y = newY;\n }\n }\n });\n } else {\n // top gravity pack\n this.nodes.forEach((n, i) => {\n if (n.locked) return;\n while (n.y > 0) {\n let newY = i === 0 ? 0 : n.y - 1;\n let canBeMoved = i === 0 || !this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!canBeMoved) break;\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n });\n }\n return this;\n }\n\n /**\n * given a random node, makes sure it's coordinates/values are valid in the current grid\n * @param node to adjust\n * @param resizing if out of bound, resize down or move into the grid to fit ?\n */\n public prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode {\n node = node || {};\n node._id = node._id || GridStackEngine._idSeq++;\n\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n\n // assign defaults for missing required fields\n let defaults: GridStackNode = { x: 0, y: 0, w: 1, h: 1};\n Utils.defaults(node, defaults);\n\n if (!node.autoPosition) { delete node.autoPosition; }\n if (!node.noResize) { delete node.noResize; }\n if (!node.noMove) { delete node.noMove; }\n\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (typeof node.x == 'string') { node.x = Number(node.x); }\n if (typeof node.y == 'string') { node.y = Number(node.y); }\n if (typeof node.w == 'string') { node.w = Number(node.w); }\n if (typeof node.h == 'string') { node.h = Number(node.h); }\n if (isNaN(node.x)) { node.x = defaults.x; node.autoPosition = true; }\n if (isNaN(node.y)) { node.y = defaults.y; node.autoPosition = true; }\n if (isNaN(node.w)) { node.w = defaults.w; }\n if (isNaN(node.h)) { node.h = defaults.h; }\n\n return this.nodeBoundFix(node, resizing);\n }\n\n /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */\n public nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode {\n\n let before = node._orig || Utils.copyPos({}, node);\n\n if (node.maxW) { node.w = Math.min(node.w, node.maxW); }\n if (node.maxH) { node.h = Math.min(node.h, node.maxH); }\n if (node.minW && node.minW <= this.column) { node.w = Math.max(node.w, node.minW); }\n if (node.minH) { node.h = Math.max(node.h, node.minH); }\n\n if (node.w > this.column) {\n // if user loaded a larger than allowed widget for current # of columns,\n // remember it's full width so we can restore back (1 -> 12 column) #1655\n // IFF we're not in the middle of column resizing!\n if (this.column < 12 && !this._inColumnResize) {\n node.w = Math.min(12, node.w);\n this.cacheOneLayout(node, 12);\n }\n node.w = this.column;\n } else if (node.w < 1) {\n node.w = 1;\n }\n\n if (this.maxRow && node.h > this.maxRow) {\n node.h = this.maxRow;\n } else if (node.h < 1) {\n node.h = 1;\n }\n\n if (node.x < 0) {\n node.x = 0;\n }\n if (node.y < 0) {\n node.y = 0;\n }\n\n if (node.x + node.w > this.column) {\n if (resizing) {\n node.w = this.column - node.x;\n } else {\n node.x = this.column - node.w;\n }\n }\n if (this.maxRow && node.y + node.h > this.maxRow) {\n if (resizing) {\n node.h = this.maxRow - node.y;\n } else {\n node.y = this.maxRow - node.h;\n }\n }\n\n if (!Utils.samePos(node, before)) {\n node._dirty = true;\n }\n\n return node;\n }\n\n /** returns a list of modified nodes from their original values */\n public getDirtyNodes(verify?: boolean): GridStackNode[] {\n // compare original x,y,w,h instead as _dirty can be a temporary state\n if (verify) {\n return this.nodes.filter(n => n._dirty && !Utils.samePos(n, n._orig));\n }\n return this.nodes.filter(n => n._dirty);\n }\n\n /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */\n protected _notify(removedNodes?: GridStackNode[]): GridStackEngine {\n if (this.batchMode || !this.onChange) return this;\n let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes());\n this.onChange(dirtyNodes);\n return this;\n }\n\n /** @internal remove dirty and last tried info */\n public cleanNodes(): GridStackEngine {\n if (this.batchMode) return this;\n this.nodes.forEach(n => {\n delete n._dirty;\n delete n._lastTried;\n });\n return this;\n }\n\n /** @internal called to save initial position/size to track real dirty state.\n * Note: should be called right after we call change event (so next API is can detect changes)\n * as well as right before we start move/resize/enter (so we can restore items to prev values) */\n public saveInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n n._orig = Utils.copyPos({}, n);\n delete n._dirty;\n });\n this._hasLocked = this.nodes.some(n => n.locked);\n return this;\n }\n\n /** @internal restore all the nodes back to initial values (called when we leave) */\n public restoreInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n if (Utils.samePos(n, n._orig)) return;\n Utils.copyPos(n, n._orig);\n n._dirty = true;\n });\n this._notify();\n return this;\n }\n\n /** call to add the given node to our list, fixing collision and re-packing */\n public addNode(node: GridStackNode, triggerAddEvent = false): GridStackNode {\n let dup = this.nodes.find(n => n._id === node._id);\n if (dup) return dup; // prevent inserting twice! return it instead.\n\n // skip prepareNode if we're in middle of column resize (not new) but do check for bounds!\n node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);\n delete node._temporaryRemoved;\n delete node._removeDOM;\n\n if (node.autoPosition) {\n this.sortNodes();\n\n for (let i = 0;; ++i) {\n let x = i % this.column;\n let y = Math.floor(i / this.column);\n if (x + node.w > this.column) {\n continue;\n }\n let box = {x, y, w: node.w, h: node.h};\n if (!this.nodes.find(n => Utils.isIntercepted(box, n))) {\n node.x = x;\n node.y = y;\n delete node.autoPosition; // found our slot\n break;\n }\n }\n }\n\n this.nodes.push(node);\n if (triggerAddEvent) { this.addedNodes.push(node); }\n\n this._fixCollisions(node);\n if (!this.batchMode) { this._packNodes()._notify(); }\n return node;\n }\n\n public removeNode(node: GridStackNode, removeDOM = true, triggerEvent = false): GridStackEngine {\n if (!this.nodes.find(n => n === node)) {\n // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)\n return this;\n }\n if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag)\n this.removedNodes.push(node);\n }\n if (removeDOM) node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.\n this.nodes = this.nodes.filter(n => n !== node);\n return this._packNodes()\n ._notify([node]);\n }\n\n public removeAll(removeDOM = true): GridStackEngine {\n delete this._layouts;\n if (this.nodes.length === 0) return this;\n removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n this.removedNodes = this.nodes;\n this.nodes = [];\n return this._notify(this.removedNodes);\n }\n\n /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.\n * In more complicated cases (maxRow) it will attempt at moving the item and fixing\n * others in a clone first, then apply those changes if still within specs. */\n public moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean {\n // if (node.locked) return false;\n if (!this.changedPosConstrain(node, o)) return false;\n o.pack = true;\n\n // simpler case: move item directly...\n if (!this.maxRow) {\n return this.moveNode(node, o);\n }\n\n // complex case: create a clone with NO maxRow (will check for out of bounds at the end)\n let clonedNode: GridStackNode;\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {\n if (n === node) {\n clonedNode = {...n};\n return clonedNode;\n }\n return {...n};\n })\n });\n if (!clonedNode) return false;\n\n // make sure we are still valid size\n let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow;\n // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing\n if (!canMove && !o.resizing) {\n let collide = this.collide(node, o);\n if (collide && this.swap(node, collide)) {\n this._notify();\n return true;\n }\n }\n if (!canMove) return false;\n\n // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over!\n // Note: we can't use the list directly as elements and other parts point to actual node, so copy content\n clone.nodes.filter(n => n._dirty).forEach(c => {\n let n = this.nodes.find(a => a._id === c._id);\n if (!n) return;\n Utils.copyPos(n, c);\n n._dirty = true;\n });\n this._notify();\n return true;\n }\n\n /** return true if can fit in grid height constrain only (always true if no maxRow) */\n public willItFit(node: GridStackNode): boolean {\n delete node._willFitPos;\n if (!this.maxRow) return true;\n // create a clone with NO maxRow and check if still within size\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {return {...n}})\n });\n let n = {...node}; // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687\n this.cleanupNode(n);\n delete n.el; delete n._id; delete n.content; delete n.grid;\n clone.addNode(n);\n if (clone.getRow() <= this.maxRow) {\n node._willFitPos = Utils.copyPos({}, n);\n return true;\n }\n return false;\n }\n\n /** true if x,y or w,h are different after clamping to min/max */\n public changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean {\n // first make sure w,h are set for caller\n p.w = p.w || node.w;\n p.h = p.h || node.h;\n if (node.x !== p.x || node.y !== p.y) return true;\n // check constrained w,h\n if (node.maxW) { p.w = Math.min(p.w, node.maxW); }\n if (node.maxH) { p.h = Math.min(p.h, node.maxH); }\n if (node.minW) { p.w = Math.max(p.w, node.minW); }\n if (node.minH) { p.h = Math.max(p.h, node.minH); }\n return (node.w !== p.w || node.h !== p.h);\n }\n\n /** return true if the passed in node was actually moved (checks for no-op and locked) */\n public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {\n if (!node || /*node.locked ||*/ !o) return false;\n if (o.pack === undefined) o.pack = true;\n\n // constrain the passed in values and check if we're still changing our node\n if (typeof o.x !== 'number') { o.x = node.x; }\n if (typeof o.y !== 'number') { o.y = node.y; }\n if (typeof o.w !== 'number') { o.w = node.w; }\n if (typeof o.h !== 'number') { o.h = node.h; }\n let resizing = (node.w !== o.w || node.h !== o.h);\n let nn: GridStackNode = Utils.copyPos({}, node, true); // get min/max out first, then opt positions next\n Utils.copyPos(nn, o);\n nn = this.nodeBoundFix(nn, resizing);\n Utils.copyPos(o, nn);\n\n if (Utils.samePos(node, o)) return false;\n let prevPos: GridStackPosition = Utils.copyPos({}, node);\n\n // check if we will need to fix collision at our new location\n let collides = this.collideAll(node, nn, o.skip);\n let needToMove = true;\n if (collides.length) {\n // now check to make sure we actually collided over 50% surface area while dragging\n let collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0];\n if (collide) {\n needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved...\n } else {\n needToMove = false; // we didn't cover >50% for a move, skip...\n }\n }\n\n // now move (to the original ask vs the collision version which might differ) and repack things\n if (needToMove) {\n node._dirty = true;\n Utils.copyPos(node, nn);\n }\n if (o.pack) {\n this._packNodes()\n ._notify();\n }\n return !Utils.samePos(node, prevPos); // pack might have moved things back\n }\n\n public getRow(): number {\n return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0);\n }\n\n public beginUpdate(node: GridStackNode): GridStackEngine {\n if (!node._updating) {\n node._updating = true;\n delete node._skipDown;\n if (!this.batchMode) this.saveInitial();\n }\n return this;\n }\n\n public endUpdate(): GridStackEngine {\n let n = this.nodes.find(n => n._updating);\n if (n) {\n delete n._updating;\n delete n._skipDown;\n }\n return this;\n }\n\n /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout),\n * returning a list of widgets for serialization */\n public save(saveElement = true): GridStackNode[] {\n // use the highest layout for any saved info so we can have full detail on reload #1849\n let len = this._layouts?.length;\n let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null;\n let list: GridStackNode[] = [];\n this.sortNodes();\n this.nodes.forEach(n => {\n let wl = layout?.find(l => l._id === n._id);\n let w: GridStackNode = {...n};\n // use layout info instead if set\n if (wl) { w.x = wl.x; w.y = wl.y; w.w = wl.w; }\n // delete internals\n for (let key in w) { if (key[0] === '_' || w[key] === null || w[key] === undefined ) delete w[key]; }\n delete w.grid;\n if (!saveElement) delete w.el;\n // delete default values (will be re-created on read)\n if (!w.autoPosition) delete w.autoPosition;\n if (!w.noResize) delete w.noResize;\n if (!w.noMove) delete w.noMove;\n if (!w.locked) delete w.locked;\n list.push(w);\n });\n return list;\n }\n\n /** @internal called whenever a node is added or moved - updates the cached layouts */\n public layoutsNodesChange(nodes: GridStackNode[]): GridStackEngine {\n if (!this._layouts || this._inColumnResize) return this;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach((layout, column) => {\n if (!layout || column === this.column) return this;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785\n let ratio = column / this.column;\n nodes.forEach(node => {\n if (!node._orig) return; // didn't change (newly added ?)\n let n = layout.find(l => l._id === node._id);\n if (!n) return; // no cache for new nodes. Will use those values.\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._orig.y) {\n n.y += (node.y - node._orig.y);\n }\n // X changed, scale from new position\n if (node.x !== node._orig.x) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.w !== node._orig.w) {\n n.w = Math.round(node.w * ratio);\n }\n // ...height always carries over from cache\n });\n }\n });\n return this;\n }\n\n /**\n * @internal Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * @param prevColumn previous number of columns\n * @param column new column number\n * @param nodes different sorted list (ex: DOM order) instead of current list\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n public updateNodeWidths(prevColumn: number, column: number, nodes: GridStackNode[], layout: ColumnOptions = 'moveScale'): GridStackEngine {\n if (!this.nodes.length || !column || prevColumn === column) return this;\n\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n this.cacheLayout(this.nodes, prevColumn);\n this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision\n let newNodes: GridStackNode[] = [];\n\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n let domOrder = false;\n if (column === 1 && nodes?.length) {\n domOrder = true;\n let top = 0;\n nodes.forEach(n => {\n n.x = 0;\n n.w = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.h;\n });\n newNodes = nodes;\n nodes = [];\n } else {\n nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n\n // see if we have cached previous layout IFF we are going up in size (restore) otherwise always\n // generate next size down from where we are (looks more natural as you gradually size down).\n let cacheNodes: GridStackNode[] = [];\n if (column > prevColumn) {\n cacheNodes = this._layouts[column] || [];\n // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate\n // by pretending we came from that larger column by assigning those values as starting point\n let lastIndex = this._layouts.length - 1;\n if (!cacheNodes.length && prevColumn !== lastIndex && this._layouts[lastIndex]?.length) {\n prevColumn = lastIndex;\n this._layouts[lastIndex].forEach(cacheNode => {\n let n = nodes.find(n => n._id === cacheNode._id);\n if (n) {\n // still current, use cache info positions\n n.x = cacheNode.x;\n n.y = cacheNode.y;\n n.w = cacheNode.w;\n }\n });\n }\n }\n\n // if we found cache re-use those nodes that are still current\n cacheNodes.forEach(cacheNode => {\n let j = nodes.findIndex(n => n._id === cacheNode._id);\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].w = cacheNode.w;\n newNodes.push(nodes[j]);\n nodes.splice(j, 1);\n }\n });\n // ...and add any extra non-cached ones\n if (nodes.length) {\n if (typeof layout === 'function') {\n layout(column, prevColumn, newNodes, nodes);\n } else if (!domOrder) {\n let ratio = column / prevColumn;\n let move = (layout === 'move' || layout === 'moveScale');\n let scale = (layout === 'scale' || layout === 'moveScale');\n nodes.forEach(node => {\n // NOTE: x + w could be outside of the grid, but addNode() below will handle that\n node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));\n node.w = ((column === 1 || prevColumn === 1) ? 1 :\n scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));\n newNodes.push(node);\n });\n nodes = [];\n }\n }\n\n // finally re-layout them in reverse order (to get correct placement)\n newNodes = Utils.sort(newNodes, -1, column);\n this._inColumnResize = true; // prevent cache update\n this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout\n newNodes.forEach(node => {\n this.addNode(node, false); // 'false' for add event trigger\n delete node._orig; // make sure the commit doesn't try to restore things back to original\n });\n this.batchUpdate(false);\n delete this._inColumnResize;\n return this;\n }\n\n /**\n * call to cache the given layout internally to the given location so we can restore back when column changes size\n * @param nodes list of nodes\n * @param column corresponding column index to save it under\n * @param clear if true, will force other caches to be removed (default false)\n */\n public cacheLayout(nodes: GridStackNode[], column: number, clear = false): GridStackEngine {\n let copy: GridStackNode[] = [];\n nodes.forEach((n, i) => {\n n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set\n copy[i] = {x: n.x, y: n.y, w: n.w, _id: n._id} // only thing we change is x,y,w and id to find it back\n });\n this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick\n this._layouts[column] = copy;\n return this;\n }\n\n /**\n * call to cache the given node layout internally to the given location so we can restore back when column changes size\n * @param node single node to cache\n * @param column corresponding column index to save it under\n */\n public cacheOneLayout(n: GridStackNode, column: number): GridStackEngine {\n n._id = n._id || GridStackEngine._idSeq++;\n let layout: GridStackNode = {x: n.x, y: n.y, w: n.w, _id: n._id}\n this._layouts = this._layouts || [];\n this._layouts[column] = this._layouts[column] || [];\n let index = this._layouts[column].findIndex(l => l._id === n._id);\n index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout;\n return this;\n }\n\n\n /** called to remove all internal values but the _id */\n public cleanupNode(node: GridStackNode): GridStackEngine {\n for (let prop in node) {\n if (prop[0] === '_' && prop !== '_id') delete node[prop];\n }\n return this;\n }\n}\n","/*!\r\n * GridStack 6.0.1-dev\r\n * https://gridstackjs.com/\r\n *\r\n * Copyright (c) 2021-2022 Alain Dumesny\r\n * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE\r\n */\r\nimport { GridStackEngine } from './gridstack-engine';\r\nimport { Utils, HeightData, obsolete } from './utils';\r\nimport { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback,\r\n GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\n\r\n// export all dependent file as well to make it easier for users to just import the main file\r\nexport * from './types';\r\nexport * from './utils';\r\nexport * from './gridstack-engine';\r\n\r\nexport interface GridHTMLElement extends HTMLElement {\r\n gridstack?: GridStack; // grid's parent DOM element points back to grid class\r\n}\r\n/** list of possible events, or space separated list of them */\r\nexport type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' |\r\n 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string;\r\n\r\n/** Defines the coordinates of an object */\r\nexport interface MousePosition {\r\n top: number;\r\n left: number;\r\n}\r\n\r\n/** Defines the position of a cell inside the grid*/\r\nexport interface CellPosition {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface GridCSSStyleSheet extends CSSStyleSheet {\r\n _id?: string; // random id we will use to style us\r\n _max?: number; // internal tracker of the max # of rows we created\\\r\n}\r\n\r\n// default values for grid options - used during init and when saving out\r\nconst GridDefaults: GridStackOptions = {\r\n column: 12,\r\n minRow: 0,\r\n maxRow: 0,\r\n itemClass: 'grid-stack-item',\r\n placeholderClass: 'grid-stack-placeholder',\r\n placeholderText: '',\r\n handle: '.grid-stack-item-content',\r\n handleClass: null,\r\n styleInHead: false,\r\n cellHeight: 'auto',\r\n cellHeightThrottle: 100,\r\n margin: 10,\r\n auto: true,\r\n oneColumnSize: 768,\r\n float: false,\r\n staticGrid: false,\r\n animate: true,\r\n alwaysShowResizeHandle: 'mobile',\r\n resizable: {\r\n handles: 'se'\r\n },\r\n draggable: {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body'\r\n },\r\n disableDrag: false,\r\n disableResize: false,\r\n rtl: 'auto',\r\n removable: false,\r\n removableOptions: {\r\n accept: '.grid-stack-item'\r\n },\r\n marginUnit: 'px',\r\n cellHeightUnit: 'px',\r\n disableOneColumnMode: false,\r\n oneColumnModeDomSort: false,\r\n};\r\n\r\n/**\r\n * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.\r\n * Note: your grid elements MUST have the following classes for the CSS layout to work:\r\n * @example\r\n *
\r\n *
\r\n *
Item 1
\r\n *
\r\n *
\r\n */\r\nexport class GridStack {\r\n\r\n /**\r\n * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will\r\n * simply return the existing instance (ignore any passed options). There is also an initAll() version that support\r\n * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.\r\n * @param options grid options (optional)\r\n * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n *\r\n * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later\r\n * let grid = document.querySelector('.grid-stack').gridstack;\r\n */\r\n public static init(options: GridStackOptions = {}, elOrString: GridStackElement = '.grid-stack'): GridStack {\r\n let el = GridStack.getGridElement(elOrString);\r\n if (!el) {\r\n if (typeof elOrString === 'string') {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + elOrString + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n } else {\r\n console.error('GridStack.init() no grid element was passed.');\r\n }\r\n return null;\r\n }\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n }\r\n return el.gridstack\r\n }\r\n\r\n /**\r\n * Will initialize a list of elements (given a selector) and return an array of grids.\r\n * @param options grid options (optional)\r\n * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grids = GridStack.initAll();\r\n * grids.forEach(...)\r\n */\r\n public static initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[] {\r\n let grids: GridStack[] = [];\r\n GridStack.getGridElements(selector).forEach(el => {\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n delete options.dragIn; delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)\r\n }\r\n grids.push(el.gridstack);\r\n });\r\n if (grids.length === 0) {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + selector + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n }\r\n return grids;\r\n }\r\n\r\n /**\r\n * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then\r\n * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from\r\n * JSON serialized data, including options.\r\n * @param parent HTML element parent to the grid\r\n * @param opt grids options used to initialize the grid, and list of children\r\n */\r\n public static addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack {\r\n if (!parent) return null;\r\n\r\n // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead\r\n let el = parent;\r\n if (!parent.classList.contains('grid-stack')) {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n parent.appendChild(el);\r\n }\r\n\r\n // create grid class and load any children\r\n let grid = GridStack.init(opt, el);\r\n if (grid.opts.children) {\r\n let children = grid.opts.children;\r\n delete grid.opts.children;\r\n grid.load(children);\r\n }\r\n return grid;\r\n }\r\n\r\n /** call this method to register your engine instead of the default one.\r\n * See instead `GridStackOptions.engineClass` if you only need to\r\n * replace just one instance.\r\n */\r\n static registerEngine(engineClass: typeof GridStackEngine) {\r\n GridStack.engineClass = engineClass;\r\n }\r\n\r\n /** scoping so users can call GridStack.Utils.sort() for example */\r\n public static Utils = Utils;\r\n\r\n /** scoping so users can call new GridStack.Engine(12) for example */\r\n public static Engine = GridStackEngine;\r\n\r\n /** the HTML element tied to this grid after it's been initialized */\r\n public el: GridHTMLElement;\r\n\r\n /** engine used to implement non DOM grid functionality */\r\n public engine: GridStackEngine;\r\n\r\n /** grid options - public for classes to access, but use methods to modify! */\r\n public opts: GridStackOptions;\r\n\r\n protected static engineClass: typeof GridStackEngine;\r\n\r\n /** @internal create placeholder DIV as needed */\r\n public get placeholder(): HTMLElement {\r\n if (!this._placeholder) {\r\n let placeholderChild = document.createElement('div'); // child so padding match item-content\r\n placeholderChild.className = 'placeholder-content';\r\n if (this.opts.placeholderText) {\r\n placeholderChild.innerHTML = this.opts.placeholderText;\r\n }\r\n this._placeholder = document.createElement('div');\r\n this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass);\r\n this.placeholder.appendChild(placeholderChild);\r\n }\r\n return this._placeholder;\r\n }\r\n /** @internal */\r\n protected _placeholder: HTMLElement;\r\n /** @internal */\r\n protected _prevColumn: number;\r\n /** @internal */\r\n protected _ignoreLayoutsNodeChange: boolean;\r\n /** @internal */\r\n public _gsEventHandler = {};\r\n /** @internal */\r\n protected _styles: GridCSSStyleSheet;\r\n /** @internal flag to keep cells square during resize */\r\n protected _isAutoCellHeight: boolean;\r\n /** @internal track event binding to window resize so we can remove */\r\n protected _windowResizeBind: () => void;\r\n /** @internal limit auto cell resizing method */\r\n protected _cellHeightThrottle: () => void;\r\n /** @internal true when loading items to insert first rather than append */\r\n protected _insertNotAppend: boolean;\r\n /** @internal extra row added when dragging at the bottom of the grid */\r\n protected _extraDragRow = 0;\r\n /** @internal true if nested grid should get column count from our width */\r\n protected _autoColumn?: boolean;\r\n\r\n /**\r\n * Construct a grid item from the given element and options\r\n * @param el\r\n * @param opts\r\n */\r\n public constructor(el: GridHTMLElement, opts: GridStackOptions = {}) {\r\n this.el = el; // exposed HTML element to the user\r\n opts = opts || {}; // handles null/undefined/0\r\n\r\n // if row property exists, replace minRow and maxRow instead\r\n if (opts.row) {\r\n opts.minRow = opts.maxRow = opts.row;\r\n delete opts.row;\r\n }\r\n let rowAttr = Utils.toNumber(el.getAttribute('gs-row'));\r\n\r\n // flag only valid in sub-grids (handled by parent, not here)\r\n if (opts.column === 'auto') {\r\n delete opts.column;\r\n }\r\n // 'minWidth' legacy support in 5.1\r\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\r\n let anyOpts = opts as any;\r\n if (anyOpts.minWidth !== undefined) {\r\n opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;\r\n delete anyOpts.minWidth;\r\n }\r\n // save original setting so we can restore on save\r\n if (opts.alwaysShowResizeHandle !== undefined) {\r\n (opts as any)._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;\r\n }\r\n\r\n // elements DOM attributes override any passed options (like CSS style) - merge the two together\r\n let defaults: GridStackOptions = {...Utils.cloneDeep(GridDefaults),\r\n column: Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column,\r\n minRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow,\r\n maxRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow,\r\n staticGrid: Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid,\r\n _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0),\r\n draggable: {\r\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle,\r\n },\r\n removableOptions: {\r\n accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept,\r\n },\r\n };\r\n if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead\r\n defaults.animate = Utils.toBool(el.getAttribute('gs-animate'))\r\n }\r\n\r\n this.opts = Utils.defaults(opts, defaults);\r\n opts = null; // make sure we use this.opts instead\r\n this._initMargin(); // part of settings defaults...\r\n\r\n // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)\r\n if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {\r\n this._prevColumn = this.getColumn();\r\n this.opts.column = 1;\r\n }\r\n\r\n if (this.opts.rtl === 'auto') {\r\n this.opts.rtl = (el.style.direction === 'rtl');\r\n }\r\n if (this.opts.rtl) {\r\n this.el.classList.add('grid-stack-rtl');\r\n }\r\n\r\n // check if we're been nested, and if so update our style and keep pointer around (used during save)\r\n let parentGridItemEl = Utils.closestByClass(this.el, GridDefaults.itemClass) as GridItemHTMLElement;\r\n if (parentGridItemEl && parentGridItemEl.gridstackNode) {\r\n this.opts._isNested = parentGridItemEl.gridstackNode;\r\n this.opts._isNested.subGrid = this;\r\n parentGridItemEl.classList.add('grid-stack-nested');\r\n this.el.classList.add('grid-stack-nested');\r\n }\r\n\r\n this._isAutoCellHeight = (this.opts.cellHeight === 'auto');\r\n if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {\r\n // make the cell content square initially (will use resize/column event to keep it square)\r\n this.cellHeight(undefined, false);\r\n } else {\r\n // append unit if any are set\r\n if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) {\r\n this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;\r\n delete this.opts.cellHeightUnit;\r\n }\r\n this.cellHeight(this.opts.cellHeight, false);\r\n }\r\n\r\n // see if we need to adjust auto-hide\r\n if (this.opts.alwaysShowResizeHandle === 'mobile') {\r\n this.opts.alwaysShowResizeHandle = isTouch;\r\n }\r\n\r\n this.el.classList.add(this.opts._styleSheetClass);\r\n\r\n this._setStaticClass();\r\n\r\n let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;\r\n this.engine = new engineClass({\r\n column: this.getColumn(),\r\n float: this.opts.float,\r\n maxRow: this.opts.maxRow,\r\n onChange: (cbNodes) => {\r\n let maxH = 0;\r\n this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) });\r\n cbNodes.forEach(n => {\r\n let el = n.el;\r\n if (!el) return;\r\n if (n._removeDOM) {\r\n if (el) el.remove();\r\n delete n._removeDOM;\r\n } else {\r\n this._writePosAttr(el, n);\r\n }\r\n });\r\n this._updateStyles(false, maxH); // false = don't recreate, just append if need be\r\n }\r\n });\r\n\r\n if (this.opts.auto) {\r\n this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...\r\n let elements: {el: HTMLElement; i: number}[] = [];\r\n this.getGridItems().forEach(el => { // get dom elements (not nodes yet)\r\n let x = parseInt(el.getAttribute('gs-x'));\r\n let y = parseInt(el.getAttribute('gs-y'));\r\n elements.push({\r\n el,\r\n // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order\r\n i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * this.getColumn()\r\n });\r\n });\r\n elements.sort((a, b) => a.i - b.i).forEach(e => this._prepareElement(e.el));\r\n this.batchUpdate(false);\r\n }\r\n\r\n this.setAnimation(this.opts.animate);\r\n\r\n this._updateStyles();\r\n if (this.opts.column != 12) {\r\n this.el.classList.add('grid-stack-' + this.opts.column);\r\n }\r\n\r\n // legacy support to appear 'per grid` options when really global.\r\n if (this.opts.dragIn) GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);\r\n delete this.opts.dragIn;\r\n delete this.opts.dragInOptions;\r\n\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this._updateWindowResizeEvent();\r\n }\r\n\r\n public change() {\r\n this._triggerChangeEvent();\r\n }\r\n\r\n /**\r\n * add a new widget and returns it.\r\n *\r\n * Widget will be always placed even if result height is more than actual grid height.\r\n * You need to use `willItFit()` before calling addWidget for additional check.\r\n * See also `makeWidget()`.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.addWidget({w: 3, content: 'hello'});\r\n * grid.addWidget('
hello
', {w: 3});\r\n *\r\n * @param el GridStackWidget (which can have content string as well), html element, or string definition to add\r\n * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget\r\n */\r\n public addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1,\r\n opt: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++],\r\n minW:a[i++], maxW:a[i++], minH:a[i++], maxH:a[i++], id:a[i++] };\r\n return this.addWidget(els, opt);\r\n }\r\n\r\n function isGridStackWidget(w: GridStackWidget): w is GridStackWidget { // https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0\r\n return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;\r\n }\r\n\r\n let el: HTMLElement;\r\n if (typeof els === 'string') {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = els;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {\r\n let content = els ? (els as GridStackWidget).content || '' : '';\r\n options = els;\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
${content}
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else {\r\n el = els as HTMLElement;\r\n }\r\n\r\n // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos\r\n // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node.\r\n // So make sure we load any DOM attributes that are not specified in passed in options (which override)\r\n let domAttr = this._readAttr(el);\r\n options = Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it\r\n Utils.defaults(options, domAttr);\r\n let node = this.engine.prepareNode(options);\r\n this._writeAttr(el, options);\r\n\r\n if (this._insertNotAppend) {\r\n this.el.prepend(el);\r\n } else {\r\n this.el.appendChild(el);\r\n }\r\n\r\n // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id\r\n this._prepareElement(el, true, options);\r\n this._updateContainerHeight();\r\n\r\n // check if nested grid definition is present\r\n if (node.subGrid && !(node.subGrid as GridStack).el) { // see if there is a sub-grid to create too\r\n // if column special case it set, remember that flag and set default\r\n let autoColumn: boolean;\r\n let ops = node.subGrid as GridStackOptions;\r\n if (ops.column === 'auto') {\r\n ops.column = node.w;\r\n ops.disableOneColumnMode = true; // driven by parent\r\n autoColumn = true;\r\n }\r\n let content = node.el.querySelector('.grid-stack-item-content') as HTMLElement;\r\n node.subGrid = GridStack.addGrid(content, node.subGrid as GridStackOptions);\r\n if (autoColumn) { node.subGrid._autoColumn = true; }\r\n }\r\n\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n /**\r\n * saves the current layout returning a list of widgets for serialization which might include any nested grids.\r\n * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will\r\n * be removed.\r\n * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()\r\n * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.\r\n * @returns list of widgets or full grid option, including .children list of widgets\r\n */\r\n public save(saveContent = true, saveGridOpt = false): GridStackWidget[] | GridStackOptions {\r\n // return copied nodes we can modify at will...\r\n let list = this.engine.save(saveContent);\r\n\r\n // check for HTML content and nested grids\r\n list.forEach(n => {\r\n if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content\r\n let sub = n.el.querySelector('.grid-stack-item-content');\r\n n.content = sub ? sub.innerHTML : undefined;\r\n if (!n.content) delete n.content;\r\n } else {\r\n if (!saveContent) { delete n.content; }\r\n // check for nested grid\r\n if (n.subGrid) {\r\n n.subGrid = (n.subGrid as GridStack).save(saveContent, true) as GridStackOptions;\r\n }\r\n }\r\n delete n.el;\r\n });\r\n\r\n // check if save entire grid options (needed for recursive) + children...\r\n if (saveGridOpt) {\r\n let o: GridStackOptions = Utils.cloneDeep(this.opts);\r\n // delete default values that will be recreated on launch\r\n if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {\r\n o.margin = o.marginTop;\r\n delete o.marginTop; delete o.marginRight; delete o.marginBottom; delete o.marginLeft;\r\n }\r\n if (o.rtl === (this.el.style.direction === 'rtl')) { o.rtl = 'auto' }\r\n if (this._isAutoCellHeight) {\r\n o.cellHeight = 'auto'\r\n }\r\n if (this._autoColumn) {\r\n o.column = 'auto';\r\n delete o.disableOneColumnMode;\r\n }\r\n const origShow = (o as any)._alwaysShowResizeHandle;\r\n delete (o as any)._alwaysShowResizeHandle;\r\n if (origShow !== undefined) {\r\n o.alwaysShowResizeHandle = origShow;\r\n } else {\r\n delete o.alwaysShowResizeHandle;\r\n }\r\n Utils.removeInternalAndSame(o, GridDefaults);\r\n o.children = list;\r\n return o;\r\n }\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.\r\n *\r\n * @param layout list of widgets definition to update/create\r\n * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving\r\n * the user control of insertion.\r\n *\r\n * @example\r\n * see http://gridstackjs.com/demo/serialization.html\r\n **/\r\n public load(layout: GridStackWidget[], addAndRemove: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement) = true): GridStack {\r\n let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort\r\n this._insertNotAppend = true; // since create in reverse order...\r\n\r\n // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save\r\n // the original wanted layout so we can scale back up correctly #1471\r\n if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) {\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this.engine.cacheLayout(items, this._prevColumn, true);\r\n }\r\n\r\n let removed: GridStackNode[] = [];\r\n this.batchUpdate();\r\n\r\n // see if any items are missing from new layout and need to be removed first\r\n if (addAndRemove) {\r\n let copyNodes = [...this.engine.nodes]; // don't loop through array you modify\r\n copyNodes.forEach(n => {\r\n let item = items.find(w => n.id === w.id);\r\n if (!item) {\r\n if (typeof(addAndRemove) === 'function') {\r\n addAndRemove(this, n, false);\r\n } else {\r\n removed.push(n); // batch keep track\r\n this.removeWidget(n.el, true, false);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // now add/update the widgets\r\n items.forEach(w => {\r\n let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined;\r\n if (item) {\r\n this.update(item.el, w);\r\n if (w.subGrid && (w.subGrid as GridStackOptions).children) { // update any sub grid as well\r\n let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;\r\n if (sub && sub.gridstack) {\r\n sub.gridstack.load((w.subGrid as GridStackOptions).children); // TODO: support updating grid options ?\r\n this._insertNotAppend = true; // got reset by above call\r\n }\r\n }\r\n } else if (addAndRemove) {\r\n if (typeof(addAndRemove) === 'function') {\r\n w = addAndRemove(this, w, true).gridstackNode;\r\n } else {\r\n w = this.addWidget(w).gridstackNode;\r\n }\r\n }\r\n });\r\n\r\n this.engine.removedNodes = removed;\r\n this.batchUpdate(false);\r\n\r\n // after commit, clear that flag\r\n delete this._ignoreLayoutsNodeChange;\r\n delete this._insertNotAppend;\r\n return this;\r\n }\r\n\r\n /**\r\n * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)\r\n * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.\r\n */\r\n public batchUpdate(flag = true): GridStack {\r\n this.engine.batchUpdate(flag);\r\n if (!flag) {\r\n this._triggerRemoveEvent();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets current cell height.\r\n */\r\n public getCellHeight(forcePixel = false): number {\r\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&\r\n (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {\r\n return this.opts.cellHeight as number;\r\n }\r\n // else get first cell height\r\n let el = this.el.querySelector('.' + this.opts.itemClass) as HTMLElement;\r\n if (el) {\r\n let height = Utils.toNumber(el.getAttribute('gs-h'));\r\n return Math.round(el.offsetHeight / height);\r\n }\r\n // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)\r\n let rows = parseInt(this.el.getAttribute('gs-current-row'));\r\n return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight as number;\r\n }\r\n\r\n /**\r\n * Update current cell height - see `GridStackOptions.cellHeight` for format.\r\n * This method rebuilds an internal CSS style sheet.\r\n * Note: You can expect performance issues if call this method too often.\r\n *\r\n * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),\r\n * if pass 0 the CSS will be generated by the application instead.\r\n * @param update (Optional) if false, styles will not be updated\r\n *\r\n * @example\r\n * grid.cellHeight(100); // same as 100px\r\n * grid.cellHeight('70px');\r\n * grid.cellHeight(grid.cellWidth() * 1.2);\r\n */\r\n public cellHeight(val?: numberOrString, update = true): GridStack {\r\n\r\n // if not called internally, check if we're changing mode\r\n if (update && val !== undefined) {\r\n if (this._isAutoCellHeight !== (val === 'auto')) {\r\n this._isAutoCellHeight = (val === 'auto');\r\n this._updateWindowResizeEvent();\r\n }\r\n }\r\n if (val === 'initial' || val === 'auto') { val = undefined; }\r\n\r\n // make item content be square\r\n if (val === undefined) {\r\n let marginDiff = - (this.opts.marginRight as number) - (this.opts.marginLeft as number)\r\n + (this.opts.marginTop as number) + (this.opts.marginBottom as number);\r\n val = this.cellWidth() + marginDiff;\r\n }\r\n\r\n let data = Utils.parseHeight(val);\r\n if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {\r\n return this;\r\n }\r\n this.opts.cellHeightUnit = data.unit;\r\n this.opts.cellHeight = data.h;\r\n\r\n if (update) {\r\n this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows\r\n }\r\n return this;\r\n }\r\n\r\n /** Gets current cell width. */\r\n public cellWidth(): number {\r\n return this._widthOrContainer() / this.getColumn();\r\n }\r\n /** return our expected width (or parent) for 1 column check */\r\n protected _widthOrContainer(): number {\r\n // use `offsetWidth` or `clientWidth` (no scrollbar) ?\r\n // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);\r\n }\r\n\r\n /** re-layout grid items to reclaim any empty space */\r\n public compact(): GridStack {\r\n this.engine.compact();\r\n this._triggerChangeEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,\r\n * as well as cache the original layout so you can revert back to previous positions without loss.\r\n * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],\r\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\r\n * @param column - Integer > 0 (default 12).\r\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\r\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\r\n */\r\n public column(column: number, layout: ColumnOptions = 'moveScale'): GridStack {\r\n if (column < 1 || this.opts.column === column) return this;\r\n let oldColumn = this.getColumn();\r\n\r\n // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)\r\n // then remember the original columns so we can restore.\r\n if (column === 1) {\r\n this._prevColumn = oldColumn;\r\n } else {\r\n delete this._prevColumn;\r\n }\r\n\r\n this.el.classList.remove('grid-stack-' + oldColumn);\r\n this.el.classList.add('grid-stack-' + column);\r\n this.opts.column = this.engine.column = column;\r\n\r\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\r\n let domNodes: GridStackNode[];\r\n if (column === 1 && this.opts.oneColumnModeDomSort) {\r\n domNodes = [];\r\n this.getGridItems().forEach(el => { // get dom elements in order\r\n if (el.gridstackNode) { domNodes.push(el.gridstackNode); }\r\n });\r\n if (!domNodes.length) { domNodes = undefined; }\r\n }\r\n this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);\r\n if (this._isAutoCellHeight) this.cellHeight();\r\n\r\n // and trigger our event last...\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this._triggerChangeEvent();\r\n delete this._ignoreLayoutsNodeChange;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * get the number of columns in the grid (default 12)\r\n */\r\n public getColumn(): number {\r\n return this.opts.column as number;\r\n }\r\n\r\n /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */\r\n public getGridItems(): GridItemHTMLElement[] {\r\n return Array.from(this.el.children)\r\n .filter((el: HTMLElement) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass)) as GridItemHTMLElement[];\r\n }\r\n\r\n /**\r\n * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.\r\n * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).\r\n */\r\n public destroy(removeDOM = true): GridStack {\r\n if (!this.el) return; // prevent multiple calls\r\n this._updateWindowResizeEvent(true);\r\n this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)\r\n this.setAnimation(false);\r\n if (!removeDOM) {\r\n this.removeAll(removeDOM);\r\n this.el.classList.remove(this.opts._styleSheetClass);\r\n } else {\r\n this.el.parentNode.removeChild(this.el);\r\n }\r\n this._removeStylesheet();\r\n this.el.removeAttribute('gs-current-row');\r\n delete this.opts._isNested;\r\n delete this.opts;\r\n delete this._placeholder;\r\n delete this.engine;\r\n delete this.el.gridstack; // remove circular dependency that would prevent a freeing\r\n delete this.el;\r\n return this;\r\n }\r\n\r\n /**\r\n * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)\r\n */\r\n public float(val: boolean): GridStack {\r\n if (this.opts.float !== val) {\r\n this.opts.float = this.engine.float = val;\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get the current float mode\r\n */\r\n public getFloat(): boolean {\r\n return this.engine.float;\r\n }\r\n\r\n /**\r\n * Get the position of the cell under a pixel on screen.\r\n * @param position the position of the pixel to resolve in\r\n * absolute coordinates, as an object with top and left properties\r\n * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).\r\n * Useful when grid is within `position: relative` element\r\n *\r\n * Returns an object with properties `x` and `y` i.e. the column and row in the grid.\r\n */\r\n public getCellFromPixel(position: MousePosition, useDocRelative = false): CellPosition {\r\n let box = this.el.getBoundingClientRect();\r\n // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)\r\n let containerPos: {top: number, left: number};\r\n if (useDocRelative) {\r\n containerPos = {top: box.top + document.documentElement.scrollTop, left: box.left};\r\n // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)\r\n } else {\r\n containerPos = {top: this.el.offsetTop, left: this.el.offsetLeft}\r\n // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)\r\n }\r\n let relativeLeft = position.left - containerPos.left;\r\n let relativeTop = position.top - containerPos.top;\r\n\r\n let columnWidth = (box.width / this.getColumn());\r\n let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));\r\n\r\n return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)};\r\n }\r\n\r\n /** returns the current number of rows, which will be at least `minRow` if set */\r\n public getRow(): number {\r\n return Math.max(this.engine.getRow(), this.opts.minRow);\r\n }\r\n\r\n /**\r\n * Checks if specified area is empty.\r\n * @param x the position x.\r\n * @param y the position y.\r\n * @param w the width of to check\r\n * @param h the height of to check\r\n */\r\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\r\n return this.engine.isAreaEmpty(x, y, w, h);\r\n }\r\n\r\n /**\r\n * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.\r\n * If you want gridstack to add the elements for you, use `addWidget()` instead.\r\n * Makes the given element a widget and returns it.\r\n * @param els widget or single selector to convert.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.el.appendChild('
');\r\n * grid.makeWidget('#gsi-1');\r\n */\r\n public makeWidget(els: GridStackElement): GridItemHTMLElement {\r\n let el = GridStack.getElement(els);\r\n this._prepareElement(el, true);\r\n this._updateContainerHeight();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n return el;\r\n }\r\n\r\n /**\r\n * Event handler that extracts our CustomEvent data out automatically for receiving custom\r\n * notifications (see doc for supported events)\r\n * @param name of the event (see possible values) or list of names space separated\r\n * @param callback function called with event and optional second/third param\r\n * (see README documentation for each signature).\r\n *\r\n * @example\r\n * grid.on('added', function(e, items) { log('added ', items)} );\r\n * or\r\n * grid.on('added removed change', function(e, items) { log(e.type, items)} );\r\n *\r\n * Note: in some cases it is the same as calling native handler and parsing the event.\r\n * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );\r\n *\r\n */\r\n public on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.on(name, callback));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // native CustomEvent handlers - cash the generic handlers so we can easily remove\r\n let noData = (name === 'enable' || name === 'disable');\r\n if (noData) {\r\n this._gsEventHandler[name] = (event: Event) => callback(event);\r\n } else {\r\n this._gsEventHandler[name] = (event: CustomEvent) => callback(event, event.detail);\r\n }\r\n this.el.addEventListener(name, this._gsEventHandler[name]);\r\n } else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {\r\n // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.\r\n // do same for start event to make it easier...\r\n this._gsEventHandler[name] = callback;\r\n } else {\r\n console.log('GridStack.on(' + name + ') event not supported, but you can still use $(\".grid-stack\").on(...) while jquery-ui is still used internally.');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * unsubscribe from the 'on' event below\r\n * @param name of the event (see possible values)\r\n */\r\n public off(name: GridStackEvent): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.off(name));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // remove native CustomEvent handlers\r\n if (this._gsEventHandler[name]) {\r\n this.el.removeEventListener(name, this._gsEventHandler[name]);\r\n }\r\n }\r\n delete this._gsEventHandler[name];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes widget from the grid.\r\n * @param el widget or selector to modify\r\n * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).\r\n * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).\r\n */\r\n public removeWidget(els: GridStackElement, removeDOM = true, triggerEvent = true): GridStack {\r\n GridStack.getElements(els).forEach(el => {\r\n if (el.parentElement !== this.el) return; // not our child!\r\n let node = el.gridstackNode;\r\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\r\n if (!node) {\r\n node = this.engine.nodes.find(n => el === n.el);\r\n }\r\n if (!node) return;\r\n\r\n // remove our DOM data (circular link) and drag&drop permanently\r\n delete el.gridstackNode;\r\n this._removeDD(el);\r\n\r\n this.engine.removeNode(node, removeDOM, triggerEvent);\r\n\r\n if (removeDOM && el.parentElement) {\r\n el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM\r\n }\r\n });\r\n if (triggerEvent) {\r\n this._triggerRemoveEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all widgets from the grid.\r\n * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).\r\n */\r\n public removeAll(removeDOM = true): GridStack {\r\n // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently\r\n this.engine.nodes.forEach(n => {\r\n delete n.el.gridstackNode;\r\n this._removeDD(n.el);\r\n });\r\n this.engine.removeAll(removeDOM);\r\n this._triggerRemoveEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid animation state. Toggles the `grid-stack-animate` class.\r\n * @param doAnimate if true the grid will animate.\r\n */\r\n public setAnimation(doAnimate: boolean): GridStack {\r\n if (doAnimate) {\r\n this.el.classList.add('grid-stack-animate');\r\n } else {\r\n this.el.classList.remove('grid-stack-animate');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.\r\n * Also toggle the grid-stack-static class.\r\n * @param val if true the grid become static.\r\n */\r\n public setStatic(val: boolean, updateClass = true): GridStack {\r\n if (this.opts.staticGrid === val) return this;\r\n this.opts.staticGrid = val;\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this.engine.nodes.forEach(n => this._prepareDragDropByNode(n)); // either delete or init Drag&drop\r\n if (updateClass) { this._setStaticClass(); }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed.\r\n * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)\r\n * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.\r\n */\r\n public update(els: GridStackElement, opt: GridStackWidget): GridStack {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1;\r\n opt = { x:a[i++], y:a[i++], w:a[i++], h:a[i++] };\r\n return this.update(els, opt);\r\n }\r\n\r\n GridStack.getElements(els).forEach(el => {\r\n if (!el || !el.gridstackNode) return;\r\n let n = el.gridstackNode;\r\n let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items\r\n delete w.autoPosition;\r\n\r\n // move/resize widget if anything changed\r\n let keys = ['x', 'y', 'w', 'h'];\r\n let m: GridStackWidget;\r\n if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) {\r\n m = {};\r\n keys.forEach(k => {\r\n m[k] = (w[k] !== undefined) ? w[k] : n[k];\r\n delete w[k];\r\n });\r\n }\r\n // for a move as well IFF there is any min/max fields set\r\n if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {\r\n m = {}; // will use node position but validate values\r\n }\r\n\r\n // check for content changing\r\n if (w.content) {\r\n let sub = el.querySelector('.grid-stack-item-content');\r\n if (sub && sub.innerHTML !== w.content) {\r\n sub.innerHTML = w.content;\r\n }\r\n delete w.content;\r\n }\r\n\r\n // any remaining fields are assigned, but check for dragging changes, resize constrain\r\n let changed = false;\r\n let ddChanged = false;\r\n for (const key in w) {\r\n if (key[0] !== '_' && n[key] !== w[key]) {\r\n n[key] = w[key];\r\n changed = true;\r\n ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));\r\n }\r\n }\r\n\r\n // finally move the widget\r\n if (m) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(n)\r\n .moveNode(n, m);\r\n this._updateContainerHeight();\r\n this._triggerChangeEvent();\r\n this.engine.endUpdate();\r\n }\r\n if (changed) { // move will only update x,y,w,h so update the rest too\r\n this._writeAttr(el, n);\r\n }\r\n if (ddChanged) {\r\n this._prepareDragDropByNode(n);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number).\r\n * @param value margin value\r\n */\r\n public margin(value: numberOrString): GridStack {\r\n let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);\r\n // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)\r\n if (!isMultiValue) {\r\n let data = Utils.parseHeight(value);\r\n if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) return;\r\n }\r\n // re-use existing margin handling\r\n this.opts.margin = value;\r\n this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;\r\n this._initMargin();\r\n\r\n this._updateStyles(true); // true = force re-create\r\n\r\n return this;\r\n }\r\n\r\n /** returns current margin number value (undefined if 4 sides don't match) */\r\n public getMargin(): number { return this.opts.margin as number; }\r\n\r\n /**\r\n * Returns true if the height of the grid will be less than the vertical\r\n * constraint. Always returns true if grid doesn't have height constraint.\r\n * @param node contains x,y,w,h,auto-position options\r\n *\r\n * @example\r\n * if (grid.willItFit(newWidget)) {\r\n * grid.addWidget(newWidget);\r\n * } else {\r\n * alert('Not enough free space to place the widget');\r\n * }\r\n */\r\n public willItFit(node: GridStackWidget): boolean {\r\n // support legacy call for now\r\n if (arguments.length > 1) {\r\n console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 0,\r\n w: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++] };\r\n return this.willItFit(w);\r\n }\r\n return this.engine.willItFit(node);\r\n }\r\n\r\n /** @internal */\r\n protected _triggerChangeEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n let elements = this.engine.getDirtyNodes(true); // verify they really changed\r\n if (elements && elements.length) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(elements);\r\n }\r\n this._triggerEvent('change', elements);\r\n }\r\n this.engine.saveInitial(); // we called, now reset initial values & dirty flags\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerAddEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(this.engine.addedNodes);\r\n }\r\n // prevent added nodes from also triggering 'change' event (which is called next)\r\n this.engine.addedNodes.forEach(n => { delete n._dirty; });\r\n this._triggerEvent('added', this.engine.addedNodes);\r\n this.engine.addedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n public _triggerRemoveEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {\r\n this._triggerEvent('removed', this.engine.removedNodes);\r\n this.engine.removedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerEvent(name: string, data?: GridStackNode[]): GridStack {\r\n let event = data ? new CustomEvent(name, {bubbles: false, detail: data}) : new Event(name);\r\n this.el.dispatchEvent(event);\r\n return this;\r\n }\r\n\r\n /** @internal called to delete the current dynamic style sheet used for our layout */\r\n protected _removeStylesheet(): GridStack {\r\n\r\n if (this._styles) {\r\n Utils.removeStylesheet(this._styles._id);\r\n delete this._styles;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal updated/create the CSS styles for row based layout and initial margin setting */\r\n protected _updateStyles(forceUpdate = false, maxH?: number): GridStack {\r\n // call to delete existing one if we change cellHeight / margin\r\n if (forceUpdate) {\r\n this._removeStylesheet();\r\n }\r\n\r\n this._updateContainerHeight();\r\n\r\n // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??\r\n if (this.opts.cellHeight === 0) {\r\n return this;\r\n }\r\n\r\n let cellHeight = this.opts.cellHeight as number;\r\n let cellHeightUnit = this.opts.cellHeightUnit;\r\n let prefix = `.${this.opts._styleSheetClass} > .${this.opts.itemClass}`;\r\n\r\n // create one as needed\r\n if (!this._styles) {\r\n let id = 'gridstack-style-' + (Math.random() * 100000).toFixed();\r\n // insert style to parent (instead of 'head' by default) to support WebComponent\r\n let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement;\r\n this._styles = Utils.createStylesheet(id, styleLocation);\r\n if (!this._styles) return this;\r\n this._styles._id = id;\r\n this._styles._max = 0;\r\n\r\n // these are done once only\r\n Utils.addCSSRule(this._styles, prefix, `min-height: ${cellHeight}${cellHeightUnit}`);\r\n // content margins\r\n let top: string = this.opts.marginTop + this.opts.marginUnit;\r\n let bottom: string = this.opts.marginBottom + this.opts.marginUnit;\r\n let right: string = this.opts.marginRight + this.opts.marginUnit;\r\n let left: string = this.opts.marginLeft + this.opts.marginUnit;\r\n let content = `${prefix} > .grid-stack-item-content`;\r\n let placeholder = `.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;\r\n Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n // resize handles offset (to match margin)\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`);\r\n }\r\n\r\n // now update the height specific fields\r\n maxH = maxH || this._styles._max;\r\n if (maxH > this._styles._max) {\r\n let getHeight = (rows: number): string => (cellHeight * rows) + cellHeightUnit;\r\n for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1\r\n let h: string = getHeight(i);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-y=\"${i-1}\"]`, `top: ${getHeight(i-1)}`); // start at 0\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-h=\"${i}\"]`, `height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-min-h=\"${i}\"]`, `min-height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-max-h=\"${i}\"]`, `max-height: ${h}`);\r\n }\r\n this._styles._max = maxH;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _updateContainerHeight(): GridStack {\r\n if (!this.engine || this.engine.batchMode) return this;\r\n let row = this.getRow() + this._extraDragRow; // checks for minRow already\r\n // check for css min height\r\n // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary\r\n // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.\r\n // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);\r\n // if (cssMinHeight > 0) {\r\n // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));\r\n // if (row < minRow) {\r\n // row = minRow;\r\n // }\r\n // }\r\n this.el.setAttribute('gs-current-row', String(row));\r\n if (row === 0) {\r\n this.el.style.removeProperty('height');\r\n return this;\r\n }\r\n let cellHeight = this.opts.cellHeight as number;\r\n let unit = this.opts.cellHeightUnit;\r\n if (!cellHeight) return this;\r\n this.el.style.height = row * cellHeight + unit;\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _prepareElement(el: GridItemHTMLElement, triggerAddEvent = false, node?: GridStackNode): GridStack {\r\n if (!node) {\r\n el.classList.add(this.opts.itemClass);\r\n node = this._readAttr(el);\r\n }\r\n el.gridstackNode = node;\r\n node.el = el;\r\n node.grid = this;\r\n let copy = {...node};\r\n node = this.engine.addNode(node, triggerAddEvent);\r\n // write node attr back in case there was collision or we have to fix bad values during addNode()\r\n if (!Utils.same(node, copy)) {\r\n this._writeAttr(el, node);\r\n }\r\n this._prepareDragDropByNode(node);\r\n return this;\r\n }\r\n\r\n /** @internal call to write position x,y,w,h attributes back to element */\r\n protected _writePosAttr(el: HTMLElement, n: GridStackPosition): GridStack {\r\n if (n.x !== undefined && n.x !== null) { el.setAttribute('gs-x', String(n.x)); }\r\n if (n.y !== undefined && n.y !== null) { el.setAttribute('gs-y', String(n.y)); }\r\n if (n.w) { el.setAttribute('gs-w', String(n.w)); }\r\n if (n.h) { el.setAttribute('gs-h', String(n.h)); }\r\n return this;\r\n }\r\n\r\n /** @internal call to write any default attributes back to element */\r\n protected _writeAttr(el: HTMLElement, node: GridStackWidget): GridStack {\r\n if (!node) return this;\r\n this._writePosAttr(el, node);\r\n\r\n let attrs /*: GridStackWidget but strings */ = { // remaining attributes\r\n autoPosition: 'gs-auto-position',\r\n minW: 'gs-min-w',\r\n minH: 'gs-min-h',\r\n maxW: 'gs-max-w',\r\n maxH: 'gs-max-h',\r\n noResize: 'gs-no-resize',\r\n noMove: 'gs-no-move',\r\n locked: 'gs-locked',\r\n id: 'gs-id',\r\n resizeHandles: 'gs-resize-handles'\r\n };\r\n for (const key in attrs) {\r\n if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway\r\n el.setAttribute(attrs[key], String(node[key]));\r\n } else {\r\n el.removeAttribute(attrs[key]);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal call to read any default attributes from element */\r\n protected _readAttr(el: HTMLElement): GridStackWidget {\r\n let node: GridStackNode = {};\r\n node.x = Utils.toNumber(el.getAttribute('gs-x'));\r\n node.y = Utils.toNumber(el.getAttribute('gs-y'));\r\n node.w = Utils.toNumber(el.getAttribute('gs-w'));\r\n node.h = Utils.toNumber(el.getAttribute('gs-h'));\r\n node.maxW = Utils.toNumber(el.getAttribute('gs-max-w'));\r\n node.minW = Utils.toNumber(el.getAttribute('gs-min-w'));\r\n node.maxH = Utils.toNumber(el.getAttribute('gs-max-h'));\r\n node.minH = Utils.toNumber(el.getAttribute('gs-min-h'));\r\n node.autoPosition = Utils.toBool(el.getAttribute('gs-auto-position'));\r\n node.noResize = Utils.toBool(el.getAttribute('gs-no-resize'));\r\n node.noMove = Utils.toBool(el.getAttribute('gs-no-move'));\r\n node.locked = Utils.toBool(el.getAttribute('gs-locked'));\r\n node.resizeHandles = el.getAttribute('gs-resize-handles');\r\n node.id = el.getAttribute('gs-id');\r\n\r\n // remove any key not found (null or false which is default)\r\n for (const key in node) {\r\n if (!node.hasOwnProperty(key)) return;\r\n if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)\r\n delete node[key];\r\n }\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /** @internal */\r\n protected _setStaticClass(): GridStack {\r\n let classes = ['grid-stack-static'];\r\n\r\n if (this.opts.staticGrid) {\r\n this.el.classList.add(...classes);\r\n this.el.setAttribute('gs-static', 'true');\r\n } else {\r\n this.el.classList.remove(...classes);\r\n this.el.removeAttribute('gs-static');\r\n\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off\r\n * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)\r\n */\r\n public onParentResize(): GridStack {\r\n if (!this.el || !this.el.clientWidth) return; // return if we're gone or no size yet (will get called again)\r\n let changedColumn = false;\r\n\r\n // see if we're nested and take our column count from our parent....\r\n if (this._autoColumn && this.opts._isNested) {\r\n if (this.opts.column !== this.opts._isNested.w) {\r\n changedColumn = true;\r\n this.column(this.opts._isNested.w, 'none');\r\n }\r\n } else {\r\n // else check for 1 column in/out behavior\r\n let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;\r\n if ((this.opts.column === 1) !== oneColumn) {\r\n changedColumn = true;\r\n if (this.opts.animate) { this.setAnimation(false); } // 1 <-> 12 is too radical, turn off animation\r\n this.column(oneColumn ? 1 : this._prevColumn);\r\n if (this.opts.animate) { this.setAnimation(true); }\r\n }\r\n }\r\n\r\n // make the cells content square again\r\n if (this._isAutoCellHeight) {\r\n if (!changedColumn && this.opts.cellHeightThrottle) {\r\n if (!this._cellHeightThrottle) {\r\n this._cellHeightThrottle = Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle);\r\n }\r\n this._cellHeightThrottle();\r\n } else {\r\n // immediate update if we've changed column count or have no threshold\r\n this.cellHeight();\r\n }\r\n }\r\n\r\n // finally update any nested grids\r\n this.engine.nodes.forEach(n => {\r\n if (n.subGrid) {(n.subGrid as GridStack).onParentResize()}\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /** add or remove the window size event handler */\r\n protected _updateWindowResizeEvent(forceRemove = false): GridStack {\r\n // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)\r\n const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested;\r\n\r\n if (!forceRemove && workTodo && !this._windowResizeBind) {\r\n this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later\r\n window.addEventListener('resize', this._windowResizeBind);\r\n } else if ((forceRemove || !workTodo) && this._windowResizeBind) {\r\n window.removeEventListener('resize', this._windowResizeBind);\r\n delete this._windowResizeBind; // remove link to us so we can free\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** @internal convert a potential selector into actual element */\r\n public static getElement(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement { return Utils.getElement(els) }\r\n /** @internal */\r\n public static getElements(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement[] { return Utils.getElements(els) }\r\n /** @internal */\r\n public static getGridElement(els: GridStackElement): GridHTMLElement { return GridStack.getElement(els) }\r\n /** @internal */\r\n public static getGridElements(els: string): GridHTMLElement[] { return Utils.getElements(els) }\r\n\r\n /** @internal initialize margin top/bottom/left/right and units */\r\n protected _initMargin(): GridStack {\r\n\r\n let data: HeightData;\r\n let margin = 0;\r\n\r\n // support passing multiple values like CSS (ex: '5px 10px 0 20px')\r\n let margins: string[] = [];\r\n if (typeof this.opts.margin === 'string') {\r\n margins = this.opts.margin.split(' ')\r\n }\r\n if (margins.length === 2) { // top/bot, left/right like CSS\r\n this.opts.marginTop = this.opts.marginBottom = margins[0];\r\n this.opts.marginLeft = this.opts.marginRight = margins[1];\r\n } else if (margins.length === 4) { // Clockwise like CSS\r\n this.opts.marginTop = margins[0];\r\n this.opts.marginRight = margins[1];\r\n this.opts.marginBottom = margins[2];\r\n this.opts.marginLeft = margins[3];\r\n } else {\r\n data = Utils.parseHeight(this.opts.margin);\r\n this.opts.marginUnit = data.unit;\r\n margin = this.opts.margin = data.h;\r\n }\r\n\r\n // see if top/bottom/left/right need to be set as well\r\n if (this.opts.marginTop === undefined) {\r\n this.opts.marginTop = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginTop);\r\n this.opts.marginTop = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginBottom === undefined) {\r\n this.opts.marginBottom = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginBottom);\r\n this.opts.marginBottom = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginRight === undefined) {\r\n this.opts.marginRight = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginRight);\r\n this.opts.marginRight = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginLeft === undefined) {\r\n this.opts.marginLeft = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginLeft);\r\n this.opts.marginLeft = data.h;\r\n delete this.opts.margin;\r\n }\r\n this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...\r\n if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {\r\n this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()\r\n }\r\n return this;\r\n }\r\n\r\n static GDRev = '6.0.1-dev';\r\n\r\n /*\r\n * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid\r\n * so we don't incur the load unless needed.\r\n * NOTE: had to make those methods public in order to define them else as\r\n * GridStack.prototype._setupAcceptWidget = function()\r\n * maybe there is a better way ????\r\n */\r\n /* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n /**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n * @param dragIn string selector (ex: '.sidebar .grid-stack-item')\r\n * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}\r\n **/\r\n public static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void { /* implemented in dd-gridstack.ts */ }\r\n\r\n /**\r\n * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids.\r\n * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\n public movable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\n public resizable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\n public disable(): GridStack { return this }\r\n /**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\n public enable(): GridStack { return this }\r\n /**\r\n * Enables/disables widget moving. No-op for static grids.\r\n */\r\n public enableMove(doEnable: boolean): GridStack { return this }\r\n /**\r\n * Enables/disables widget resizing. No-op for static grids.\r\n */\r\n public enableResize(doEnable: boolean): GridStack { return this }\r\n\r\n /** @internal removes any drag&drop present (called during destroy) */\r\n public _removeDD(el: GridItemHTMLElement): GridStack { return this }\r\n /** @internal called to add drag over support to support widgets */\r\n public _setupAcceptWidget(): GridStack { return this }\r\n /** @internal called to setup a trash drop zone if the user specifies it */\r\n public _setupRemoveDrop(): GridStack { return this }\r\n /** @internal prepares the element for drag&drop **/\r\n public _prepareDragDropByNode(node: GridStackNode): GridStack { return this }\r\n /** @internal handles actual drag/resize start **/\r\n public _onStartMoving(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal handles actual drag/resize **/\r\n public _dragOrResize(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal called when a node leaves our area (mouse out or shape outside) **/\r\n public _leave(el: GridItemHTMLElement, helper?: GridItemHTMLElement): void { return }\r\n // legacy method removed\r\n public commit(): GridStack { obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }\r\n}\r\n\r\n/*\r\n * and include D&D by default, which override some methods here\r\n * TODO: while we can generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)\r\n * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts\r\n */\r\nimport { DDGridStack } from './dd-gridstack';\r\nimport { isTouch } from './dd-touch';\r\nexport * from './dd-gridstack';\r\n","/**\r\n * utils.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types';\r\n\r\nexport interface HeightData {\r\n h: number;\r\n unit: string;\r\n}\r\n\r\n/** checks for obsolete method names */\r\n// eslint-disable-next-line\r\nexport function obsolete(self, f, oldName: string, newName: string, rev: string): (...args: any[]) => any {\r\n let wrapper = (...args) => {\r\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\r\n 'with `' + newName + '`. It will be **removed** in a future release');\r\n return f.apply(self, args);\r\n }\r\n wrapper.prototype = f.prototype;\r\n return wrapper;\r\n}\r\n\r\n/** checks for obsolete grid options (can be used for any fields, but msg is about options) */\r\nexport function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void {\r\n if (opts[oldName] !== undefined) {\r\n opts[newName] = opts[oldName];\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/** checks for obsolete grid options which are gone */\r\nexport function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void {\r\n if (opts[oldName] !== undefined) {\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\r\n }\r\n}\r\n\r\n/** checks for obsolete Jquery element attributes */\r\nexport function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void {\r\n let oldAttr = el.getAttribute(oldName);\r\n if (oldAttr !== null) {\r\n el.setAttribute(newName, oldAttr);\r\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods\r\n */\r\nexport class Utils {\r\n\r\n /** convert a potential selector into actual list of html elements */\r\n static getElements(els: GridStackElement): HTMLElement[] {\r\n if (typeof els === 'string') {\r\n let list = document.querySelectorAll(els);\r\n if (!list.length && els[0] !== '.' && els[0] !== '#') {\r\n list = document.querySelectorAll('.' + els);\r\n if (!list.length) { list = document.querySelectorAll('#' + els) }\r\n }\r\n return Array.from(list) as HTMLElement[];\r\n }\r\n return [els];\r\n }\r\n\r\n /** convert a potential selector into actual single element */\r\n static getElement(els: GridStackElement): HTMLElement {\r\n if (typeof els === 'string') {\r\n if (!els.length) return null;\r\n if (els[0] === '#') {\r\n return document.getElementById(els.substring(1));\r\n }\r\n if (els[0] === '.' || els[0] === '[') {\r\n return document.querySelector(els);\r\n }\r\n\r\n // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS\r\n if(!isNaN(+els[0])) { // start with digit\r\n return document.getElementById(els);\r\n }\r\n\r\n // finally try string, then id then class\r\n let el = document.querySelector(els);\r\n if (!el) { el = document.getElementById(els) }\r\n if (!el) { el = document.querySelector('.' + els) }\r\n return el as HTMLElement;\r\n }\r\n return els;\r\n }\r\n\r\n /** returns true if a and b overlap */\r\n static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w);\r\n }\r\n\r\n /** returns true if a and b touch edges or corners */\r\n static isTouching(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return Utils.isIntercepted(a, {x: b.x-0.5, y: b.y-0.5, w: b.w+1, h: b.h+1})\r\n }\r\n /**\r\n * Sorts array of nodes\r\n * @param nodes array to sort\r\n * @param dir 1 for asc, -1 for desc (optional)\r\n * @param width width of the grid. If undefined the width will be calculated automatically (optional).\r\n **/\r\n static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[] {\r\n column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12;\r\n if (dir === -1)\r\n return nodes.sort((a, b) => (b.x + b.y * column)-(a.x + a.y * column));\r\n else\r\n return nodes.sort((b, a) => (b.x + b.y * column)-(a.x + a.y * column));\r\n }\r\n\r\n /**\r\n * creates a style sheet with style id under given parent\r\n * @param id will set the 'gs-style-id' attribute to that id\r\n * @param parent to insert the stylesheet as first child,\r\n * if none supplied it will be appended to the document head instead.\r\n */\r\n static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet {\r\n let style: HTMLStyleElement = document.createElement('style');\r\n style.setAttribute('type', 'text/css');\r\n style.setAttribute('gs-style-id', id);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if ((style as any).styleSheet) { // TODO: only CSSImportRule have that and different beast ??\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (style as any).styleSheet.cssText = '';\r\n } else {\r\n style.appendChild(document.createTextNode('')); // WebKit hack\r\n }\r\n if (!parent) {\r\n // default to head\r\n parent = document.getElementsByTagName('head')[0];\r\n parent.appendChild(style);\r\n } else {\r\n parent.insertBefore(style, parent.firstChild);\r\n }\r\n return style.sheet as CSSStyleSheet;\r\n }\r\n\r\n /** removed the given stylesheet id */\r\n static removeStylesheet(id: string): void {\r\n let el = document.querySelector('STYLE[gs-style-id=' + id + ']');\r\n if (el && el.parentNode) el.remove();\r\n }\r\n\r\n /** inserts a CSS rule */\r\n static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void {\r\n if (typeof sheet.addRule === 'function') {\r\n sheet.addRule(selector, rules);\r\n } else if (typeof sheet.insertRule === 'function') {\r\n sheet.insertRule(`${selector}{${rules}}`);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n static toBool(v: unknown): boolean {\r\n if (typeof v === 'boolean') {\r\n return v;\r\n }\r\n if (typeof v === 'string') {\r\n v = v.toLowerCase();\r\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\r\n }\r\n return Boolean(v);\r\n }\r\n\r\n static toNumber(value: null | string): number {\r\n return (value === null || value.length === 0) ? undefined : Number(value);\r\n }\r\n\r\n static parseHeight(val: numberOrString): HeightData {\r\n let h: number;\r\n let unit = 'px';\r\n if (typeof val === 'string') {\r\n let match = val.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\r\n if (!match) {\r\n throw new Error('Invalid height');\r\n }\r\n unit = match[2] || 'px';\r\n h = parseFloat(match[1]);\r\n } else {\r\n h = val;\r\n }\r\n return { h, unit };\r\n }\r\n\r\n /** copies unset fields in target to use the given default sources values */\r\n // eslint-disable-next-line\r\n static defaults(target, ...sources): {} {\r\n\r\n sources.forEach(source => {\r\n for (const key in source) {\r\n if (!source.hasOwnProperty(key)) return;\r\n if (target[key] === null || target[key] === undefined) {\r\n target[key] = source[key];\r\n } else if (typeof source[key] === 'object' && typeof target[key] === 'object') {\r\n // property is an object, recursively add it's field over... #1373\r\n this.defaults(target[key], source[key]);\r\n }\r\n }\r\n });\r\n\r\n return target;\r\n }\r\n\r\n /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */\r\n static same(a: unknown, b: unknown): boolean {\r\n if (typeof a !== 'object') return a == b;\r\n if (typeof a !== typeof b) return false;\r\n // else we have object, check just 1 level deep for being same things...\r\n if (Object.keys(a).length !== Object.keys(b).length) return false;\r\n for (const key in a) {\r\n if (a[key] !== b[key]) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /** copies over b size & position (GridStackPosition), and possibly min/max as well */\r\n static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax = false): GridStackWidget {\r\n a.x = b.x;\r\n a.y = b.y;\r\n a.w = b.w;\r\n a.h = b.h;\r\n if (doMinMax) {\r\n if (b.minW) a.minW = b.minW;\r\n if (b.minH) a.minH = b.minH;\r\n if (b.maxW) a.maxW = b.maxW;\r\n if (b.maxH) a.maxH = b.maxH;\r\n }\r\n return a;\r\n }\r\n\r\n /** true if a and b has same size & position */\r\n static samePos(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\r\n }\r\n\r\n /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */\r\n static removeInternalAndSame(a: unknown, b: unknown):void {\r\n if (typeof a !== 'object' || typeof b !== 'object') return;\r\n for (let key in a) {\r\n let val = a[key];\r\n if (key[0] === '_' || val === b[key]) {\r\n delete a[key]\r\n } else if (val && typeof val === 'object' && b[key] !== undefined) {\r\n for (let i in val) {\r\n if (val[i] === b[key][i] || i[0] === '_') { delete val[i] }\r\n }\r\n if (!Object.keys(val).length) { delete a[key] }\r\n }\r\n }\r\n }\r\n\r\n /** return the closest parent (or itself) matching the given class */\r\n static closestByClass(el: HTMLElement, name: string): HTMLElement {\r\n while (el) {\r\n if (el.classList.contains(name)) return el;\r\n el = el.parentElement\r\n }\r\n return null;\r\n }\r\n\r\n /** delay calling the given function for given delay, preventing new calls from happening while waiting */\r\n static throttle(func: () => void, delay: number): () => void {\r\n let isWaiting = false;\r\n return (...args) => {\r\n if (!isWaiting) {\r\n isWaiting = true;\r\n setTimeout(() => { func(...args); isWaiting = false; }, delay);\r\n }\r\n }\r\n }\r\n\r\n static removePositioningStyles(el: HTMLElement): void {\r\n let style = el.style;\r\n if (style.position) {\r\n style.removeProperty('position');\r\n }\r\n if (style.left) {\r\n style.removeProperty('left');\r\n }\r\n if (style.top) {\r\n style.removeProperty('top');\r\n }\r\n if (style.width) {\r\n style.removeProperty('width');\r\n }\r\n if (style.height) {\r\n style.removeProperty('height');\r\n }\r\n }\r\n\r\n /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */\r\n static getScrollElement(el?: HTMLElement): HTMLElement {\r\n if (!el) return document.scrollingElement as HTMLElement || document.documentElement; // IE support\r\n const style = getComputedStyle(el);\r\n const overflowRegex = /(auto|scroll)/;\r\n\r\n if (overflowRegex.test(style.overflow + style.overflowY)) {\r\n return el;\r\n } else {\r\n return this.getScrollElement(el.parentElement);\r\n }\r\n }\r\n\r\n /** @internal */\r\n static updateScrollPosition(el: HTMLElement, position: {top: number}, distance: number): void {\r\n // is widget in view?\r\n let rect = el.getBoundingClientRect();\r\n let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\r\n if (rect.top < 0 ||\r\n rect.bottom > innerHeightOrClientHeight\r\n ) {\r\n // set scrollTop of first parent that scrolls\r\n // if parent is larger than el, set as low as possible\r\n // to get entire widget on screen\r\n let offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\r\n let offsetDiffUp = rect.top;\r\n let scrollEl = this.getScrollElement(el);\r\n if (scrollEl !== null) {\r\n let prevScroll = scrollEl.scrollTop;\r\n if (rect.top < 0 && distance < 0) {\r\n // moving up\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\r\n }\r\n } else if (distance > 0) {\r\n // moving down\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\r\n }\r\n }\r\n // move widget y by amount scrolled\r\n position.top += scrollEl.scrollTop - prevScroll;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal Function used to scroll the page.\r\n *\r\n * @param event `MouseEvent` that triggers the resize\r\n * @param el `HTMLElement` that's being resized\r\n * @param distance Distance from the V edges to start scrolling\r\n */\r\n static updateScrollResize(event: MouseEvent, el: HTMLElement, distance: number): void {\r\n const scrollEl = this.getScrollElement(el);\r\n const height = scrollEl.clientHeight;\r\n // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top\r\n // #1745 Special situation if scrollEl is document 'html': here browser spec states that\r\n // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;\r\n // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.\r\n const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top;\r\n const pointerPosY = event.clientY - offsetTop;\r\n const top = pointerPosY < distance;\r\n const bottom = pointerPosY > height - distance;\r\n\r\n if (top) {\r\n // This also can be done with a timeout to keep scrolling while the mouse is\r\n // in the scrolling zone. (will have smoother behavior)\r\n scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance});\r\n } else if (bottom) {\r\n scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY)});\r\n }\r\n }\r\n\r\n /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */\r\n static clone(obj: T): T {\r\n if (obj === null || obj === undefined || typeof(obj) !== 'object') {\r\n return obj;\r\n }\r\n // return Object.assign({}, obj);\r\n if (obj instanceof Array) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return [...obj] as any;\r\n }\r\n return {...obj};\r\n }\r\n\r\n /**\r\n * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.\r\n * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.\r\n */\r\n static cloneDeep(obj: T): T {\r\n // list of fields we will skip during cloneDeep (nested objects, other internal)\r\n const skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine'];\r\n // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ?\r\n const ret = Utils.clone(obj);\r\n for (const key in ret) {\r\n // NOTE: we don't support function/circular dependencies so skip those properties for now...\r\n if (ret.hasOwnProperty(key) && typeof(ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) {\r\n ret[key] = Utils.cloneDeep(obj[key]);\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /** deep clone the given HTML node, removing teh unique id field */\r\n public static cloneNode(el: HTMLElement): HTMLElement {\r\n const node = el.cloneNode(true) as HTMLElement;\r\n node.removeAttribute('id');\r\n return node;\r\n }\r\n\r\n public static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void {\r\n let parentNode: HTMLElement;\r\n if (typeof parent === 'string') {\r\n parentNode = document.querySelector(parent as string);\r\n } else {\r\n parentNode = parent as HTMLElement;\r\n }\r\n if (parentNode) {\r\n parentNode.appendChild(el);\r\n }\r\n }\r\n\r\n // public static setPositionRelative(el: HTMLElement): void {\r\n // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) {\r\n // el.style.position = \"relative\";\r\n // }\r\n // }\r\n\r\n public static addElStyles(el: HTMLElement, styles: { [prop: string]: string | string[] }): void {\r\n if (styles instanceof Object) {\r\n for (const s in styles) {\r\n if (styles.hasOwnProperty(s)) {\r\n if (Array.isArray(styles[s])) {\r\n // support fallback value\r\n (styles[s] as string[]).forEach(val => {\r\n el.style[s] = val;\r\n });\r\n } else {\r\n el.style[s] = styles[s];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public static initEvent(e: DragEvent | MouseEvent, info: { type: string; target?: EventTarget }): T {\r\n const evt = { type: info.type };\r\n const obj = {\r\n button: 0,\r\n which: 0,\r\n buttons: 1,\r\n bubbles: true,\r\n cancelable: true,\r\n target: info.target ? info.target : e.target\r\n };\r\n // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540\r\n if ((e as DragEvent).dataTransfer) {\r\n evt['dataTransfer'] = (e as DragEvent).dataTransfer; // workaround 'readonly' field.\r\n }\r\n ['altKey','ctrlKey','metaKey','shiftKey'].forEach(p => evt[p] = e[p]); // keys\r\n ['pageX','pageY','clientX','clientY','screenX','screenY'].forEach(p => evt[p] = e[p]); // point info\r\n return {...evt, ...obj} as unknown as T;\r\n }\r\n\r\n /** returns true if event is inside the given element rectangle */\r\n // Note: Safari Mac has null event.relatedTarget which causes #1684 so check if DragEvent is inside the coordinates instead\r\n // this.el.contains(event.relatedTarget as HTMLElement)\r\n // public static inside(e: MouseEvent, el: HTMLElement): boolean {\r\n // // srcElement, toElement, target: all set to placeholder when leaving simple grid, so we can't use that (Chrome)\r\n // let target: HTMLElement = e.relatedTarget || (e as any).fromElement;\r\n // if (!target) {\r\n // const { bottom, left, right, top } = el.getBoundingClientRect();\r\n // return (e.x < right && e.x > left && e.y < bottom && e.y > top);\r\n // }\r\n // return el.contains(target);\r\n // }\r\n}\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(270);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/gridstack-engine.d.ts b/dist/gridstack-engine.d.ts new file mode 100644 index 000000000..97e09d74b --- /dev/null +++ b/dist/gridstack-engine.d.ts @@ -0,0 +1,96 @@ +/** + * gridstack-engine.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +import { GridStackNode, GridStackPosition, GridStackMoveOpts } from './types'; +/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */ +declare type OnChangeCB = (nodes: GridStackNode[]) => void; +/** options used during creation - similar to GridStackOptions */ +export interface GridStackEngineOptions { + column?: number; + maxRow?: number; + float?: boolean; + nodes?: GridStackNode[]; + onChange?: OnChangeCB; +} +/** + * Defines the GridStack engine that does most no DOM grid manipulation. + * See GridStack methods and vars for descriptions. + * + * NOTE: values should not be modified directly - call the main GridStack API instead + */ +export declare class GridStackEngine { + column: number; + maxRow: number; + nodes: GridStackNode[]; + addedNodes: GridStackNode[]; + removedNodes: GridStackNode[]; + batchMode: boolean; + constructor(opts?: GridStackEngineOptions); + batchUpdate(flag?: boolean): GridStackEngine; + protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean; + /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */ + collide(skip: GridStackNode, area?: GridStackNode, skip2?: GridStackNode): GridStackNode; + collideAll(skip: GridStackNode, area?: GridStackNode, skip2?: GridStackNode): GridStackNode[]; + /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */ + collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode; + /** called to cache the nodes pixel rectangles used for collision detection during drag */ + cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine; + /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */ + swap(a: GridStackNode, b: GridStackNode): boolean; + isAreaEmpty(x: number, y: number, w: number, h: number): boolean; + /** re-layout grid items to reclaim any empty space */ + compact(): GridStackEngine; + /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */ + set float(val: boolean); + /** float getter method */ + get float(): boolean; + /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */ + sortNodes(dir?: -1 | 1): GridStackEngine; + /** + * given a random node, makes sure it's coordinates/values are valid in the current grid + * @param node to adjust + * @param resizing if out of bound, resize down or move into the grid to fit ? + */ + prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode; + /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */ + nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode; + /** returns a list of modified nodes from their original values */ + getDirtyNodes(verify?: boolean): GridStackNode[]; + /** call to add the given node to our list, fixing collision and re-packing */ + addNode(node: GridStackNode, triggerAddEvent?: boolean): GridStackNode; + removeNode(node: GridStackNode, removeDOM?: boolean, triggerEvent?: boolean): GridStackEngine; + removeAll(removeDOM?: boolean): GridStackEngine; + /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move. + * In more complicated cases (maxRow) it will attempt at moving the item and fixing + * others in a clone first, then apply those changes if still within specs. */ + moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean; + /** return true if can fit in grid height constrain only (always true if no maxRow) */ + willItFit(node: GridStackNode): boolean; + /** true if x,y or w,h are different after clamping to min/max */ + changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean; + /** return true if the passed in node was actually moved (checks for no-op and locked) */ + moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean; + getRow(): number; + beginUpdate(node: GridStackNode): GridStackEngine; + endUpdate(): GridStackEngine; + /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout), + * returning a list of widgets for serialization */ + save(saveElement?: boolean): GridStackNode[]; + /** + * call to cache the given layout internally to the given location so we can restore back when column changes size + * @param nodes list of nodes + * @param column corresponding column index to save it under + * @param clear if true, will force other caches to be removed (default false) + */ + cacheLayout(nodes: GridStackNode[], column: number, clear?: boolean): GridStackEngine; + /** + * call to cache the given node layout internally to the given location so we can restore back when column changes size + * @param node single node to cache + * @param column corresponding column index to save it under + */ + cacheOneLayout(n: GridStackNode, column: number): GridStackEngine; + /** called to remove all internal values but the _id */ + cleanupNode(node: GridStackNode): GridStackEngine; +} +export {}; diff --git a/dist/gridstack-engine.js b/dist/gridstack-engine.js new file mode 100644 index 000000000..a7ed51339 --- /dev/null +++ b/dist/gridstack-engine.js @@ -0,0 +1,903 @@ +"use strict"; +/** + * gridstack-engine.ts 6.0.1-dev + * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GridStackEngine = void 0; +const utils_1 = require("./utils"); +/** + * Defines the GridStack engine that does most no DOM grid manipulation. + * See GridStack methods and vars for descriptions. + * + * NOTE: values should not be modified directly - call the main GridStack API instead + */ +class GridStackEngine { + constructor(opts = {}) { + this.addedNodes = []; + this.removedNodes = []; + this.column = opts.column || 12; + this.maxRow = opts.maxRow; + this._float = opts.float; + this.nodes = opts.nodes || []; + this.onChange = opts.onChange; + } + batchUpdate(flag = true) { + if (!!this.batchMode === flag) + return this; + this.batchMode = flag; + if (flag) { + this._prevFloat = this._float; + this._float = true; // let things go anywhere for now... will restore and possibly reposition later + this.saveInitial(); // since begin update (which is called multiple times) won't do this + } + else { + this._float = this._prevFloat; + delete this._prevFloat; + this._packNodes()._notify(); + } + return this; + } + // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip + _useEntireRowArea(node, nn) { + return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y); + } + /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found. + * return true if we moved. */ + _fixCollisions(node, nn = node, collide, opt = {}) { + this.sortNodes(-1); // from last to first, so recursive collision move items in the right order + collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none... + if (!collide) + return false; + // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size + if (node._moving && !opt.nested && !this.float) { + if (this.swap(node, collide)) + return true; + } + // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid) + let area = nn; + if (this._useEntireRowArea(node, nn)) { + area = { x: 0, w: this.column, y: nn.y, h: nn.h }; + collide = this.collide(node, area, opt.skip); // force new hit + } + let didMove = false; + let newOpt = { nested: true, pack: false }; + while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each + let moved; + // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide, + // but remember that skip down so we only do this once (and push others otherwise). + if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float && + // can take space we had, or before where we're going + (!this.collide(collide, Object.assign(Object.assign({}, collide), { y: node.y }), node) || !this.collide(collide, Object.assign(Object.assign({}, collide), { y: nn.y - collide.h }), node))) { + node._skipDown = (node._skipDown || nn.y > node.y); + moved = this.moveNode(node, Object.assign(Object.assign(Object.assign({}, nn), { y: collide.y + collide.h }), newOpt)); + if (collide.locked && moved) { + utils_1.Utils.copyPos(nn, node); // moving after lock become our new desired location + } + else if (!collide.locked && moved && opt.pack) { + // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way + this._packNodes(); + nn.y = collide.y + collide.h; + utils_1.Utils.copyPos(node, nn); + } + didMove = didMove || moved; + } + else { + // move collide down *after* where we will be, ignoring where we are now (don't collide with us) + moved = this.moveNode(collide, Object.assign(Object.assign(Object.assign({}, collide), { y: nn.y + nn.h, skip: node }), newOpt)); + } + if (!moved) { + return didMove; + } // break inf loop if we couldn't move after all (ex: maxRow, fixed) + collide = undefined; + } + return didMove; + } + /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */ + collide(skip, area = skip, skip2) { + return this.nodes.find(n => n !== skip && n !== skip2 && utils_1.Utils.isIntercepted(n, area)); + } + collideAll(skip, area = skip, skip2) { + return this.nodes.filter(n => n !== skip && n !== skip2 && utils_1.Utils.isIntercepted(n, area)); + } + /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */ + collideCoverage(node, o, collides) { + if (!o.rect || !node._rect) + return; + let r0 = node._rect; // where started + let r = Object.assign({}, o.rect); // where we are + // update dragged rect to show where it's coming from (above or below, etc...) + if (r.y > r0.y) { + r.h += r.y - r0.y; + r.y = r0.y; + } + else { + r.h += r0.y - r.y; + } + if (r.x > r0.x) { + r.w += r.x - r0.x; + r.x = r0.x; + } + else { + r.w += r0.x - r.x; + } + let collide; + collides.forEach(n => { + if (n.locked || !n._rect) + return; + let r2 = n._rect; // overlapping target + let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50% + // depending on which side we started from, compute the overlap % of coverage + // (ex: from above/below we only compute the max horizontal line coverage) + if (r0.y < r2.y) { // from above + yOver = ((r.y + r.h) - r2.y) / r2.h; + } + else if (r0.y + r0.h > r2.y + r2.h) { // from below + yOver = ((r2.y + r2.h) - r.y) / r2.h; + } + if (r0.x < r2.x) { // from the left + xOver = ((r.x + r.w) - r2.x) / r2.w; + } + else if (r0.x + r0.w > r2.x + r2.w) { // from the right + xOver = ((r2.x + r2.w) - r.x) / r2.w; + } + let over = Math.min(xOver, yOver); + if (over > overMax) { + overMax = over; + collide = n; + } + }); + return collide; + } + /** called to cache the nodes pixel rectangles used for collision detection during drag */ + cacheRects(w, h, top, right, bottom, left) { + this.nodes.forEach(n => n._rect = { + y: n.y * h + top, + x: n.x * w + left, + w: n.w * w - left - right, + h: n.h * h - top - bottom + }); + return this; + } + /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */ + swap(a, b) { + if (!b || b.locked || !a || a.locked) + return false; + function _doSwap() { + let x = b.x, y = b.y; + b.x = a.x; + b.y = a.y; // b -> a position + if (a.h != b.h) { + a.x = x; + a.y = b.y + b.h; // a -> goes after b + } + else if (a.w != b.w) { + a.x = b.x + b.w; + a.y = y; // a -> goes after b + } + else { + a.x = x; + a.y = y; // a -> old b position + } + a._dirty = b._dirty = true; + return true; + } + let touching; // remember if we called it (vs undefined) + // same size and same row or column, and touching + if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = utils_1.Utils.isTouching(a, b))) + return _doSwap(); + if (touching === false) + return; // IFF ran test and fail, bail out + // check for taking same columns (but different height) and touching + if (a.w === b.w && a.x === b.x && (touching || (touching = utils_1.Utils.isTouching(a, b)))) { + if (b.y < a.y) { + let t = a; + a = b; + b = t; + } // swap a <-> b vars so a is first + return _doSwap(); + } + if (touching === false) + return; + // check if taking same row (but different width) and touching + if (a.h === b.h && a.y === b.y && (touching || (touching = utils_1.Utils.isTouching(a, b)))) { + if (b.x < a.x) { + let t = a; + a = b; + b = t; + } // swap a <-> b vars so a is first + return _doSwap(); + } + return false; + } + isAreaEmpty(x, y, w, h) { + let nn = { x: x || 0, y: y || 0, w: w || 1, h: h || 1 }; + return !this.collide(nn); + } + /** re-layout grid items to reclaim any empty space */ + compact() { + if (this.nodes.length === 0) + return this; + this.batchUpdate() + .sortNodes(); + let copyNodes = this.nodes; + this.nodes = []; // pretend we have no nodes to conflict layout to start with... + copyNodes.forEach(node => { + if (!node.locked) { + node.autoPosition = true; + } + this.addNode(node, false); // 'false' for add event trigger + node._dirty = true; // will force attr update + }); + return this.batchUpdate(false); + } + /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */ + set float(val) { + if (this._float === val) + return; + this._float = val || false; + if (!val) { + this._packNodes()._notify(); + } + } + /** float getter method */ + get float() { return this._float || false; } + /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */ + sortNodes(dir) { + this.nodes = utils_1.Utils.sort(this.nodes, dir, this.column); + return this; + } + /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */ + _packNodes() { + if (this.batchMode) { + return this; + } + this.sortNodes(); // first to last + if (this.float) { + // restore original Y pos + this.nodes.forEach(n => { + if (n._updating || n._orig === undefined || n.y === n._orig.y) + return; + let newY = n.y; + while (newY > n._orig.y) { + --newY; + let collide = this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h }); + if (!collide) { + n._dirty = true; + n.y = newY; + } + } + }); + } + else { + // top gravity pack + this.nodes.forEach((n, i) => { + if (n.locked) + return; + while (n.y > 0) { + let newY = i === 0 ? 0 : n.y - 1; + let canBeMoved = i === 0 || !this.collide(n, { x: n.x, y: newY, w: n.w, h: n.h }); + if (!canBeMoved) + break; + // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions + // and move items back. The user 'change' CB should detect changes from the original + // starting position instead. + n._dirty = (n.y !== newY); + n.y = newY; + } + }); + } + return this; + } + /** + * given a random node, makes sure it's coordinates/values are valid in the current grid + * @param node to adjust + * @param resizing if out of bound, resize down or move into the grid to fit ? + */ + prepareNode(node, resizing) { + node = node || {}; + node._id = node._id || GridStackEngine._idSeq++; + // if we're missing position, have the grid position us automatically (before we set them to 0,0) + if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) { + node.autoPosition = true; + } + // assign defaults for missing required fields + let defaults = { x: 0, y: 0, w: 1, h: 1 }; + utils_1.Utils.defaults(node, defaults); + if (!node.autoPosition) { + delete node.autoPosition; + } + if (!node.noResize) { + delete node.noResize; + } + if (!node.noMove) { + delete node.noMove; + } + // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #) + if (typeof node.x == 'string') { + node.x = Number(node.x); + } + if (typeof node.y == 'string') { + node.y = Number(node.y); + } + if (typeof node.w == 'string') { + node.w = Number(node.w); + } + if (typeof node.h == 'string') { + node.h = Number(node.h); + } + if (isNaN(node.x)) { + node.x = defaults.x; + node.autoPosition = true; + } + if (isNaN(node.y)) { + node.y = defaults.y; + node.autoPosition = true; + } + if (isNaN(node.w)) { + node.w = defaults.w; + } + if (isNaN(node.h)) { + node.h = defaults.h; + } + return this.nodeBoundFix(node, resizing); + } + /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */ + nodeBoundFix(node, resizing) { + let before = node._orig || utils_1.Utils.copyPos({}, node); + if (node.maxW) { + node.w = Math.min(node.w, node.maxW); + } + if (node.maxH) { + node.h = Math.min(node.h, node.maxH); + } + if (node.minW && node.minW <= this.column) { + node.w = Math.max(node.w, node.minW); + } + if (node.minH) { + node.h = Math.max(node.h, node.minH); + } + if (node.w > this.column) { + // if user loaded a larger than allowed widget for current # of columns, + // remember it's full width so we can restore back (1 -> 12 column) #1655 + // IFF we're not in the middle of column resizing! + if (this.column < 12 && !this._inColumnResize) { + node.w = Math.min(12, node.w); + this.cacheOneLayout(node, 12); + } + node.w = this.column; + } + else if (node.w < 1) { + node.w = 1; + } + if (this.maxRow && node.h > this.maxRow) { + node.h = this.maxRow; + } + else if (node.h < 1) { + node.h = 1; + } + if (node.x < 0) { + node.x = 0; + } + if (node.y < 0) { + node.y = 0; + } + if (node.x + node.w > this.column) { + if (resizing) { + node.w = this.column - node.x; + } + else { + node.x = this.column - node.w; + } + } + if (this.maxRow && node.y + node.h > this.maxRow) { + if (resizing) { + node.h = this.maxRow - node.y; + } + else { + node.y = this.maxRow - node.h; + } + } + if (!utils_1.Utils.samePos(node, before)) { + node._dirty = true; + } + return node; + } + /** returns a list of modified nodes from their original values */ + getDirtyNodes(verify) { + // compare original x,y,w,h instead as _dirty can be a temporary state + if (verify) { + return this.nodes.filter(n => n._dirty && !utils_1.Utils.samePos(n, n._orig)); + } + return this.nodes.filter(n => n._dirty); + } + /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */ + _notify(removedNodes) { + if (this.batchMode || !this.onChange) + return this; + let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes()); + this.onChange(dirtyNodes); + return this; + } + /** @internal remove dirty and last tried info */ + cleanNodes() { + if (this.batchMode) + return this; + this.nodes.forEach(n => { + delete n._dirty; + delete n._lastTried; + }); + return this; + } + /** @internal called to save initial position/size to track real dirty state. + * Note: should be called right after we call change event (so next API is can detect changes) + * as well as right before we start move/resize/enter (so we can restore items to prev values) */ + saveInitial() { + this.nodes.forEach(n => { + n._orig = utils_1.Utils.copyPos({}, n); + delete n._dirty; + }); + this._hasLocked = this.nodes.some(n => n.locked); + return this; + } + /** @internal restore all the nodes back to initial values (called when we leave) */ + restoreInitial() { + this.nodes.forEach(n => { + if (utils_1.Utils.samePos(n, n._orig)) + return; + utils_1.Utils.copyPos(n, n._orig); + n._dirty = true; + }); + this._notify(); + return this; + } + /** call to add the given node to our list, fixing collision and re-packing */ + addNode(node, triggerAddEvent = false) { + let dup = this.nodes.find(n => n._id === node._id); + if (dup) + return dup; // prevent inserting twice! return it instead. + // skip prepareNode if we're in middle of column resize (not new) but do check for bounds! + node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node); + delete node._temporaryRemoved; + delete node._removeDOM; + if (node.autoPosition) { + this.sortNodes(); + for (let i = 0;; ++i) { + let x = i % this.column; + let y = Math.floor(i / this.column); + if (x + node.w > this.column) { + continue; + } + let box = { x, y, w: node.w, h: node.h }; + if (!this.nodes.find(n => utils_1.Utils.isIntercepted(box, n))) { + node.x = x; + node.y = y; + delete node.autoPosition; // found our slot + break; + } + } + } + this.nodes.push(node); + if (triggerAddEvent) { + this.addedNodes.push(node); + } + this._fixCollisions(node); + if (!this.batchMode) { + this._packNodes()._notify(); + } + return node; + } + removeNode(node, removeDOM = true, triggerEvent = false) { + if (!this.nodes.find(n => n === node)) { + // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`) + return this; + } + if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag) + this.removedNodes.push(node); + } + if (removeDOM) + node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info) + // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times. + this.nodes = this.nodes.filter(n => n !== node); + return this._packNodes() + ._notify([node]); + } + removeAll(removeDOM = true) { + delete this._layouts; + if (this.nodes.length === 0) + return this; + removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info) + this.removedNodes = this.nodes; + this.nodes = []; + return this._notify(this.removedNodes); + } + /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move. + * In more complicated cases (maxRow) it will attempt at moving the item and fixing + * others in a clone first, then apply those changes if still within specs. */ + moveNodeCheck(node, o) { + // if (node.locked) return false; + if (!this.changedPosConstrain(node, o)) + return false; + o.pack = true; + // simpler case: move item directly... + if (!this.maxRow) { + return this.moveNode(node, o); + } + // complex case: create a clone with NO maxRow (will check for out of bounds at the end) + let clonedNode; + let clone = new GridStackEngine({ + column: this.column, + float: this.float, + nodes: this.nodes.map(n => { + if (n === node) { + clonedNode = Object.assign({}, n); + return clonedNode; + } + return Object.assign({}, n); + }) + }); + if (!clonedNode) + return false; + // make sure we are still valid size + let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow; + // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing + if (!canMove && !o.resizing) { + let collide = this.collide(node, o); + if (collide && this.swap(node, collide)) { + this._notify(); + return true; + } + } + if (!canMove) + return false; + // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over! + // Note: we can't use the list directly as elements and other parts point to actual node, so copy content + clone.nodes.filter(n => n._dirty).forEach(c => { + let n = this.nodes.find(a => a._id === c._id); + if (!n) + return; + utils_1.Utils.copyPos(n, c); + n._dirty = true; + }); + this._notify(); + return true; + } + /** return true if can fit in grid height constrain only (always true if no maxRow) */ + willItFit(node) { + delete node._willFitPos; + if (!this.maxRow) + return true; + // create a clone with NO maxRow and check if still within size + let clone = new GridStackEngine({ + column: this.column, + float: this.float, + nodes: this.nodes.map(n => { return Object.assign({}, n); }) + }); + let n = Object.assign({}, node); // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687 + this.cleanupNode(n); + delete n.el; + delete n._id; + delete n.content; + delete n.grid; + clone.addNode(n); + if (clone.getRow() <= this.maxRow) { + node._willFitPos = utils_1.Utils.copyPos({}, n); + return true; + } + return false; + } + /** true if x,y or w,h are different after clamping to min/max */ + changedPosConstrain(node, p) { + // first make sure w,h are set for caller + p.w = p.w || node.w; + p.h = p.h || node.h; + if (node.x !== p.x || node.y !== p.y) + return true; + // check constrained w,h + if (node.maxW) { + p.w = Math.min(p.w, node.maxW); + } + if (node.maxH) { + p.h = Math.min(p.h, node.maxH); + } + if (node.minW) { + p.w = Math.max(p.w, node.minW); + } + if (node.minH) { + p.h = Math.max(p.h, node.minH); + } + return (node.w !== p.w || node.h !== p.h); + } + /** return true if the passed in node was actually moved (checks for no-op and locked) */ + moveNode(node, o) { + if (!node || /*node.locked ||*/ !o) + return false; + if (o.pack === undefined) + o.pack = true; + // constrain the passed in values and check if we're still changing our node + if (typeof o.x !== 'number') { + o.x = node.x; + } + if (typeof o.y !== 'number') { + o.y = node.y; + } + if (typeof o.w !== 'number') { + o.w = node.w; + } + if (typeof o.h !== 'number') { + o.h = node.h; + } + let resizing = (node.w !== o.w || node.h !== o.h); + let nn = utils_1.Utils.copyPos({}, node, true); // get min/max out first, then opt positions next + utils_1.Utils.copyPos(nn, o); + nn = this.nodeBoundFix(nn, resizing); + utils_1.Utils.copyPos(o, nn); + if (utils_1.Utils.samePos(node, o)) + return false; + let prevPos = utils_1.Utils.copyPos({}, node); + // check if we will need to fix collision at our new location + let collides = this.collideAll(node, nn, o.skip); + let needToMove = true; + if (collides.length) { + // now check to make sure we actually collided over 50% surface area while dragging + let collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0]; + if (collide) { + needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved... + } + else { + needToMove = false; // we didn't cover >50% for a move, skip... + } + } + // now move (to the original ask vs the collision version which might differ) and repack things + if (needToMove) { + node._dirty = true; + utils_1.Utils.copyPos(node, nn); + } + if (o.pack) { + this._packNodes() + ._notify(); + } + return !utils_1.Utils.samePos(node, prevPos); // pack might have moved things back + } + getRow() { + return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0); + } + beginUpdate(node) { + if (!node._updating) { + node._updating = true; + delete node._skipDown; + if (!this.batchMode) + this.saveInitial(); + } + return this; + } + endUpdate() { + let n = this.nodes.find(n => n._updating); + if (n) { + delete n._updating; + delete n._skipDown; + } + return this; + } + /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout), + * returning a list of widgets for serialization */ + save(saveElement = true) { + var _a; + // use the highest layout for any saved info so we can have full detail on reload #1849 + let len = (_a = this._layouts) === null || _a === void 0 ? void 0 : _a.length; + let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null; + let list = []; + this.sortNodes(); + this.nodes.forEach(n => { + let wl = layout === null || layout === void 0 ? void 0 : layout.find(l => l._id === n._id); + let w = Object.assign({}, n); + // use layout info instead if set + if (wl) { + w.x = wl.x; + w.y = wl.y; + w.w = wl.w; + } + // delete internals + for (let key in w) { + if (key[0] === '_' || w[key] === null || w[key] === undefined) + delete w[key]; + } + delete w.grid; + if (!saveElement) + delete w.el; + // delete default values (will be re-created on read) + if (!w.autoPosition) + delete w.autoPosition; + if (!w.noResize) + delete w.noResize; + if (!w.noMove) + delete w.noMove; + if (!w.locked) + delete w.locked; + list.push(w); + }); + return list; + } + /** @internal called whenever a node is added or moved - updates the cached layouts */ + layoutsNodesChange(nodes) { + if (!this._layouts || this._inColumnResize) + return this; + // remove smaller layouts - we will re-generate those on the fly... larger ones need to update + this._layouts.forEach((layout, column) => { + if (!layout || column === this.column) + return this; + if (column < this.column) { + this._layouts[column] = undefined; + } + else { + // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better. + // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785 + let ratio = column / this.column; + nodes.forEach(node => { + if (!node._orig) + return; // didn't change (newly added ?) + let n = layout.find(l => l._id === node._id); + if (!n) + return; // no cache for new nodes. Will use those values. + // Y changed, push down same amount + // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode) + if (node.y !== node._orig.y) { + n.y += (node.y - node._orig.y); + } + // X changed, scale from new position + if (node.x !== node._orig.x) { + n.x = Math.round(node.x * ratio); + } + // width changed, scale from new width + if (node.w !== node._orig.w) { + n.w = Math.round(node.w * ratio); + } + // ...height always carries over from cache + }); + } + }); + return this; + } + /** + * @internal Called to scale the widget width & position up/down based on the column change. + * Note we store previous layouts (especially original ones) to make it possible to go + * from say 12 -> 1 -> 12 and get back to where we were. + * + * @param prevColumn previous number of columns + * @param column new column number + * @param nodes different sorted list (ex: DOM order) instead of current list + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + updateNodeWidths(prevColumn, column, nodes, layout = 'moveScale') { + var _a; + if (!this.nodes.length || !column || prevColumn === column) + return this; + // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data + this.cacheLayout(this.nodes, prevColumn); + this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision + let newNodes = []; + // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout + let domOrder = false; + if (column === 1 && (nodes === null || nodes === void 0 ? void 0 : nodes.length)) { + domOrder = true; + let top = 0; + nodes.forEach(n => { + n.x = 0; + n.w = 1; + n.y = Math.max(n.y, top); + top = n.y + n.h; + }); + newNodes = nodes; + nodes = []; + } + else { + nodes = utils_1.Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision) + } + // see if we have cached previous layout IFF we are going up in size (restore) otherwise always + // generate next size down from where we are (looks more natural as you gradually size down). + let cacheNodes = []; + if (column > prevColumn) { + cacheNodes = this._layouts[column] || []; + // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate + // by pretending we came from that larger column by assigning those values as starting point + let lastIndex = this._layouts.length - 1; + if (!cacheNodes.length && prevColumn !== lastIndex && ((_a = this._layouts[lastIndex]) === null || _a === void 0 ? void 0 : _a.length)) { + prevColumn = lastIndex; + this._layouts[lastIndex].forEach(cacheNode => { + let n = nodes.find(n => n._id === cacheNode._id); + if (n) { + // still current, use cache info positions + n.x = cacheNode.x; + n.y = cacheNode.y; + n.w = cacheNode.w; + } + }); + } + } + // if we found cache re-use those nodes that are still current + cacheNodes.forEach(cacheNode => { + let j = nodes.findIndex(n => n._id === cacheNode._id); + if (j !== -1) { + // still current, use cache info positions + nodes[j].x = cacheNode.x; + nodes[j].y = cacheNode.y; + nodes[j].w = cacheNode.w; + newNodes.push(nodes[j]); + nodes.splice(j, 1); + } + }); + // ...and add any extra non-cached ones + if (nodes.length) { + if (typeof layout === 'function') { + layout(column, prevColumn, newNodes, nodes); + } + else if (!domOrder) { + let ratio = column / prevColumn; + let move = (layout === 'move' || layout === 'moveScale'); + let scale = (layout === 'scale' || layout === 'moveScale'); + nodes.forEach(node => { + // NOTE: x + w could be outside of the grid, but addNode() below will handle that + node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1))); + node.w = ((column === 1 || prevColumn === 1) ? 1 : + scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column))); + newNodes.push(node); + }); + nodes = []; + } + } + // finally re-layout them in reverse order (to get correct placement) + newNodes = utils_1.Utils.sort(newNodes, -1, column); + this._inColumnResize = true; // prevent cache update + this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout + newNodes.forEach(node => { + this.addNode(node, false); // 'false' for add event trigger + delete node._orig; // make sure the commit doesn't try to restore things back to original + }); + this.batchUpdate(false); + delete this._inColumnResize; + return this; + } + /** + * call to cache the given layout internally to the given location so we can restore back when column changes size + * @param nodes list of nodes + * @param column corresponding column index to save it under + * @param clear if true, will force other caches to be removed (default false) + */ + cacheLayout(nodes, column, clear = false) { + let copy = []; + nodes.forEach((n, i) => { + n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set + copy[i] = { x: n.x, y: n.y, w: n.w, _id: n._id }; // only thing we change is x,y,w and id to find it back + }); + this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick + this._layouts[column] = copy; + return this; + } + /** + * call to cache the given node layout internally to the given location so we can restore back when column changes size + * @param node single node to cache + * @param column corresponding column index to save it under + */ + cacheOneLayout(n, column) { + n._id = n._id || GridStackEngine._idSeq++; + let layout = { x: n.x, y: n.y, w: n.w, _id: n._id }; + this._layouts = this._layouts || []; + this._layouts[column] = this._layouts[column] || []; + let index = this._layouts[column].findIndex(l => l._id === n._id); + index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout; + return this; + } + /** called to remove all internal values but the _id */ + cleanupNode(node) { + for (let prop in node) { + if (prop[0] === '_' && prop !== '_id') + delete node[prop]; + } + return this; + } +} +exports.GridStackEngine = GridStackEngine; +/** @internal unique global internal _id counter NOT starting at 0 */ +GridStackEngine._idSeq = 1; +//# sourceMappingURL=gridstack-engine.js.map \ No newline at end of file diff --git a/dist/gridstack-engine.js.map b/dist/gridstack-engine.js.map new file mode 100644 index 000000000..601d314cc --- /dev/null +++ b/dist/gridstack-engine.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gridstack-engine.js","sourceRoot":"","sources":["../src/gridstack-engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * gridstack-engine.ts 6.0.1-dev\n * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license\n */\n\nimport { Utils } from './utils';\nimport { GridStackNode, ColumnOptions, GridStackPosition, GridStackMoveOpts } from './types';\n\n/** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */\ntype OnChangeCB = (nodes: GridStackNode[]) => void;\n\n/** options used during creation - similar to GridStackOptions */\nexport interface GridStackEngineOptions {\n column?: number;\n maxRow?: number;\n float?: boolean;\n nodes?: GridStackNode[];\n onChange?: OnChangeCB;\n}\n\n/**\n * Defines the GridStack engine that does most no DOM grid manipulation.\n * See GridStack methods and vars for descriptions.\n *\n * NOTE: values should not be modified directly - call the main GridStack API instead\n */\nexport class GridStackEngine {\n public column: number;\n public maxRow: number;\n public nodes: GridStackNode[];\n public addedNodes: GridStackNode[] = [];\n public removedNodes: GridStackNode[] = [];\n public batchMode: boolean;\n /** @internal callback to update the DOM attributes */\n protected onChange: OnChangeCB;\n /** @internal */\n protected _float: boolean;\n /** @internal */\n protected _prevFloat: boolean;\n /** @internal cached layouts of difference column count so we can restore ack (eg 12 -> 1 -> 12) */\n protected _layouts?: GridStackNode[][]; // maps column # to array of values nodes\n /** @internal true while we are resizing widgets during column resize to skip certain parts */\n protected _inColumnResize: boolean;\n /** @internal true if we have some items locked */\n protected _hasLocked: boolean;\n /** @internal unique global internal _id counter NOT starting at 0 */\n protected static _idSeq = 1;\n\n public constructor(opts: GridStackEngineOptions = {}) {\n this.column = opts.column || 12;\n this.maxRow = opts.maxRow;\n this._float = opts.float;\n this.nodes = opts.nodes || [];\n this.onChange = opts.onChange;\n }\n\n public batchUpdate(flag = true): GridStackEngine {\n if (!!this.batchMode === flag) return this;\n this.batchMode = flag;\n if (flag) {\n this._prevFloat = this._float;\n this._float = true; // let things go anywhere for now... will restore and possibly reposition later\n this.saveInitial(); // since begin update (which is called multiple times) won't do this\n } else {\n this._float = this._prevFloat;\n delete this._prevFloat;\n this._packNodes()._notify();\n }\n return this;\n }\n\n // use entire row for hitting area (will use bottom reverse sorted first) if we not actively moving DOWN and didn't already skip\n protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean {\n return !this.float && !this._hasLocked && (!node._moving || node._skipDown || nn.y <= node.y);\n }\n\n /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found.\n * return true if we moved. */\n protected _fixCollisions(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {}): boolean {\n this.sortNodes(-1); // from last to first, so recursive collision move items in the right order\n\n collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none...\n if (!collide) return false;\n\n // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size\n if (node._moving && !opt.nested && !this.float) {\n if (this.swap(node, collide)) return true;\n }\n\n // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)\n let area = nn;\n if (this._useEntireRowArea(node, nn)) {\n area = {x: 0, w: this.column, y: nn.y, h: nn.h};\n collide = this.collide(node, area, opt.skip); // force new hit\n }\n\n let didMove = false;\n let newOpt: GridStackMoveOpts = {nested: true, pack: false};\n while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each\n let moved: boolean;\n // if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,\n // but remember that skip down so we only do this once (and push others otherwise).\n if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&\n // can take space we had, or before where we're going\n (!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {\n node._skipDown = (node._skipDown || nn.y > node.y);\n moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});\n if (collide.locked && moved) {\n Utils.copyPos(nn, node); // moving after lock become our new desired location\n } else if (!collide.locked && moved && opt.pack) {\n // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way\n this._packNodes();\n nn.y = collide.y + collide.h;\n Utils.copyPos(node, nn);\n }\n didMove = didMove || moved;\n } else {\n // move collide down *after* where we will be, ignoring where we are now (don't collide with us)\n moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt});\n }\n if (!moved) { return didMove; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)\n collide = undefined;\n }\n return didMove;\n }\n\n /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */\n public collide(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode {\n return this.nodes.find(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n public collideAll(skip: GridStackNode, area = skip, skip2?: GridStackNode): GridStackNode[] {\n return this.nodes.filter(n => n !== skip && n !== skip2 && Utils.isIntercepted(n, area));\n }\n\n /** does a pixel coverage collision, returning the node that has the most coverage that is >50% mid line */\n public collideCoverage(node: GridStackNode, o: GridStackMoveOpts, collides: GridStackNode[]): GridStackNode {\n if (!o.rect || !node._rect) return;\n let r0 = node._rect; // where started\n let r = {...o.rect}; // where we are\n\n // update dragged rect to show where it's coming from (above or below, etc...)\n if (r.y > r0.y) {\n r.h += r.y - r0.y;\n r.y = r0.y;\n } else {\n r.h += r0.y - r.y;\n }\n if (r.x > r0.x) {\n r.w += r.x - r0.x;\n r.x = r0.x;\n } else {\n r.w += r0.x - r.x;\n }\n\n let collide: GridStackNode;\n collides.forEach(n => {\n if (n.locked || !n._rect) return;\n let r2 = n._rect; // overlapping target\n let yOver = Number.MAX_VALUE, xOver = Number.MAX_VALUE, overMax = 0.5; // need >50%\n // depending on which side we started from, compute the overlap % of coverage\n // (ex: from above/below we only compute the max horizontal line coverage)\n if (r0.y < r2.y) { // from above\n yOver = ((r.y + r.h) - r2.y) / r2.h;\n } else if (r0.y+r0.h > r2.y+r2.h) { // from below\n yOver = ((r2.y + r2.h) - r.y) / r2.h;\n }\n if (r0.x < r2.x) { // from the left\n xOver = ((r.x + r.w) - r2.x) / r2.w;\n } else if (r0.x+r0.w > r2.x+r2.w) { // from the right\n xOver = ((r2.x + r2.w) - r.x) / r2.w;\n }\n let over = Math.min(xOver, yOver);\n if (over > overMax) {\n overMax = over;\n collide = n;\n }\n });\n return collide;\n }\n\n /** called to cache the nodes pixel rectangles used for collision detection during drag */\n public cacheRects(w: number, h: number, top: number, right: number, bottom: number, left: number): GridStackEngine\n {\n this.nodes.forEach(n =>\n n._rect = {\n y: n.y * h + top,\n x: n.x * w + left,\n w: n.w * w - left - right,\n h: n.h * h - top - bottom\n }\n );\n return this;\n }\n\n /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */\n public swap(a: GridStackNode, b: GridStackNode): boolean {\n if (!b || b.locked || !a || a.locked) return false;\n\n function _doSwap(): true { // assumes a is before b IFF they have different height (put after rather than exact swap)\n let x = b.x, y = b.y;\n b.x = a.x; b.y = a.y; // b -> a position\n if (a.h != b.h) {\n a.x = x; a.y = b.y + b.h; // a -> goes after b\n } else if (a.w != b.w) {\n a.x = b.x + b.w; a.y = y; // a -> goes after b\n } else {\n a.x = x; a.y = y; // a -> old b position\n }\n a._dirty = b._dirty = true;\n return true;\n }\n let touching: boolean; // remember if we called it (vs undefined)\n\n // same size and same row or column, and touching\n if (a.w === b.w && a.h === b.h && (a.x === b.x || a.y === b.y) && (touching = Utils.isTouching(a, b)))\n return _doSwap();\n if (touching === false) return; // IFF ran test and fail, bail out\n\n // check for taking same columns (but different height) and touching\n if (a.w === b.w && a.x === b.x && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.y < a.y) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n if (touching === false) return;\n\n // check if taking same row (but different width) and touching\n if (a.h === b.h && a.y === b.y && (touching || (touching = Utils.isTouching(a, b)))) {\n if (b.x < a.x) { let t = a; a = b; b = t; } // swap a <-> b vars so a is first\n return _doSwap();\n }\n return false;\n }\n\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\n let nn: GridStackNode = {x: x || 0, y: y || 0, w: w || 1, h: h || 1};\n return !this.collide(nn);\n }\n\n /** re-layout grid items to reclaim any empty space */\n public compact(): GridStackEngine {\n if (this.nodes.length === 0) return this;\n this.batchUpdate()\n .sortNodes();\n let copyNodes = this.nodes;\n this.nodes = []; // pretend we have no nodes to conflict layout to start with...\n copyNodes.forEach(node => {\n if (!node.locked) {\n node.autoPosition = true;\n }\n this.addNode(node, false); // 'false' for add event trigger\n node._dirty = true; // will force attr update\n });\n return this.batchUpdate(false);\n }\n\n /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */\n public set float(val: boolean) {\n if (this._float === val) return;\n this._float = val || false;\n if (!val) {\n this._packNodes()._notify();\n }\n }\n\n /** float getter method */\n public get float(): boolean { return this._float || false; }\n\n /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */\n public sortNodes(dir?: -1 | 1): GridStackEngine {\n this.nodes = Utils.sort(this.nodes, dir, this.column);\n return this;\n }\n\n /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */\n protected _packNodes(): GridStackEngine {\n if (this.batchMode) { return this; }\n this.sortNodes(); // first to last\n\n if (this.float) {\n // restore original Y pos\n this.nodes.forEach(n => {\n if (n._updating || n._orig === undefined || n.y === n._orig.y) return;\n let newY = n.y;\n while (newY > n._orig.y) {\n --newY;\n let collide = this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!collide) {\n n._dirty = true;\n n.y = newY;\n }\n }\n });\n } else {\n // top gravity pack\n this.nodes.forEach((n, i) => {\n if (n.locked) return;\n while (n.y > 0) {\n let newY = i === 0 ? 0 : n.y - 1;\n let canBeMoved = i === 0 || !this.collide(n, {x: n.x, y: newY, w: n.w, h: n.h});\n if (!canBeMoved) break;\n // Note: must be dirty (from last position) for GridStack::OnChange CB to update positions\n // and move items back. The user 'change' CB should detect changes from the original\n // starting position instead.\n n._dirty = (n.y !== newY);\n n.y = newY;\n }\n });\n }\n return this;\n }\n\n /**\n * given a random node, makes sure it's coordinates/values are valid in the current grid\n * @param node to adjust\n * @param resizing if out of bound, resize down or move into the grid to fit ?\n */\n public prepareNode(node: GridStackNode, resizing?: boolean): GridStackNode {\n node = node || {};\n node._id = node._id || GridStackEngine._idSeq++;\n\n // if we're missing position, have the grid position us automatically (before we set them to 0,0)\n if (node.x === undefined || node.y === undefined || node.x === null || node.y === null) {\n node.autoPosition = true;\n }\n\n // assign defaults for missing required fields\n let defaults: GridStackNode = { x: 0, y: 0, w: 1, h: 1};\n Utils.defaults(node, defaults);\n\n if (!node.autoPosition) { delete node.autoPosition; }\n if (!node.noResize) { delete node.noResize; }\n if (!node.noMove) { delete node.noMove; }\n\n // check for NaN (in case messed up strings were passed. can't do parseInt() || defaults.x above as 0 is valid #)\n if (typeof node.x == 'string') { node.x = Number(node.x); }\n if (typeof node.y == 'string') { node.y = Number(node.y); }\n if (typeof node.w == 'string') { node.w = Number(node.w); }\n if (typeof node.h == 'string') { node.h = Number(node.h); }\n if (isNaN(node.x)) { node.x = defaults.x; node.autoPosition = true; }\n if (isNaN(node.y)) { node.y = defaults.y; node.autoPosition = true; }\n if (isNaN(node.w)) { node.w = defaults.w; }\n if (isNaN(node.h)) { node.h = defaults.h; }\n\n return this.nodeBoundFix(node, resizing);\n }\n\n /** part2 of preparing a node to fit inside our grid - checks for x,y from grid dimensions */\n public nodeBoundFix(node: GridStackNode, resizing?: boolean): GridStackNode {\n\n let before = node._orig || Utils.copyPos({}, node);\n\n if (node.maxW) { node.w = Math.min(node.w, node.maxW); }\n if (node.maxH) { node.h = Math.min(node.h, node.maxH); }\n if (node.minW && node.minW <= this.column) { node.w = Math.max(node.w, node.minW); }\n if (node.minH) { node.h = Math.max(node.h, node.minH); }\n\n if (node.w > this.column) {\n // if user loaded a larger than allowed widget for current # of columns,\n // remember it's full width so we can restore back (1 -> 12 column) #1655\n // IFF we're not in the middle of column resizing!\n if (this.column < 12 && !this._inColumnResize) {\n node.w = Math.min(12, node.w);\n this.cacheOneLayout(node, 12);\n }\n node.w = this.column;\n } else if (node.w < 1) {\n node.w = 1;\n }\n\n if (this.maxRow && node.h > this.maxRow) {\n node.h = this.maxRow;\n } else if (node.h < 1) {\n node.h = 1;\n }\n\n if (node.x < 0) {\n node.x = 0;\n }\n if (node.y < 0) {\n node.y = 0;\n }\n\n if (node.x + node.w > this.column) {\n if (resizing) {\n node.w = this.column - node.x;\n } else {\n node.x = this.column - node.w;\n }\n }\n if (this.maxRow && node.y + node.h > this.maxRow) {\n if (resizing) {\n node.h = this.maxRow - node.y;\n } else {\n node.y = this.maxRow - node.h;\n }\n }\n\n if (!Utils.samePos(node, before)) {\n node._dirty = true;\n }\n\n return node;\n }\n\n /** returns a list of modified nodes from their original values */\n public getDirtyNodes(verify?: boolean): GridStackNode[] {\n // compare original x,y,w,h instead as _dirty can be a temporary state\n if (verify) {\n return this.nodes.filter(n => n._dirty && !Utils.samePos(n, n._orig));\n }\n return this.nodes.filter(n => n._dirty);\n }\n\n /** @internal call this to call onChange callback with dirty nodes so DOM can be updated */\n protected _notify(removedNodes?: GridStackNode[]): GridStackEngine {\n if (this.batchMode || !this.onChange) return this;\n let dirtyNodes = (removedNodes || []).concat(this.getDirtyNodes());\n this.onChange(dirtyNodes);\n return this;\n }\n\n /** @internal remove dirty and last tried info */\n public cleanNodes(): GridStackEngine {\n if (this.batchMode) return this;\n this.nodes.forEach(n => {\n delete n._dirty;\n delete n._lastTried;\n });\n return this;\n }\n\n /** @internal called to save initial position/size to track real dirty state.\n * Note: should be called right after we call change event (so next API is can detect changes)\n * as well as right before we start move/resize/enter (so we can restore items to prev values) */\n public saveInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n n._orig = Utils.copyPos({}, n);\n delete n._dirty;\n });\n this._hasLocked = this.nodes.some(n => n.locked);\n return this;\n }\n\n /** @internal restore all the nodes back to initial values (called when we leave) */\n public restoreInitial(): GridStackEngine {\n this.nodes.forEach(n => {\n if (Utils.samePos(n, n._orig)) return;\n Utils.copyPos(n, n._orig);\n n._dirty = true;\n });\n this._notify();\n return this;\n }\n\n /** call to add the given node to our list, fixing collision and re-packing */\n public addNode(node: GridStackNode, triggerAddEvent = false): GridStackNode {\n let dup = this.nodes.find(n => n._id === node._id);\n if (dup) return dup; // prevent inserting twice! return it instead.\n\n // skip prepareNode if we're in middle of column resize (not new) but do check for bounds!\n node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);\n delete node._temporaryRemoved;\n delete node._removeDOM;\n\n if (node.autoPosition) {\n this.sortNodes();\n\n for (let i = 0;; ++i) {\n let x = i % this.column;\n let y = Math.floor(i / this.column);\n if (x + node.w > this.column) {\n continue;\n }\n let box = {x, y, w: node.w, h: node.h};\n if (!this.nodes.find(n => Utils.isIntercepted(box, n))) {\n node.x = x;\n node.y = y;\n delete node.autoPosition; // found our slot\n break;\n }\n }\n }\n\n this.nodes.push(node);\n if (triggerAddEvent) { this.addedNodes.push(node); }\n\n this._fixCollisions(node);\n if (!this.batchMode) { this._packNodes()._notify(); }\n return node;\n }\n\n public removeNode(node: GridStackNode, removeDOM = true, triggerEvent = false): GridStackEngine {\n if (!this.nodes.find(n => n === node)) {\n // TEST console.log(`Error: GridStackEngine.removeNode() node._id=${node._id} not found!`)\n return this;\n }\n if (triggerEvent) { // we wait until final drop to manually track removed items (rather than during drag)\n this.removedNodes.push(node);\n }\n if (removeDOM) node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.\n this.nodes = this.nodes.filter(n => n !== node);\n return this._packNodes()\n ._notify([node]);\n }\n\n public removeAll(removeDOM = true): GridStackEngine {\n delete this._layouts;\n if (this.nodes.length === 0) return this;\n removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)\n this.removedNodes = this.nodes;\n this.nodes = [];\n return this._notify(this.removedNodes);\n }\n\n /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.\n * In more complicated cases (maxRow) it will attempt at moving the item and fixing\n * others in a clone first, then apply those changes if still within specs. */\n public moveNodeCheck(node: GridStackNode, o: GridStackMoveOpts): boolean {\n // if (node.locked) return false;\n if (!this.changedPosConstrain(node, o)) return false;\n o.pack = true;\n\n // simpler case: move item directly...\n if (!this.maxRow) {\n return this.moveNode(node, o);\n }\n\n // complex case: create a clone with NO maxRow (will check for out of bounds at the end)\n let clonedNode: GridStackNode;\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {\n if (n === node) {\n clonedNode = {...n};\n return clonedNode;\n }\n return {...n};\n })\n });\n if (!clonedNode) return false;\n\n // make sure we are still valid size\n let canMove = clone.moveNode(clonedNode, o) && clone.getRow() <= this.maxRow;\n // turns out we can't grow, then see if we can swap instead (ex: full grid) if we're not resizing\n if (!canMove && !o.resizing) {\n let collide = this.collide(node, o);\n if (collide && this.swap(node, collide)) {\n this._notify();\n return true;\n }\n }\n if (!canMove) return false;\n\n // if clone was able to move, copy those mods over to us now instead of caller trying to do this all over!\n // Note: we can't use the list directly as elements and other parts point to actual node, so copy content\n clone.nodes.filter(n => n._dirty).forEach(c => {\n let n = this.nodes.find(a => a._id === c._id);\n if (!n) return;\n Utils.copyPos(n, c);\n n._dirty = true;\n });\n this._notify();\n return true;\n }\n\n /** return true if can fit in grid height constrain only (always true if no maxRow) */\n public willItFit(node: GridStackNode): boolean {\n delete node._willFitPos;\n if (!this.maxRow) return true;\n // create a clone with NO maxRow and check if still within size\n let clone = new GridStackEngine({\n column: this.column,\n float: this.float,\n nodes: this.nodes.map(n => {return {...n}})\n });\n let n = {...node}; // clone node so we don't mod any settings on it but have full autoPosition and min/max as well! #1687\n this.cleanupNode(n);\n delete n.el; delete n._id; delete n.content; delete n.grid;\n clone.addNode(n);\n if (clone.getRow() <= this.maxRow) {\n node._willFitPos = Utils.copyPos({}, n);\n return true;\n }\n return false;\n }\n\n /** true if x,y or w,h are different after clamping to min/max */\n public changedPosConstrain(node: GridStackNode, p: GridStackPosition): boolean {\n // first make sure w,h are set for caller\n p.w = p.w || node.w;\n p.h = p.h || node.h;\n if (node.x !== p.x || node.y !== p.y) return true;\n // check constrained w,h\n if (node.maxW) { p.w = Math.min(p.w, node.maxW); }\n if (node.maxH) { p.h = Math.min(p.h, node.maxH); }\n if (node.minW) { p.w = Math.max(p.w, node.minW); }\n if (node.minH) { p.h = Math.max(p.h, node.minH); }\n return (node.w !== p.w || node.h !== p.h);\n }\n\n /** return true if the passed in node was actually moved (checks for no-op and locked) */\n public moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {\n if (!node || /*node.locked ||*/ !o) return false;\n if (o.pack === undefined) o.pack = true;\n\n // constrain the passed in values and check if we're still changing our node\n if (typeof o.x !== 'number') { o.x = node.x; }\n if (typeof o.y !== 'number') { o.y = node.y; }\n if (typeof o.w !== 'number') { o.w = node.w; }\n if (typeof o.h !== 'number') { o.h = node.h; }\n let resizing = (node.w !== o.w || node.h !== o.h);\n let nn: GridStackNode = Utils.copyPos({}, node, true); // get min/max out first, then opt positions next\n Utils.copyPos(nn, o);\n nn = this.nodeBoundFix(nn, resizing);\n Utils.copyPos(o, nn);\n\n if (Utils.samePos(node, o)) return false;\n let prevPos: GridStackPosition = Utils.copyPos({}, node);\n\n // check if we will need to fix collision at our new location\n let collides = this.collideAll(node, nn, o.skip);\n let needToMove = true;\n if (collides.length) {\n // now check to make sure we actually collided over 50% surface area while dragging\n let collide = node._moving && !o.nested ? this.collideCoverage(node, o, collides) : collides[0];\n if (collide) {\n needToMove = !this._fixCollisions(node, nn, collide, o); // check if already moved...\n } else {\n needToMove = false; // we didn't cover >50% for a move, skip...\n }\n }\n\n // now move (to the original ask vs the collision version which might differ) and repack things\n if (needToMove) {\n node._dirty = true;\n Utils.copyPos(node, nn);\n }\n if (o.pack) {\n this._packNodes()\n ._notify();\n }\n return !Utils.samePos(node, prevPos); // pack might have moved things back\n }\n\n public getRow(): number {\n return this.nodes.reduce((row, n) => Math.max(row, n.y + n.h), 0);\n }\n\n public beginUpdate(node: GridStackNode): GridStackEngine {\n if (!node._updating) {\n node._updating = true;\n delete node._skipDown;\n if (!this.batchMode) this.saveInitial();\n }\n return this;\n }\n\n public endUpdate(): GridStackEngine {\n let n = this.nodes.find(n => n._updating);\n if (n) {\n delete n._updating;\n delete n._skipDown;\n }\n return this;\n }\n\n /** saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode, so we don't loose orig layout),\n * returning a list of widgets for serialization */\n public save(saveElement = true): GridStackNode[] {\n // use the highest layout for any saved info so we can have full detail on reload #1849\n let len = this._layouts?.length;\n let layout = len && this.column !== (len - 1) ? this._layouts[len - 1] : null;\n let list: GridStackNode[] = [];\n this.sortNodes();\n this.nodes.forEach(n => {\n let wl = layout?.find(l => l._id === n._id);\n let w: GridStackNode = {...n};\n // use layout info instead if set\n if (wl) { w.x = wl.x; w.y = wl.y; w.w = wl.w; }\n // delete internals\n for (let key in w) { if (key[0] === '_' || w[key] === null || w[key] === undefined ) delete w[key]; }\n delete w.grid;\n if (!saveElement) delete w.el;\n // delete default values (will be re-created on read)\n if (!w.autoPosition) delete w.autoPosition;\n if (!w.noResize) delete w.noResize;\n if (!w.noMove) delete w.noMove;\n if (!w.locked) delete w.locked;\n list.push(w);\n });\n return list;\n }\n\n /** @internal called whenever a node is added or moved - updates the cached layouts */\n public layoutsNodesChange(nodes: GridStackNode[]): GridStackEngine {\n if (!this._layouts || this._inColumnResize) return this;\n // remove smaller layouts - we will re-generate those on the fly... larger ones need to update\n this._layouts.forEach((layout, column) => {\n if (!layout || column === this.column) return this;\n if (column < this.column) {\n this._layouts[column] = undefined;\n }\n else {\n // we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.\n // NOTE: we don't need to check against out of bound scaling/moving as that will be done when using those cache values. #1785\n let ratio = column / this.column;\n nodes.forEach(node => {\n if (!node._orig) return; // didn't change (newly added ?)\n let n = layout.find(l => l._id === node._id);\n if (!n) return; // no cache for new nodes. Will use those values.\n // Y changed, push down same amount\n // TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)\n if (node.y !== node._orig.y) {\n n.y += (node.y - node._orig.y);\n }\n // X changed, scale from new position\n if (node.x !== node._orig.x) {\n n.x = Math.round(node.x * ratio);\n }\n // width changed, scale from new width\n if (node.w !== node._orig.w) {\n n.w = Math.round(node.w * ratio);\n }\n // ...height always carries over from cache\n });\n }\n });\n return this;\n }\n\n /**\n * @internal Called to scale the widget width & position up/down based on the column change.\n * Note we store previous layouts (especially original ones) to make it possible to go\n * from say 12 -> 1 -> 12 and get back to where we were.\n *\n * @param prevColumn previous number of columns\n * @param column new column number\n * @param nodes different sorted list (ex: DOM order) instead of current list\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\n */\n public updateNodeWidths(prevColumn: number, column: number, nodes: GridStackNode[], layout: ColumnOptions = 'moveScale'): GridStackEngine {\n if (!this.nodes.length || !column || prevColumn === column) return this;\n\n // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data\n this.cacheLayout(this.nodes, prevColumn);\n this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision\n let newNodes: GridStackNode[] = [];\n\n // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout\n let domOrder = false;\n if (column === 1 && nodes?.length) {\n domOrder = true;\n let top = 0;\n nodes.forEach(n => {\n n.x = 0;\n n.w = 1;\n n.y = Math.max(n.y, top);\n top = n.y + n.h;\n });\n newNodes = nodes;\n nodes = [];\n } else {\n nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)\n }\n\n // see if we have cached previous layout IFF we are going up in size (restore) otherwise always\n // generate next size down from where we are (looks more natural as you gradually size down).\n let cacheNodes: GridStackNode[] = [];\n if (column > prevColumn) {\n cacheNodes = this._layouts[column] || [];\n // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate\n // by pretending we came from that larger column by assigning those values as starting point\n let lastIndex = this._layouts.length - 1;\n if (!cacheNodes.length && prevColumn !== lastIndex && this._layouts[lastIndex]?.length) {\n prevColumn = lastIndex;\n this._layouts[lastIndex].forEach(cacheNode => {\n let n = nodes.find(n => n._id === cacheNode._id);\n if (n) {\n // still current, use cache info positions\n n.x = cacheNode.x;\n n.y = cacheNode.y;\n n.w = cacheNode.w;\n }\n });\n }\n }\n\n // if we found cache re-use those nodes that are still current\n cacheNodes.forEach(cacheNode => {\n let j = nodes.findIndex(n => n._id === cacheNode._id);\n if (j !== -1) {\n // still current, use cache info positions\n nodes[j].x = cacheNode.x;\n nodes[j].y = cacheNode.y;\n nodes[j].w = cacheNode.w;\n newNodes.push(nodes[j]);\n nodes.splice(j, 1);\n }\n });\n // ...and add any extra non-cached ones\n if (nodes.length) {\n if (typeof layout === 'function') {\n layout(column, prevColumn, newNodes, nodes);\n } else if (!domOrder) {\n let ratio = column / prevColumn;\n let move = (layout === 'move' || layout === 'moveScale');\n let scale = (layout === 'scale' || layout === 'moveScale');\n nodes.forEach(node => {\n // NOTE: x + w could be outside of the grid, but addNode() below will handle that\n node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));\n node.w = ((column === 1 || prevColumn === 1) ? 1 :\n scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));\n newNodes.push(node);\n });\n nodes = [];\n }\n }\n\n // finally re-layout them in reverse order (to get correct placement)\n newNodes = Utils.sort(newNodes, -1, column);\n this._inColumnResize = true; // prevent cache update\n this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout\n newNodes.forEach(node => {\n this.addNode(node, false); // 'false' for add event trigger\n delete node._orig; // make sure the commit doesn't try to restore things back to original\n });\n this.batchUpdate(false);\n delete this._inColumnResize;\n return this;\n }\n\n /**\n * call to cache the given layout internally to the given location so we can restore back when column changes size\n * @param nodes list of nodes\n * @param column corresponding column index to save it under\n * @param clear if true, will force other caches to be removed (default false)\n */\n public cacheLayout(nodes: GridStackNode[], column: number, clear = false): GridStackEngine {\n let copy: GridStackNode[] = [];\n nodes.forEach((n, i) => {\n n._id = n._id || GridStackEngine._idSeq++; // make sure we have an id in case this is new layout, else re-use id already set\n copy[i] = {x: n.x, y: n.y, w: n.w, _id: n._id} // only thing we change is x,y,w and id to find it back\n });\n this._layouts = clear ? [] : this._layouts || []; // use array to find larger quick\n this._layouts[column] = copy;\n return this;\n }\n\n /**\n * call to cache the given node layout internally to the given location so we can restore back when column changes size\n * @param node single node to cache\n * @param column corresponding column index to save it under\n */\n public cacheOneLayout(n: GridStackNode, column: number): GridStackEngine {\n n._id = n._id || GridStackEngine._idSeq++;\n let layout: GridStackNode = {x: n.x, y: n.y, w: n.w, _id: n._id}\n this._layouts = this._layouts || [];\n this._layouts[column] = this._layouts[column] || [];\n let index = this._layouts[column].findIndex(l => l._id === n._id);\n index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout;\n return this;\n }\n\n\n /** called to remove all internal values but the _id */\n public cleanupNode(node: GridStackNode): GridStackEngine {\n for (let prop in node) {\n if (prop[0] === '_' && prop !== '_id') delete node[prop];\n }\n return this;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/gridstack-extra.css b/dist/gridstack-extra.css new file mode 100644 index 000000000..6ceeb36a3 --- /dev/null +++ b/dist/gridstack-extra.css @@ -0,0 +1,823 @@ +/** + * default to generate [2-11] columns as 1 (oneColumnMode) and 12 (default) are in the main css + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +.grid-stack.grid-stack-2 > .grid-stack-item { + min-width: 50%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-w="1"] { + width: 50%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-x="1"] { + left: 50%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-min-w="1"] { + min-width: 50%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-max-w="1"] { + max-width: 50%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-w="2"] { + width: 100%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-x="2"] { + left: 100%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-min-w="2"] { + min-width: 100%; +} +.grid-stack.grid-stack-2 > .grid-stack-item[gs-max-w="2"] { + max-width: 100%; +} + +.grid-stack.grid-stack-3 > .grid-stack-item { + min-width: 33.3333333333%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-w="1"] { + width: 33.3333333333%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-x="1"] { + left: 33.3333333333%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-min-w="1"] { + min-width: 33.3333333333%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-max-w="1"] { + max-width: 33.3333333333%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-w="2"] { + width: 66.6666666667%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-x="2"] { + left: 66.6666666667%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-min-w="2"] { + min-width: 66.6666666667%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-max-w="2"] { + max-width: 66.6666666667%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-w="3"] { + width: 100%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-x="3"] { + left: 100%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-min-w="3"] { + min-width: 100%; +} +.grid-stack.grid-stack-3 > .grid-stack-item[gs-max-w="3"] { + max-width: 100%; +} + +.grid-stack.grid-stack-4 > .grid-stack-item { + min-width: 25%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-w="1"] { + width: 25%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-x="1"] { + left: 25%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-min-w="1"] { + min-width: 25%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-max-w="1"] { + max-width: 25%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-w="2"] { + width: 50%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-x="2"] { + left: 50%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-min-w="2"] { + min-width: 50%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-max-w="2"] { + max-width: 50%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-w="3"] { + width: 75%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-x="3"] { + left: 75%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-min-w="3"] { + min-width: 75%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-max-w="3"] { + max-width: 75%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-w="4"] { + width: 100%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-x="4"] { + left: 100%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-min-w="4"] { + min-width: 100%; +} +.grid-stack.grid-stack-4 > .grid-stack-item[gs-max-w="4"] { + max-width: 100%; +} + +.grid-stack.grid-stack-5 > .grid-stack-item { + min-width: 20%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-w="1"] { + width: 20%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-x="1"] { + left: 20%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-min-w="1"] { + min-width: 20%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-max-w="1"] { + max-width: 20%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-w="2"] { + width: 40%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-x="2"] { + left: 40%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-min-w="2"] { + min-width: 40%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-max-w="2"] { + max-width: 40%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-w="3"] { + width: 60%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-x="3"] { + left: 60%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-min-w="3"] { + min-width: 60%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-max-w="3"] { + max-width: 60%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-w="4"] { + width: 80%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-x="4"] { + left: 80%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-min-w="4"] { + min-width: 80%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-max-w="4"] { + max-width: 80%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-w="5"] { + width: 100%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-x="5"] { + left: 100%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-min-w="5"] { + min-width: 100%; +} +.grid-stack.grid-stack-5 > .grid-stack-item[gs-max-w="5"] { + max-width: 100%; +} + +.grid-stack.grid-stack-6 > .grid-stack-item { + min-width: 16.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="1"] { + width: 16.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="1"] { + left: 16.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="1"] { + min-width: 16.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="1"] { + max-width: 16.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="2"] { + width: 33.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="2"] { + left: 33.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="2"] { + min-width: 33.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="2"] { + max-width: 33.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="3"] { + width: 50%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="3"] { + left: 50%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="3"] { + min-width: 50%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="3"] { + max-width: 50%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="4"] { + width: 66.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="4"] { + left: 66.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="4"] { + min-width: 66.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="4"] { + max-width: 66.6666666667%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="5"] { + width: 83.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="5"] { + left: 83.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="5"] { + min-width: 83.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="5"] { + max-width: 83.3333333333%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-w="6"] { + width: 100%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-x="6"] { + left: 100%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-min-w="6"] { + min-width: 100%; +} +.grid-stack.grid-stack-6 > .grid-stack-item[gs-max-w="6"] { + max-width: 100%; +} + +.grid-stack.grid-stack-7 > .grid-stack-item { + min-width: 14.2857142857%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="1"] { + width: 14.2857142857%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="1"] { + left: 14.2857142857%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="1"] { + min-width: 14.2857142857%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="1"] { + max-width: 14.2857142857%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="2"] { + width: 28.5714285714%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="2"] { + left: 28.5714285714%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="2"] { + min-width: 28.5714285714%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="2"] { + max-width: 28.5714285714%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="3"] { + width: 42.8571428571%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="3"] { + left: 42.8571428571%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="3"] { + min-width: 42.8571428571%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="3"] { + max-width: 42.8571428571%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="4"] { + width: 57.1428571429%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="4"] { + left: 57.1428571429%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="4"] { + min-width: 57.1428571429%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="4"] { + max-width: 57.1428571429%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="5"] { + width: 71.4285714286%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="5"] { + left: 71.4285714286%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="5"] { + min-width: 71.4285714286%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="5"] { + max-width: 71.4285714286%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="6"] { + width: 85.7142857143%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="6"] { + left: 85.7142857143%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="6"] { + min-width: 85.7142857143%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="6"] { + max-width: 85.7142857143%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-w="7"] { + width: 100%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-x="7"] { + left: 100%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-min-w="7"] { + min-width: 100%; +} +.grid-stack.grid-stack-7 > .grid-stack-item[gs-max-w="7"] { + max-width: 100%; +} + +.grid-stack.grid-stack-8 > .grid-stack-item { + min-width: 12.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="1"] { + width: 12.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="1"] { + left: 12.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="1"] { + min-width: 12.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="1"] { + max-width: 12.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="2"] { + width: 25%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="2"] { + left: 25%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="2"] { + min-width: 25%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="2"] { + max-width: 25%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="3"] { + width: 37.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="3"] { + left: 37.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="3"] { + min-width: 37.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="3"] { + max-width: 37.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="4"] { + width: 50%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="4"] { + left: 50%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="4"] { + min-width: 50%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="4"] { + max-width: 50%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="5"] { + width: 62.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="5"] { + left: 62.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="5"] { + min-width: 62.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="5"] { + max-width: 62.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="6"] { + width: 75%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="6"] { + left: 75%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="6"] { + min-width: 75%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="6"] { + max-width: 75%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="7"] { + width: 87.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="7"] { + left: 87.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="7"] { + min-width: 87.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="7"] { + max-width: 87.5%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-w="8"] { + width: 100%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-x="8"] { + left: 100%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-min-w="8"] { + min-width: 100%; +} +.grid-stack.grid-stack-8 > .grid-stack-item[gs-max-w="8"] { + max-width: 100%; +} + +.grid-stack.grid-stack-9 > .grid-stack-item { + min-width: 11.1111111111%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="1"] { + width: 11.1111111111%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="1"] { + left: 11.1111111111%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="1"] { + min-width: 11.1111111111%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="1"] { + max-width: 11.1111111111%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="2"] { + width: 22.2222222222%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="2"] { + left: 22.2222222222%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="2"] { + min-width: 22.2222222222%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="2"] { + max-width: 22.2222222222%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="3"] { + width: 33.3333333333%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="3"] { + left: 33.3333333333%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="3"] { + min-width: 33.3333333333%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="3"] { + max-width: 33.3333333333%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="4"] { + width: 44.4444444444%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="4"] { + left: 44.4444444444%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="4"] { + min-width: 44.4444444444%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="4"] { + max-width: 44.4444444444%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="5"] { + width: 55.5555555556%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="5"] { + left: 55.5555555556%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="5"] { + min-width: 55.5555555556%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="5"] { + max-width: 55.5555555556%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="6"] { + width: 66.6666666667%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="6"] { + left: 66.6666666667%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="6"] { + min-width: 66.6666666667%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="6"] { + max-width: 66.6666666667%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="7"] { + width: 77.7777777778%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="7"] { + left: 77.7777777778%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="7"] { + min-width: 77.7777777778%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="7"] { + max-width: 77.7777777778%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="8"] { + width: 88.8888888889%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="8"] { + left: 88.8888888889%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="8"] { + min-width: 88.8888888889%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="8"] { + max-width: 88.8888888889%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-w="9"] { + width: 100%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-x="9"] { + left: 100%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-min-w="9"] { + min-width: 100%; +} +.grid-stack.grid-stack-9 > .grid-stack-item[gs-max-w="9"] { + max-width: 100%; +} + +.grid-stack.grid-stack-10 > .grid-stack-item { + min-width: 10%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="1"] { + width: 10%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="1"] { + left: 10%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="1"] { + min-width: 10%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="1"] { + max-width: 10%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="2"] { + width: 20%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="2"] { + left: 20%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="2"] { + min-width: 20%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="2"] { + max-width: 20%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="3"] { + width: 30%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="3"] { + left: 30%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="3"] { + min-width: 30%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="3"] { + max-width: 30%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="4"] { + width: 40%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="4"] { + left: 40%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="4"] { + min-width: 40%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="4"] { + max-width: 40%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="5"] { + width: 50%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="5"] { + left: 50%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="5"] { + min-width: 50%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="5"] { + max-width: 50%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="6"] { + width: 60%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="6"] { + left: 60%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="6"] { + min-width: 60%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="6"] { + max-width: 60%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="7"] { + width: 70%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="7"] { + left: 70%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="7"] { + min-width: 70%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="7"] { + max-width: 70%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="8"] { + width: 80%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="8"] { + left: 80%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="8"] { + min-width: 80%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="8"] { + max-width: 80%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="9"] { + width: 90%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="9"] { + left: 90%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="9"] { + min-width: 90%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="9"] { + max-width: 90%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-w="10"] { + width: 100%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-x="10"] { + left: 100%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-min-w="10"] { + min-width: 100%; +} +.grid-stack.grid-stack-10 > .grid-stack-item[gs-max-w="10"] { + max-width: 100%; +} + +.grid-stack.grid-stack-11 > .grid-stack-item { + min-width: 9.0909090909%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="1"] { + width: 9.0909090909%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="1"] { + left: 9.0909090909%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="1"] { + min-width: 9.0909090909%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="1"] { + max-width: 9.0909090909%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="2"] { + width: 18.1818181818%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="2"] { + left: 18.1818181818%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="2"] { + min-width: 18.1818181818%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="2"] { + max-width: 18.1818181818%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="3"] { + width: 27.2727272727%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="3"] { + left: 27.2727272727%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="3"] { + min-width: 27.2727272727%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="3"] { + max-width: 27.2727272727%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="4"] { + width: 36.3636363636%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="4"] { + left: 36.3636363636%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="4"] { + min-width: 36.3636363636%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="4"] { + max-width: 36.3636363636%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="5"] { + width: 45.4545454545%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="5"] { + left: 45.4545454545%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="5"] { + min-width: 45.4545454545%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="5"] { + max-width: 45.4545454545%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="6"] { + width: 54.5454545455%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="6"] { + left: 54.5454545455%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="6"] { + min-width: 54.5454545455%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="6"] { + max-width: 54.5454545455%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="7"] { + width: 63.6363636364%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="7"] { + left: 63.6363636364%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="7"] { + min-width: 63.6363636364%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="7"] { + max-width: 63.6363636364%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="8"] { + width: 72.7272727273%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="8"] { + left: 72.7272727273%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="8"] { + min-width: 72.7272727273%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="8"] { + max-width: 72.7272727273%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="9"] { + width: 81.8181818182%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="9"] { + left: 81.8181818182%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="9"] { + min-width: 81.8181818182%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="9"] { + max-width: 81.8181818182%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="10"] { + width: 90.9090909091%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="10"] { + left: 90.9090909091%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="10"] { + min-width: 90.9090909091%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="10"] { + max-width: 90.9090909091%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-w="11"] { + width: 100%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-x="11"] { + left: 100%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-min-w="11"] { + min-width: 100%; +} +.grid-stack.grid-stack-11 > .grid-stack-item[gs-max-w="11"] { + max-width: 100%; +} \ No newline at end of file diff --git a/dist/gridstack-extra.min.css b/dist/gridstack-extra.min.css new file mode 100644 index 000000000..0c769ee59 --- /dev/null +++ b/dist/gridstack-extra.min.css @@ -0,0 +1 @@ +.grid-stack.grid-stack-2>.grid-stack-item{min-width:50%}.grid-stack.grid-stack-2>.grid-stack-item[gs-w="1"]{width:50%}.grid-stack.grid-stack-2>.grid-stack-item[gs-x="1"]{left:50%}.grid-stack.grid-stack-2>.grid-stack-item[gs-min-w="1"]{min-width:50%}.grid-stack.grid-stack-2>.grid-stack-item[gs-max-w="1"]{max-width:50%}.grid-stack.grid-stack-2>.grid-stack-item[gs-w="2"]{width:100%}.grid-stack.grid-stack-2>.grid-stack-item[gs-x="2"]{left:100%}.grid-stack.grid-stack-2>.grid-stack-item[gs-min-w="2"]{min-width:100%}.grid-stack.grid-stack-2>.grid-stack-item[gs-max-w="2"]{max-width:100%}.grid-stack.grid-stack-3>.grid-stack-item{min-width:33.3333333333%}.grid-stack.grid-stack-3>.grid-stack-item[gs-w="1"]{width:33.3333333333%}.grid-stack.grid-stack-3>.grid-stack-item[gs-x="1"]{left:33.3333333333%}.grid-stack.grid-stack-3>.grid-stack-item[gs-min-w="1"]{min-width:33.3333333333%}.grid-stack.grid-stack-3>.grid-stack-item[gs-max-w="1"]{max-width:33.3333333333%}.grid-stack.grid-stack-3>.grid-stack-item[gs-w="2"]{width:66.6666666667%}.grid-stack.grid-stack-3>.grid-stack-item[gs-x="2"]{left:66.6666666667%}.grid-stack.grid-stack-3>.grid-stack-item[gs-min-w="2"]{min-width:66.6666666667%}.grid-stack.grid-stack-3>.grid-stack-item[gs-max-w="2"]{max-width:66.6666666667%}.grid-stack.grid-stack-3>.grid-stack-item[gs-w="3"]{width:100%}.grid-stack.grid-stack-3>.grid-stack-item[gs-x="3"]{left:100%}.grid-stack.grid-stack-3>.grid-stack-item[gs-min-w="3"]{min-width:100%}.grid-stack.grid-stack-3>.grid-stack-item[gs-max-w="3"]{max-width:100%}.grid-stack.grid-stack-4>.grid-stack-item{min-width:25%}.grid-stack.grid-stack-4>.grid-stack-item[gs-w="1"]{width:25%}.grid-stack.grid-stack-4>.grid-stack-item[gs-x="1"]{left:25%}.grid-stack.grid-stack-4>.grid-stack-item[gs-min-w="1"]{min-width:25%}.grid-stack.grid-stack-4>.grid-stack-item[gs-max-w="1"]{max-width:25%}.grid-stack.grid-stack-4>.grid-stack-item[gs-w="2"]{width:50%}.grid-stack.grid-stack-4>.grid-stack-item[gs-x="2"]{left:50%}.grid-stack.grid-stack-4>.grid-stack-item[gs-min-w="2"]{min-width:50%}.grid-stack.grid-stack-4>.grid-stack-item[gs-max-w="2"]{max-width:50%}.grid-stack.grid-stack-4>.grid-stack-item[gs-w="3"]{width:75%}.grid-stack.grid-stack-4>.grid-stack-item[gs-x="3"]{left:75%}.grid-stack.grid-stack-4>.grid-stack-item[gs-min-w="3"]{min-width:75%}.grid-stack.grid-stack-4>.grid-stack-item[gs-max-w="3"]{max-width:75%}.grid-stack.grid-stack-4>.grid-stack-item[gs-w="4"]{width:100%}.grid-stack.grid-stack-4>.grid-stack-item[gs-x="4"]{left:100%}.grid-stack.grid-stack-4>.grid-stack-item[gs-min-w="4"]{min-width:100%}.grid-stack.grid-stack-4>.grid-stack-item[gs-max-w="4"]{max-width:100%}.grid-stack.grid-stack-5>.grid-stack-item{min-width:20%}.grid-stack.grid-stack-5>.grid-stack-item[gs-w="1"]{width:20%}.grid-stack.grid-stack-5>.grid-stack-item[gs-x="1"]{left:20%}.grid-stack.grid-stack-5>.grid-stack-item[gs-min-w="1"]{min-width:20%}.grid-stack.grid-stack-5>.grid-stack-item[gs-max-w="1"]{max-width:20%}.grid-stack.grid-stack-5>.grid-stack-item[gs-w="2"]{width:40%}.grid-stack.grid-stack-5>.grid-stack-item[gs-x="2"]{left:40%}.grid-stack.grid-stack-5>.grid-stack-item[gs-min-w="2"]{min-width:40%}.grid-stack.grid-stack-5>.grid-stack-item[gs-max-w="2"]{max-width:40%}.grid-stack.grid-stack-5>.grid-stack-item[gs-w="3"]{width:60%}.grid-stack.grid-stack-5>.grid-stack-item[gs-x="3"]{left:60%}.grid-stack.grid-stack-5>.grid-stack-item[gs-min-w="3"]{min-width:60%}.grid-stack.grid-stack-5>.grid-stack-item[gs-max-w="3"]{max-width:60%}.grid-stack.grid-stack-5>.grid-stack-item[gs-w="4"]{width:80%}.grid-stack.grid-stack-5>.grid-stack-item[gs-x="4"]{left:80%}.grid-stack.grid-stack-5>.grid-stack-item[gs-min-w="4"]{min-width:80%}.grid-stack.grid-stack-5>.grid-stack-item[gs-max-w="4"]{max-width:80%}.grid-stack.grid-stack-5>.grid-stack-item[gs-w="5"]{width:100%}.grid-stack.grid-stack-5>.grid-stack-item[gs-x="5"]{left:100%}.grid-stack.grid-stack-5>.grid-stack-item[gs-min-w="5"]{min-width:100%}.grid-stack.grid-stack-5>.grid-stack-item[gs-max-w="5"]{max-width:100%}.grid-stack.grid-stack-6>.grid-stack-item{min-width:16.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="1"]{width:16.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="1"]{left:16.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="1"]{min-width:16.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="1"]{max-width:16.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="2"]{width:33.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="2"]{left:33.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="2"]{min-width:33.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="2"]{max-width:33.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="3"]{width:50%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="3"]{left:50%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="3"]{min-width:50%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="3"]{max-width:50%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="4"]{width:66.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="4"]{left:66.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="4"]{min-width:66.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="4"]{max-width:66.6666666667%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="5"]{width:83.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="5"]{left:83.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="5"]{min-width:83.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="5"]{max-width:83.3333333333%}.grid-stack.grid-stack-6>.grid-stack-item[gs-w="6"]{width:100%}.grid-stack.grid-stack-6>.grid-stack-item[gs-x="6"]{left:100%}.grid-stack.grid-stack-6>.grid-stack-item[gs-min-w="6"]{min-width:100%}.grid-stack.grid-stack-6>.grid-stack-item[gs-max-w="6"]{max-width:100%}.grid-stack.grid-stack-7>.grid-stack-item{min-width:14.2857142857%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="1"]{width:14.2857142857%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="1"]{left:14.2857142857%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="1"]{min-width:14.2857142857%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="1"]{max-width:14.2857142857%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="2"]{width:28.5714285714%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="2"]{left:28.5714285714%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="2"]{min-width:28.5714285714%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="2"]{max-width:28.5714285714%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="3"]{width:42.8571428571%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="3"]{left:42.8571428571%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="3"]{min-width:42.8571428571%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="3"]{max-width:42.8571428571%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="4"]{width:57.1428571429%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="4"]{left:57.1428571429%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="4"]{min-width:57.1428571429%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="4"]{max-width:57.1428571429%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="5"]{width:71.4285714286%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="5"]{left:71.4285714286%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="5"]{min-width:71.4285714286%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="5"]{max-width:71.4285714286%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="6"]{width:85.7142857143%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="6"]{left:85.7142857143%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="6"]{min-width:85.7142857143%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="6"]{max-width:85.7142857143%}.grid-stack.grid-stack-7>.grid-stack-item[gs-w="7"]{width:100%}.grid-stack.grid-stack-7>.grid-stack-item[gs-x="7"]{left:100%}.grid-stack.grid-stack-7>.grid-stack-item[gs-min-w="7"]{min-width:100%}.grid-stack.grid-stack-7>.grid-stack-item[gs-max-w="7"]{max-width:100%}.grid-stack.grid-stack-8>.grid-stack-item{min-width:12.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="1"]{width:12.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="1"]{left:12.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="1"]{min-width:12.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="1"]{max-width:12.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="2"]{width:25%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="2"]{left:25%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="2"]{min-width:25%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="2"]{max-width:25%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="3"]{width:37.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="3"]{left:37.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="3"]{min-width:37.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="3"]{max-width:37.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="4"]{width:50%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="4"]{left:50%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="4"]{min-width:50%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="4"]{max-width:50%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="5"]{width:62.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="5"]{left:62.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="5"]{min-width:62.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="5"]{max-width:62.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="6"]{width:75%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="6"]{left:75%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="6"]{min-width:75%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="6"]{max-width:75%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="7"]{width:87.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="7"]{left:87.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="7"]{min-width:87.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="7"]{max-width:87.5%}.grid-stack.grid-stack-8>.grid-stack-item[gs-w="8"]{width:100%}.grid-stack.grid-stack-8>.grid-stack-item[gs-x="8"]{left:100%}.grid-stack.grid-stack-8>.grid-stack-item[gs-min-w="8"]{min-width:100%}.grid-stack.grid-stack-8>.grid-stack-item[gs-max-w="8"]{max-width:100%}.grid-stack.grid-stack-9>.grid-stack-item{min-width:11.1111111111%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="1"]{width:11.1111111111%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="1"]{left:11.1111111111%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="1"]{min-width:11.1111111111%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="1"]{max-width:11.1111111111%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="2"]{width:22.2222222222%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="2"]{left:22.2222222222%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="2"]{min-width:22.2222222222%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="2"]{max-width:22.2222222222%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="3"]{width:33.3333333333%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="3"]{left:33.3333333333%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="3"]{min-width:33.3333333333%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="3"]{max-width:33.3333333333%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="4"]{width:44.4444444444%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="4"]{left:44.4444444444%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="4"]{min-width:44.4444444444%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="4"]{max-width:44.4444444444%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="5"]{width:55.5555555556%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="5"]{left:55.5555555556%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="5"]{min-width:55.5555555556%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="5"]{max-width:55.5555555556%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="6"]{width:66.6666666667%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="6"]{left:66.6666666667%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="6"]{min-width:66.6666666667%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="6"]{max-width:66.6666666667%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="7"]{width:77.7777777778%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="7"]{left:77.7777777778%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="7"]{min-width:77.7777777778%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="7"]{max-width:77.7777777778%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="8"]{width:88.8888888889%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="8"]{left:88.8888888889%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="8"]{min-width:88.8888888889%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="8"]{max-width:88.8888888889%}.grid-stack.grid-stack-9>.grid-stack-item[gs-w="9"]{width:100%}.grid-stack.grid-stack-9>.grid-stack-item[gs-x="9"]{left:100%}.grid-stack.grid-stack-9>.grid-stack-item[gs-min-w="9"]{min-width:100%}.grid-stack.grid-stack-9>.grid-stack-item[gs-max-w="9"]{max-width:100%}.grid-stack.grid-stack-10>.grid-stack-item{min-width:10%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="1"]{width:10%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="1"]{left:10%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="1"]{min-width:10%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="1"]{max-width:10%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="2"]{width:20%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="2"]{left:20%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="2"]{min-width:20%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="2"]{max-width:20%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="3"]{width:30%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="3"]{left:30%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="3"]{min-width:30%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="3"]{max-width:30%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="4"]{width:40%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="4"]{left:40%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="4"]{min-width:40%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="4"]{max-width:40%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="5"]{width:50%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="5"]{left:50%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="5"]{min-width:50%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="5"]{max-width:50%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="6"]{width:60%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="6"]{left:60%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="6"]{min-width:60%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="6"]{max-width:60%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="7"]{width:70%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="7"]{left:70%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="7"]{min-width:70%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="7"]{max-width:70%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="8"]{width:80%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="8"]{left:80%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="8"]{min-width:80%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="8"]{max-width:80%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="9"]{width:90%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="9"]{left:90%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="9"]{min-width:90%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="9"]{max-width:90%}.grid-stack.grid-stack-10>.grid-stack-item[gs-w="10"]{width:100%}.grid-stack.grid-stack-10>.grid-stack-item[gs-x="10"]{left:100%}.grid-stack.grid-stack-10>.grid-stack-item[gs-min-w="10"]{min-width:100%}.grid-stack.grid-stack-10>.grid-stack-item[gs-max-w="10"]{max-width:100%}.grid-stack.grid-stack-11>.grid-stack-item{min-width:9.0909090909%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="1"]{width:9.0909090909%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="1"]{left:9.0909090909%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="1"]{min-width:9.0909090909%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="1"]{max-width:9.0909090909%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="2"]{width:18.1818181818%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="2"]{left:18.1818181818%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="2"]{min-width:18.1818181818%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="2"]{max-width:18.1818181818%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="3"]{width:27.2727272727%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="3"]{left:27.2727272727%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="3"]{min-width:27.2727272727%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="3"]{max-width:27.2727272727%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="4"]{width:36.3636363636%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="4"]{left:36.3636363636%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="4"]{min-width:36.3636363636%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="4"]{max-width:36.3636363636%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="5"]{width:45.4545454545%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="5"]{left:45.4545454545%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="5"]{min-width:45.4545454545%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="5"]{max-width:45.4545454545%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="6"]{width:54.5454545455%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="6"]{left:54.5454545455%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="6"]{min-width:54.5454545455%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="6"]{max-width:54.5454545455%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="7"]{width:63.6363636364%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="7"]{left:63.6363636364%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="7"]{min-width:63.6363636364%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="7"]{max-width:63.6363636364%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="8"]{width:72.7272727273%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="8"]{left:72.7272727273%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="8"]{min-width:72.7272727273%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="8"]{max-width:72.7272727273%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="9"]{width:81.8181818182%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="9"]{left:81.8181818182%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="9"]{min-width:81.8181818182%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="9"]{max-width:81.8181818182%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="10"]{width:90.9090909091%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="10"]{left:90.9090909091%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="10"]{min-width:90.9090909091%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="10"]{max-width:90.9090909091%}.grid-stack.grid-stack-11>.grid-stack-item[gs-w="11"]{width:100%}.grid-stack.grid-stack-11>.grid-stack-item[gs-x="11"]{left:100%}.grid-stack.grid-stack-11>.grid-stack-item[gs-min-w="11"]{min-width:100%}.grid-stack.grid-stack-11>.grid-stack-item[gs-max-w="11"]{max-width:100%} \ No newline at end of file diff --git a/dist/gridstack.css b/dist/gridstack.css new file mode 100644 index 000000000..8155b3501 --- /dev/null +++ b/dist/gridstack.css @@ -0,0 +1,320 @@ +/** + * gridstack SASS styles 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +:root .grid-stack-item > .ui-resizable-handle { + filter: none; +} + +.grid-stack { + position: relative; +} +.grid-stack.grid-stack-rtl { + direction: ltr; +} +.grid-stack.grid-stack-rtl > .grid-stack-item { + direction: rtl; +} +.grid-stack .grid-stack-placeholder > .placeholder-content { + background-color: rgba(0, 0, 0, 0.1); + margin: 0; + position: absolute; + width: auto; + z-index: 0 !important; + text-align: center; +} +.grid-stack > .grid-stack-item { + min-width: 8.3333333333%; + position: absolute; + padding: 0; +} +.grid-stack > .grid-stack-item > .grid-stack-item-content { + margin: 0; + position: absolute; + width: auto; + overflow-x: hidden; + overflow-y: auto; +} +.grid-stack > .grid-stack-item > .ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; +} +.grid-stack > .grid-stack-item.ui-resizable-disabled > .ui-resizable-handle, .grid-stack > .grid-stack-item.ui-resizable-autohide > .ui-resizable-handle { + display: none; +} +.grid-stack > .grid-stack-item > .ui-resizable-se, +.grid-stack > .grid-stack-item > .ui-resizable-sw { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); + background-repeat: no-repeat; + background-position: center; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.grid-stack > .grid-stack-item > .ui-resizable-se { + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -ms-transform: rotate(-45deg); + -o-transform: rotate(-45deg); + transform: rotate(-45deg); +} +.grid-stack > .grid-stack-item > .ui-resizable-nw { + cursor: nw-resize; + width: 20px; + height: 20px; + top: 0; +} +.grid-stack > .grid-stack-item > .ui-resizable-n { + cursor: n-resize; + height: 10px; + top: 0; + left: 25px; + right: 25px; +} +.grid-stack > .grid-stack-item > .ui-resizable-ne { + cursor: ne-resize; + width: 20px; + height: 20px; + top: 0; +} +.grid-stack > .grid-stack-item > .ui-resizable-e { + cursor: e-resize; + width: 10px; + top: 15px; + bottom: 15px; +} +.grid-stack > .grid-stack-item > .ui-resizable-se { + cursor: se-resize; + width: 20px; + height: 20px; +} +.grid-stack > .grid-stack-item > .ui-resizable-s { + cursor: s-resize; + height: 10px; + left: 25px; + bottom: 0; + right: 25px; +} +.grid-stack > .grid-stack-item > .ui-resizable-sw { + cursor: sw-resize; + width: 20px; + height: 20px; +} +.grid-stack > .grid-stack-item > .ui-resizable-w { + cursor: w-resize; + width: 10px; + top: 15px; + bottom: 15px; +} +.grid-stack > .grid-stack-item.ui-draggable-dragging > .ui-resizable-handle { + display: none !important; +} +.grid-stack > .grid-stack-item[gs-w="0"] { + width: 0%; +} +.grid-stack > .grid-stack-item[gs-x="0"] { + left: 0%; +} +.grid-stack > .grid-stack-item[gs-min-w="0"] { + min-width: 0%; +} +.grid-stack > .grid-stack-item[gs-max-w="0"] { + max-width: 0%; +} +.grid-stack > .grid-stack-item[gs-w="1"] { + width: 8.3333333333%; +} +.grid-stack > .grid-stack-item[gs-x="1"] { + left: 8.3333333333%; +} +.grid-stack > .grid-stack-item[gs-min-w="1"] { + min-width: 8.3333333333%; +} +.grid-stack > .grid-stack-item[gs-max-w="1"] { + max-width: 8.3333333333%; +} +.grid-stack > .grid-stack-item[gs-w="2"] { + width: 16.6666666667%; +} +.grid-stack > .grid-stack-item[gs-x="2"] { + left: 16.6666666667%; +} +.grid-stack > .grid-stack-item[gs-min-w="2"] { + min-width: 16.6666666667%; +} +.grid-stack > .grid-stack-item[gs-max-w="2"] { + max-width: 16.6666666667%; +} +.grid-stack > .grid-stack-item[gs-w="3"] { + width: 25%; +} +.grid-stack > .grid-stack-item[gs-x="3"] { + left: 25%; +} +.grid-stack > .grid-stack-item[gs-min-w="3"] { + min-width: 25%; +} +.grid-stack > .grid-stack-item[gs-max-w="3"] { + max-width: 25%; +} +.grid-stack > .grid-stack-item[gs-w="4"] { + width: 33.3333333333%; +} +.grid-stack > .grid-stack-item[gs-x="4"] { + left: 33.3333333333%; +} +.grid-stack > .grid-stack-item[gs-min-w="4"] { + min-width: 33.3333333333%; +} +.grid-stack > .grid-stack-item[gs-max-w="4"] { + max-width: 33.3333333333%; +} +.grid-stack > .grid-stack-item[gs-w="5"] { + width: 41.6666666667%; +} +.grid-stack > .grid-stack-item[gs-x="5"] { + left: 41.6666666667%; +} +.grid-stack > .grid-stack-item[gs-min-w="5"] { + min-width: 41.6666666667%; +} +.grid-stack > .grid-stack-item[gs-max-w="5"] { + max-width: 41.6666666667%; +} +.grid-stack > .grid-stack-item[gs-w="6"] { + width: 50%; +} +.grid-stack > .grid-stack-item[gs-x="6"] { + left: 50%; +} +.grid-stack > .grid-stack-item[gs-min-w="6"] { + min-width: 50%; +} +.grid-stack > .grid-stack-item[gs-max-w="6"] { + max-width: 50%; +} +.grid-stack > .grid-stack-item[gs-w="7"] { + width: 58.3333333333%; +} +.grid-stack > .grid-stack-item[gs-x="7"] { + left: 58.3333333333%; +} +.grid-stack > .grid-stack-item[gs-min-w="7"] { + min-width: 58.3333333333%; +} +.grid-stack > .grid-stack-item[gs-max-w="7"] { + max-width: 58.3333333333%; +} +.grid-stack > .grid-stack-item[gs-w="8"] { + width: 66.6666666667%; +} +.grid-stack > .grid-stack-item[gs-x="8"] { + left: 66.6666666667%; +} +.grid-stack > .grid-stack-item[gs-min-w="8"] { + min-width: 66.6666666667%; +} +.grid-stack > .grid-stack-item[gs-max-w="8"] { + max-width: 66.6666666667%; +} +.grid-stack > .grid-stack-item[gs-w="9"] { + width: 75%; +} +.grid-stack > .grid-stack-item[gs-x="9"] { + left: 75%; +} +.grid-stack > .grid-stack-item[gs-min-w="9"] { + min-width: 75%; +} +.grid-stack > .grid-stack-item[gs-max-w="9"] { + max-width: 75%; +} +.grid-stack > .grid-stack-item[gs-w="10"] { + width: 83.3333333333%; +} +.grid-stack > .grid-stack-item[gs-x="10"] { + left: 83.3333333333%; +} +.grid-stack > .grid-stack-item[gs-min-w="10"] { + min-width: 83.3333333333%; +} +.grid-stack > .grid-stack-item[gs-max-w="10"] { + max-width: 83.3333333333%; +} +.grid-stack > .grid-stack-item[gs-w="11"] { + width: 91.6666666667%; +} +.grid-stack > .grid-stack-item[gs-x="11"] { + left: 91.6666666667%; +} +.grid-stack > .grid-stack-item[gs-min-w="11"] { + min-width: 91.6666666667%; +} +.grid-stack > .grid-stack-item[gs-max-w="11"] { + max-width: 91.6666666667%; +} +.grid-stack > .grid-stack-item[gs-w="12"] { + width: 100%; +} +.grid-stack > .grid-stack-item[gs-x="12"] { + left: 100%; +} +.grid-stack > .grid-stack-item[gs-min-w="12"] { + min-width: 100%; +} +.grid-stack > .grid-stack-item[gs-max-w="12"] { + max-width: 100%; +} +.grid-stack.grid-stack-1 > .grid-stack-item { + min-width: 100%; +} +.grid-stack.grid-stack-1 > .grid-stack-item[gs-w="1"] { + width: 100%; +} +.grid-stack.grid-stack-1 > .grid-stack-item[gs-x="1"] { + left: 100%; +} +.grid-stack.grid-stack-1 > .grid-stack-item[gs-min-w="1"] { + min-width: 100%; +} +.grid-stack.grid-stack-1 > .grid-stack-item[gs-max-w="1"] { + max-width: 100%; +} +.grid-stack.grid-stack-animate, .grid-stack.grid-stack-animate .grid-stack-item { + -webkit-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s; + -moz-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s; + -ms-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s; + -o-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s; + transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s; +} +.grid-stack.grid-stack-animate .grid-stack-item.ui-draggable-dragging, .grid-stack.grid-stack-animate .grid-stack-item.ui-resizable-resizing, .grid-stack.grid-stack-animate .grid-stack-item.grid-stack-placeholder { + -webkit-transition: left 0s, top 0s, height 0s, width 0s; + -moz-transition: left 0s, top 0s, height 0s, width 0s; + -ms-transition: left 0s, top 0s, height 0s, width 0s; + -o-transition: left 0s, top 0s, height 0s, width 0s; + transition: left 0s, top 0s, height 0s, width 0s; +} + +.ui-draggable-dragging, +.ui-resizable-resizing { + z-index: 100; +} +.ui-draggable-dragging > .grid-stack-item-content, +.ui-resizable-resizing > .grid-stack-item-content { + box-shadow: 1px 4px 6px rgba(0, 0, 0, 0.2); + opacity: 0.8; +} + +.ui-draggable-dragging { + will-change: left, top; + cursor: move; +} + +.ui-resizable-resizing { + will-change: width, height; +} \ No newline at end of file diff --git a/dist/gridstack.d.ts b/dist/gridstack.d.ts new file mode 100644 index 000000000..eb4f06035 --- /dev/null +++ b/dist/gridstack.d.ts @@ -0,0 +1,352 @@ +/*! + * GridStack 6.0.1-dev + * https://gridstackjs.com/ + * + * Copyright (c) 2021-2022 Alain Dumesny + * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE + */ +import { GridStackEngine } from './gridstack-engine'; +import { Utils } from './utils'; +import { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback, GridStackOptions, GridStackWidget, numberOrString, DDDragInOpt } from './types'; +export * from './types'; +export * from './utils'; +export * from './gridstack-engine'; +export interface GridHTMLElement extends HTMLElement { + gridstack?: GridStack; +} +/** list of possible events, or space separated list of them */ +export declare type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' | 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string; +/** Defines the coordinates of an object */ +export interface MousePosition { + top: number; + left: number; +} +/** Defines the position of a cell inside the grid*/ +export interface CellPosition { + x: number; + y: number; +} +/** + * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid. + * Note: your grid elements MUST have the following classes for the CSS layout to work: + * @example + *
+ *
+ *
Item 1
+ *
+ *
+ */ +export declare class GridStack { + /** + * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will + * simply return the existing instance (ignore any passed options). There is also an initAll() version that support + * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON. + * @param options grid options (optional) + * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector) + * + * @example + * let grid = GridStack.init(); + * + * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later + * let grid = document.querySelector('.grid-stack').gridstack; + */ + static init(options?: GridStackOptions, elOrString?: GridStackElement): GridStack; + /** + * Will initialize a list of elements (given a selector) and return an array of grids. + * @param options grid options (optional) + * @param selector elements selector to convert to grids (default to '.grid-stack' class selector) + * + * @example + * let grids = GridStack.initAll(); + * grids.forEach(...) + */ + static initAll(options?: GridStackOptions, selector?: string): GridStack[]; + /** + * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then + * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from + * JSON serialized data, including options. + * @param parent HTML element parent to the grid + * @param opt grids options used to initialize the grid, and list of children + */ + static addGrid(parent: HTMLElement, opt?: GridStackOptions): GridStack; + /** call this method to register your engine instead of the default one. + * See instead `GridStackOptions.engineClass` if you only need to + * replace just one instance. + */ + static registerEngine(engineClass: typeof GridStackEngine): void; + /** scoping so users can call GridStack.Utils.sort() for example */ + static Utils: typeof Utils; + /** scoping so users can call new GridStack.Engine(12) for example */ + static Engine: typeof GridStackEngine; + /** the HTML element tied to this grid after it's been initialized */ + el: GridHTMLElement; + /** engine used to implement non DOM grid functionality */ + engine: GridStackEngine; + /** grid options - public for classes to access, but use methods to modify! */ + opts: GridStackOptions; + protected static engineClass: typeof GridStackEngine; + /** + * Construct a grid item from the given element and options + * @param el + * @param opts + */ + constructor(el: GridHTMLElement, opts?: GridStackOptions); + change(): void; + /** + * add a new widget and returns it. + * + * Widget will be always placed even if result height is more than actual grid height. + * You need to use `willItFit()` before calling addWidget for additional check. + * See also `makeWidget()`. + * + * @example + * let grid = GridStack.init(); + * grid.addWidget({w: 3, content: 'hello'}); + * grid.addWidget('
hello
', {w: 3}); + * + * @param el GridStackWidget (which can have content string as well), html element, or string definition to add + * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget + */ + addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement; + /** + /** + * saves the current layout returning a list of widgets for serialization which might include any nested grids. + * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will + * be removed. + * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() + * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead. + * @returns list of widgets or full grid option, including .children list of widgets + */ + save(saveContent?: boolean, saveGridOpt?: boolean): GridStackWidget[] | GridStackOptions; + /** + * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there. + * + * @param layout list of widgets definition to update/create + * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving + * the user control of insertion. + * + * @example + * see http://gridstackjs.com/demo/serialization.html + **/ + load(layout: GridStackWidget[], addAndRemove?: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement)): GridStack; + /** + * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient) + * and get a single event callback. You will see no changes until `batchUpdate(false)` is called. + */ + batchUpdate(flag?: boolean): GridStack; + /** + * Gets current cell height. + */ + getCellHeight(forcePixel?: boolean): number; + /** + * Update current cell height - see `GridStackOptions.cellHeight` for format. + * This method rebuilds an internal CSS style sheet. + * Note: You can expect performance issues if call this method too often. + * + * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin), + * if pass 0 the CSS will be generated by the application instead. + * @param update (Optional) if false, styles will not be updated + * + * @example + * grid.cellHeight(100); // same as 100px + * grid.cellHeight('70px'); + * grid.cellHeight(grid.cellWidth() * 1.2); + */ + cellHeight(val?: numberOrString, update?: boolean): GridStack; + /** Gets current cell width. */ + cellWidth(): number; + /** return our expected width (or parent) for 1 column check */ + protected _widthOrContainer(): number; + /** re-layout grid items to reclaim any empty space */ + compact(): GridStack; + /** + * set the number of columns in the grid. Will update existing widgets to conform to new number of columns, + * as well as cache the original layout so you can revert back to previous positions without loss. + * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11], + * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns) + * @param column - Integer > 0 (default 12). + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + column(column: number, layout?: ColumnOptions): GridStack; + /** + * get the number of columns in the grid (default 12) + */ + getColumn(): number; + /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */ + getGridItems(): GridItemHTMLElement[]; + /** + * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members. + * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`). + */ + destroy(removeDOM?: boolean): GridStack; + /** + * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) + */ + float(val: boolean): GridStack; + /** + * get the current float mode + */ + getFloat(): boolean; + /** + * Get the position of the cell under a pixel on screen. + * @param position the position of the pixel to resolve in + * absolute coordinates, as an object with top and left properties + * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false). + * Useful when grid is within `position: relative` element + * + * Returns an object with properties `x` and `y` i.e. the column and row in the grid. + */ + getCellFromPixel(position: MousePosition, useDocRelative?: boolean): CellPosition; + /** returns the current number of rows, which will be at least `minRow` if set */ + getRow(): number; + /** + * Checks if specified area is empty. + * @param x the position x. + * @param y the position y. + * @param w the width of to check + * @param h the height of to check + */ + isAreaEmpty(x: number, y: number, w: number, h: number): boolean; + /** + * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets. + * If you want gridstack to add the elements for you, use `addWidget()` instead. + * Makes the given element a widget and returns it. + * @param els widget or single selector to convert. + * + * @example + * let grid = GridStack.init(); + * grid.el.appendChild('
'); + * grid.makeWidget('#gsi-1'); + */ + makeWidget(els: GridStackElement): GridItemHTMLElement; + /** + * Event handler that extracts our CustomEvent data out automatically for receiving custom + * notifications (see doc for supported events) + * @param name of the event (see possible values) or list of names space separated + * @param callback function called with event and optional second/third param + * (see README documentation for each signature). + * + * @example + * grid.on('added', function(e, items) { log('added ', items)} ); + * or + * grid.on('added removed change', function(e, items) { log(e.type, items)} ); + * + * Note: in some cases it is the same as calling native handler and parsing the event. + * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} ); + * + */ + on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack; + /** + * unsubscribe from the 'on' event below + * @param name of the event (see possible values) + */ + off(name: GridStackEvent): GridStack; + /** + * Removes widget from the grid. + * @param el widget or selector to modify + * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true). + * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true). + */ + removeWidget(els: GridStackElement, removeDOM?: boolean, triggerEvent?: boolean): GridStack; + /** + * Removes all widgets from the grid. + * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`). + */ + removeAll(removeDOM?: boolean): GridStack; + /** + * Toggle the grid animation state. Toggles the `grid-stack-animate` class. + * @param doAnimate if true the grid will animate. + */ + setAnimation(doAnimate: boolean): GridStack; + /** + * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on. + * Also toggle the grid-stack-static class. + * @param val if true the grid become static. + */ + setStatic(val: boolean, updateClass?: boolean): GridStack; + /** + * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed. + * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted) + * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated. + */ + update(els: GridStackElement, opt: GridStackWidget): GridStack; + /** + * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number). + * @param value margin value + */ + margin(value: numberOrString): GridStack; + /** returns current margin number value (undefined if 4 sides don't match) */ + getMargin(): number; + /** + * Returns true if the height of the grid will be less than the vertical + * constraint. Always returns true if grid doesn't have height constraint. + * @param node contains x,y,w,h,auto-position options + * + * @example + * if (grid.willItFit(newWidget)) { + * grid.addWidget(newWidget); + * } else { + * alert('Not enough free space to place the widget'); + * } + */ + willItFit(node: GridStackWidget): boolean; + /** + * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off + * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square) + */ + onParentResize(): GridStack; + /** add or remove the window size event handler */ + protected _updateWindowResizeEvent(forceRemove?: boolean): GridStack; + static GDRev: string; + /** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + * @param dragIn string selector (ex: '.sidebar .grid-stack-item') + * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'} + **/ + static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void; + /** + * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids. + * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ + movable(els: GridStackElement, val: boolean): GridStack; + /** + * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ + resizable(els: GridStackElement, val: boolean): GridStack; + /** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ + disable(): GridStack; + /** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ + enable(): GridStack; + /** + * Enables/disables widget moving. No-op for static grids. + */ + enableMove(doEnable: boolean): GridStack; + /** + * Enables/disables widget resizing. No-op for static grids. + */ + enableResize(doEnable: boolean): GridStack; + commit(): GridStack; +} +export * from './dd-gridstack'; diff --git a/dist/gridstack.js b/dist/gridstack.js new file mode 100644 index 000000000..4cb5ceae1 --- /dev/null +++ b/dist/gridstack.js @@ -0,0 +1,1487 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GridStack = void 0; +/*! + * GridStack 6.0.1-dev + * https://gridstackjs.com/ + * + * Copyright (c) 2021-2022 Alain Dumesny + * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE + */ +const gridstack_engine_1 = require("./gridstack-engine"); +const utils_1 = require("./utils"); +// export all dependent file as well to make it easier for users to just import the main file +__exportStar(require("./types"), exports); +__exportStar(require("./utils"), exports); +__exportStar(require("./gridstack-engine"), exports); +// default values for grid options - used during init and when saving out +const GridDefaults = { + column: 12, + minRow: 0, + maxRow: 0, + itemClass: 'grid-stack-item', + placeholderClass: 'grid-stack-placeholder', + placeholderText: '', + handle: '.grid-stack-item-content', + handleClass: null, + styleInHead: false, + cellHeight: 'auto', + cellHeightThrottle: 100, + margin: 10, + auto: true, + oneColumnSize: 768, + float: false, + staticGrid: false, + animate: true, + alwaysShowResizeHandle: 'mobile', + resizable: { + handles: 'se' + }, + draggable: { + handle: '.grid-stack-item-content', + appendTo: 'body' + }, + disableDrag: false, + disableResize: false, + rtl: 'auto', + removable: false, + removableOptions: { + accept: '.grid-stack-item' + }, + marginUnit: 'px', + cellHeightUnit: 'px', + disableOneColumnMode: false, + oneColumnModeDomSort: false, +}; +/** + * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid. + * Note: your grid elements MUST have the following classes for the CSS layout to work: + * @example + *
+ *
+ *
Item 1
+ *
+ *
+ */ +class GridStack { + /** + * Construct a grid item from the given element and options + * @param el + * @param opts + */ + constructor(el, opts = {}) { + /** @internal */ + this._gsEventHandler = {}; + /** @internal extra row added when dragging at the bottom of the grid */ + this._extraDragRow = 0; + this.el = el; // exposed HTML element to the user + opts = opts || {}; // handles null/undefined/0 + // if row property exists, replace minRow and maxRow instead + if (opts.row) { + opts.minRow = opts.maxRow = opts.row; + delete opts.row; + } + let rowAttr = utils_1.Utils.toNumber(el.getAttribute('gs-row')); + // flag only valid in sub-grids (handled by parent, not here) + if (opts.column === 'auto') { + delete opts.column; + } + // 'minWidth' legacy support in 5.1 + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + let anyOpts = opts; + if (anyOpts.minWidth !== undefined) { + opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth; + delete anyOpts.minWidth; + } + // save original setting so we can restore on save + if (opts.alwaysShowResizeHandle !== undefined) { + opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle; + } + // elements DOM attributes override any passed options (like CSS style) - merge the two together + let defaults = Object.assign(Object.assign({}, utils_1.Utils.cloneDeep(GridDefaults)), { column: utils_1.Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column, minRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow, maxRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow, staticGrid: utils_1.Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid, _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0), draggable: { + handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle, + }, removableOptions: { + accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept, + } }); + if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead + defaults.animate = utils_1.Utils.toBool(el.getAttribute('gs-animate')); + } + this.opts = utils_1.Utils.defaults(opts, defaults); + opts = null; // make sure we use this.opts instead + this._initMargin(); // part of settings defaults... + // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column) + if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) { + this._prevColumn = this.getColumn(); + this.opts.column = 1; + } + if (this.opts.rtl === 'auto') { + this.opts.rtl = (el.style.direction === 'rtl'); + } + if (this.opts.rtl) { + this.el.classList.add('grid-stack-rtl'); + } + // check if we're been nested, and if so update our style and keep pointer around (used during save) + let parentGridItemEl = utils_1.Utils.closestByClass(this.el, GridDefaults.itemClass); + if (parentGridItemEl && parentGridItemEl.gridstackNode) { + this.opts._isNested = parentGridItemEl.gridstackNode; + this.opts._isNested.subGrid = this; + parentGridItemEl.classList.add('grid-stack-nested'); + this.el.classList.add('grid-stack-nested'); + } + this._isAutoCellHeight = (this.opts.cellHeight === 'auto'); + if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') { + // make the cell content square initially (will use resize/column event to keep it square) + this.cellHeight(undefined, false); + } + else { + // append unit if any are set + if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) { + this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit; + delete this.opts.cellHeightUnit; + } + this.cellHeight(this.opts.cellHeight, false); + } + // see if we need to adjust auto-hide + if (this.opts.alwaysShowResizeHandle === 'mobile') { + this.opts.alwaysShowResizeHandle = dd_touch_1.isTouch; + } + this.el.classList.add(this.opts._styleSheetClass); + this._setStaticClass(); + let engineClass = this.opts.engineClass || GridStack.engineClass || gridstack_engine_1.GridStackEngine; + this.engine = new engineClass({ + column: this.getColumn(), + float: this.opts.float, + maxRow: this.opts.maxRow, + onChange: (cbNodes) => { + let maxH = 0; + this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h); }); + cbNodes.forEach(n => { + let el = n.el; + if (!el) + return; + if (n._removeDOM) { + if (el) + el.remove(); + delete n._removeDOM; + } + else { + this._writePosAttr(el, n); + } + }); + this._updateStyles(false, maxH); // false = don't recreate, just append if need be + } + }); + if (this.opts.auto) { + this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check... + let elements = []; + this.getGridItems().forEach(el => { + let x = parseInt(el.getAttribute('gs-x')); + let y = parseInt(el.getAttribute('gs-y')); + elements.push({ + el, + // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order + i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * this.getColumn() + }); + }); + elements.sort((a, b) => a.i - b.i).forEach(e => this._prepareElement(e.el)); + this.batchUpdate(false); + } + this.setAnimation(this.opts.animate); + this._updateStyles(); + if (this.opts.column != 12) { + this.el.classList.add('grid-stack-' + this.opts.column); + } + // legacy support to appear 'per grid` options when really global. + if (this.opts.dragIn) + GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions); + delete this.opts.dragIn; + delete this.opts.dragInOptions; + this._setupRemoveDrop(); + this._setupAcceptWidget(); + this._updateWindowResizeEvent(); + } + /** + * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will + * simply return the existing instance (ignore any passed options). There is also an initAll() version that support + * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON. + * @param options grid options (optional) + * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector) + * + * @example + * let grid = GridStack.init(); + * + * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later + * let grid = document.querySelector('.grid-stack').gridstack; + */ + static init(options = {}, elOrString = '.grid-stack') { + let el = GridStack.getGridElement(elOrString); + if (!el) { + if (typeof elOrString === 'string') { + console.error('GridStack.initAll() no grid was found with selector "' + elOrString + '" - element missing or wrong selector ?' + + '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'); + } + else { + console.error('GridStack.init() no grid element was passed.'); + } + return null; + } + if (!el.gridstack) { + el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options)); + } + return el.gridstack; + } + /** + * Will initialize a list of elements (given a selector) and return an array of grids. + * @param options grid options (optional) + * @param selector elements selector to convert to grids (default to '.grid-stack' class selector) + * + * @example + * let grids = GridStack.initAll(); + * grids.forEach(...) + */ + static initAll(options = {}, selector = '.grid-stack') { + let grids = []; + GridStack.getGridElements(selector).forEach(el => { + if (!el.gridstack) { + el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options)); + delete options.dragIn; + delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid) + } + grids.push(el.gridstack); + }); + if (grids.length === 0) { + console.error('GridStack.initAll() no grid was found with selector "' + selector + '" - element missing or wrong selector ?' + + '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.'); + } + return grids; + } + /** + * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then + * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from + * JSON serialized data, including options. + * @param parent HTML element parent to the grid + * @param opt grids options used to initialize the grid, and list of children + */ + static addGrid(parent, opt = {}) { + if (!parent) + return null; + // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead + let el = parent; + if (!parent.classList.contains('grid-stack')) { + let doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = `
`; + el = doc.body.children[0]; + parent.appendChild(el); + } + // create grid class and load any children + let grid = GridStack.init(opt, el); + if (grid.opts.children) { + let children = grid.opts.children; + delete grid.opts.children; + grid.load(children); + } + return grid; + } + /** call this method to register your engine instead of the default one. + * See instead `GridStackOptions.engineClass` if you only need to + * replace just one instance. + */ + static registerEngine(engineClass) { + GridStack.engineClass = engineClass; + } + /** @internal create placeholder DIV as needed */ + get placeholder() { + if (!this._placeholder) { + let placeholderChild = document.createElement('div'); // child so padding match item-content + placeholderChild.className = 'placeholder-content'; + if (this.opts.placeholderText) { + placeholderChild.innerHTML = this.opts.placeholderText; + } + this._placeholder = document.createElement('div'); + this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass); + this.placeholder.appendChild(placeholderChild); + } + return this._placeholder; + } + change() { + this._triggerChangeEvent(); + } + /** + * add a new widget and returns it. + * + * Widget will be always placed even if result height is more than actual grid height. + * You need to use `willItFit()` before calling addWidget for additional check. + * See also `makeWidget()`. + * + * @example + * let grid = GridStack.init(); + * grid.addWidget({w: 3, content: 'hello'}); + * grid.addWidget('
hello
', {w: 3}); + * + * @param el GridStackWidget (which can have content string as well), html element, or string definition to add + * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget + */ + addWidget(els, options) { + // support legacy call for now ? + if (arguments.length > 2) { + console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + let a = arguments, i = 1, opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++], + minW: a[i++], maxW: a[i++], minH: a[i++], maxH: a[i++], id: a[i++] }; + return this.addWidget(els, opt); + } + function isGridStackWidget(w) { + return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false; + } + let el; + if (typeof els === 'string') { + let doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = els; + el = doc.body.children[0]; + } + else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) { + let content = els ? els.content || '' : ''; + options = els; + let doc = document.implementation.createHTMLDocument(''); // IE needs a param + doc.body.innerHTML = `
${content}
`; + el = doc.body.children[0]; + } + else { + el = els; + } + // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos + // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node. + // So make sure we load any DOM attributes that are not specified in passed in options (which override) + let domAttr = this._readAttr(el); + options = utils_1.Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it + utils_1.Utils.defaults(options, domAttr); + let node = this.engine.prepareNode(options); + this._writeAttr(el, options); + if (this._insertNotAppend) { + this.el.prepend(el); + } + else { + this.el.appendChild(el); + } + // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id + this._prepareElement(el, true, options); + this._updateContainerHeight(); + // check if nested grid definition is present + if (node.subGrid && !node.subGrid.el) { // see if there is a sub-grid to create too + // if column special case it set, remember that flag and set default + let autoColumn; + let ops = node.subGrid; + if (ops.column === 'auto') { + ops.column = node.w; + ops.disableOneColumnMode = true; // driven by parent + autoColumn = true; + } + let content = node.el.querySelector('.grid-stack-item-content'); + node.subGrid = GridStack.addGrid(content, node.subGrid); + if (autoColumn) { + node.subGrid._autoColumn = true; + } + } + this._triggerAddEvent(); + this._triggerChangeEvent(); + return el; + } + /** + /** + * saves the current layout returning a list of widgets for serialization which might include any nested grids. + * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will + * be removed. + * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() + * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead. + * @returns list of widgets or full grid option, including .children list of widgets + */ + save(saveContent = true, saveGridOpt = false) { + // return copied nodes we can modify at will... + let list = this.engine.save(saveContent); + // check for HTML content and nested grids + list.forEach(n => { + if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content + let sub = n.el.querySelector('.grid-stack-item-content'); + n.content = sub ? sub.innerHTML : undefined; + if (!n.content) + delete n.content; + } + else { + if (!saveContent) { + delete n.content; + } + // check for nested grid + if (n.subGrid) { + n.subGrid = n.subGrid.save(saveContent, true); + } + } + delete n.el; + }); + // check if save entire grid options (needed for recursive) + children... + if (saveGridOpt) { + let o = utils_1.Utils.cloneDeep(this.opts); + // delete default values that will be recreated on launch + if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) { + o.margin = o.marginTop; + delete o.marginTop; + delete o.marginRight; + delete o.marginBottom; + delete o.marginLeft; + } + if (o.rtl === (this.el.style.direction === 'rtl')) { + o.rtl = 'auto'; + } + if (this._isAutoCellHeight) { + o.cellHeight = 'auto'; + } + if (this._autoColumn) { + o.column = 'auto'; + delete o.disableOneColumnMode; + } + const origShow = o._alwaysShowResizeHandle; + delete o._alwaysShowResizeHandle; + if (origShow !== undefined) { + o.alwaysShowResizeHandle = origShow; + } + else { + delete o.alwaysShowResizeHandle; + } + utils_1.Utils.removeInternalAndSame(o, GridDefaults); + o.children = list; + return o; + } + return list; + } + /** + * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there. + * + * @param layout list of widgets definition to update/create + * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving + * the user control of insertion. + * + * @example + * see http://gridstackjs.com/demo/serialization.html + **/ + load(layout, addAndRemove = true) { + let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort + this._insertNotAppend = true; // since create in reverse order... + // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save + // the original wanted layout so we can scale back up correctly #1471 + if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) { + this._ignoreLayoutsNodeChange = true; // skip layout update + this.engine.cacheLayout(items, this._prevColumn, true); + } + let removed = []; + this.batchUpdate(); + // see if any items are missing from new layout and need to be removed first + if (addAndRemove) { + let copyNodes = [...this.engine.nodes]; // don't loop through array you modify + copyNodes.forEach(n => { + let item = items.find(w => n.id === w.id); + if (!item) { + if (typeof (addAndRemove) === 'function') { + addAndRemove(this, n, false); + } + else { + removed.push(n); // batch keep track + this.removeWidget(n.el, true, false); + } + } + }); + } + // now add/update the widgets + items.forEach(w => { + let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined; + if (item) { + this.update(item.el, w); + if (w.subGrid && w.subGrid.children) { // update any sub grid as well + let sub = item.el.querySelector('.grid-stack'); + if (sub && sub.gridstack) { + sub.gridstack.load(w.subGrid.children); // TODO: support updating grid options ? + this._insertNotAppend = true; // got reset by above call + } + } + } + else if (addAndRemove) { + if (typeof (addAndRemove) === 'function') { + w = addAndRemove(this, w, true).gridstackNode; + } + else { + w = this.addWidget(w).gridstackNode; + } + } + }); + this.engine.removedNodes = removed; + this.batchUpdate(false); + // after commit, clear that flag + delete this._ignoreLayoutsNodeChange; + delete this._insertNotAppend; + return this; + } + /** + * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient) + * and get a single event callback. You will see no changes until `batchUpdate(false)` is called. + */ + batchUpdate(flag = true) { + this.engine.batchUpdate(flag); + if (!flag) { + this._triggerRemoveEvent(); + this._triggerAddEvent(); + this._triggerChangeEvent(); + } + return this; + } + /** + * Gets current cell height. + */ + getCellHeight(forcePixel = false) { + if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' && + (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) { + return this.opts.cellHeight; + } + // else get first cell height + let el = this.el.querySelector('.' + this.opts.itemClass); + if (el) { + let height = utils_1.Utils.toNumber(el.getAttribute('gs-h')); + return Math.round(el.offsetHeight / height); + } + // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain) + let rows = parseInt(this.el.getAttribute('gs-current-row')); + return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight; + } + /** + * Update current cell height - see `GridStackOptions.cellHeight` for format. + * This method rebuilds an internal CSS style sheet. + * Note: You can expect performance issues if call this method too often. + * + * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin), + * if pass 0 the CSS will be generated by the application instead. + * @param update (Optional) if false, styles will not be updated + * + * @example + * grid.cellHeight(100); // same as 100px + * grid.cellHeight('70px'); + * grid.cellHeight(grid.cellWidth() * 1.2); + */ + cellHeight(val, update = true) { + // if not called internally, check if we're changing mode + if (update && val !== undefined) { + if (this._isAutoCellHeight !== (val === 'auto')) { + this._isAutoCellHeight = (val === 'auto'); + this._updateWindowResizeEvent(); + } + } + if (val === 'initial' || val === 'auto') { + val = undefined; + } + // make item content be square + if (val === undefined) { + let marginDiff = -this.opts.marginRight - this.opts.marginLeft + + this.opts.marginTop + this.opts.marginBottom; + val = this.cellWidth() + marginDiff; + } + let data = utils_1.Utils.parseHeight(val); + if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) { + return this; + } + this.opts.cellHeightUnit = data.unit; + this.opts.cellHeight = data.h; + if (update) { + this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows + } + return this; + } + /** Gets current cell width. */ + cellWidth() { + return this._widthOrContainer() / this.getColumn(); + } + /** return our expected width (or parent) for 1 column check */ + _widthOrContainer() { + // use `offsetWidth` or `clientWidth` (no scrollbar) ? + // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively + return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth); + } + /** re-layout grid items to reclaim any empty space */ + compact() { + this.engine.compact(); + this._triggerChangeEvent(); + return this; + } + /** + * set the number of columns in the grid. Will update existing widgets to conform to new number of columns, + * as well as cache the original layout so you can revert back to previous positions without loss. + * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11], + * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns) + * @param column - Integer > 0 (default 12). + * @param layout specify the type of re-layout that will happen (position, size, etc...). + * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column + */ + column(column, layout = 'moveScale') { + if (column < 1 || this.opts.column === column) + return this; + let oldColumn = this.getColumn(); + // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on) + // then remember the original columns so we can restore. + if (column === 1) { + this._prevColumn = oldColumn; + } + else { + delete this._prevColumn; + } + this.el.classList.remove('grid-stack-' + oldColumn); + this.el.classList.add('grid-stack-' + column); + this.opts.column = this.engine.column = column; + // update the items now - see if the dom order nodes should be passed instead (else default to current list) + let domNodes; + if (column === 1 && this.opts.oneColumnModeDomSort) { + domNodes = []; + this.getGridItems().forEach(el => { + if (el.gridstackNode) { + domNodes.push(el.gridstackNode); + } + }); + if (!domNodes.length) { + domNodes = undefined; + } + } + this.engine.updateNodeWidths(oldColumn, column, domNodes, layout); + if (this._isAutoCellHeight) + this.cellHeight(); + // and trigger our event last... + this._ignoreLayoutsNodeChange = true; // skip layout update + this._triggerChangeEvent(); + delete this._ignoreLayoutsNodeChange; + return this; + } + /** + * get the number of columns in the grid (default 12) + */ + getColumn() { + return this.opts.column; + } + /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */ + getGridItems() { + return Array.from(this.el.children) + .filter((el) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass)); + } + /** + * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members. + * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`). + */ + destroy(removeDOM = true) { + if (!this.el) + return; // prevent multiple calls + this._updateWindowResizeEvent(true); + this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away) + this.setAnimation(false); + if (!removeDOM) { + this.removeAll(removeDOM); + this.el.classList.remove(this.opts._styleSheetClass); + } + else { + this.el.parentNode.removeChild(this.el); + } + this._removeStylesheet(); + this.el.removeAttribute('gs-current-row'); + delete this.opts._isNested; + delete this.opts; + delete this._placeholder; + delete this.engine; + delete this.el.gridstack; // remove circular dependency that would prevent a freeing + delete this.el; + return this; + } + /** + * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) + */ + float(val) { + if (this.opts.float !== val) { + this.opts.float = this.engine.float = val; + this._triggerChangeEvent(); + } + return this; + } + /** + * get the current float mode + */ + getFloat() { + return this.engine.float; + } + /** + * Get the position of the cell under a pixel on screen. + * @param position the position of the pixel to resolve in + * absolute coordinates, as an object with top and left properties + * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false). + * Useful when grid is within `position: relative` element + * + * Returns an object with properties `x` and `y` i.e. the column and row in the grid. + */ + getCellFromPixel(position, useDocRelative = false) { + let box = this.el.getBoundingClientRect(); + // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`) + let containerPos; + if (useDocRelative) { + containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left }; + // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`) + } + else { + containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft }; + // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`) + } + let relativeLeft = position.left - containerPos.left; + let relativeTop = position.top - containerPos.top; + let columnWidth = (box.width / this.getColumn()); + let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row'))); + return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) }; + } + /** returns the current number of rows, which will be at least `minRow` if set */ + getRow() { + return Math.max(this.engine.getRow(), this.opts.minRow); + } + /** + * Checks if specified area is empty. + * @param x the position x. + * @param y the position y. + * @param w the width of to check + * @param h the height of to check + */ + isAreaEmpty(x, y, w, h) { + return this.engine.isAreaEmpty(x, y, w, h); + } + /** + * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets. + * If you want gridstack to add the elements for you, use `addWidget()` instead. + * Makes the given element a widget and returns it. + * @param els widget or single selector to convert. + * + * @example + * let grid = GridStack.init(); + * grid.el.appendChild('
'); + * grid.makeWidget('#gsi-1'); + */ + makeWidget(els) { + let el = GridStack.getElement(els); + this._prepareElement(el, true); + this._updateContainerHeight(); + this._triggerAddEvent(); + this._triggerChangeEvent(); + return el; + } + /** + * Event handler that extracts our CustomEvent data out automatically for receiving custom + * notifications (see doc for supported events) + * @param name of the event (see possible values) or list of names space separated + * @param callback function called with event and optional second/third param + * (see README documentation for each signature). + * + * @example + * grid.on('added', function(e, items) { log('added ', items)} ); + * or + * grid.on('added removed change', function(e, items) { log(e.type, items)} ); + * + * Note: in some cases it is the same as calling native handler and parsing the event. + * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} ); + * + */ + on(name, callback) { + // check for array of names being passed instead + if (name.indexOf(' ') !== -1) { + let names = name.split(' '); + names.forEach(name => this.on(name, callback)); + return this; + } + if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') { + // native CustomEvent handlers - cash the generic handlers so we can easily remove + let noData = (name === 'enable' || name === 'disable'); + if (noData) { + this._gsEventHandler[name] = (event) => callback(event); + } + else { + this._gsEventHandler[name] = (event) => callback(event, event.detail); + } + this.el.addEventListener(name, this._gsEventHandler[name]); + } + else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') { + // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself. + // do same for start event to make it easier... + this._gsEventHandler[name] = callback; + } + else { + console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.'); + } + return this; + } + /** + * unsubscribe from the 'on' event below + * @param name of the event (see possible values) + */ + off(name) { + // check for array of names being passed instead + if (name.indexOf(' ') !== -1) { + let names = name.split(' '); + names.forEach(name => this.off(name)); + return this; + } + if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') { + // remove native CustomEvent handlers + if (this._gsEventHandler[name]) { + this.el.removeEventListener(name, this._gsEventHandler[name]); + } + } + delete this._gsEventHandler[name]; + return this; + } + /** + * Removes widget from the grid. + * @param el widget or selector to modify + * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true). + * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true). + */ + removeWidget(els, removeDOM = true, triggerEvent = true) { + GridStack.getElements(els).forEach(el => { + if (el.parentElement !== this.el) + return; // not our child! + let node = el.gridstackNode; + // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272 + if (!node) { + node = this.engine.nodes.find(n => el === n.el); + } + if (!node) + return; + // remove our DOM data (circular link) and drag&drop permanently + delete el.gridstackNode; + this._removeDD(el); + this.engine.removeNode(node, removeDOM, triggerEvent); + if (removeDOM && el.parentElement) { + el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM + } + }); + if (triggerEvent) { + this._triggerRemoveEvent(); + this._triggerChangeEvent(); + } + return this; + } + /** + * Removes all widgets from the grid. + * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`). + */ + removeAll(removeDOM = true) { + // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently + this.engine.nodes.forEach(n => { + delete n.el.gridstackNode; + this._removeDD(n.el); + }); + this.engine.removeAll(removeDOM); + this._triggerRemoveEvent(); + return this; + } + /** + * Toggle the grid animation state. Toggles the `grid-stack-animate` class. + * @param doAnimate if true the grid will animate. + */ + setAnimation(doAnimate) { + if (doAnimate) { + this.el.classList.add('grid-stack-animate'); + } + else { + this.el.classList.remove('grid-stack-animate'); + } + return this; + } + /** + * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on. + * Also toggle the grid-stack-static class. + * @param val if true the grid become static. + */ + setStatic(val, updateClass = true) { + if (this.opts.staticGrid === val) + return this; + this.opts.staticGrid = val; + this._setupRemoveDrop(); + this._setupAcceptWidget(); + this.engine.nodes.forEach(n => this._prepareDragDropByNode(n)); // either delete or init Drag&drop + if (updateClass) { + this._setStaticClass(); + } + return this; + } + /** + * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed. + * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted) + * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated. + */ + update(els, opt) { + // support legacy call for now ? + if (arguments.length > 2) { + console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + let a = arguments, i = 1; + opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] }; + return this.update(els, opt); + } + GridStack.getElements(els).forEach(el => { + if (!el || !el.gridstackNode) + return; + let n = el.gridstackNode; + let w = utils_1.Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items + delete w.autoPosition; + // move/resize widget if anything changed + let keys = ['x', 'y', 'w', 'h']; + let m; + if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) { + m = {}; + keys.forEach(k => { + m[k] = (w[k] !== undefined) ? w[k] : n[k]; + delete w[k]; + }); + } + // for a move as well IFF there is any min/max fields set + if (!m && (w.minW || w.minH || w.maxW || w.maxH)) { + m = {}; // will use node position but validate values + } + // check for content changing + if (w.content) { + let sub = el.querySelector('.grid-stack-item-content'); + if (sub && sub.innerHTML !== w.content) { + sub.innerHTML = w.content; + } + delete w.content; + } + // any remaining fields are assigned, but check for dragging changes, resize constrain + let changed = false; + let ddChanged = false; + for (const key in w) { + if (key[0] !== '_' && n[key] !== w[key]) { + n[key] = w[key]; + changed = true; + ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked')); + } + } + // finally move the widget + if (m) { + this.engine.cleanNodes() + .beginUpdate(n) + .moveNode(n, m); + this._updateContainerHeight(); + this._triggerChangeEvent(); + this.engine.endUpdate(); + } + if (changed) { // move will only update x,y,w,h so update the rest too + this._writeAttr(el, n); + } + if (ddChanged) { + this._prepareDragDropByNode(n); + } + }); + return this; + } + /** + * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number). + * @param value margin value + */ + margin(value) { + let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1); + // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle) + if (!isMultiValue) { + let data = utils_1.Utils.parseHeight(value); + if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) + return; + } + // re-use existing margin handling + this.opts.margin = value; + this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined; + this._initMargin(); + this._updateStyles(true); // true = force re-create + return this; + } + /** returns current margin number value (undefined if 4 sides don't match) */ + getMargin() { return this.opts.margin; } + /** + * Returns true if the height of the grid will be less than the vertical + * constraint. Always returns true if grid doesn't have height constraint. + * @param node contains x,y,w,h,auto-position options + * + * @example + * if (grid.willItFit(newWidget)) { + * grid.addWidget(newWidget); + * } else { + * alert('Not enough free space to place the widget'); + * } + */ + willItFit(node) { + // support legacy call for now + if (arguments.length > 1) { + console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon'); + // eslint-disable-next-line prefer-rest-params + let a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] }; + return this.willItFit(w); + } + return this.engine.willItFit(node); + } + /** @internal */ + _triggerChangeEvent() { + if (this.engine.batchMode) + return this; + let elements = this.engine.getDirtyNodes(true); // verify they really changed + if (elements && elements.length) { + if (!this._ignoreLayoutsNodeChange) { + this.engine.layoutsNodesChange(elements); + } + this._triggerEvent('change', elements); + } + this.engine.saveInitial(); // we called, now reset initial values & dirty flags + return this; + } + /** @internal */ + _triggerAddEvent() { + if (this.engine.batchMode) + return this; + if (this.engine.addedNodes && this.engine.addedNodes.length > 0) { + if (!this._ignoreLayoutsNodeChange) { + this.engine.layoutsNodesChange(this.engine.addedNodes); + } + // prevent added nodes from also triggering 'change' event (which is called next) + this.engine.addedNodes.forEach(n => { delete n._dirty; }); + this._triggerEvent('added', this.engine.addedNodes); + this.engine.addedNodes = []; + } + return this; + } + /** @internal */ + _triggerRemoveEvent() { + if (this.engine.batchMode) + return this; + if (this.engine.removedNodes && this.engine.removedNodes.length > 0) { + this._triggerEvent('removed', this.engine.removedNodes); + this.engine.removedNodes = []; + } + return this; + } + /** @internal */ + _triggerEvent(name, data) { + let event = data ? new CustomEvent(name, { bubbles: false, detail: data }) : new Event(name); + this.el.dispatchEvent(event); + return this; + } + /** @internal called to delete the current dynamic style sheet used for our layout */ + _removeStylesheet() { + if (this._styles) { + utils_1.Utils.removeStylesheet(this._styles._id); + delete this._styles; + } + return this; + } + /** @internal updated/create the CSS styles for row based layout and initial margin setting */ + _updateStyles(forceUpdate = false, maxH) { + // call to delete existing one if we change cellHeight / margin + if (forceUpdate) { + this._removeStylesheet(); + } + this._updateContainerHeight(); + // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ?? + if (this.opts.cellHeight === 0) { + return this; + } + let cellHeight = this.opts.cellHeight; + let cellHeightUnit = this.opts.cellHeightUnit; + let prefix = `.${this.opts._styleSheetClass} > .${this.opts.itemClass}`; + // create one as needed + if (!this._styles) { + let id = 'gridstack-style-' + (Math.random() * 100000).toFixed(); + // insert style to parent (instead of 'head' by default) to support WebComponent + let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode; + this._styles = utils_1.Utils.createStylesheet(id, styleLocation); + if (!this._styles) + return this; + this._styles._id = id; + this._styles._max = 0; + // these are done once only + utils_1.Utils.addCSSRule(this._styles, prefix, `min-height: ${cellHeight}${cellHeightUnit}`); + // content margins + let top = this.opts.marginTop + this.opts.marginUnit; + let bottom = this.opts.marginBottom + this.opts.marginUnit; + let right = this.opts.marginRight + this.opts.marginUnit; + let left = this.opts.marginLeft + this.opts.marginUnit; + let content = `${prefix} > .grid-stack-item-content`; + let placeholder = `.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`; + utils_1.Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`); + utils_1.Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`); + // resize handles offset (to match margin) + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`); + } + // now update the height specific fields + maxH = maxH || this._styles._max; + if (maxH > this._styles._max) { + let getHeight = (rows) => (cellHeight * rows) + cellHeightUnit; + for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1 + let h = getHeight(i); + utils_1.Utils.addCSSRule(this._styles, `${prefix}[gs-y="${i - 1}"]`, `top: ${getHeight(i - 1)}`); // start at 0 + utils_1.Utils.addCSSRule(this._styles, `${prefix}[gs-h="${i}"]`, `height: ${h}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix}[gs-min-h="${i}"]`, `min-height: ${h}`); + utils_1.Utils.addCSSRule(this._styles, `${prefix}[gs-max-h="${i}"]`, `max-height: ${h}`); + } + this._styles._max = maxH; + } + return this; + } + /** @internal */ + _updateContainerHeight() { + if (!this.engine || this.engine.batchMode) + return this; + let row = this.getRow() + this._extraDragRow; // checks for minRow already + // check for css min height + // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary + // rows as the CSS will make us bigger than our set height if needed... not sure why we had this. + // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']); + // if (cssMinHeight > 0) { + // let minRow = Math.round(cssMinHeight / this.getCellHeight(true)); + // if (row < minRow) { + // row = minRow; + // } + // } + this.el.setAttribute('gs-current-row', String(row)); + if (row === 0) { + this.el.style.removeProperty('height'); + return this; + } + let cellHeight = this.opts.cellHeight; + let unit = this.opts.cellHeightUnit; + if (!cellHeight) + return this; + this.el.style.height = row * cellHeight + unit; + return this; + } + /** @internal */ + _prepareElement(el, triggerAddEvent = false, node) { + if (!node) { + el.classList.add(this.opts.itemClass); + node = this._readAttr(el); + } + el.gridstackNode = node; + node.el = el; + node.grid = this; + let copy = Object.assign({}, node); + node = this.engine.addNode(node, triggerAddEvent); + // write node attr back in case there was collision or we have to fix bad values during addNode() + if (!utils_1.Utils.same(node, copy)) { + this._writeAttr(el, node); + } + this._prepareDragDropByNode(node); + return this; + } + /** @internal call to write position x,y,w,h attributes back to element */ + _writePosAttr(el, n) { + if (n.x !== undefined && n.x !== null) { + el.setAttribute('gs-x', String(n.x)); + } + if (n.y !== undefined && n.y !== null) { + el.setAttribute('gs-y', String(n.y)); + } + if (n.w) { + el.setAttribute('gs-w', String(n.w)); + } + if (n.h) { + el.setAttribute('gs-h', String(n.h)); + } + return this; + } + /** @internal call to write any default attributes back to element */ + _writeAttr(el, node) { + if (!node) + return this; + this._writePosAttr(el, node); + let attrs /*: GridStackWidget but strings */ = { + autoPosition: 'gs-auto-position', + minW: 'gs-min-w', + minH: 'gs-min-h', + maxW: 'gs-max-w', + maxH: 'gs-max-h', + noResize: 'gs-no-resize', + noMove: 'gs-no-move', + locked: 'gs-locked', + id: 'gs-id', + resizeHandles: 'gs-resize-handles' + }; + for (const key in attrs) { + if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway + el.setAttribute(attrs[key], String(node[key])); + } + else { + el.removeAttribute(attrs[key]); + } + } + return this; + } + /** @internal call to read any default attributes from element */ + _readAttr(el) { + let node = {}; + node.x = utils_1.Utils.toNumber(el.getAttribute('gs-x')); + node.y = utils_1.Utils.toNumber(el.getAttribute('gs-y')); + node.w = utils_1.Utils.toNumber(el.getAttribute('gs-w')); + node.h = utils_1.Utils.toNumber(el.getAttribute('gs-h')); + node.maxW = utils_1.Utils.toNumber(el.getAttribute('gs-max-w')); + node.minW = utils_1.Utils.toNumber(el.getAttribute('gs-min-w')); + node.maxH = utils_1.Utils.toNumber(el.getAttribute('gs-max-h')); + node.minH = utils_1.Utils.toNumber(el.getAttribute('gs-min-h')); + node.autoPosition = utils_1.Utils.toBool(el.getAttribute('gs-auto-position')); + node.noResize = utils_1.Utils.toBool(el.getAttribute('gs-no-resize')); + node.noMove = utils_1.Utils.toBool(el.getAttribute('gs-no-move')); + node.locked = utils_1.Utils.toBool(el.getAttribute('gs-locked')); + node.resizeHandles = el.getAttribute('gs-resize-handles'); + node.id = el.getAttribute('gs-id'); + // remove any key not found (null or false which is default) + for (const key in node) { + if (!node.hasOwnProperty(key)) + return; + if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really) + delete node[key]; + } + } + return node; + } + /** @internal */ + _setStaticClass() { + let classes = ['grid-stack-static']; + if (this.opts.staticGrid) { + this.el.classList.add(...classes); + this.el.setAttribute('gs-static', 'true'); + } + else { + this.el.classList.remove(...classes); + this.el.removeAttribute('gs-static'); + } + return this; + } + /** + * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off + * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square) + */ + onParentResize() { + if (!this.el || !this.el.clientWidth) + return; // return if we're gone or no size yet (will get called again) + let changedColumn = false; + // see if we're nested and take our column count from our parent.... + if (this._autoColumn && this.opts._isNested) { + if (this.opts.column !== this.opts._isNested.w) { + changedColumn = true; + this.column(this.opts._isNested.w, 'none'); + } + } + else { + // else check for 1 column in/out behavior + let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize; + if ((this.opts.column === 1) !== oneColumn) { + changedColumn = true; + if (this.opts.animate) { + this.setAnimation(false); + } // 1 <-> 12 is too radical, turn off animation + this.column(oneColumn ? 1 : this._prevColumn); + if (this.opts.animate) { + this.setAnimation(true); + } + } + } + // make the cells content square again + if (this._isAutoCellHeight) { + if (!changedColumn && this.opts.cellHeightThrottle) { + if (!this._cellHeightThrottle) { + this._cellHeightThrottle = utils_1.Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle); + } + this._cellHeightThrottle(); + } + else { + // immediate update if we've changed column count or have no threshold + this.cellHeight(); + } + } + // finally update any nested grids + this.engine.nodes.forEach(n => { + if (n.subGrid) { + n.subGrid.onParentResize(); + } + }); + return this; + } + /** add or remove the window size event handler */ + _updateWindowResizeEvent(forceRemove = false) { + // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work) + const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested; + if (!forceRemove && workTodo && !this._windowResizeBind) { + this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later + window.addEventListener('resize', this._windowResizeBind); + } + else if ((forceRemove || !workTodo) && this._windowResizeBind) { + window.removeEventListener('resize', this._windowResizeBind); + delete this._windowResizeBind; // remove link to us so we can free + } + return this; + } + /** @internal convert a potential selector into actual element */ + static getElement(els = '.grid-stack-item') { return utils_1.Utils.getElement(els); } + /** @internal */ + static getElements(els = '.grid-stack-item') { return utils_1.Utils.getElements(els); } + /** @internal */ + static getGridElement(els) { return GridStack.getElement(els); } + /** @internal */ + static getGridElements(els) { return utils_1.Utils.getElements(els); } + /** @internal initialize margin top/bottom/left/right and units */ + _initMargin() { + let data; + let margin = 0; + // support passing multiple values like CSS (ex: '5px 10px 0 20px') + let margins = []; + if (typeof this.opts.margin === 'string') { + margins = this.opts.margin.split(' '); + } + if (margins.length === 2) { // top/bot, left/right like CSS + this.opts.marginTop = this.opts.marginBottom = margins[0]; + this.opts.marginLeft = this.opts.marginRight = margins[1]; + } + else if (margins.length === 4) { // Clockwise like CSS + this.opts.marginTop = margins[0]; + this.opts.marginRight = margins[1]; + this.opts.marginBottom = margins[2]; + this.opts.marginLeft = margins[3]; + } + else { + data = utils_1.Utils.parseHeight(this.opts.margin); + this.opts.marginUnit = data.unit; + margin = this.opts.margin = data.h; + } + // see if top/bottom/left/right need to be set as well + if (this.opts.marginTop === undefined) { + this.opts.marginTop = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginTop); + this.opts.marginTop = data.h; + delete this.opts.margin; + } + if (this.opts.marginBottom === undefined) { + this.opts.marginBottom = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginBottom); + this.opts.marginBottom = data.h; + delete this.opts.margin; + } + if (this.opts.marginRight === undefined) { + this.opts.marginRight = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginRight); + this.opts.marginRight = data.h; + delete this.opts.margin; + } + if (this.opts.marginLeft === undefined) { + this.opts.marginLeft = margin; + } + else { + data = utils_1.Utils.parseHeight(this.opts.marginLeft); + this.opts.marginLeft = data.h; + delete this.opts.margin; + } + this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead... + if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) { + this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin() + } + return this; + } + /* + * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid + * so we don't incur the load unless needed. + * NOTE: had to make those methods public in order to define them else as + * GridStack.prototype._setupAcceptWidget = function() + * maybe there is a better way ???? + */ + /* eslint-disable @typescript-eslint/no-unused-vars */ + /** + * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options. + * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar + * is dynamically create and needs to change later. + * @param dragIn string selector (ex: '.sidebar .grid-stack-item') + * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'} + **/ + static setupDragIn(dragIn, dragInOptions) { } + /** + * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids. + * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead. + * @param els widget or selector to modify. + * @param val if true widget will be draggable. + */ + movable(els, val) { return this; } + /** + * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids. + * @param els widget or selector to modify + * @param val if true widget will be resizable. + */ + resizable(els, val) { return this; } + /** + * Temporarily disables widgets moving/resizing. + * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead. + * Note: no-op for static grid + * This is a shortcut for: + * @example + * grid.enableMove(false); + * grid.enableResize(false); + */ + disable() { return this; } + /** + * Re-enables widgets moving/resizing - see disable(). + * Note: no-op for static grid. + * This is a shortcut for: + * @example + * grid.enableMove(true); + * grid.enableResize(true); + */ + enable() { return this; } + /** + * Enables/disables widget moving. No-op for static grids. + */ + enableMove(doEnable) { return this; } + /** + * Enables/disables widget resizing. No-op for static grids. + */ + enableResize(doEnable) { return this; } + /** @internal removes any drag&drop present (called during destroy) */ + _removeDD(el) { return this; } + /** @internal called to add drag over support to support widgets */ + _setupAcceptWidget() { return this; } + /** @internal called to setup a trash drop zone if the user specifies it */ + _setupRemoveDrop() { return this; } + /** @internal prepares the element for drag&drop **/ + _prepareDragDropByNode(node) { return this; } + /** @internal handles actual drag/resize start **/ + _onStartMoving(el, event, ui, node, cellWidth, cellHeight) { return; } + /** @internal handles actual drag/resize **/ + _dragOrResize(el, event, ui, node, cellWidth, cellHeight) { return; } + /** @internal called when a node leaves our area (mouse out or shape outside) **/ + _leave(el, helper) { return; } + // legacy method removed + commit() { utils_1.obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; } +} +exports.GridStack = GridStack; +/** scoping so users can call GridStack.Utils.sort() for example */ +GridStack.Utils = utils_1.Utils; +/** scoping so users can call new GridStack.Engine(12) for example */ +GridStack.Engine = gridstack_engine_1.GridStackEngine; +GridStack.GDRev = '6.0.1-dev'; +const dd_touch_1 = require("./dd-touch"); +__exportStar(require("./dd-gridstack"), exports); +//# sourceMappingURL=gridstack.js.map \ No newline at end of file diff --git a/dist/gridstack.js.map b/dist/gridstack.js.map new file mode 100644 index 000000000..257f53508 --- /dev/null +++ b/dist/gridstack.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gridstack.js","sourceRoot":"","sources":["../src/gridstack.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\r\n * GridStack 6.0.1-dev\r\n * https://gridstackjs.com/\r\n *\r\n * Copyright (c) 2021-2022 Alain Dumesny\r\n * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE\r\n */\r\nimport { GridStackEngine } from './gridstack-engine';\r\nimport { Utils, HeightData, obsolete } from './utils';\r\nimport { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback,\r\n GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData, DDDragInOpt, GridStackPosition } from './types';\r\n\r\n// export all dependent file as well to make it easier for users to just import the main file\r\nexport * from './types';\r\nexport * from './utils';\r\nexport * from './gridstack-engine';\r\n\r\nexport interface GridHTMLElement extends HTMLElement {\r\n gridstack?: GridStack; // grid's parent DOM element points back to grid class\r\n}\r\n/** list of possible events, or space separated list of them */\r\nexport type GridStackEvent = 'added' | 'change' | 'disable' | 'drag' | 'dragstart' | 'dragstop' | 'dropped' |\r\n 'enable' | 'removed' | 'resize' | 'resizestart' | 'resizestop' | string;\r\n\r\n/** Defines the coordinates of an object */\r\nexport interface MousePosition {\r\n top: number;\r\n left: number;\r\n}\r\n\r\n/** Defines the position of a cell inside the grid*/\r\nexport interface CellPosition {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface GridCSSStyleSheet extends CSSStyleSheet {\r\n _id?: string; // random id we will use to style us\r\n _max?: number; // internal tracker of the max # of rows we created\\\r\n}\r\n\r\n// default values for grid options - used during init and when saving out\r\nconst GridDefaults: GridStackOptions = {\r\n column: 12,\r\n minRow: 0,\r\n maxRow: 0,\r\n itemClass: 'grid-stack-item',\r\n placeholderClass: 'grid-stack-placeholder',\r\n placeholderText: '',\r\n handle: '.grid-stack-item-content',\r\n handleClass: null,\r\n styleInHead: false,\r\n cellHeight: 'auto',\r\n cellHeightThrottle: 100,\r\n margin: 10,\r\n auto: true,\r\n oneColumnSize: 768,\r\n float: false,\r\n staticGrid: false,\r\n animate: true,\r\n alwaysShowResizeHandle: 'mobile',\r\n resizable: {\r\n handles: 'se'\r\n },\r\n draggable: {\r\n handle: '.grid-stack-item-content',\r\n appendTo: 'body'\r\n },\r\n disableDrag: false,\r\n disableResize: false,\r\n rtl: 'auto',\r\n removable: false,\r\n removableOptions: {\r\n accept: '.grid-stack-item'\r\n },\r\n marginUnit: 'px',\r\n cellHeightUnit: 'px',\r\n disableOneColumnMode: false,\r\n oneColumnModeDomSort: false,\r\n};\r\n\r\n/**\r\n * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.\r\n * Note: your grid elements MUST have the following classes for the CSS layout to work:\r\n * @example\r\n *
\r\n *
\r\n *
Item 1
\r\n *
\r\n *
\r\n */\r\nexport class GridStack {\r\n\r\n /**\r\n * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will\r\n * simply return the existing instance (ignore any passed options). There is also an initAll() version that support\r\n * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.\r\n * @param options grid options (optional)\r\n * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n *\r\n * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later\r\n * let grid = document.querySelector('.grid-stack').gridstack;\r\n */\r\n public static init(options: GridStackOptions = {}, elOrString: GridStackElement = '.grid-stack'): GridStack {\r\n let el = GridStack.getGridElement(elOrString);\r\n if (!el) {\r\n if (typeof elOrString === 'string') {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + elOrString + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n } else {\r\n console.error('GridStack.init() no grid element was passed.');\r\n }\r\n return null;\r\n }\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n }\r\n return el.gridstack\r\n }\r\n\r\n /**\r\n * Will initialize a list of elements (given a selector) and return an array of grids.\r\n * @param options grid options (optional)\r\n * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)\r\n *\r\n * @example\r\n * let grids = GridStack.initAll();\r\n * grids.forEach(...)\r\n */\r\n public static initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[] {\r\n let grids: GridStack[] = [];\r\n GridStack.getGridElements(selector).forEach(el => {\r\n if (!el.gridstack) {\r\n el.gridstack = new GridStack(el, Utils.cloneDeep(options));\r\n delete options.dragIn; delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)\r\n }\r\n grids.push(el.gridstack);\r\n });\r\n if (grids.length === 0) {\r\n console.error('GridStack.initAll() no grid was found with selector \"' + selector + '\" - element missing or wrong selector ?' +\r\n '\\nNote: \".grid-stack\" is required for proper CSS styling and drag/drop, and is the default selector.');\r\n }\r\n return grids;\r\n }\r\n\r\n /**\r\n * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then\r\n * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from\r\n * JSON serialized data, including options.\r\n * @param parent HTML element parent to the grid\r\n * @param opt grids options used to initialize the grid, and list of children\r\n */\r\n public static addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack {\r\n if (!parent) return null;\r\n\r\n // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead\r\n let el = parent;\r\n if (!parent.classList.contains('grid-stack')) {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n parent.appendChild(el);\r\n }\r\n\r\n // create grid class and load any children\r\n let grid = GridStack.init(opt, el);\r\n if (grid.opts.children) {\r\n let children = grid.opts.children;\r\n delete grid.opts.children;\r\n grid.load(children);\r\n }\r\n return grid;\r\n }\r\n\r\n /** call this method to register your engine instead of the default one.\r\n * See instead `GridStackOptions.engineClass` if you only need to\r\n * replace just one instance.\r\n */\r\n static registerEngine(engineClass: typeof GridStackEngine) {\r\n GridStack.engineClass = engineClass;\r\n }\r\n\r\n /** scoping so users can call GridStack.Utils.sort() for example */\r\n public static Utils = Utils;\r\n\r\n /** scoping so users can call new GridStack.Engine(12) for example */\r\n public static Engine = GridStackEngine;\r\n\r\n /** the HTML element tied to this grid after it's been initialized */\r\n public el: GridHTMLElement;\r\n\r\n /** engine used to implement non DOM grid functionality */\r\n public engine: GridStackEngine;\r\n\r\n /** grid options - public for classes to access, but use methods to modify! */\r\n public opts: GridStackOptions;\r\n\r\n protected static engineClass: typeof GridStackEngine;\r\n\r\n /** @internal create placeholder DIV as needed */\r\n public get placeholder(): HTMLElement {\r\n if (!this._placeholder) {\r\n let placeholderChild = document.createElement('div'); // child so padding match item-content\r\n placeholderChild.className = 'placeholder-content';\r\n if (this.opts.placeholderText) {\r\n placeholderChild.innerHTML = this.opts.placeholderText;\r\n }\r\n this._placeholder = document.createElement('div');\r\n this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass);\r\n this.placeholder.appendChild(placeholderChild);\r\n }\r\n return this._placeholder;\r\n }\r\n /** @internal */\r\n protected _placeholder: HTMLElement;\r\n /** @internal */\r\n protected _prevColumn: number;\r\n /** @internal */\r\n protected _ignoreLayoutsNodeChange: boolean;\r\n /** @internal */\r\n public _gsEventHandler = {};\r\n /** @internal */\r\n protected _styles: GridCSSStyleSheet;\r\n /** @internal flag to keep cells square during resize */\r\n protected _isAutoCellHeight: boolean;\r\n /** @internal track event binding to window resize so we can remove */\r\n protected _windowResizeBind: () => void;\r\n /** @internal limit auto cell resizing method */\r\n protected _cellHeightThrottle: () => void;\r\n /** @internal true when loading items to insert first rather than append */\r\n protected _insertNotAppend: boolean;\r\n /** @internal extra row added when dragging at the bottom of the grid */\r\n protected _extraDragRow = 0;\r\n /** @internal true if nested grid should get column count from our width */\r\n protected _autoColumn?: boolean;\r\n\r\n /**\r\n * Construct a grid item from the given element and options\r\n * @param el\r\n * @param opts\r\n */\r\n public constructor(el: GridHTMLElement, opts: GridStackOptions = {}) {\r\n this.el = el; // exposed HTML element to the user\r\n opts = opts || {}; // handles null/undefined/0\r\n\r\n // if row property exists, replace minRow and maxRow instead\r\n if (opts.row) {\r\n opts.minRow = opts.maxRow = opts.row;\r\n delete opts.row;\r\n }\r\n let rowAttr = Utils.toNumber(el.getAttribute('gs-row'));\r\n\r\n // flag only valid in sub-grids (handled by parent, not here)\r\n if (opts.column === 'auto') {\r\n delete opts.column;\r\n }\r\n // 'minWidth' legacy support in 5.1\r\n /* eslint-disable-next-line @typescript-eslint/no-explicit-any */\r\n let anyOpts = opts as any;\r\n if (anyOpts.minWidth !== undefined) {\r\n opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;\r\n delete anyOpts.minWidth;\r\n }\r\n // save original setting so we can restore on save\r\n if (opts.alwaysShowResizeHandle !== undefined) {\r\n (opts as any)._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;\r\n }\r\n\r\n // elements DOM attributes override any passed options (like CSS style) - merge the two together\r\n let defaults: GridStackOptions = {...Utils.cloneDeep(GridDefaults),\r\n column: Utils.toNumber(el.getAttribute('gs-column')) || GridDefaults.column,\r\n minRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-min-row')) || GridDefaults.minRow,\r\n maxRow: rowAttr ? rowAttr : Utils.toNumber(el.getAttribute('gs-max-row')) || GridDefaults.maxRow,\r\n staticGrid: Utils.toBool(el.getAttribute('gs-static')) || GridDefaults.staticGrid,\r\n _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0),\r\n draggable: {\r\n handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || GridDefaults.draggable.handle,\r\n },\r\n removableOptions: {\r\n accept: opts.itemClass ? '.' + opts.itemClass : GridDefaults.removableOptions.accept,\r\n },\r\n };\r\n if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead\r\n defaults.animate = Utils.toBool(el.getAttribute('gs-animate'))\r\n }\r\n\r\n this.opts = Utils.defaults(opts, defaults);\r\n opts = null; // make sure we use this.opts instead\r\n this._initMargin(); // part of settings defaults...\r\n\r\n // Now check if we're loading into 1 column mode FIRST so we don't do un-necessary work (like cellHeight = width / 12 then go 1 column)\r\n if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {\r\n this._prevColumn = this.getColumn();\r\n this.opts.column = 1;\r\n }\r\n\r\n if (this.opts.rtl === 'auto') {\r\n this.opts.rtl = (el.style.direction === 'rtl');\r\n }\r\n if (this.opts.rtl) {\r\n this.el.classList.add('grid-stack-rtl');\r\n }\r\n\r\n // check if we're been nested, and if so update our style and keep pointer around (used during save)\r\n let parentGridItemEl = Utils.closestByClass(this.el, GridDefaults.itemClass) as GridItemHTMLElement;\r\n if (parentGridItemEl && parentGridItemEl.gridstackNode) {\r\n this.opts._isNested = parentGridItemEl.gridstackNode;\r\n this.opts._isNested.subGrid = this;\r\n parentGridItemEl.classList.add('grid-stack-nested');\r\n this.el.classList.add('grid-stack-nested');\r\n }\r\n\r\n this._isAutoCellHeight = (this.opts.cellHeight === 'auto');\r\n if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {\r\n // make the cell content square initially (will use resize/column event to keep it square)\r\n this.cellHeight(undefined, false);\r\n } else {\r\n // append unit if any are set\r\n if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) {\r\n this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;\r\n delete this.opts.cellHeightUnit;\r\n }\r\n this.cellHeight(this.opts.cellHeight, false);\r\n }\r\n\r\n // see if we need to adjust auto-hide\r\n if (this.opts.alwaysShowResizeHandle === 'mobile') {\r\n this.opts.alwaysShowResizeHandle = isTouch;\r\n }\r\n\r\n this.el.classList.add(this.opts._styleSheetClass);\r\n\r\n this._setStaticClass();\r\n\r\n let engineClass = this.opts.engineClass || GridStack.engineClass || GridStackEngine;\r\n this.engine = new engineClass({\r\n column: this.getColumn(),\r\n float: this.opts.float,\r\n maxRow: this.opts.maxRow,\r\n onChange: (cbNodes) => {\r\n let maxH = 0;\r\n this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) });\r\n cbNodes.forEach(n => {\r\n let el = n.el;\r\n if (!el) return;\r\n if (n._removeDOM) {\r\n if (el) el.remove();\r\n delete n._removeDOM;\r\n } else {\r\n this._writePosAttr(el, n);\r\n }\r\n });\r\n this._updateStyles(false, maxH); // false = don't recreate, just append if need be\r\n }\r\n });\r\n\r\n if (this.opts.auto) {\r\n this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...\r\n let elements: {el: HTMLElement; i: number}[] = [];\r\n this.getGridItems().forEach(el => { // get dom elements (not nodes yet)\r\n let x = parseInt(el.getAttribute('gs-x'));\r\n let y = parseInt(el.getAttribute('gs-y'));\r\n elements.push({\r\n el,\r\n // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order\r\n i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * this.getColumn()\r\n });\r\n });\r\n elements.sort((a, b) => a.i - b.i).forEach(e => this._prepareElement(e.el));\r\n this.batchUpdate(false);\r\n }\r\n\r\n this.setAnimation(this.opts.animate);\r\n\r\n this._updateStyles();\r\n if (this.opts.column != 12) {\r\n this.el.classList.add('grid-stack-' + this.opts.column);\r\n }\r\n\r\n // legacy support to appear 'per grid` options when really global.\r\n if (this.opts.dragIn) GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);\r\n delete this.opts.dragIn;\r\n delete this.opts.dragInOptions;\r\n\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this._updateWindowResizeEvent();\r\n }\r\n\r\n public change() {\r\n this._triggerChangeEvent();\r\n }\r\n\r\n /**\r\n * add a new widget and returns it.\r\n *\r\n * Widget will be always placed even if result height is more than actual grid height.\r\n * You need to use `willItFit()` before calling addWidget for additional check.\r\n * See also `makeWidget()`.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.addWidget({w: 3, content: 'hello'});\r\n * grid.addWidget('
hello
', {w: 3});\r\n *\r\n * @param el GridStackWidget (which can have content string as well), html element, or string definition to add\r\n * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget\r\n */\r\n public addWidget(els?: GridStackWidget | GridStackElement, options?: GridStackWidget): GridItemHTMLElement {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1,\r\n opt: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++],\r\n minW:a[i++], maxW:a[i++], minH:a[i++], maxH:a[i++], id:a[i++] };\r\n return this.addWidget(els, opt);\r\n }\r\n\r\n function isGridStackWidget(w: GridStackWidget): w is GridStackWidget { // https://medium.com/ovrsea/checking-the-type-of-an-object-in-typescript-the-type-guards-24d98d9119b0\r\n return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;\r\n }\r\n\r\n let el: HTMLElement;\r\n if (typeof els === 'string') {\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = els;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {\r\n let content = els ? (els as GridStackWidget).content || '' : '';\r\n options = els;\r\n let doc = document.implementation.createHTMLDocument(''); // IE needs a param\r\n doc.body.innerHTML = `
${content}
`;\r\n el = doc.body.children[0] as HTMLElement;\r\n } else {\r\n el = els as HTMLElement;\r\n }\r\n\r\n // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos\r\n // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node.\r\n // So make sure we load any DOM attributes that are not specified in passed in options (which override)\r\n let domAttr = this._readAttr(el);\r\n options = Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it\r\n Utils.defaults(options, domAttr);\r\n let node = this.engine.prepareNode(options);\r\n this._writeAttr(el, options);\r\n\r\n if (this._insertNotAppend) {\r\n this.el.prepend(el);\r\n } else {\r\n this.el.appendChild(el);\r\n }\r\n\r\n // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id\r\n this._prepareElement(el, true, options);\r\n this._updateContainerHeight();\r\n\r\n // check if nested grid definition is present\r\n if (node.subGrid && !(node.subGrid as GridStack).el) { // see if there is a sub-grid to create too\r\n // if column special case it set, remember that flag and set default\r\n let autoColumn: boolean;\r\n let ops = node.subGrid as GridStackOptions;\r\n if (ops.column === 'auto') {\r\n ops.column = node.w;\r\n ops.disableOneColumnMode = true; // driven by parent\r\n autoColumn = true;\r\n }\r\n let content = node.el.querySelector('.grid-stack-item-content') as HTMLElement;\r\n node.subGrid = GridStack.addGrid(content, node.subGrid as GridStackOptions);\r\n if (autoColumn) { node.subGrid._autoColumn = true; }\r\n }\r\n\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n\r\n return el;\r\n }\r\n\r\n /**\r\n /**\r\n * saves the current layout returning a list of widgets for serialization which might include any nested grids.\r\n * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will\r\n * be removed.\r\n * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()\r\n * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.\r\n * @returns list of widgets or full grid option, including .children list of widgets\r\n */\r\n public save(saveContent = true, saveGridOpt = false): GridStackWidget[] | GridStackOptions {\r\n // return copied nodes we can modify at will...\r\n let list = this.engine.save(saveContent);\r\n\r\n // check for HTML content and nested grids\r\n list.forEach(n => {\r\n if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content\r\n let sub = n.el.querySelector('.grid-stack-item-content');\r\n n.content = sub ? sub.innerHTML : undefined;\r\n if (!n.content) delete n.content;\r\n } else {\r\n if (!saveContent) { delete n.content; }\r\n // check for nested grid\r\n if (n.subGrid) {\r\n n.subGrid = (n.subGrid as GridStack).save(saveContent, true) as GridStackOptions;\r\n }\r\n }\r\n delete n.el;\r\n });\r\n\r\n // check if save entire grid options (needed for recursive) + children...\r\n if (saveGridOpt) {\r\n let o: GridStackOptions = Utils.cloneDeep(this.opts);\r\n // delete default values that will be recreated on launch\r\n if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {\r\n o.margin = o.marginTop;\r\n delete o.marginTop; delete o.marginRight; delete o.marginBottom; delete o.marginLeft;\r\n }\r\n if (o.rtl === (this.el.style.direction === 'rtl')) { o.rtl = 'auto' }\r\n if (this._isAutoCellHeight) {\r\n o.cellHeight = 'auto'\r\n }\r\n if (this._autoColumn) {\r\n o.column = 'auto';\r\n delete o.disableOneColumnMode;\r\n }\r\n const origShow = (o as any)._alwaysShowResizeHandle;\r\n delete (o as any)._alwaysShowResizeHandle;\r\n if (origShow !== undefined) {\r\n o.alwaysShowResizeHandle = origShow;\r\n } else {\r\n delete o.alwaysShowResizeHandle;\r\n }\r\n Utils.removeInternalAndSame(o, GridDefaults);\r\n o.children = list;\r\n return o;\r\n }\r\n\r\n return list;\r\n }\r\n\r\n /**\r\n * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.\r\n *\r\n * @param layout list of widgets definition to update/create\r\n * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving\r\n * the user control of insertion.\r\n *\r\n * @example\r\n * see http://gridstackjs.com/demo/serialization.html\r\n **/\r\n public load(layout: GridStackWidget[], addAndRemove: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement) = true): GridStack {\r\n let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort\r\n this._insertNotAppend = true; // since create in reverse order...\r\n\r\n // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save\r\n // the original wanted layout so we can scale back up correctly #1471\r\n if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(n => (n.x + n.w) > this.opts.column)) {\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this.engine.cacheLayout(items, this._prevColumn, true);\r\n }\r\n\r\n let removed: GridStackNode[] = [];\r\n this.batchUpdate();\r\n\r\n // see if any items are missing from new layout and need to be removed first\r\n if (addAndRemove) {\r\n let copyNodes = [...this.engine.nodes]; // don't loop through array you modify\r\n copyNodes.forEach(n => {\r\n let item = items.find(w => n.id === w.id);\r\n if (!item) {\r\n if (typeof(addAndRemove) === 'function') {\r\n addAndRemove(this, n, false);\r\n } else {\r\n removed.push(n); // batch keep track\r\n this.removeWidget(n.el, true, false);\r\n }\r\n }\r\n });\r\n }\r\n\r\n // now add/update the widgets\r\n items.forEach(w => {\r\n let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined;\r\n if (item) {\r\n this.update(item.el, w);\r\n if (w.subGrid && (w.subGrid as GridStackOptions).children) { // update any sub grid as well\r\n let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;\r\n if (sub && sub.gridstack) {\r\n sub.gridstack.load((w.subGrid as GridStackOptions).children); // TODO: support updating grid options ?\r\n this._insertNotAppend = true; // got reset by above call\r\n }\r\n }\r\n } else if (addAndRemove) {\r\n if (typeof(addAndRemove) === 'function') {\r\n w = addAndRemove(this, w, true).gridstackNode;\r\n } else {\r\n w = this.addWidget(w).gridstackNode;\r\n }\r\n }\r\n });\r\n\r\n this.engine.removedNodes = removed;\r\n this.batchUpdate(false);\r\n\r\n // after commit, clear that flag\r\n delete this._ignoreLayoutsNodeChange;\r\n delete this._insertNotAppend;\r\n return this;\r\n }\r\n\r\n /**\r\n * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)\r\n * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.\r\n */\r\n public batchUpdate(flag = true): GridStack {\r\n this.engine.batchUpdate(flag);\r\n if (!flag) {\r\n this._triggerRemoveEvent();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets current cell height.\r\n */\r\n public getCellHeight(forcePixel = false): number {\r\n if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&\r\n (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {\r\n return this.opts.cellHeight as number;\r\n }\r\n // else get first cell height\r\n let el = this.el.querySelector('.' + this.opts.itemClass) as HTMLElement;\r\n if (el) {\r\n let height = Utils.toNumber(el.getAttribute('gs-h'));\r\n return Math.round(el.offsetHeight / height);\r\n }\r\n // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)\r\n let rows = parseInt(this.el.getAttribute('gs-current-row'));\r\n return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight as number;\r\n }\r\n\r\n /**\r\n * Update current cell height - see `GridStackOptions.cellHeight` for format.\r\n * This method rebuilds an internal CSS style sheet.\r\n * Note: You can expect performance issues if call this method too often.\r\n *\r\n * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),\r\n * if pass 0 the CSS will be generated by the application instead.\r\n * @param update (Optional) if false, styles will not be updated\r\n *\r\n * @example\r\n * grid.cellHeight(100); // same as 100px\r\n * grid.cellHeight('70px');\r\n * grid.cellHeight(grid.cellWidth() * 1.2);\r\n */\r\n public cellHeight(val?: numberOrString, update = true): GridStack {\r\n\r\n // if not called internally, check if we're changing mode\r\n if (update && val !== undefined) {\r\n if (this._isAutoCellHeight !== (val === 'auto')) {\r\n this._isAutoCellHeight = (val === 'auto');\r\n this._updateWindowResizeEvent();\r\n }\r\n }\r\n if (val === 'initial' || val === 'auto') { val = undefined; }\r\n\r\n // make item content be square\r\n if (val === undefined) {\r\n let marginDiff = - (this.opts.marginRight as number) - (this.opts.marginLeft as number)\r\n + (this.opts.marginTop as number) + (this.opts.marginBottom as number);\r\n val = this.cellWidth() + marginDiff;\r\n }\r\n\r\n let data = Utils.parseHeight(val);\r\n if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {\r\n return this;\r\n }\r\n this.opts.cellHeightUnit = data.unit;\r\n this.opts.cellHeight = data.h;\r\n\r\n if (update) {\r\n this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows\r\n }\r\n return this;\r\n }\r\n\r\n /** Gets current cell width. */\r\n public cellWidth(): number {\r\n return this._widthOrContainer() / this.getColumn();\r\n }\r\n /** return our expected width (or parent) for 1 column check */\r\n protected _widthOrContainer(): number {\r\n // use `offsetWidth` or `clientWidth` (no scrollbar) ?\r\n // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively\r\n return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);\r\n }\r\n\r\n /** re-layout grid items to reclaim any empty space */\r\n public compact(): GridStack {\r\n this.engine.compact();\r\n this._triggerChangeEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,\r\n * as well as cache the original layout so you can revert back to previous positions without loss.\r\n * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],\r\n * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)\r\n * @param column - Integer > 0 (default 12).\r\n * @param layout specify the type of re-layout that will happen (position, size, etc...).\r\n * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column\r\n */\r\n public column(column: number, layout: ColumnOptions = 'moveScale'): GridStack {\r\n if (column < 1 || this.opts.column === column) return this;\r\n let oldColumn = this.getColumn();\r\n\r\n // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)\r\n // then remember the original columns so we can restore.\r\n if (column === 1) {\r\n this._prevColumn = oldColumn;\r\n } else {\r\n delete this._prevColumn;\r\n }\r\n\r\n this.el.classList.remove('grid-stack-' + oldColumn);\r\n this.el.classList.add('grid-stack-' + column);\r\n this.opts.column = this.engine.column = column;\r\n\r\n // update the items now - see if the dom order nodes should be passed instead (else default to current list)\r\n let domNodes: GridStackNode[];\r\n if (column === 1 && this.opts.oneColumnModeDomSort) {\r\n domNodes = [];\r\n this.getGridItems().forEach(el => { // get dom elements in order\r\n if (el.gridstackNode) { domNodes.push(el.gridstackNode); }\r\n });\r\n if (!domNodes.length) { domNodes = undefined; }\r\n }\r\n this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);\r\n if (this._isAutoCellHeight) this.cellHeight();\r\n\r\n // and trigger our event last...\r\n this._ignoreLayoutsNodeChange = true; // skip layout update\r\n this._triggerChangeEvent();\r\n delete this._ignoreLayoutsNodeChange;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * get the number of columns in the grid (default 12)\r\n */\r\n public getColumn(): number {\r\n return this.opts.column as number;\r\n }\r\n\r\n /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */\r\n public getGridItems(): GridItemHTMLElement[] {\r\n return Array.from(this.el.children)\r\n .filter((el: HTMLElement) => el.matches('.' + this.opts.itemClass) && !el.matches('.' + this.opts.placeholderClass)) as GridItemHTMLElement[];\r\n }\r\n\r\n /**\r\n * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.\r\n * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).\r\n */\r\n public destroy(removeDOM = true): GridStack {\r\n if (!this.el) return; // prevent multiple calls\r\n this._updateWindowResizeEvent(true);\r\n this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)\r\n this.setAnimation(false);\r\n if (!removeDOM) {\r\n this.removeAll(removeDOM);\r\n this.el.classList.remove(this.opts._styleSheetClass);\r\n } else {\r\n this.el.parentNode.removeChild(this.el);\r\n }\r\n this._removeStylesheet();\r\n this.el.removeAttribute('gs-current-row');\r\n delete this.opts._isNested;\r\n delete this.opts;\r\n delete this._placeholder;\r\n delete this.engine;\r\n delete this.el.gridstack; // remove circular dependency that would prevent a freeing\r\n delete this.el;\r\n return this;\r\n }\r\n\r\n /**\r\n * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)\r\n */\r\n public float(val: boolean): GridStack {\r\n if (this.opts.float !== val) {\r\n this.opts.float = this.engine.float = val;\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get the current float mode\r\n */\r\n public getFloat(): boolean {\r\n return this.engine.float;\r\n }\r\n\r\n /**\r\n * Get the position of the cell under a pixel on screen.\r\n * @param position the position of the pixel to resolve in\r\n * absolute coordinates, as an object with top and left properties\r\n * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).\r\n * Useful when grid is within `position: relative` element\r\n *\r\n * Returns an object with properties `x` and `y` i.e. the column and row in the grid.\r\n */\r\n public getCellFromPixel(position: MousePosition, useDocRelative = false): CellPosition {\r\n let box = this.el.getBoundingClientRect();\r\n // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)\r\n let containerPos: {top: number, left: number};\r\n if (useDocRelative) {\r\n containerPos = {top: box.top + document.documentElement.scrollTop, left: box.left};\r\n // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)\r\n } else {\r\n containerPos = {top: this.el.offsetTop, left: this.el.offsetLeft}\r\n // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)\r\n }\r\n let relativeLeft = position.left - containerPos.left;\r\n let relativeTop = position.top - containerPos.top;\r\n\r\n let columnWidth = (box.width / this.getColumn());\r\n let rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));\r\n\r\n return {x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight)};\r\n }\r\n\r\n /** returns the current number of rows, which will be at least `minRow` if set */\r\n public getRow(): number {\r\n return Math.max(this.engine.getRow(), this.opts.minRow);\r\n }\r\n\r\n /**\r\n * Checks if specified area is empty.\r\n * @param x the position x.\r\n * @param y the position y.\r\n * @param w the width of to check\r\n * @param h the height of to check\r\n */\r\n public isAreaEmpty(x: number, y: number, w: number, h: number): boolean {\r\n return this.engine.isAreaEmpty(x, y, w, h);\r\n }\r\n\r\n /**\r\n * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.\r\n * If you want gridstack to add the elements for you, use `addWidget()` instead.\r\n * Makes the given element a widget and returns it.\r\n * @param els widget or single selector to convert.\r\n *\r\n * @example\r\n * let grid = GridStack.init();\r\n * grid.el.appendChild('
');\r\n * grid.makeWidget('#gsi-1');\r\n */\r\n public makeWidget(els: GridStackElement): GridItemHTMLElement {\r\n let el = GridStack.getElement(els);\r\n this._prepareElement(el, true);\r\n this._updateContainerHeight();\r\n this._triggerAddEvent();\r\n this._triggerChangeEvent();\r\n return el;\r\n }\r\n\r\n /**\r\n * Event handler that extracts our CustomEvent data out automatically for receiving custom\r\n * notifications (see doc for supported events)\r\n * @param name of the event (see possible values) or list of names space separated\r\n * @param callback function called with event and optional second/third param\r\n * (see README documentation for each signature).\r\n *\r\n * @example\r\n * grid.on('added', function(e, items) { log('added ', items)} );\r\n * or\r\n * grid.on('added removed change', function(e, items) { log(e.type, items)} );\r\n *\r\n * Note: in some cases it is the same as calling native handler and parsing the event.\r\n * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );\r\n *\r\n */\r\n public on(name: GridStackEvent, callback: GridStackEventHandlerCallback): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.on(name, callback));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // native CustomEvent handlers - cash the generic handlers so we can easily remove\r\n let noData = (name === 'enable' || name === 'disable');\r\n if (noData) {\r\n this._gsEventHandler[name] = (event: Event) => callback(event);\r\n } else {\r\n this._gsEventHandler[name] = (event: CustomEvent) => callback(event, event.detail);\r\n }\r\n this.el.addEventListener(name, this._gsEventHandler[name]);\r\n } else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {\r\n // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.\r\n // do same for start event to make it easier...\r\n this._gsEventHandler[name] = callback;\r\n } else {\r\n console.log('GridStack.on(' + name + ') event not supported, but you can still use $(\".grid-stack\").on(...) while jquery-ui is still used internally.');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * unsubscribe from the 'on' event below\r\n * @param name of the event (see possible values)\r\n */\r\n public off(name: GridStackEvent): GridStack {\r\n // check for array of names being passed instead\r\n if (name.indexOf(' ') !== -1) {\r\n let names = name.split(' ') as GridStackEvent[];\r\n names.forEach(name => this.off(name));\r\n return this;\r\n }\r\n\r\n if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {\r\n // remove native CustomEvent handlers\r\n if (this._gsEventHandler[name]) {\r\n this.el.removeEventListener(name, this._gsEventHandler[name]);\r\n }\r\n }\r\n delete this._gsEventHandler[name];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes widget from the grid.\r\n * @param el widget or selector to modify\r\n * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).\r\n * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).\r\n */\r\n public removeWidget(els: GridStackElement, removeDOM = true, triggerEvent = true): GridStack {\r\n GridStack.getElements(els).forEach(el => {\r\n if (el.parentElement !== this.el) return; // not our child!\r\n let node = el.gridstackNode;\r\n // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272\r\n if (!node) {\r\n node = this.engine.nodes.find(n => el === n.el);\r\n }\r\n if (!node) return;\r\n\r\n // remove our DOM data (circular link) and drag&drop permanently\r\n delete el.gridstackNode;\r\n this._removeDD(el);\r\n\r\n this.engine.removeNode(node, removeDOM, triggerEvent);\r\n\r\n if (removeDOM && el.parentElement) {\r\n el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM\r\n }\r\n });\r\n if (triggerEvent) {\r\n this._triggerRemoveEvent();\r\n this._triggerChangeEvent();\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Removes all widgets from the grid.\r\n * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).\r\n */\r\n public removeAll(removeDOM = true): GridStack {\r\n // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently\r\n this.engine.nodes.forEach(n => {\r\n delete n.el.gridstackNode;\r\n this._removeDD(n.el);\r\n });\r\n this.engine.removeAll(removeDOM);\r\n this._triggerRemoveEvent();\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid animation state. Toggles the `grid-stack-animate` class.\r\n * @param doAnimate if true the grid will animate.\r\n */\r\n public setAnimation(doAnimate: boolean): GridStack {\r\n if (doAnimate) {\r\n this.el.classList.add('grid-stack-animate');\r\n } else {\r\n this.el.classList.remove('grid-stack-animate');\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.\r\n * Also toggle the grid-stack-static class.\r\n * @param val if true the grid become static.\r\n */\r\n public setStatic(val: boolean, updateClass = true): GridStack {\r\n if (this.opts.staticGrid === val) return this;\r\n this.opts.staticGrid = val;\r\n this._setupRemoveDrop();\r\n this._setupAcceptWidget();\r\n this.engine.nodes.forEach(n => this._prepareDragDropByNode(n)); // either delete or init Drag&drop\r\n if (updateClass) { this._setStaticClass(); }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates widget position/size and other info. Note: if you need to call this on all nodes, use load() instead which will update what changed.\r\n * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)\r\n * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.\r\n */\r\n public update(els: GridStackElement, opt: GridStackWidget): GridStack {\r\n\r\n // support legacy call for now ?\r\n if (arguments.length > 2) {\r\n console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 1;\r\n opt = { x:a[i++], y:a[i++], w:a[i++], h:a[i++] };\r\n return this.update(els, opt);\r\n }\r\n\r\n GridStack.getElements(els).forEach(el => {\r\n if (!el || !el.gridstackNode) return;\r\n let n = el.gridstackNode;\r\n let w = Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items\r\n delete w.autoPosition;\r\n\r\n // move/resize widget if anything changed\r\n let keys = ['x', 'y', 'w', 'h'];\r\n let m: GridStackWidget;\r\n if (keys.some(k => w[k] !== undefined && w[k] !== n[k])) {\r\n m = {};\r\n keys.forEach(k => {\r\n m[k] = (w[k] !== undefined) ? w[k] : n[k];\r\n delete w[k];\r\n });\r\n }\r\n // for a move as well IFF there is any min/max fields set\r\n if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {\r\n m = {}; // will use node position but validate values\r\n }\r\n\r\n // check for content changing\r\n if (w.content) {\r\n let sub = el.querySelector('.grid-stack-item-content');\r\n if (sub && sub.innerHTML !== w.content) {\r\n sub.innerHTML = w.content;\r\n }\r\n delete w.content;\r\n }\r\n\r\n // any remaining fields are assigned, but check for dragging changes, resize constrain\r\n let changed = false;\r\n let ddChanged = false;\r\n for (const key in w) {\r\n if (key[0] !== '_' && n[key] !== w[key]) {\r\n n[key] = w[key];\r\n changed = true;\r\n ddChanged = ddChanged || (!this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));\r\n }\r\n }\r\n\r\n // finally move the widget\r\n if (m) {\r\n this.engine.cleanNodes()\r\n .beginUpdate(n)\r\n .moveNode(n, m);\r\n this._updateContainerHeight();\r\n this._triggerChangeEvent();\r\n this.engine.endUpdate();\r\n }\r\n if (changed) { // move will only update x,y,w,h so update the rest too\r\n this._writeAttr(el, n);\r\n }\r\n if (ddChanged) {\r\n this._prepareDragDropByNode(n);\r\n }\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the margins which will set all 4 sides at once - see `GridStackOptions.margin` for format options (CSS string format of 1,2,4 values or single number).\r\n * @param value margin value\r\n */\r\n public margin(value: numberOrString): GridStack {\r\n let isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);\r\n // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)\r\n if (!isMultiValue) {\r\n let data = Utils.parseHeight(value);\r\n if (this.opts.marginUnit === data.unit && this.opts.margin === data.h) return;\r\n }\r\n // re-use existing margin handling\r\n this.opts.margin = value;\r\n this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;\r\n this._initMargin();\r\n\r\n this._updateStyles(true); // true = force re-create\r\n\r\n return this;\r\n }\r\n\r\n /** returns current margin number value (undefined if 4 sides don't match) */\r\n public getMargin(): number { return this.opts.margin as number; }\r\n\r\n /**\r\n * Returns true if the height of the grid will be less than the vertical\r\n * constraint. Always returns true if grid doesn't have height constraint.\r\n * @param node contains x,y,w,h,auto-position options\r\n *\r\n * @example\r\n * if (grid.willItFit(newWidget)) {\r\n * grid.addWidget(newWidget);\r\n * } else {\r\n * alert('Not enough free space to place the widget');\r\n * }\r\n */\r\n public willItFit(node: GridStackWidget): boolean {\r\n // support legacy call for now\r\n if (arguments.length > 1) {\r\n console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');\r\n // eslint-disable-next-line prefer-rest-params\r\n let a = arguments, i = 0,\r\n w: GridStackWidget = { x:a[i++], y:a[i++], w:a[i++], h:a[i++], autoPosition:a[i++] };\r\n return this.willItFit(w);\r\n }\r\n return this.engine.willItFit(node);\r\n }\r\n\r\n /** @internal */\r\n protected _triggerChangeEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n let elements = this.engine.getDirtyNodes(true); // verify they really changed\r\n if (elements && elements.length) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(elements);\r\n }\r\n this._triggerEvent('change', elements);\r\n }\r\n this.engine.saveInitial(); // we called, now reset initial values & dirty flags\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerAddEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {\r\n if (!this._ignoreLayoutsNodeChange) {\r\n this.engine.layoutsNodesChange(this.engine.addedNodes);\r\n }\r\n // prevent added nodes from also triggering 'change' event (which is called next)\r\n this.engine.addedNodes.forEach(n => { delete n._dirty; });\r\n this._triggerEvent('added', this.engine.addedNodes);\r\n this.engine.addedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n public _triggerRemoveEvent(): GridStack {\r\n if (this.engine.batchMode) return this;\r\n if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {\r\n this._triggerEvent('removed', this.engine.removedNodes);\r\n this.engine.removedNodes = [];\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _triggerEvent(name: string, data?: GridStackNode[]): GridStack {\r\n let event = data ? new CustomEvent(name, {bubbles: false, detail: data}) : new Event(name);\r\n this.el.dispatchEvent(event);\r\n return this;\r\n }\r\n\r\n /** @internal called to delete the current dynamic style sheet used for our layout */\r\n protected _removeStylesheet(): GridStack {\r\n\r\n if (this._styles) {\r\n Utils.removeStylesheet(this._styles._id);\r\n delete this._styles;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal updated/create the CSS styles for row based layout and initial margin setting */\r\n protected _updateStyles(forceUpdate = false, maxH?: number): GridStack {\r\n // call to delete existing one if we change cellHeight / margin\r\n if (forceUpdate) {\r\n this._removeStylesheet();\r\n }\r\n\r\n this._updateContainerHeight();\r\n\r\n // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??\r\n if (this.opts.cellHeight === 0) {\r\n return this;\r\n }\r\n\r\n let cellHeight = this.opts.cellHeight as number;\r\n let cellHeightUnit = this.opts.cellHeightUnit;\r\n let prefix = `.${this.opts._styleSheetClass} > .${this.opts.itemClass}`;\r\n\r\n // create one as needed\r\n if (!this._styles) {\r\n let id = 'gridstack-style-' + (Math.random() * 100000).toFixed();\r\n // insert style to parent (instead of 'head' by default) to support WebComponent\r\n let styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement;\r\n this._styles = Utils.createStylesheet(id, styleLocation);\r\n if (!this._styles) return this;\r\n this._styles._id = id;\r\n this._styles._max = 0;\r\n\r\n // these are done once only\r\n Utils.addCSSRule(this._styles, prefix, `min-height: ${cellHeight}${cellHeightUnit}`);\r\n // content margins\r\n let top: string = this.opts.marginTop + this.opts.marginUnit;\r\n let bottom: string = this.opts.marginBottom + this.opts.marginUnit;\r\n let right: string = this.opts.marginRight + this.opts.marginUnit;\r\n let left: string = this.opts.marginLeft + this.opts.marginUnit;\r\n let content = `${prefix} > .grid-stack-item-content`;\r\n let placeholder = `.${this.opts._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`;\r\n Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`);\r\n // resize handles offset (to match margin)\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`);\r\n Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`);\r\n }\r\n\r\n // now update the height specific fields\r\n maxH = maxH || this._styles._max;\r\n if (maxH > this._styles._max) {\r\n let getHeight = (rows: number): string => (cellHeight * rows) + cellHeightUnit;\r\n for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1\r\n let h: string = getHeight(i);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-y=\"${i-1}\"]`, `top: ${getHeight(i-1)}`); // start at 0\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-h=\"${i}\"]`, `height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-min-h=\"${i}\"]`, `min-height: ${h}`);\r\n Utils.addCSSRule(this._styles, `${prefix}[gs-max-h=\"${i}\"]`, `max-height: ${h}`);\r\n }\r\n this._styles._max = maxH;\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _updateContainerHeight(): GridStack {\r\n if (!this.engine || this.engine.batchMode) return this;\r\n let row = this.getRow() + this._extraDragRow; // checks for minRow already\r\n // check for css min height\r\n // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary\r\n // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.\r\n // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);\r\n // if (cssMinHeight > 0) {\r\n // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));\r\n // if (row < minRow) {\r\n // row = minRow;\r\n // }\r\n // }\r\n this.el.setAttribute('gs-current-row', String(row));\r\n if (row === 0) {\r\n this.el.style.removeProperty('height');\r\n return this;\r\n }\r\n let cellHeight = this.opts.cellHeight as number;\r\n let unit = this.opts.cellHeightUnit;\r\n if (!cellHeight) return this;\r\n this.el.style.height = row * cellHeight + unit;\r\n return this;\r\n }\r\n\r\n /** @internal */\r\n protected _prepareElement(el: GridItemHTMLElement, triggerAddEvent = false, node?: GridStackNode): GridStack {\r\n if (!node) {\r\n el.classList.add(this.opts.itemClass);\r\n node = this._readAttr(el);\r\n }\r\n el.gridstackNode = node;\r\n node.el = el;\r\n node.grid = this;\r\n let copy = {...node};\r\n node = this.engine.addNode(node, triggerAddEvent);\r\n // write node attr back in case there was collision or we have to fix bad values during addNode()\r\n if (!Utils.same(node, copy)) {\r\n this._writeAttr(el, node);\r\n }\r\n this._prepareDragDropByNode(node);\r\n return this;\r\n }\r\n\r\n /** @internal call to write position x,y,w,h attributes back to element */\r\n protected _writePosAttr(el: HTMLElement, n: GridStackPosition): GridStack {\r\n if (n.x !== undefined && n.x !== null) { el.setAttribute('gs-x', String(n.x)); }\r\n if (n.y !== undefined && n.y !== null) { el.setAttribute('gs-y', String(n.y)); }\r\n if (n.w) { el.setAttribute('gs-w', String(n.w)); }\r\n if (n.h) { el.setAttribute('gs-h', String(n.h)); }\r\n return this;\r\n }\r\n\r\n /** @internal call to write any default attributes back to element */\r\n protected _writeAttr(el: HTMLElement, node: GridStackWidget): GridStack {\r\n if (!node) return this;\r\n this._writePosAttr(el, node);\r\n\r\n let attrs /*: GridStackWidget but strings */ = { // remaining attributes\r\n autoPosition: 'gs-auto-position',\r\n minW: 'gs-min-w',\r\n minH: 'gs-min-h',\r\n maxW: 'gs-max-w',\r\n maxH: 'gs-max-h',\r\n noResize: 'gs-no-resize',\r\n noMove: 'gs-no-move',\r\n locked: 'gs-locked',\r\n id: 'gs-id',\r\n resizeHandles: 'gs-resize-handles'\r\n };\r\n for (const key in attrs) {\r\n if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway\r\n el.setAttribute(attrs[key], String(node[key]));\r\n } else {\r\n el.removeAttribute(attrs[key]);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /** @internal call to read any default attributes from element */\r\n protected _readAttr(el: HTMLElement): GridStackWidget {\r\n let node: GridStackNode = {};\r\n node.x = Utils.toNumber(el.getAttribute('gs-x'));\r\n node.y = Utils.toNumber(el.getAttribute('gs-y'));\r\n node.w = Utils.toNumber(el.getAttribute('gs-w'));\r\n node.h = Utils.toNumber(el.getAttribute('gs-h'));\r\n node.maxW = Utils.toNumber(el.getAttribute('gs-max-w'));\r\n node.minW = Utils.toNumber(el.getAttribute('gs-min-w'));\r\n node.maxH = Utils.toNumber(el.getAttribute('gs-max-h'));\r\n node.minH = Utils.toNumber(el.getAttribute('gs-min-h'));\r\n node.autoPosition = Utils.toBool(el.getAttribute('gs-auto-position'));\r\n node.noResize = Utils.toBool(el.getAttribute('gs-no-resize'));\r\n node.noMove = Utils.toBool(el.getAttribute('gs-no-move'));\r\n node.locked = Utils.toBool(el.getAttribute('gs-locked'));\r\n node.resizeHandles = el.getAttribute('gs-resize-handles');\r\n node.id = el.getAttribute('gs-id');\r\n\r\n // remove any key not found (null or false which is default)\r\n for (const key in node) {\r\n if (!node.hasOwnProperty(key)) return;\r\n if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)\r\n delete node[key];\r\n }\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /** @internal */\r\n protected _setStaticClass(): GridStack {\r\n let classes = ['grid-stack-static'];\r\n\r\n if (this.opts.staticGrid) {\r\n this.el.classList.add(...classes);\r\n this.el.setAttribute('gs-static', 'true');\r\n } else {\r\n this.el.classList.remove(...classes);\r\n this.el.removeAttribute('gs-static');\r\n\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off\r\n * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)\r\n */\r\n public onParentResize(): GridStack {\r\n if (!this.el || !this.el.clientWidth) return; // return if we're gone or no size yet (will get called again)\r\n let changedColumn = false;\r\n\r\n // see if we're nested and take our column count from our parent....\r\n if (this._autoColumn && this.opts._isNested) {\r\n if (this.opts.column !== this.opts._isNested.w) {\r\n changedColumn = true;\r\n this.column(this.opts._isNested.w, 'none');\r\n }\r\n } else {\r\n // else check for 1 column in/out behavior\r\n let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;\r\n if ((this.opts.column === 1) !== oneColumn) {\r\n changedColumn = true;\r\n if (this.opts.animate) { this.setAnimation(false); } // 1 <-> 12 is too radical, turn off animation\r\n this.column(oneColumn ? 1 : this._prevColumn);\r\n if (this.opts.animate) { this.setAnimation(true); }\r\n }\r\n }\r\n\r\n // make the cells content square again\r\n if (this._isAutoCellHeight) {\r\n if (!changedColumn && this.opts.cellHeightThrottle) {\r\n if (!this._cellHeightThrottle) {\r\n this._cellHeightThrottle = Utils.throttle(() => this.cellHeight(), this.opts.cellHeightThrottle);\r\n }\r\n this._cellHeightThrottle();\r\n } else {\r\n // immediate update if we've changed column count or have no threshold\r\n this.cellHeight();\r\n }\r\n }\r\n\r\n // finally update any nested grids\r\n this.engine.nodes.forEach(n => {\r\n if (n.subGrid) {(n.subGrid as GridStack).onParentResize()}\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /** add or remove the window size event handler */\r\n protected _updateWindowResizeEvent(forceRemove = false): GridStack {\r\n // only add event if we're not nested (parent will call us) and we're auto sizing cells or supporting oneColumn (i.e. doing work)\r\n const workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested;\r\n\r\n if (!forceRemove && workTodo && !this._windowResizeBind) {\r\n this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later\r\n window.addEventListener('resize', this._windowResizeBind);\r\n } else if ((forceRemove || !workTodo) && this._windowResizeBind) {\r\n window.removeEventListener('resize', this._windowResizeBind);\r\n delete this._windowResizeBind; // remove link to us so we can free\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /** @internal convert a potential selector into actual element */\r\n public static getElement(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement { return Utils.getElement(els) }\r\n /** @internal */\r\n public static getElements(els: GridStackElement = '.grid-stack-item'): GridItemHTMLElement[] { return Utils.getElements(els) }\r\n /** @internal */\r\n public static getGridElement(els: GridStackElement): GridHTMLElement { return GridStack.getElement(els) }\r\n /** @internal */\r\n public static getGridElements(els: string): GridHTMLElement[] { return Utils.getElements(els) }\r\n\r\n /** @internal initialize margin top/bottom/left/right and units */\r\n protected _initMargin(): GridStack {\r\n\r\n let data: HeightData;\r\n let margin = 0;\r\n\r\n // support passing multiple values like CSS (ex: '5px 10px 0 20px')\r\n let margins: string[] = [];\r\n if (typeof this.opts.margin === 'string') {\r\n margins = this.opts.margin.split(' ')\r\n }\r\n if (margins.length === 2) { // top/bot, left/right like CSS\r\n this.opts.marginTop = this.opts.marginBottom = margins[0];\r\n this.opts.marginLeft = this.opts.marginRight = margins[1];\r\n } else if (margins.length === 4) { // Clockwise like CSS\r\n this.opts.marginTop = margins[0];\r\n this.opts.marginRight = margins[1];\r\n this.opts.marginBottom = margins[2];\r\n this.opts.marginLeft = margins[3];\r\n } else {\r\n data = Utils.parseHeight(this.opts.margin);\r\n this.opts.marginUnit = data.unit;\r\n margin = this.opts.margin = data.h;\r\n }\r\n\r\n // see if top/bottom/left/right need to be set as well\r\n if (this.opts.marginTop === undefined) {\r\n this.opts.marginTop = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginTop);\r\n this.opts.marginTop = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginBottom === undefined) {\r\n this.opts.marginBottom = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginBottom);\r\n this.opts.marginBottom = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginRight === undefined) {\r\n this.opts.marginRight = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginRight);\r\n this.opts.marginRight = data.h;\r\n delete this.opts.margin;\r\n }\r\n\r\n if (this.opts.marginLeft === undefined) {\r\n this.opts.marginLeft = margin;\r\n } else {\r\n data = Utils.parseHeight(this.opts.marginLeft);\r\n this.opts.marginLeft = data.h;\r\n delete this.opts.margin;\r\n }\r\n this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...\r\n if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {\r\n this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()\r\n }\r\n return this;\r\n }\r\n\r\n static GDRev = '6.0.1-dev';\r\n\r\n /*\r\n * drag&drop empty stubs that will be implemented in dd-gridstack.ts for non static grid\r\n * so we don't incur the load unless needed.\r\n * NOTE: had to make those methods public in order to define them else as\r\n * GridStack.prototype._setupAcceptWidget = function()\r\n * maybe there is a better way ????\r\n */\r\n /* eslint-disable @typescript-eslint/no-unused-vars */\r\n\r\n /**\r\n * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.\r\n * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar\r\n * is dynamically create and needs to change later.\r\n * @param dragIn string selector (ex: '.sidebar .grid-stack-item')\r\n * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}\r\n **/\r\n public static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void { /* implemented in dd-gridstack.ts */ }\r\n\r\n /**\r\n * Enables/Disables dragging by the user of specific grid element. If you want all items, and have it affect future items, use enableMove() instead. No-op for static grids.\r\n * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.\r\n * @param els widget or selector to modify.\r\n * @param val if true widget will be draggable.\r\n */\r\n public movable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Enables/Disables user resizing of specific grid element. If you want all items, and have it affect future items, use enableResize() instead. No-op for static grids.\r\n * @param els widget or selector to modify\r\n * @param val if true widget will be resizable.\r\n */\r\n public resizable(els: GridStackElement, val: boolean): GridStack { return this }\r\n /**\r\n * Temporarily disables widgets moving/resizing.\r\n * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.\r\n * Note: no-op for static grid\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(false);\r\n * grid.enableResize(false);\r\n */\r\n public disable(): GridStack { return this }\r\n /**\r\n * Re-enables widgets moving/resizing - see disable().\r\n * Note: no-op for static grid.\r\n * This is a shortcut for:\r\n * @example\r\n * grid.enableMove(true);\r\n * grid.enableResize(true);\r\n */\r\n public enable(): GridStack { return this }\r\n /**\r\n * Enables/disables widget moving. No-op for static grids.\r\n */\r\n public enableMove(doEnable: boolean): GridStack { return this }\r\n /**\r\n * Enables/disables widget resizing. No-op for static grids.\r\n */\r\n public enableResize(doEnable: boolean): GridStack { return this }\r\n\r\n /** @internal removes any drag&drop present (called during destroy) */\r\n public _removeDD(el: GridItemHTMLElement): GridStack { return this }\r\n /** @internal called to add drag over support to support widgets */\r\n public _setupAcceptWidget(): GridStack { return this }\r\n /** @internal called to setup a trash drop zone if the user specifies it */\r\n public _setupRemoveDrop(): GridStack { return this }\r\n /** @internal prepares the element for drag&drop **/\r\n public _prepareDragDropByNode(node: GridStackNode): GridStack { return this }\r\n /** @internal handles actual drag/resize start **/\r\n public _onStartMoving(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal handles actual drag/resize **/\r\n public _dragOrResize(el: GridItemHTMLElement, event: Event, ui: DDUIData, node: GridStackNode, cellWidth: number, cellHeight: number): void { return }\r\n /** @internal called when a node leaves our area (mouse out or shape outside) **/\r\n public _leave(el: GridItemHTMLElement, helper?: GridItemHTMLElement): void { return }\r\n // legacy method removed\r\n public commit(): GridStack { obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; }\r\n}\r\n\r\n/*\r\n * and include D&D by default, which override some methods here\r\n * TODO: while we can generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)\r\n * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts\r\n */\r\nimport { DDGridStack } from './dd-gridstack';\r\nimport { isTouch } from './dd-touch';\r\nexport * from './dd-gridstack';\r\n"]} \ No newline at end of file diff --git a/dist/gridstack.min.css b/dist/gridstack.min.css new file mode 100644 index 000000000..d2704af66 --- /dev/null +++ b/dist/gridstack.min.css @@ -0,0 +1 @@ +:root .grid-stack-item>.ui-resizable-handle{filter:none}.grid-stack{position:relative}.grid-stack.grid-stack-rtl{direction:ltr}.grid-stack.grid-stack-rtl>.grid-stack-item{direction:rtl}.grid-stack .grid-stack-placeholder>.placeholder-content{background-color:rgba(0,0,0,.1);margin:0;position:absolute;width:auto;z-index:0!important;text-align:center}.grid-stack>.grid-stack-item{min-width:8.3333333333%;position:absolute;padding:0}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;width:auto;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.grid-stack>.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack>.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack>.grid-stack-item>.ui-resizable-se,.grid-stack>.grid-stack-item>.ui-resizable-sw{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);background-repeat:no-repeat;background-position:center;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.grid-stack>.grid-stack-item>.ui-resizable-se{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.grid-stack>.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:0;left:25px;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item>.ui-resizable-se{cursor:se-resize;width:20px;height:20px}.grid-stack>.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:0;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px}.grid-stack>.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack>.grid-stack-item[gs-w="0"]{width:0%}.grid-stack>.grid-stack-item[gs-x="0"]{left:0}.grid-stack>.grid-stack-item[gs-min-w="0"]{min-width:0}.grid-stack>.grid-stack-item[gs-max-w="0"]{max-width:0%}.grid-stack>.grid-stack-item[gs-w="1"]{width:8.3333333333%}.grid-stack>.grid-stack-item[gs-x="1"]{left:8.3333333333%}.grid-stack>.grid-stack-item[gs-min-w="1"]{min-width:8.3333333333%}.grid-stack>.grid-stack-item[gs-max-w="1"]{max-width:8.3333333333%}.grid-stack>.grid-stack-item[gs-w="2"]{width:16.6666666667%}.grid-stack>.grid-stack-item[gs-x="2"]{left:16.6666666667%}.grid-stack>.grid-stack-item[gs-min-w="2"]{min-width:16.6666666667%}.grid-stack>.grid-stack-item[gs-max-w="2"]{max-width:16.6666666667%}.grid-stack>.grid-stack-item[gs-w="3"]{width:25%}.grid-stack>.grid-stack-item[gs-x="3"]{left:25%}.grid-stack>.grid-stack-item[gs-min-w="3"]{min-width:25%}.grid-stack>.grid-stack-item[gs-max-w="3"]{max-width:25%}.grid-stack>.grid-stack-item[gs-w="4"]{width:33.3333333333%}.grid-stack>.grid-stack-item[gs-x="4"]{left:33.3333333333%}.grid-stack>.grid-stack-item[gs-min-w="4"]{min-width:33.3333333333%}.grid-stack>.grid-stack-item[gs-max-w="4"]{max-width:33.3333333333%}.grid-stack>.grid-stack-item[gs-w="5"]{width:41.6666666667%}.grid-stack>.grid-stack-item[gs-x="5"]{left:41.6666666667%}.grid-stack>.grid-stack-item[gs-min-w="5"]{min-width:41.6666666667%}.grid-stack>.grid-stack-item[gs-max-w="5"]{max-width:41.6666666667%}.grid-stack>.grid-stack-item[gs-w="6"]{width:50%}.grid-stack>.grid-stack-item[gs-x="6"]{left:50%}.grid-stack>.grid-stack-item[gs-min-w="6"]{min-width:50%}.grid-stack>.grid-stack-item[gs-max-w="6"]{max-width:50%}.grid-stack>.grid-stack-item[gs-w="7"]{width:58.3333333333%}.grid-stack>.grid-stack-item[gs-x="7"]{left:58.3333333333%}.grid-stack>.grid-stack-item[gs-min-w="7"]{min-width:58.3333333333%}.grid-stack>.grid-stack-item[gs-max-w="7"]{max-width:58.3333333333%}.grid-stack>.grid-stack-item[gs-w="8"]{width:66.6666666667%}.grid-stack>.grid-stack-item[gs-x="8"]{left:66.6666666667%}.grid-stack>.grid-stack-item[gs-min-w="8"]{min-width:66.6666666667%}.grid-stack>.grid-stack-item[gs-max-w="8"]{max-width:66.6666666667%}.grid-stack>.grid-stack-item[gs-w="9"]{width:75%}.grid-stack>.grid-stack-item[gs-x="9"]{left:75%}.grid-stack>.grid-stack-item[gs-min-w="9"]{min-width:75%}.grid-stack>.grid-stack-item[gs-max-w="9"]{max-width:75%}.grid-stack>.grid-stack-item[gs-w="10"]{width:83.3333333333%}.grid-stack>.grid-stack-item[gs-x="10"]{left:83.3333333333%}.grid-stack>.grid-stack-item[gs-min-w="10"]{min-width:83.3333333333%}.grid-stack>.grid-stack-item[gs-max-w="10"]{max-width:83.3333333333%}.grid-stack>.grid-stack-item[gs-w="11"]{width:91.6666666667%}.grid-stack>.grid-stack-item[gs-x="11"]{left:91.6666666667%}.grid-stack>.grid-stack-item[gs-min-w="11"]{min-width:91.6666666667%}.grid-stack>.grid-stack-item[gs-max-w="11"]{max-width:91.6666666667%}.grid-stack>.grid-stack-item[gs-w="12"]{width:100%}.grid-stack>.grid-stack-item[gs-x="12"]{left:100%}.grid-stack>.grid-stack-item[gs-min-w="12"]{min-width:100%}.grid-stack>.grid-stack-item[gs-max-w="12"]{max-width:100%}.grid-stack.grid-stack-1>.grid-stack-item{min-width:100%}.grid-stack.grid-stack-1>.grid-stack-item[gs-w="1"]{width:100%}.grid-stack.grid-stack-1>.grid-stack-item[gs-x="1"]{left:100%}.grid-stack.grid-stack-1>.grid-stack-item[gs-min-w="1"]{min-width:100%}.grid-stack.grid-stack-1>.grid-stack-item[gs-max-w="1"]{max-width:100%}.grid-stack.grid-stack-animate,.grid-stack.grid-stack-animate .grid-stack-item{-webkit-transition:left .3s,top .3s,height .3s,width .3s;-moz-transition:left .3s,top .3s,height .3s,width .3s;-ms-transition:left .3s,top .3s,height .3s,width .3s;-o-transition:left .3s,top .3s,height .3s,width .3s;transition:left .3s,top .3s,height .3s,width .3s}.grid-stack.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack.grid-stack-animate .grid-stack-item.ui-resizable-resizing{-webkit-transition:left 0s,top 0s,height 0s,width 0s;-moz-transition:left 0s,top 0s,height 0s,width 0s;-ms-transition:left 0s,top 0s,height 0s,width 0s;-o-transition:left 0s,top 0s,height 0s,width 0s;transition:left 0s,top 0s,height 0s,width 0s}.ui-draggable-dragging,.ui-resizable-resizing{z-index:100}.ui-draggable-dragging>.grid-stack-item-content,.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px rgba(0,0,0,.2);opacity:.8}.ui-draggable-dragging{will-change:left,top;cursor:move}.ui-resizable-resizing{will-change:width,height} \ No newline at end of file diff --git a/dist/src/gridstack-extra.scss b/dist/src/gridstack-extra.scss new file mode 100644 index 000000000..cc9620d4d --- /dev/null +++ b/dist/src/gridstack-extra.scss @@ -0,0 +1,29 @@ +/** + * default to generate [2-11] columns as 1 (oneColumnMode) and 12 (default) are in the main css + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ + +@use "sass:math"; + +$gridstack-columns-start: 2 !default; +$gridstack-columns: 11 !default; + +@mixin grid-stack-items($columns) { + .grid-stack.grid-stack-#{$columns} { + + > .grid-stack-item { + min-width: math.div(100%, $columns); + + @for $i from 1 through $columns { + &[gs-w='#{$i}'] { width: math.div(100%, $columns) * $i; } + &[gs-x='#{$i}'] { left: math.div(100%, $columns) * $i; } + &[gs-min-w='#{$i}'] { min-width: math.div(100%, $columns) * $i; } + &[gs-max-w='#{$i}'] { max-width: math.div(100%, $columns) * $i; } + } + } + } +} + +@for $j from $gridstack-columns-start through $gridstack-columns { + @include grid-stack-items($j) +} diff --git a/dist/src/gridstack.scss b/dist/src/gridstack.scss new file mode 100644 index 000000000..cf35bc0f9 --- /dev/null +++ b/dist/src/gridstack.scss @@ -0,0 +1,140 @@ +/** + * gridstack SASS styles 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ + +@use "sass:math"; + +$gridstack-columns: 12 !default; +$animation_speed: .3s !default; + +@mixin vendor($property, $value...){ + -webkit-#{$property}: $value; + -moz-#{$property}: $value; + -ms-#{$property}: $value; + -o-#{$property}: $value; + #{$property}: $value; +} + +:root .grid-stack-item > .ui-resizable-handle { filter: none; } + +.grid-stack { + position: relative; + + &.grid-stack-rtl { + direction: ltr; + > .grid-stack-item { + direction: rtl; + } + } + + .grid-stack-placeholder > .placeholder-content { + background-color: rgba(0,0,0,0.1); + margin: 0; + position: absolute; + width: auto; + z-index: 0 !important; + text-align: center; + } + + > .grid-stack-item { + min-width: math.div(100%, $gridstack-columns); + position: absolute; + padding: 0; + + > .grid-stack-item-content { + margin: 0; + position: absolute; + width: auto; + overflow-x: hidden; + overflow-y: auto; + } + + > .ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; + } + + &.ui-resizable-disabled > .ui-resizable-handle, + &.ui-resizable-autohide > .ui-resizable-handle { display: none; } + + > .ui-resizable-se, + > .ui-resizable-sw { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); + background-repeat: no-repeat; + background-position: center; + @include vendor(transform, rotate(45deg)); + } + + > .ui-resizable-se { + @include vendor(transform, rotate(-45deg)); + } + + > .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; top: 0; } + > .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; } + > .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; top: 0; } + > .ui-resizable-e { cursor: e-resize; width: 10px; top: 15px; bottom: 15px; } + > .ui-resizable-se { cursor: se-resize; width: 20px; height: 20px;} + > .ui-resizable-s { cursor: s-resize; height: 10px; left: 25px; bottom: 0; right: 25px; } + > .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px;} + > .ui-resizable-w { cursor: w-resize; width: 10px; top: 15px; bottom: 15px; } + + &.ui-draggable-dragging { + &> .ui-resizable-handle { + display: none !important; + } + } + + @for $i from 0 through $gridstack-columns { + &[gs-w='#{$i}'] { width: math.div(100%, $gridstack-columns) * $i; } + &[gs-x='#{$i}'] { left: math.div(100%, $gridstack-columns) * $i; } + &[gs-min-w='#{$i}'] { min-width: math.div(100%, $gridstack-columns) * $i; } + &[gs-max-w='#{$i}'] { max-width: math.div(100%, $gridstack-columns) * $i; } + } + } + + &.grid-stack-1>.grid-stack-item { + min-width: 100%; + &[gs-w='1'] { width: 100%; } + &[gs-x='1'] { left: 100%; } + &[gs-min-w='1'] { min-width: 100%; } + &[gs-max-w='1'] { max-width: 100%; } + } + + &.grid-stack-animate, + &.grid-stack-animate .grid-stack-item { + @include vendor(transition, left $animation_speed, top $animation_speed, height $animation_speed, width $animation_speed); + } + + &.grid-stack-animate .grid-stack-item.ui-draggable-dragging, + &.grid-stack-animate .grid-stack-item.ui-resizable-resizing, + &.grid-stack-animate .grid-stack-item.grid-stack-placeholder{ + @include vendor(transition, left .0s, top .0s, height .0s, width .0s); + } + + // without this, the html5 drag will flicker between no-drop and drop when dragging over second grid + // Update: removed that as it causes nested grids to no receive dragenter events when parent drags and sets this for #992. not seeing cursor flicker (chrome). + // &.ui-droppable.ui-droppable-over > *:not(.ui-droppable) { + // pointer-events: none; + // } +} + +.ui-draggable-dragging, +.ui-resizable-resizing { + z-index: 100; + + > .grid-stack-item-content { + box-shadow: 1px 4px 6px rgba(0, 0, 0, 0.2); + opacity: 0.8; + } +} +.ui-draggable-dragging { + will-change: left, top; + cursor: move; +} +.ui-resizable-resizing { + will-change: width, height; +} \ No newline at end of file diff --git a/dist/types.d.ts b/dist/types.d.ts new file mode 100644 index 000000000..e7f857d37 --- /dev/null +++ b/dist/types.d.ts @@ -0,0 +1,262 @@ +/** + * types.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridStack } from './gridstack'; +import { GridStackEngine } from './gridstack-engine'; +/** different layout options when changing # of columns, + * including a custom function that takes new/old column count, and array of new/old positions + * Note: new list may be partially already filled if we have a cache of the layout at that size and new items were added later. + */ +export declare type ColumnOptions = 'moveScale' | 'move' | 'scale' | 'none' | ((column: number, oldColumn: number, nodes: GridStackNode[], oldNodes: GridStackNode[]) => void); +export declare type numberOrString = number | string; +export interface GridItemHTMLElement extends HTMLElement { + /** pointer to grid node instance */ + gridstackNode?: GridStackNode; +} +export declare type GridStackElement = string | HTMLElement | GridItemHTMLElement; +export declare type GridStackEventHandlerCallback = (event: Event, arg2?: GridItemHTMLElement | GridStackNode | GridStackNode[], newNode?: GridStackNode) => void; +/** + * Defines the options for a Grid + */ +export interface GridStackOptions { + /** + * accept widgets dragged from other grids or from outside (default: `false`). Can be: + * `true` (uses `'.grid-stack-item'` class filter) or `false`, + * string for explicit class name, + * function returning a boolean. See [example](http://gridstack.github.io/gridstack.js/demo/two.html) + */ + acceptWidgets?: boolean | string | ((element: Element) => boolean); + /** possible values (default: `mobile`) - does not apply to non-resizable widgets + * `false` the resizing handles are only shown while hovering over a widget + * `true` the resizing handles are always shown + * 'mobile' if running on a mobile device, default to `true` (since there is no hovering per say), else `false`. + * this uses this condition on browser agent check: + `alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent )` + See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html) */ + alwaysShowResizeHandle?: true | false | 'mobile'; + /** turns animation on (default?: true) */ + animate?: boolean; + /** if false gridstack will not initialize existing items (default?: true) */ + auto?: boolean; + /** + * one cell height (default?: 'auto'). Can be: + * an integer (px) + * a string (ex: '100px', '10em', '10rem'). Note: % doesn't right - see demo/cell-height.html + * 0, in which case the library will not generate styles for rows. Everything must be defined in your own CSS files. + * 'auto' - height will be calculated for square cells (width / column) and updated live as you resize the window - also see `cellHeightThrottle` + * 'initial' - similar to 'auto' (start at square cells) but stay that size during window resizing. + */ + cellHeight?: numberOrString; + /** throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100). + * A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event! + * */ + cellHeightThrottle?: number; + /** (internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem') */ + cellHeightUnit?: string; + /** list of children item to create when calling load() or addGrid() */ + children?: GridStackWidget[]; + /** number of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns. + * Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside + * items always to same. flag is not supported for regular non-nested grids. + */ + column?: number | 'auto'; + /** additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance. + Note: only used by addGrid(), else your element should have the needed class */ + class?: string; + /** disallows dragging of widgets (default?: false) */ + disableDrag?: boolean; + /** disables the onColumnMode when the grid width is less than oneColumnSize (default?: false) */ + disableOneColumnMode?: boolean; + /** disallows resizing of widgets (default?: false). */ + disableResize?: boolean; + /** allows to override UI draggable options. (default?: { handle?: '.grid-stack-item-content', appendTo?: 'body' }) */ + draggable?: DDDragOpt; + /** allows to drag external items using this selector - see dragInOptions. (default: undefined) */ + dragIn?: string; + /** allows to drag external items using these options. See `GridStack.setupDragIn()` instead (not per grid really). + * (default?: { handle: '.grid-stack-item-content', appendTo: 'body' }) + * helper can be 'clone' or your own function (set what the drag/dropped item will be instead) + */ + dragInOptions?: DDDragInOpt; + /** let user drag nested grid items out of a parent or not (default true - not supported yet) */ + /** the type of engine to create (so you can subclass) default to GridStackEngine */ + engineClass?: typeof GridStackEngine; + /** enable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html) */ + float?: boolean; + /** draggable handle selector (default?: '.grid-stack-item-content') */ + handle?: string; + /** draggable handle class (e.g. 'grid-stack-item-content'). If set 'handle' is ignored (default?: null) */ + handleClass?: string; + /** id used to debug grid instance, not currently stored in DOM attributes */ + id?: numberOrString; + /** additional widget class (default?: 'grid-stack-item') */ + itemClass?: string; + /** + * gap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below + * an integer (px) + * a string with possible units (ex: '2em', '20px', '2rem') + * string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS). + * Note: all sides must have same units (last one wins, default px) + */ + margin?: numberOrString; + /** OLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side. */ + marginTop?: numberOrString; + marginRight?: numberOrString; + marginBottom?: numberOrString; + marginLeft?: numberOrString; + /** (internal) unit for margin (default? 'px') set when `margin` is set as string with unit (ex: 2rem') */ + marginUnit?: string; + /** maximum rows amount. Default? is 0 which means no maximum rows */ + maxRow?: number; + /** minimum rows amount. Default is `0`. You can also do this with `min-height` CSS attribute + * on the grid div in pixels, which will round to the closest row. + */ + minRow?: number; + /** minimal width before grid will be shown in one column mode (default?: 768) */ + oneColumnSize?: number; + /** + * set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column + * layouts during sorting. This enables you to have custom 1 column layout that differ from the rest. (default?: false) + */ + oneColumnModeDomSort?: boolean; + /** class for placeholder (default?: 'grid-stack-placeholder') */ + placeholderClass?: string; + /** placeholder default content (default?: '') */ + placeholderText?: string; + /** allows to override UI resizable options. (default?: { handles: 'se' }) */ + resizable?: DDResizeOpt; + /** + * if true widgets could be removed by dragging outside of the grid. It could also be a selector string (ex: ".trash"), + * in this case widgets will be removed by dropping them there (default?: false) + * See example (http://gridstack.github.io/gridstack.js/demo/two.html) + */ + removable?: boolean | string; + /** allows to override UI removable options. (default?: { accept: '.grid-stack-item' }) */ + removableOptions?: DDRemoveOpt; + /** fix grid number of rows. This is a shortcut of writing `minRow:N, maxRow:N`. (default `0` no constrain) */ + row?: number; + /** + * if true turns grid to RTL. Possible values are true, false, 'auto' (default?: 'auto') + * See [example](http://gridstack.github.io/gridstack.js/demo/rtl.html) + */ + rtl?: boolean | 'auto'; + /** + * makes grid static (default?: false). If `true` widgets are not movable/resizable. + * You don't even need draggable/resizable. A CSS class + * 'grid-stack-static' is also added to the element. + */ + staticGrid?: boolean; + /** if `true` will add style element to `` otherwise will add it to element's parent node (default `false`). */ + styleInHead?: boolean; +} +/** options used during GridStackEngine.moveNode() */ +export interface GridStackMoveOpts extends GridStackPosition { + /** node to skip collision */ + skip?: GridStackNode; + /** do we pack (default true) */ + pack?: boolean; + /** true if we are calling this recursively to prevent simple swap or coverage collision - default false*/ + nested?: boolean; + /** vars to calculate other cells coordinates */ + cellWidth?: number; + cellHeight?: number; + marginTop?: number; + marginBottom?: number; + marginLeft?: number; + marginRight?: number; + /** position in pixels of the currently dragged items (for overlap check) */ + rect?: GridStackPosition; + /** true if we're live resizing */ + resizing?: boolean; +} +export interface GridStackPosition { + /** widget position x (default?: 0) */ + x?: number; + /** widget position y (default?: 0) */ + y?: number; + /** widget dimension width (default?: 1) */ + w?: number; + /** widget dimension height (default?: 1) */ + h?: number; +} +/** + * GridStack Widget creation options + */ +export interface GridStackWidget extends GridStackPosition { + /** if true then x, y parameters will be ignored and widget will be places on the first available position (default?: false) */ + autoPosition?: boolean; + /** minimum width allowed during resize/creation (default?: undefined = un-constrained) */ + minW?: number; + /** maximum width allowed during resize/creation (default?: undefined = un-constrained) */ + maxW?: number; + /** minimum height allowed during resize/creation (default?: undefined = un-constrained) */ + minH?: number; + /** maximum height allowed during resize/creation (default?: undefined = un-constrained) */ + maxH?: number; + /** prevent resizing (default?: undefined = un-constrained) */ + noResize?: boolean; + /** prevents moving (default?: undefined = un-constrained) */ + noMove?: boolean; + /** prevents being moved by others during their (default?: undefined = un-constrained) */ + locked?: boolean; + /** widgets can have their own custom resize handles. For example 'e,w' will make that particular widget only resize east and west. See `resizable: {handles: string}` option */ + resizeHandles?: string; + /** value for `gs-id` stored on the widget (default?: undefined) */ + id?: numberOrString; + /** html to append inside as content */ + content?: string; + /** optional nested grid options and list of children, which then turns into actual instance at runtime */ + subGrid?: GridStackOptions | GridStack; +} +/** Drag&Drop resize options */ +export interface DDResizeOpt { + /** do resize handle hide by default until mouse over ? - default: true on desktop, false on mobile*/ + autoHide?: boolean; + /** + * sides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east) + * Note: it is not recommended to resize from the top sides as weird side effect may occur. + */ + handles?: string; +} +/** Drag&Drop remove options */ +export interface DDRemoveOpt { + /** class that can be removed (default?: '.' + opts.itemClass) */ + accept?: string; +} +/** Drag&Drop dragging options */ +export interface DDDragOpt { + /** class selector of items that can be dragged. default to '.grid-stack-item-content' */ + handle?: string; + /** default to 'body' */ + appendTo?: string; +} +export interface DDDragInOpt extends DDDragOpt { + /** used when dragging item from the outside, and canceling (ex: 'invalid' or your own method)*/ + /** helper function when dropping (ex: 'clone' or your own method) */ + helper?: string | ((event: Event) => HTMLElement); +} +export interface Size { + width: number; + height: number; +} +export interface Position { + top: number; + left: number; +} +export interface Rect extends Size, Position { +} +/** data that is passed during drag and resizing callbacks */ +export interface DDUIData { + position?: Position; + size?: Size; +} +/** + * internal descriptions describing the items in the grid + */ +export interface GridStackNode extends GridStackWidget { + /** pointer back to HTML element */ + el?: GridItemHTMLElement; + /** pointer back to Grid instance */ + grid?: GridStack; +} diff --git a/dist/types.js b/dist/types.js new file mode 100644 index 000000000..86d8af4a8 --- /dev/null +++ b/dist/types.js @@ -0,0 +1,7 @@ +"use strict"; +/** + * types.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/types.js.map b/dist/types.js.map new file mode 100644 index 000000000..8d44903fd --- /dev/null +++ b/dist/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\r\n * types.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStack } from './gridstack';\r\nimport { GridStackEngine } from './gridstack-engine';\r\n\r\n\r\n/** different layout options when changing # of columns,\r\n * including a custom function that takes new/old column count, and array of new/old positions\r\n * Note: new list may be partially already filled if we have a cache of the layout at that size and new items were added later.\r\n */\r\nexport type ColumnOptions = 'moveScale' | 'move' | 'scale' | 'none' |\r\n ((column: number, oldColumn: number, nodes: GridStackNode[], oldNodes: GridStackNode[]) => void);\r\n\r\nexport type numberOrString = number | string;\r\nexport interface GridItemHTMLElement extends HTMLElement {\r\n /** pointer to grid node instance */\r\n gridstackNode?: GridStackNode;\r\n /** @internal */\r\n _gridstackNodeOrig?: GridStackNode;\r\n}\r\n\r\nexport type GridStackElement = string | HTMLElement | GridItemHTMLElement;\r\n\r\nexport type GridStackEventHandlerCallback = (event: Event, arg2?: GridItemHTMLElement | GridStackNode | GridStackNode[], newNode?: GridStackNode) => void;\r\n\r\n/**\r\n * Defines the options for a Grid\r\n */\r\nexport interface GridStackOptions {\r\n /**\r\n * accept widgets dragged from other grids or from outside (default: `false`). Can be:\r\n * `true` (uses `'.grid-stack-item'` class filter) or `false`,\r\n * string for explicit class name,\r\n * function returning a boolean. See [example](http://gridstack.github.io/gridstack.js/demo/two.html)\r\n */\r\n acceptWidgets?: boolean | string | ((element: Element) => boolean);\r\n\r\n /** possible values (default: `mobile`) - does not apply to non-resizable widgets\r\n * `false` the resizing handles are only shown while hovering over a widget\r\n * `true` the resizing handles are always shown\r\n * 'mobile' if running on a mobile device, default to `true` (since there is no hovering per say), else `false`.\r\n * this uses this condition on browser agent check:\r\n `alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent )`\r\n See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html) */\r\n alwaysShowResizeHandle?: true | false | 'mobile';\r\n\r\n /** turns animation on (default?: true) */\r\n animate?: boolean;\r\n\r\n /** if false gridstack will not initialize existing items (default?: true) */\r\n auto?: boolean;\r\n\r\n /**\r\n * one cell height (default?: 'auto'). Can be:\r\n * an integer (px)\r\n * a string (ex: '100px', '10em', '10rem'). Note: % doesn't right - see demo/cell-height.html\r\n * 0, in which case the library will not generate styles for rows. Everything must be defined in your own CSS files.\r\n * 'auto' - height will be calculated for square cells (width / column) and updated live as you resize the window - also see `cellHeightThrottle`\r\n * 'initial' - similar to 'auto' (start at square cells) but stay that size during window resizing.\r\n */\r\n cellHeight?: numberOrString;\r\n\r\n /** throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100).\r\n * A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event!\r\n * */\r\n cellHeightThrottle?: number;\r\n\r\n /** (internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem') */\r\n cellHeightUnit?: string;\r\n\r\n /** list of children item to create when calling load() or addGrid() */\r\n children?: GridStackWidget[];\r\n\r\n /** number of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns.\r\n * Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside\r\n * items always to same. flag is not supported for regular non-nested grids.\r\n */\r\n column?: number | 'auto';\r\n\r\n /** additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance.\r\n Note: only used by addGrid(), else your element should have the needed class */\r\n class?: string;\r\n\r\n /** disallows dragging of widgets (default?: false) */\r\n disableDrag?: boolean;\r\n\r\n /** disables the onColumnMode when the grid width is less than oneColumnSize (default?: false) */\r\n disableOneColumnMode?: boolean;\r\n\r\n /** disallows resizing of widgets (default?: false). */\r\n disableResize?: boolean;\r\n\r\n /** allows to override UI draggable options. (default?: { handle?: '.grid-stack-item-content', appendTo?: 'body' }) */\r\n draggable?: DDDragOpt;\r\n\r\n /** allows to drag external items using this selector - see dragInOptions. (default: undefined) */\r\n dragIn?: string;\r\n\r\n /** allows to drag external items using these options. See `GridStack.setupDragIn()` instead (not per grid really).\r\n * (default?: { handle: '.grid-stack-item-content', appendTo: 'body' })\r\n * helper can be 'clone' or your own function (set what the drag/dropped item will be instead)\r\n */\r\n dragInOptions?: DDDragInOpt;\r\n\r\n /** let user drag nested grid items out of a parent or not (default true - not supported yet) */\r\n //dragOut?: boolean;\r\n\r\n /** the type of engine to create (so you can subclass) default to GridStackEngine */\r\n engineClass?: typeof GridStackEngine;\r\n\r\n /** enable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html) */\r\n float?: boolean;\r\n\r\n /** draggable handle selector (default?: '.grid-stack-item-content') */\r\n handle?: string;\r\n\r\n /** draggable handle class (e.g. 'grid-stack-item-content'). If set 'handle' is ignored (default?: null) */\r\n handleClass?: string;\r\n\r\n /** id used to debug grid instance, not currently stored in DOM attributes */\r\n id?: numberOrString;\r\n\r\n /** additional widget class (default?: 'grid-stack-item') */\r\n itemClass?: string;\r\n\r\n /**\r\n * gap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below\r\n * an integer (px)\r\n * a string with possible units (ex: '2em', '20px', '2rem')\r\n * string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS).\r\n * Note: all sides must have same units (last one wins, default px)\r\n */\r\n margin?: numberOrString;\r\n\r\n /** OLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side. */\r\n marginTop?: numberOrString;\r\n marginRight?: numberOrString;\r\n marginBottom?: numberOrString;\r\n marginLeft?: numberOrString;\r\n\r\n /** (internal) unit for margin (default? 'px') set when `margin` is set as string with unit (ex: 2rem') */\r\n marginUnit?: string;\r\n\r\n /** maximum rows amount. Default? is 0 which means no maximum rows */\r\n maxRow?: number;\r\n\r\n /** minimum rows amount. Default is `0`. You can also do this with `min-height` CSS attribute\r\n * on the grid div in pixels, which will round to the closest row.\r\n */\r\n minRow?: number;\r\n\r\n /** minimal width before grid will be shown in one column mode (default?: 768) */\r\n oneColumnSize?: number;\r\n\r\n /**\r\n * set to true if you want oneColumnMode to use the DOM order and ignore x,y from normal multi column\r\n * layouts during sorting. This enables you to have custom 1 column layout that differ from the rest. (default?: false)\r\n */\r\n oneColumnModeDomSort?: boolean;\r\n\r\n /** class for placeholder (default?: 'grid-stack-placeholder') */\r\n placeholderClass?: string;\r\n\r\n /** placeholder default content (default?: '') */\r\n placeholderText?: string;\r\n\r\n /** allows to override UI resizable options. (default?: { handles: 'se' }) */\r\n resizable?: DDResizeOpt;\r\n\r\n /**\r\n * if true widgets could be removed by dragging outside of the grid. It could also be a selector string (ex: \".trash\"),\r\n * in this case widgets will be removed by dropping them there (default?: false)\r\n * See example (http://gridstack.github.io/gridstack.js/demo/two.html)\r\n */\r\n removable?: boolean | string;\r\n\r\n /** allows to override UI removable options. (default?: { accept: '.grid-stack-item' }) */\r\n removableOptions?: DDRemoveOpt;\r\n\r\n /** fix grid number of rows. This is a shortcut of writing `minRow:N, maxRow:N`. (default `0` no constrain) */\r\n row?: number;\r\n\r\n /**\r\n * if true turns grid to RTL. Possible values are true, false, 'auto' (default?: 'auto')\r\n * See [example](http://gridstack.github.io/gridstack.js/demo/rtl.html)\r\n */\r\n rtl?: boolean | 'auto';\r\n\r\n /**\r\n * makes grid static (default?: false). If `true` widgets are not movable/resizable.\r\n * You don't even need draggable/resizable. A CSS class\r\n * 'grid-stack-static' is also added to the element.\r\n */\r\n staticGrid?: boolean;\r\n\r\n /** if `true` will add style element to `` otherwise will add it to element's parent node (default `false`). */\r\n styleInHead?: boolean;\r\n\r\n /** @internal point to a parent grid item if we're nested */\r\n _isNested?: GridStackNode;\r\n /** @internal unique class name for our generated CSS style sheet */\r\n _styleSheetClass?: string;\r\n}\r\n\r\n/** options used during GridStackEngine.moveNode() */\r\nexport interface GridStackMoveOpts extends GridStackPosition {\r\n /** node to skip collision */\r\n skip?: GridStackNode;\r\n /** do we pack (default true) */\r\n pack?: boolean;\r\n /** true if we are calling this recursively to prevent simple swap or coverage collision - default false*/\r\n nested?: boolean;\r\n /** vars to calculate other cells coordinates */\r\n cellWidth?: number;\r\n cellHeight?: number;\r\n marginTop?: number;\r\n marginBottom?: number;\r\n marginLeft?: number;\r\n marginRight?: number;\r\n /** position in pixels of the currently dragged items (for overlap check) */\r\n rect?: GridStackPosition;\r\n /** true if we're live resizing */\r\n resizing?: boolean;\r\n}\r\n\r\nexport interface GridStackPosition {\r\n /** widget position x (default?: 0) */\r\n x?: number;\r\n /** widget position y (default?: 0) */\r\n y?: number;\r\n /** widget dimension width (default?: 1) */\r\n w?: number;\r\n /** widget dimension height (default?: 1) */\r\n h?: number;\r\n}\r\n\r\n/**\r\n * GridStack Widget creation options\r\n */\r\nexport interface GridStackWidget extends GridStackPosition {\r\n /** if true then x, y parameters will be ignored and widget will be places on the first available position (default?: false) */\r\n autoPosition?: boolean;\r\n /** minimum width allowed during resize/creation (default?: undefined = un-constrained) */\r\n minW?: number;\r\n /** maximum width allowed during resize/creation (default?: undefined = un-constrained) */\r\n maxW?: number;\r\n /** minimum height allowed during resize/creation (default?: undefined = un-constrained) */\r\n minH?: number;\r\n /** maximum height allowed during resize/creation (default?: undefined = un-constrained) */\r\n maxH?: number;\r\n /** prevent resizing (default?: undefined = un-constrained) */\r\n noResize?: boolean;\r\n /** prevents moving (default?: undefined = un-constrained) */\r\n noMove?: boolean;\r\n /** prevents being moved by others during their (default?: undefined = un-constrained) */\r\n locked?: boolean;\r\n /** widgets can have their own custom resize handles. For example 'e,w' will make that particular widget only resize east and west. See `resizable: {handles: string}` option */\r\n resizeHandles?: string;\r\n /** value for `gs-id` stored on the widget (default?: undefined) */\r\n id?: numberOrString;\r\n /** html to append inside as content */\r\n content?: string;\r\n /** optional nested grid options and list of children, which then turns into actual instance at runtime */\r\n subGrid?: GridStackOptions | GridStack;\r\n}\r\n\r\n/** Drag&Drop resize options */\r\nexport interface DDResizeOpt {\r\n /** do resize handle hide by default until mouse over ? - default: true on desktop, false on mobile*/\r\n autoHide?: boolean;\r\n /**\r\n * sides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east)\r\n * Note: it is not recommended to resize from the top sides as weird side effect may occur.\r\n */\r\n handles?: string;\r\n}\r\n\r\n/** Drag&Drop remove options */\r\nexport interface DDRemoveOpt {\r\n /** class that can be removed (default?: '.' + opts.itemClass) */\r\n accept?: string;\r\n}\r\n\r\n/** Drag&Drop dragging options */\r\nexport interface DDDragOpt {\r\n /** class selector of items that can be dragged. default to '.grid-stack-item-content' */\r\n handle?: string;\r\n /** default to 'body' */\r\n appendTo?: string;\r\n /** default to `true` */\r\n // scroll?: boolean;\r\n /** parent constraining where item can be dragged out from (default: null = no constrain) */\r\n // containment?: string;\r\n}\r\nexport interface DDDragInOpt extends DDDragOpt {\r\n /** used when dragging item from the outside, and canceling (ex: 'invalid' or your own method)*/\r\n // revert?: string | ((event: Event) => HTMLElement);\r\n /** helper function when dropping (ex: 'clone' or your own method) */\r\n helper?: string | ((event: Event) => HTMLElement);\r\n}\r\n\r\nexport interface Size {\r\n width: number;\r\n height: number;\r\n}\r\nexport interface Position {\r\n top: number;\r\n left: number;\r\n}\r\nexport interface Rect extends Size, Position {}\r\n\r\n/** data that is passed during drag and resizing callbacks */\r\nexport interface DDUIData {\r\n position?: Position;\r\n size?: Size;\r\n /* fields not used by GridStack but sent by jq ? leave in case we go back to them...\r\n originalPosition? : Position;\r\n offset?: Position;\r\n originalSize?: Size;\r\n element?: HTMLElement[];\r\n helper?: HTMLElement[];\r\n originalElement?: HTMLElement[];\r\n */\r\n}\r\n\r\n/**\r\n * internal descriptions describing the items in the grid\r\n */\r\nexport interface GridStackNode extends GridStackWidget {\r\n /** pointer back to HTML element */\r\n el?: GridItemHTMLElement;\r\n /** pointer back to Grid instance */\r\n grid?: GridStack;\r\n /** @internal internal id used to match when cloning engines or saving column layouts */\r\n _id?: number;\r\n /** @internal */\r\n _dirty?: boolean;\r\n /** @internal */\r\n _updating?: boolean;\r\n /** @internal true when over trash/another grid so we don't bother removing drag CSS style that would animate back to old position */\r\n _isAboutToRemove?: boolean;\r\n /** @internal true if item came from outside of the grid -> actual item need to be moved over */\r\n _isExternal?: boolean;\r\n /** @internal moving vs resizing */\r\n _moving?: boolean;\r\n /** @internal true if we jumped down past item below (one time jump so we don't have to totally pass it) */\r\n _skipDown?: boolean;\r\n /** @internal original values before a drag/size */\r\n _orig?: GridStackPosition;\r\n /** @internal position in pixels used during collision check */\r\n _rect?: GridStackPosition;\r\n /** @internal top/left pixel location before a drag so we can detect direction of move from last position*/\r\n _lastUiPosition?: Position;\r\n /** @internal set on the item being dragged/resized remember the last positions we've tried (but failed) so we don't try again during drag/resize */\r\n _lastTried?: GridStackPosition;\r\n /** @internal position willItFit() will use to position the item */\r\n _willFitPos?: GridStackPosition;\r\n /** @internal last drag Y pixel position used to incrementally update V scroll bar */\r\n _prevYPix?: number;\r\n /** @internal true if we've remove the item from ourself (dragging out) but might revert it back (release on nothing -> goes back) */\r\n _temporaryRemoved?: boolean;\r\n /** @internal true if we should remove DOM element on _notify() rather than clearing _id (old way) */\r\n _removeDOM?: boolean;\r\n /** @internal */\r\n _initDD?: boolean;\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/utils.d.ts b/dist/utils.d.ts new file mode 100644 index 000000000..be71753ad --- /dev/null +++ b/dist/utils.d.ts @@ -0,0 +1,83 @@ +/** + * utils.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +import { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types'; +export interface HeightData { + h: number; + unit: string; +} +/** checks for obsolete method names */ +export declare function obsolete(self: any, f: any, oldName: string, newName: string, rev: string): (...args: any[]) => any; +/** checks for obsolete grid options (can be used for any fields, but msg is about options) */ +export declare function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void; +/** checks for obsolete grid options which are gone */ +export declare function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void; +/** checks for obsolete Jquery element attributes */ +export declare function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void; +/** + * Utility methods + */ +export declare class Utils { + /** convert a potential selector into actual list of html elements */ + static getElements(els: GridStackElement): HTMLElement[]; + /** convert a potential selector into actual single element */ + static getElement(els: GridStackElement): HTMLElement; + /** returns true if a and b overlap */ + static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean; + /** returns true if a and b touch edges or corners */ + static isTouching(a: GridStackPosition, b: GridStackPosition): boolean; + /** + * Sorts array of nodes + * @param nodes array to sort + * @param dir 1 for asc, -1 for desc (optional) + * @param width width of the grid. If undefined the width will be calculated automatically (optional). + **/ + static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[]; + /** + * creates a style sheet with style id under given parent + * @param id will set the 'gs-style-id' attribute to that id + * @param parent to insert the stylesheet as first child, + * if none supplied it will be appended to the document head instead. + */ + static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet; + /** removed the given stylesheet id */ + static removeStylesheet(id: string): void; + /** inserts a CSS rule */ + static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void; + static toBool(v: unknown): boolean; + static toNumber(value: null | string): number; + static parseHeight(val: numberOrString): HeightData; + /** copies unset fields in target to use the given default sources values */ + static defaults(target: any, ...sources: any[]): {}; + /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */ + static same(a: unknown, b: unknown): boolean; + /** copies over b size & position (GridStackPosition), and possibly min/max as well */ + static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax?: boolean): GridStackWidget; + /** true if a and b has same size & position */ + static samePos(a: GridStackPosition, b: GridStackPosition): boolean; + /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */ + static removeInternalAndSame(a: unknown, b: unknown): void; + /** return the closest parent (or itself) matching the given class */ + static closestByClass(el: HTMLElement, name: string): HTMLElement; + /** delay calling the given function for given delay, preventing new calls from happening while waiting */ + static throttle(func: () => void, delay: number): () => void; + static removePositioningStyles(el: HTMLElement): void; + /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */ + static clone(obj: T): T; + /** + * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY. + * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies. + */ + static cloneDeep(obj: T): T; + /** deep clone the given HTML node, removing teh unique id field */ + static cloneNode(el: HTMLElement): HTMLElement; + static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void; + static addElStyles(el: HTMLElement, styles: { + [prop: string]: string | string[]; + }): void; + static initEvent(e: DragEvent | MouseEvent, info: { + type: string; + target?: EventTarget; + }): T; +} diff --git a/dist/utils.js b/dist/utils.js new file mode 100644 index 000000000..f07b500c4 --- /dev/null +++ b/dist/utils.js @@ -0,0 +1,465 @@ +"use strict"; +/** + * utils.ts 6.0.1-dev + * Copyright (c) 2021 Alain Dumesny - see GridStack root license + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Utils = exports.obsoleteAttr = exports.obsoleteOptsDel = exports.obsoleteOpts = exports.obsolete = void 0; +/** checks for obsolete method names */ +// eslint-disable-next-line +function obsolete(self, f, oldName, newName, rev) { + let wrapper = (...args) => { + console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' + + 'with `' + newName + '`. It will be **removed** in a future release'); + return f.apply(self, args); + }; + wrapper.prototype = f.prototype; + return wrapper; +} +exports.obsolete = obsolete; +/** checks for obsolete grid options (can be used for any fields, but msg is about options) */ +function obsoleteOpts(opts, oldName, newName, rev) { + if (opts[oldName] !== undefined) { + opts[newName] = opts[oldName]; + console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' + + newName + '`. It will be **removed** in a future release'); + } +} +exports.obsoleteOpts = obsoleteOpts; +/** checks for obsolete grid options which are gone */ +function obsoleteOptsDel(opts, oldName, rev, info) { + if (opts[oldName] !== undefined) { + console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info); + } +} +exports.obsoleteOptsDel = obsoleteOptsDel; +/** checks for obsolete Jquery element attributes */ +function obsoleteAttr(el, oldName, newName, rev) { + let oldAttr = el.getAttribute(oldName); + if (oldAttr !== null) { + el.setAttribute(newName, oldAttr); + console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' + + newName + '`. It will be **removed** in a future release'); + } +} +exports.obsoleteAttr = obsoleteAttr; +/** + * Utility methods + */ +class Utils { + /** convert a potential selector into actual list of html elements */ + static getElements(els) { + if (typeof els === 'string') { + let list = document.querySelectorAll(els); + if (!list.length && els[0] !== '.' && els[0] !== '#') { + list = document.querySelectorAll('.' + els); + if (!list.length) { + list = document.querySelectorAll('#' + els); + } + } + return Array.from(list); + } + return [els]; + } + /** convert a potential selector into actual single element */ + static getElement(els) { + if (typeof els === 'string') { + if (!els.length) + return null; + if (els[0] === '#') { + return document.getElementById(els.substring(1)); + } + if (els[0] === '.' || els[0] === '[') { + return document.querySelector(els); + } + // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS + if (!isNaN(+els[0])) { // start with digit + return document.getElementById(els); + } + // finally try string, then id then class + let el = document.querySelector(els); + if (!el) { + el = document.getElementById(els); + } + if (!el) { + el = document.querySelector('.' + els); + } + return el; + } + return els; + } + /** returns true if a and b overlap */ + static isIntercepted(a, b) { + return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w); + } + /** returns true if a and b touch edges or corners */ + static isTouching(a, b) { + return Utils.isIntercepted(a, { x: b.x - 0.5, y: b.y - 0.5, w: b.w + 1, h: b.h + 1 }); + } + /** + * Sorts array of nodes + * @param nodes array to sort + * @param dir 1 for asc, -1 for desc (optional) + * @param width width of the grid. If undefined the width will be calculated automatically (optional). + **/ + static sort(nodes, dir, column) { + column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12; + if (dir === -1) + return nodes.sort((a, b) => (b.x + b.y * column) - (a.x + a.y * column)); + else + return nodes.sort((b, a) => (b.x + b.y * column) - (a.x + a.y * column)); + } + /** + * creates a style sheet with style id under given parent + * @param id will set the 'gs-style-id' attribute to that id + * @param parent to insert the stylesheet as first child, + * if none supplied it will be appended to the document head instead. + */ + static createStylesheet(id, parent) { + let style = document.createElement('style'); + style.setAttribute('type', 'text/css'); + style.setAttribute('gs-style-id', id); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (style.styleSheet) { // TODO: only CSSImportRule have that and different beast ?? + // eslint-disable-next-line @typescript-eslint/no-explicit-any + style.styleSheet.cssText = ''; + } + else { + style.appendChild(document.createTextNode('')); // WebKit hack + } + if (!parent) { + // default to head + parent = document.getElementsByTagName('head')[0]; + parent.appendChild(style); + } + else { + parent.insertBefore(style, parent.firstChild); + } + return style.sheet; + } + /** removed the given stylesheet id */ + static removeStylesheet(id) { + let el = document.querySelector('STYLE[gs-style-id=' + id + ']'); + if (el && el.parentNode) + el.remove(); + } + /** inserts a CSS rule */ + static addCSSRule(sheet, selector, rules) { + if (typeof sheet.addRule === 'function') { + sheet.addRule(selector, rules); + } + else if (typeof sheet.insertRule === 'function') { + sheet.insertRule(`${selector}{${rules}}`); + } + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + static toBool(v) { + if (typeof v === 'boolean') { + return v; + } + if (typeof v === 'string') { + v = v.toLowerCase(); + return !(v === '' || v === 'no' || v === 'false' || v === '0'); + } + return Boolean(v); + } + static toNumber(value) { + return (value === null || value.length === 0) ? undefined : Number(value); + } + static parseHeight(val) { + let h; + let unit = 'px'; + if (typeof val === 'string') { + let match = val.match(/^(-[0-9]+\.[0-9]+|[0-9]*\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/); + if (!match) { + throw new Error('Invalid height'); + } + unit = match[2] || 'px'; + h = parseFloat(match[1]); + } + else { + h = val; + } + return { h, unit }; + } + /** copies unset fields in target to use the given default sources values */ + // eslint-disable-next-line + static defaults(target, ...sources) { + sources.forEach(source => { + for (const key in source) { + if (!source.hasOwnProperty(key)) + return; + if (target[key] === null || target[key] === undefined) { + target[key] = source[key]; + } + else if (typeof source[key] === 'object' && typeof target[key] === 'object') { + // property is an object, recursively add it's field over... #1373 + this.defaults(target[key], source[key]); + } + } + }); + return target; + } + /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */ + static same(a, b) { + if (typeof a !== 'object') + return a == b; + if (typeof a !== typeof b) + return false; + // else we have object, check just 1 level deep for being same things... + if (Object.keys(a).length !== Object.keys(b).length) + return false; + for (const key in a) { + if (a[key] !== b[key]) + return false; + } + return true; + } + /** copies over b size & position (GridStackPosition), and possibly min/max as well */ + static copyPos(a, b, doMinMax = false) { + a.x = b.x; + a.y = b.y; + a.w = b.w; + a.h = b.h; + if (doMinMax) { + if (b.minW) + a.minW = b.minW; + if (b.minH) + a.minH = b.minH; + if (b.maxW) + a.maxW = b.maxW; + if (b.maxH) + a.maxH = b.maxH; + } + return a; + } + /** true if a and b has same size & position */ + static samePos(a, b) { + return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h; + } + /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */ + static removeInternalAndSame(a, b) { + if (typeof a !== 'object' || typeof b !== 'object') + return; + for (let key in a) { + let val = a[key]; + if (key[0] === '_' || val === b[key]) { + delete a[key]; + } + else if (val && typeof val === 'object' && b[key] !== undefined) { + for (let i in val) { + if (val[i] === b[key][i] || i[0] === '_') { + delete val[i]; + } + } + if (!Object.keys(val).length) { + delete a[key]; + } + } + } + } + /** return the closest parent (or itself) matching the given class */ + static closestByClass(el, name) { + while (el) { + if (el.classList.contains(name)) + return el; + el = el.parentElement; + } + return null; + } + /** delay calling the given function for given delay, preventing new calls from happening while waiting */ + static throttle(func, delay) { + let isWaiting = false; + return (...args) => { + if (!isWaiting) { + isWaiting = true; + setTimeout(() => { func(...args); isWaiting = false; }, delay); + } + }; + } + static removePositioningStyles(el) { + let style = el.style; + if (style.position) { + style.removeProperty('position'); + } + if (style.left) { + style.removeProperty('left'); + } + if (style.top) { + style.removeProperty('top'); + } + if (style.width) { + style.removeProperty('width'); + } + if (style.height) { + style.removeProperty('height'); + } + } + /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */ + static getScrollElement(el) { + if (!el) + return document.scrollingElement || document.documentElement; // IE support + const style = getComputedStyle(el); + const overflowRegex = /(auto|scroll)/; + if (overflowRegex.test(style.overflow + style.overflowY)) { + return el; + } + else { + return this.getScrollElement(el.parentElement); + } + } + /** @internal */ + static updateScrollPosition(el, position, distance) { + // is widget in view? + let rect = el.getBoundingClientRect(); + let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight); + if (rect.top < 0 || + rect.bottom > innerHeightOrClientHeight) { + // set scrollTop of first parent that scrolls + // if parent is larger than el, set as low as possible + // to get entire widget on screen + let offsetDiffDown = rect.bottom - innerHeightOrClientHeight; + let offsetDiffUp = rect.top; + let scrollEl = this.getScrollElement(el); + if (scrollEl !== null) { + let prevScroll = scrollEl.scrollTop; + if (rect.top < 0 && distance < 0) { + // moving up + if (el.offsetHeight > innerHeightOrClientHeight) { + scrollEl.scrollTop += distance; + } + else { + scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp; + } + } + else if (distance > 0) { + // moving down + if (el.offsetHeight > innerHeightOrClientHeight) { + scrollEl.scrollTop += distance; + } + else { + scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown; + } + } + // move widget y by amount scrolled + position.top += scrollEl.scrollTop - prevScroll; + } + } + } + /** + * @internal Function used to scroll the page. + * + * @param event `MouseEvent` that triggers the resize + * @param el `HTMLElement` that's being resized + * @param distance Distance from the V edges to start scrolling + */ + static updateScrollResize(event, el, distance) { + const scrollEl = this.getScrollElement(el); + const height = scrollEl.clientHeight; + // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top + // #1745 Special situation if scrollEl is document 'html': here browser spec states that + // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element; + // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself. + const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top; + const pointerPosY = event.clientY - offsetTop; + const top = pointerPosY < distance; + const bottom = pointerPosY > height - distance; + if (top) { + // This also can be done with a timeout to keep scrolling while the mouse is + // in the scrolling zone. (will have smoother behavior) + scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance }); + } + else if (bottom) { + scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY) }); + } + } + /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */ + static clone(obj) { + if (obj === null || obj === undefined || typeof (obj) !== 'object') { + return obj; + } + // return Object.assign({}, obj); + if (obj instanceof Array) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return [...obj]; + } + return Object.assign({}, obj); + } + /** + * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY. + * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies. + */ + static cloneDeep(obj) { + // list of fields we will skip during cloneDeep (nested objects, other internal) + const skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine']; + // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ? + const ret = Utils.clone(obj); + for (const key in ret) { + // NOTE: we don't support function/circular dependencies so skip those properties for now... + if (ret.hasOwnProperty(key) && typeof (ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) { + ret[key] = Utils.cloneDeep(obj[key]); + } + } + return ret; + } + /** deep clone the given HTML node, removing teh unique id field */ + static cloneNode(el) { + const node = el.cloneNode(true); + node.removeAttribute('id'); + return node; + } + static appendTo(el, parent) { + let parentNode; + if (typeof parent === 'string') { + parentNode = document.querySelector(parent); + } + else { + parentNode = parent; + } + if (parentNode) { + parentNode.appendChild(el); + } + } + // public static setPositionRelative(el: HTMLElement): void { + // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) { + // el.style.position = "relative"; + // } + // } + static addElStyles(el, styles) { + if (styles instanceof Object) { + for (const s in styles) { + if (styles.hasOwnProperty(s)) { + if (Array.isArray(styles[s])) { + // support fallback value + styles[s].forEach(val => { + el.style[s] = val; + }); + } + else { + el.style[s] = styles[s]; + } + } + } + } + } + static initEvent(e, info) { + const evt = { type: info.type }; + const obj = { + button: 0, + which: 0, + buttons: 1, + bubbles: true, + cancelable: true, + target: info.target ? info.target : e.target + }; + // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540 + if (e.dataTransfer) { + evt['dataTransfer'] = e.dataTransfer; // workaround 'readonly' field. + } + ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].forEach(p => evt[p] = e[p]); // keys + ['pageX', 'pageY', 'clientX', 'clientY', 'screenX', 'screenY'].forEach(p => evt[p] = e[p]); // point info + return Object.assign(Object.assign({}, evt), obj); + } +} +exports.Utils = Utils; +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/dist/utils.js.map b/dist/utils.js.map new file mode 100644 index 000000000..d1adf2b5c --- /dev/null +++ b/dist/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,uCAAuC;AACvC,2BAA2B;AAC3B,SAAgB,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,OAAe,EAAE,OAAe,EAAE,GAAW;IAC7E,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,0BAA0B,GAAG,OAAO,GAAG,qBAAqB,GAAG,GAAG,GAAG,yBAAyB;YAC3G,QAAQ,GAAG,OAAO,GAAG,+CAA+C,CAAC,CAAC;QACtE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAA;IACD,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AARD,4BAQC;AAED,8FAA8F;AAC9F,SAAgB,YAAY,CAAC,IAAsB,EAAE,OAAe,EAAE,OAAe,EAAE,GAAW;IAChG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC,wBAAwB,GAAG,OAAO,GAAG,qBAAqB,GAAG,GAAG,GAAG,+BAA+B;YAC7G,OAAO,GAAG,+CAA+C,CAAC,CAAC;KAC9D;AACH,CAAC;AAND,oCAMC;AAED,sDAAsD;AACtD,SAAgB,eAAe,CAAC,IAAsB,EAAE,OAAe,EAAE,GAAW,EAAE,IAAY;IAChG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE;QAC/B,OAAO,CAAC,IAAI,CAAC,wBAAwB,GAAG,OAAO,GAAG,qBAAqB,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;KACvF;AACH,CAAC;AAJD,0CAIC;AAED,oDAAoD;AACpD,SAAgB,YAAY,CAAC,EAAe,EAAE,OAAe,EAAE,OAAe,EAAE,GAAW;IACzF,IAAI,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,OAAO,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,2BAA2B,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,mCAAmC,GAAG,GAAG,GAAG,+BAA+B;YAC/I,OAAO,GAAG,+CAA+C,CAAC,CAAC;KAC9D;AACH,CAAC;AAPD,oCAOC;AAED;;GAEG;AACH,MAAa,KAAK;IAEhB,qEAAqE;IACrE,MAAM,CAAC,WAAW,CAAC,GAAqB;QACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B,IAAI,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBACpD,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;gBAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;oBAAE,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;iBAAE;aAClE;YACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAC;SAC1C;QACD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAED,8DAA8D;IAC9D,MAAM,CAAC,UAAU,CAAC,GAAqB;QACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YAC7B,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBAClB,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;aAClD;YACD,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;gBACpC,OAAO,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;aACpC;YAED,6GAA6G;YAC7G,IAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,mBAAmB;gBACvC,OAAO,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;aACrC;YAED,yCAAyC;YACzC,IAAI,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,CAAC,EAAE,EAAE;gBAAE,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;aAAE;YAC9C,IAAI,CAAC,EAAE,EAAE;gBAAE,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;aAAE;YACnD,OAAO,EAAiB,CAAC;SAC1B;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,sCAAsC;IACtC,MAAM,CAAC,aAAa,CAAC,CAAoB,EAAE,CAAoB;QAC7D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,qDAAqD;IACrD,MAAM,CAAC,UAAU,CAAC,CAAoB,EAAE,CAAoB;QAC1D,OAAO,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAC,CAAC,EAAC,CAAC,CAAA;IAC7E,CAAC;IACD;;;;;QAKI;IACJ,MAAM,CAAC,IAAI,CAAC,KAAsB,EAAE,GAAY,EAAE,MAAe;QAC/D,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/E,IAAI,GAAG,KAAK,CAAC,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;;YAEvE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,EAAU,EAAE,MAAoB;QACtD,IAAI,KAAK,GAAqB,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9D,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACvC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACtC,8DAA8D;QAC9D,IAAK,KAAa,CAAC,UAAU,EAAE,EAAE,4DAA4D;YAC3F,8DAA8D;YAC7D,KAAa,CAAC,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC;SACxC;aAAM;YACL,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;SAC/D;QACD,IAAI,CAAC,MAAM,EAAE;YACX,kBAAkB;YAClB,MAAM,GAAG,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;SAC3B;aAAM;YACL,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;SAC/C;QACD,OAAO,KAAK,CAAC,KAAsB,CAAC;IACtC,CAAC;IAED,sCAAsC;IACtC,MAAM,CAAC,gBAAgB,CAAC,EAAU;QAChC,IAAI,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,oBAAoB,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC;QACjE,IAAI,EAAE,IAAI,EAAE,CAAC,UAAU;YAAE,EAAE,CAAC,MAAM,EAAE,CAAC;IACvC,CAAC;IAED,yBAAyB;IACzB,MAAM,CAAC,UAAU,CAAC,KAAoB,EAAE,QAAgB,EAAE,KAAa;QACrE,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,EAAE;YACvC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;SAChC;aAAM,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,UAAU,EAAE;YACjD,KAAK,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC;SAC3C;IACH,CAAC;IAED,8DAA8D;IAC9D,MAAM,CAAC,MAAM,CAAC,CAAU;QACtB,IAAI,OAAO,CAAC,KAAK,SAAS,EAAE;YAC1B,OAAO,CAAC,CAAC;SACV;QACD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;YACzB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;YACpB,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;SAChE;QACD,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,KAAoB;QAClC,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,GAAmB;QACpC,IAAI,CAAS,CAAC;QACd,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YAC3B,IAAI,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YAC/F,IAAI,CAAC,KAAK,EAAE;gBACV,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;aACnC;YACD,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACxB,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;SAC1B;aAAM;YACL,CAAC,GAAG,GAAG,CAAC;SACT;QACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACrB,CAAC;IAED,4EAA4E;IAC5E,2BAA2B;IAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,OAAO;QAEhC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;gBACxB,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC;oBAAE,OAAO;gBACxC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;oBACrD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;iBAC3B;qBAAM,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;oBAC7E,kEAAkE;oBAClE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;iBACzC;aACF;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uIAAuI;IACvI,MAAM,CAAC,IAAI,CAAC,CAAU,EAAE,CAAU;QAChC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,KAAK,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,wEAAwE;QACxE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAClE,KAAK,MAAM,GAAG,IAAI,CAAC,EAAE;YACnB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;SACrC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sFAAsF;IACtF,MAAM,CAAC,OAAO,CAAC,CAAkB,EAAE,CAAkB,EAAE,QAAQ,GAAG,KAAK;QACrE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACV,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,CAAC,IAAI;gBAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,CAAC,IAAI;gBAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,CAAC,IAAI;gBAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,CAAC,IAAI;gBAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;SAC7B;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,+CAA+C;IAC/C,MAAM,CAAC,OAAO,CAAC,CAAoB,EAAE,CAAoB;QACvD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,mHAAmH;IACnH,MAAM,CAAC,qBAAqB,CAAC,CAAU,EAAE,CAAU;QACjD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO;QAC3D,KAAK,IAAI,GAAG,IAAI,CAAC,EAAE;YACjB,IAAI,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE;gBACpC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAA;aACd;iBAAM,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;gBACjE,KAAK,IAAI,CAAC,IAAI,GAAG,EAAE;oBACjB,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;wBAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAA;qBAAE;iBAC5D;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE;oBAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAA;iBAAE;aAChD;SACF;IACH,CAAC;IAED,qEAAqE;IACrE,MAAM,CAAC,cAAc,CAAC,EAAe,EAAE,IAAY;QACjD,OAAO,EAAE,EAAE;YACT,IAAI,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,CAAC;YAC3C,EAAE,GAAG,EAAE,CAAC,aAAa,CAAA;SACtB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0GAA0G;IAC1G,MAAM,CAAC,QAAQ,CAAC,IAAgB,EAAE,KAAa;QAC7C,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;YACjB,IAAI,CAAC,SAAS,EAAE;gBACd,SAAS,GAAG,IAAI,CAAC;gBACjB,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;aAChE;QACH,CAAC,CAAA;IACH,CAAC;IAED,MAAM,CAAC,uBAAuB,CAAC,EAAe;QAC5C,IAAI,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;QACrB,IAAI,KAAK,CAAC,QAAQ,EAAE;YAClB,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;SAClC;QACD,IAAI,KAAK,CAAC,IAAI,EAAE;YACd,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;SAC9B;QACD,IAAI,KAAK,CAAC,GAAG,EAAE;YACb,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;SAC7B;QACD,IAAI,KAAK,CAAC,KAAK,EAAE;YACf,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;SAC/B;QACD,IAAI,KAAK,CAAC,MAAM,EAAE;YAChB,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;SAChC;IACH,CAAC;IAED,yIAAyI;IACzI,MAAM,CAAC,gBAAgB,CAAC,EAAgB;QACtC,IAAI,CAAC,EAAE;YAAE,OAAO,QAAQ,CAAC,gBAA+B,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,aAAa;QACnG,MAAM,KAAK,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,aAAa,GAAG,eAAe,CAAC;QAEtC,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE;YACxD,OAAO,EAAE,CAAC;SACX;aAAM;YACL,OAAO,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;SAChD;IACH,CAAC;IAED,gBAAgB;IAChB,MAAM,CAAC,oBAAoB,CAAC,EAAe,EAAE,QAAuB,EAAE,QAAgB;QACpF,qBAAqB;QACrB,IAAI,IAAI,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;QACtC,IAAI,yBAAyB,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAC9F,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC;YACd,IAAI,CAAC,MAAM,GAAG,yBAAyB,EACvC;YACA,6CAA6C;YAC7C,sDAAsD;YACtD,iCAAiC;YACjC,IAAI,cAAc,GAAG,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC;YAC7D,IAAI,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC;YAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACzC,IAAI,QAAQ,KAAK,IAAI,EAAE;gBACrB,IAAI,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC;gBACpC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE;oBAChC,YAAY;oBACZ,IAAI,EAAE,CAAC,YAAY,GAAG,yBAAyB,EAAE;wBAC/C,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC;qBAChC;yBAAM;wBACL,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC;qBAC7F;iBACF;qBAAM,IAAI,QAAQ,GAAG,CAAC,EAAE;oBACvB,cAAc;oBACd,IAAI,EAAE,CAAC,YAAY,GAAG,yBAAyB,EAAE;wBAC/C,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC;qBAChC;yBAAM;wBACL,QAAQ,CAAC,SAAS,IAAI,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC;qBAC7E;iBACF;gBACD,mCAAmC;gBACnC,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,SAAS,GAAG,UAAU,CAAC;aACjD;SACF;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAiB,EAAE,EAAe,EAAE,QAAgB;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC;QACrC,6HAA6H;QAC7H,wFAAwF;QACxF,gGAAgG;QAChG,yGAAyG;QACzG,MAAM,SAAS,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC;QACpG,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC;QAC9C,MAAM,GAAG,GAAG,WAAW,GAAG,QAAQ,CAAC;QACnC,MAAM,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;QAE/C,IAAI,GAAG,EAAE;YACP,4EAA4E;YAC5E,uDAAuD;YACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,QAAQ,EAAC,CAAC,CAAC;SACvE;aAAM,IAAI,MAAM,EAAE;YACjB,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,EAAC,CAAC,CAAC;SAClF;IACH,CAAC;IAED,8GAA8G;IAC9G,MAAM,CAAC,KAAK,CAAI,GAAM;QACpB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,OAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;YACjE,OAAO,GAAG,CAAC;SACZ;QACD,iCAAiC;QACjC,IAAI,GAAG,YAAY,KAAK,EAAE;YACxB,8DAA8D;YAC9D,OAAO,CAAC,GAAG,GAAG,CAAQ,CAAC;SACxB;QACD,yBAAW,GAAG,EAAE;IAClB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAI,GAAM;QACxB,gFAAgF;QAChF,MAAM,UAAU,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACpE,6EAA6E;QAC7E,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE;YACrB,4FAA4F;YAC5F,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,OAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE;gBAChI,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;aACtC;SACF;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,mEAAmE;IAC5D,MAAM,CAAC,SAAS,CAAC,EAAe;QACrC,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAgB,CAAC;QAC/C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAC,EAAe,EAAE,MAAmC;QACzE,IAAI,UAAuB,CAAC;QAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAgB,CAAC,CAAC;SACvD;aAAM;YACL,UAAU,GAAG,MAAqB,CAAC;SACpC;QACD,IAAI,UAAU,EAAE;YACd,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;SAC5B;IACH,CAAC;IAED,6DAA6D;IAC7D,sEAAsE;IACtE,sCAAsC;IACtC,MAAM;IACN,IAAI;IAEG,MAAM,CAAC,WAAW,CAAC,EAAe,EAAE,MAA6C;QACtF,IAAI,MAAM,YAAY,MAAM,EAAE;YAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE;gBACtB,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;oBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;wBAC5B,yBAAyB;wBACxB,MAAM,CAAC,CAAC,CAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;4BACpC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;wBACpB,CAAC,CAAC,CAAC;qBACJ;yBAAM;wBACL,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;qBACzB;iBACF;aACF;SACF;IACH,CAAC;IAEM,MAAM,CAAC,SAAS,CAAI,CAAyB,EAAE,IAA4C;QAChG,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG;YACV,MAAM,EAAE,CAAC;YACT,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;SAC7C,CAAC;QACF,wEAAwE;QACxE,IAAK,CAAe,CAAC,YAAY,EAAE;YACjC,GAAG,CAAC,cAAc,CAAC,GAAI,CAAe,CAAC,YAAY,CAAC,CAAC,+BAA+B;SACrF;QACD,CAAC,QAAQ,EAAC,SAAS,EAAC,SAAS,EAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;QAC9E,CAAC,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,SAAS,EAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa;QACpG,OAAO,gCAAI,GAAG,GAAK,GAAG,CAAiB,CAAC;IAC1C,CAAC;CAcF;AAzaD,sBAyaC","sourcesContent":["/**\r\n * utils.ts 6.0.1-dev\r\n * Copyright (c) 2021 Alain Dumesny - see GridStack root license\r\n */\r\n\r\nimport { GridStackElement, GridStackNode, GridStackOptions, numberOrString, GridStackPosition, GridStackWidget } from './types';\r\n\r\nexport interface HeightData {\r\n h: number;\r\n unit: string;\r\n}\r\n\r\n/** checks for obsolete method names */\r\n// eslint-disable-next-line\r\nexport function obsolete(self, f, oldName: string, newName: string, rev: string): (...args: any[]) => any {\r\n let wrapper = (...args) => {\r\n console.warn('gridstack.js: Function `' + oldName + '` is deprecated in ' + rev + ' and has been replaced ' +\r\n 'with `' + newName + '`. It will be **removed** in a future release');\r\n return f.apply(self, args);\r\n }\r\n wrapper.prototype = f.prototype;\r\n return wrapper;\r\n}\r\n\r\n/** checks for obsolete grid options (can be used for any fields, but msg is about options) */\r\nexport function obsoleteOpts(opts: GridStackOptions, oldName: string, newName: string, rev: string): void {\r\n if (opts[oldName] !== undefined) {\r\n opts[newName] = opts[oldName];\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/** checks for obsolete grid options which are gone */\r\nexport function obsoleteOptsDel(opts: GridStackOptions, oldName: string, rev: string, info: string): void {\r\n if (opts[oldName] !== undefined) {\r\n console.warn('gridstack.js: Option `' + oldName + '` is deprecated in ' + rev + info);\r\n }\r\n}\r\n\r\n/** checks for obsolete Jquery element attributes */\r\nexport function obsoleteAttr(el: HTMLElement, oldName: string, newName: string, rev: string): void {\r\n let oldAttr = el.getAttribute(oldName);\r\n if (oldAttr !== null) {\r\n el.setAttribute(newName, oldAttr);\r\n console.warn('gridstack.js: attribute `' + oldName + '`=' + oldAttr + ' is deprecated on this object in ' + rev + ' and has been replaced with `' +\r\n newName + '`. It will be **removed** in a future release');\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods\r\n */\r\nexport class Utils {\r\n\r\n /** convert a potential selector into actual list of html elements */\r\n static getElements(els: GridStackElement): HTMLElement[] {\r\n if (typeof els === 'string') {\r\n let list = document.querySelectorAll(els);\r\n if (!list.length && els[0] !== '.' && els[0] !== '#') {\r\n list = document.querySelectorAll('.' + els);\r\n if (!list.length) { list = document.querySelectorAll('#' + els) }\r\n }\r\n return Array.from(list) as HTMLElement[];\r\n }\r\n return [els];\r\n }\r\n\r\n /** convert a potential selector into actual single element */\r\n static getElement(els: GridStackElement): HTMLElement {\r\n if (typeof els === 'string') {\r\n if (!els.length) return null;\r\n if (els[0] === '#') {\r\n return document.getElementById(els.substring(1));\r\n }\r\n if (els[0] === '.' || els[0] === '[') {\r\n return document.querySelector(els);\r\n }\r\n\r\n // if we start with a digit, assume it's an id (error calling querySelector('#1')) as class are not valid CSS\r\n if(!isNaN(+els[0])) { // start with digit\r\n return document.getElementById(els);\r\n }\r\n\r\n // finally try string, then id then class\r\n let el = document.querySelector(els);\r\n if (!el) { el = document.getElementById(els) }\r\n if (!el) { el = document.querySelector('.' + els) }\r\n return el as HTMLElement;\r\n }\r\n return els;\r\n }\r\n\r\n /** returns true if a and b overlap */\r\n static isIntercepted(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return !(a.y >= b.y + b.h || a.y + a.h <= b.y || a.x + a.w <= b.x || a.x >= b.x + b.w);\r\n }\r\n\r\n /** returns true if a and b touch edges or corners */\r\n static isTouching(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return Utils.isIntercepted(a, {x: b.x-0.5, y: b.y-0.5, w: b.w+1, h: b.h+1})\r\n }\r\n /**\r\n * Sorts array of nodes\r\n * @param nodes array to sort\r\n * @param dir 1 for asc, -1 for desc (optional)\r\n * @param width width of the grid. If undefined the width will be calculated automatically (optional).\r\n **/\r\n static sort(nodes: GridStackNode[], dir?: -1 | 1, column?: number): GridStackNode[] {\r\n column = column || nodes.reduce((col, n) => Math.max(n.x + n.w, col), 0) || 12;\r\n if (dir === -1)\r\n return nodes.sort((a, b) => (b.x + b.y * column)-(a.x + a.y * column));\r\n else\r\n return nodes.sort((b, a) => (b.x + b.y * column)-(a.x + a.y * column));\r\n }\r\n\r\n /**\r\n * creates a style sheet with style id under given parent\r\n * @param id will set the 'gs-style-id' attribute to that id\r\n * @param parent to insert the stylesheet as first child,\r\n * if none supplied it will be appended to the document head instead.\r\n */\r\n static createStylesheet(id: string, parent?: HTMLElement): CSSStyleSheet {\r\n let style: HTMLStyleElement = document.createElement('style');\r\n style.setAttribute('type', 'text/css');\r\n style.setAttribute('gs-style-id', id);\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n if ((style as any).styleSheet) { // TODO: only CSSImportRule have that and different beast ??\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (style as any).styleSheet.cssText = '';\r\n } else {\r\n style.appendChild(document.createTextNode('')); // WebKit hack\r\n }\r\n if (!parent) {\r\n // default to head\r\n parent = document.getElementsByTagName('head')[0];\r\n parent.appendChild(style);\r\n } else {\r\n parent.insertBefore(style, parent.firstChild);\r\n }\r\n return style.sheet as CSSStyleSheet;\r\n }\r\n\r\n /** removed the given stylesheet id */\r\n static removeStylesheet(id: string): void {\r\n let el = document.querySelector('STYLE[gs-style-id=' + id + ']');\r\n if (el && el.parentNode) el.remove();\r\n }\r\n\r\n /** inserts a CSS rule */\r\n static addCSSRule(sheet: CSSStyleSheet, selector: string, rules: string): void {\r\n if (typeof sheet.addRule === 'function') {\r\n sheet.addRule(selector, rules);\r\n } else if (typeof sheet.insertRule === 'function') {\r\n sheet.insertRule(`${selector}{${rules}}`);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n static toBool(v: unknown): boolean {\r\n if (typeof v === 'boolean') {\r\n return v;\r\n }\r\n if (typeof v === 'string') {\r\n v = v.toLowerCase();\r\n return !(v === '' || v === 'no' || v === 'false' || v === '0');\r\n }\r\n return Boolean(v);\r\n }\r\n\r\n static toNumber(value: null | string): number {\r\n return (value === null || value.length === 0) ? undefined : Number(value);\r\n }\r\n\r\n static parseHeight(val: numberOrString): HeightData {\r\n let h: number;\r\n let unit = 'px';\r\n if (typeof val === 'string') {\r\n let match = val.match(/^(-[0-9]+\\.[0-9]+|[0-9]*\\.[0-9]+|-[0-9]+|[0-9]+)(px|em|rem|vh|vw|%)?$/);\r\n if (!match) {\r\n throw new Error('Invalid height');\r\n }\r\n unit = match[2] || 'px';\r\n h = parseFloat(match[1]);\r\n } else {\r\n h = val;\r\n }\r\n return { h, unit };\r\n }\r\n\r\n /** copies unset fields in target to use the given default sources values */\r\n // eslint-disable-next-line\r\n static defaults(target, ...sources): {} {\r\n\r\n sources.forEach(source => {\r\n for (const key in source) {\r\n if (!source.hasOwnProperty(key)) return;\r\n if (target[key] === null || target[key] === undefined) {\r\n target[key] = source[key];\r\n } else if (typeof source[key] === 'object' && typeof target[key] === 'object') {\r\n // property is an object, recursively add it's field over... #1373\r\n this.defaults(target[key], source[key]);\r\n }\r\n }\r\n });\r\n\r\n return target;\r\n }\r\n\r\n /** given 2 objects return true if they have the same values. Checks for Object {} having same fields and values (just 1 level down) */\r\n static same(a: unknown, b: unknown): boolean {\r\n if (typeof a !== 'object') return a == b;\r\n if (typeof a !== typeof b) return false;\r\n // else we have object, check just 1 level deep for being same things...\r\n if (Object.keys(a).length !== Object.keys(b).length) return false;\r\n for (const key in a) {\r\n if (a[key] !== b[key]) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /** copies over b size & position (GridStackPosition), and possibly min/max as well */\r\n static copyPos(a: GridStackWidget, b: GridStackWidget, doMinMax = false): GridStackWidget {\r\n a.x = b.x;\r\n a.y = b.y;\r\n a.w = b.w;\r\n a.h = b.h;\r\n if (doMinMax) {\r\n if (b.minW) a.minW = b.minW;\r\n if (b.minH) a.minH = b.minH;\r\n if (b.maxW) a.maxW = b.maxW;\r\n if (b.maxH) a.maxH = b.maxH;\r\n }\r\n return a;\r\n }\r\n\r\n /** true if a and b has same size & position */\r\n static samePos(a: GridStackPosition, b: GridStackPosition): boolean {\r\n return a && b && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;\r\n }\r\n\r\n /** removes field from the first object if same as the second objects (like diffing) and internal '_' for saving */\r\n static removeInternalAndSame(a: unknown, b: unknown):void {\r\n if (typeof a !== 'object' || typeof b !== 'object') return;\r\n for (let key in a) {\r\n let val = a[key];\r\n if (key[0] === '_' || val === b[key]) {\r\n delete a[key]\r\n } else if (val && typeof val === 'object' && b[key] !== undefined) {\r\n for (let i in val) {\r\n if (val[i] === b[key][i] || i[0] === '_') { delete val[i] }\r\n }\r\n if (!Object.keys(val).length) { delete a[key] }\r\n }\r\n }\r\n }\r\n\r\n /** return the closest parent (or itself) matching the given class */\r\n static closestByClass(el: HTMLElement, name: string): HTMLElement {\r\n while (el) {\r\n if (el.classList.contains(name)) return el;\r\n el = el.parentElement\r\n }\r\n return null;\r\n }\r\n\r\n /** delay calling the given function for given delay, preventing new calls from happening while waiting */\r\n static throttle(func: () => void, delay: number): () => void {\r\n let isWaiting = false;\r\n return (...args) => {\r\n if (!isWaiting) {\r\n isWaiting = true;\r\n setTimeout(() => { func(...args); isWaiting = false; }, delay);\r\n }\r\n }\r\n }\r\n\r\n static removePositioningStyles(el: HTMLElement): void {\r\n let style = el.style;\r\n if (style.position) {\r\n style.removeProperty('position');\r\n }\r\n if (style.left) {\r\n style.removeProperty('left');\r\n }\r\n if (style.top) {\r\n style.removeProperty('top');\r\n }\r\n if (style.width) {\r\n style.removeProperty('width');\r\n }\r\n if (style.height) {\r\n style.removeProperty('height');\r\n }\r\n }\r\n\r\n /** @internal returns the passed element if scrollable, else the closest parent that will, up to the entire document scrolling element */\r\n static getScrollElement(el?: HTMLElement): HTMLElement {\r\n if (!el) return document.scrollingElement as HTMLElement || document.documentElement; // IE support\r\n const style = getComputedStyle(el);\r\n const overflowRegex = /(auto|scroll)/;\r\n\r\n if (overflowRegex.test(style.overflow + style.overflowY)) {\r\n return el;\r\n } else {\r\n return this.getScrollElement(el.parentElement);\r\n }\r\n }\r\n\r\n /** @internal */\r\n static updateScrollPosition(el: HTMLElement, position: {top: number}, distance: number): void {\r\n // is widget in view?\r\n let rect = el.getBoundingClientRect();\r\n let innerHeightOrClientHeight = (window.innerHeight || document.documentElement.clientHeight);\r\n if (rect.top < 0 ||\r\n rect.bottom > innerHeightOrClientHeight\r\n ) {\r\n // set scrollTop of first parent that scrolls\r\n // if parent is larger than el, set as low as possible\r\n // to get entire widget on screen\r\n let offsetDiffDown = rect.bottom - innerHeightOrClientHeight;\r\n let offsetDiffUp = rect.top;\r\n let scrollEl = this.getScrollElement(el);\r\n if (scrollEl !== null) {\r\n let prevScroll = scrollEl.scrollTop;\r\n if (rect.top < 0 && distance < 0) {\r\n // moving up\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += Math.abs(offsetDiffUp) > Math.abs(distance) ? distance : offsetDiffUp;\r\n }\r\n } else if (distance > 0) {\r\n // moving down\r\n if (el.offsetHeight > innerHeightOrClientHeight) {\r\n scrollEl.scrollTop += distance;\r\n } else {\r\n scrollEl.scrollTop += offsetDiffDown > distance ? distance : offsetDiffDown;\r\n }\r\n }\r\n // move widget y by amount scrolled\r\n position.top += scrollEl.scrollTop - prevScroll;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal Function used to scroll the page.\r\n *\r\n * @param event `MouseEvent` that triggers the resize\r\n * @param el `HTMLElement` that's being resized\r\n * @param distance Distance from the V edges to start scrolling\r\n */\r\n static updateScrollResize(event: MouseEvent, el: HTMLElement, distance: number): void {\r\n const scrollEl = this.getScrollElement(el);\r\n const height = scrollEl.clientHeight;\r\n // #1727 event.clientY is relative to viewport, so must compare this against position of scrollEl getBoundingClientRect().top\r\n // #1745 Special situation if scrollEl is document 'html': here browser spec states that\r\n // clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;\r\n // this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.\r\n const offsetTop = (scrollEl === this.getScrollElement()) ? 0 : scrollEl.getBoundingClientRect().top;\r\n const pointerPosY = event.clientY - offsetTop;\r\n const top = pointerPosY < distance;\r\n const bottom = pointerPosY > height - distance;\r\n\r\n if (top) {\r\n // This also can be done with a timeout to keep scrolling while the mouse is\r\n // in the scrolling zone. (will have smoother behavior)\r\n scrollEl.scrollBy({ behavior: 'smooth', top: pointerPosY - distance});\r\n } else if (bottom) {\r\n scrollEl.scrollBy({ behavior: 'smooth', top: distance - (height - pointerPosY)});\r\n }\r\n }\r\n\r\n /** single level clone, returning a new object with same top fields. This will share sub objects and arrays */\r\n static clone(obj: T): T {\r\n if (obj === null || obj === undefined || typeof(obj) !== 'object') {\r\n return obj;\r\n }\r\n // return Object.assign({}, obj);\r\n if (obj instanceof Array) {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n return [...obj] as any;\r\n }\r\n return {...obj};\r\n }\r\n\r\n /**\r\n * Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.\r\n * Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.\r\n */\r\n static cloneDeep(obj: T): T {\r\n // list of fields we will skip during cloneDeep (nested objects, other internal)\r\n const skipFields = ['_isNested', 'el', 'grid', 'subGrid', 'engine'];\r\n // return JSON.parse(JSON.stringify(obj)); // doesn't work with date format ?\r\n const ret = Utils.clone(obj);\r\n for (const key in ret) {\r\n // NOTE: we don't support function/circular dependencies so skip those properties for now...\r\n if (ret.hasOwnProperty(key) && typeof(ret[key]) === 'object' && key.substring(0, 2) !== '__' && !skipFields.find(k => k === key)) {\r\n ret[key] = Utils.cloneDeep(obj[key]);\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n /** deep clone the given HTML node, removing teh unique id field */\r\n public static cloneNode(el: HTMLElement): HTMLElement {\r\n const node = el.cloneNode(true) as HTMLElement;\r\n node.removeAttribute('id');\r\n return node;\r\n }\r\n\r\n public static appendTo(el: HTMLElement, parent: string | HTMLElement | Node): void {\r\n let parentNode: HTMLElement;\r\n if (typeof parent === 'string') {\r\n parentNode = document.querySelector(parent as string);\r\n } else {\r\n parentNode = parent as HTMLElement;\r\n }\r\n if (parentNode) {\r\n parentNode.appendChild(el);\r\n }\r\n }\r\n\r\n // public static setPositionRelative(el: HTMLElement): void {\r\n // if (!(/^(?:r|a|f)/).test(window.getComputedStyle(el).position)) {\r\n // el.style.position = \"relative\";\r\n // }\r\n // }\r\n\r\n public static addElStyles(el: HTMLElement, styles: { [prop: string]: string | string[] }): void {\r\n if (styles instanceof Object) {\r\n for (const s in styles) {\r\n if (styles.hasOwnProperty(s)) {\r\n if (Array.isArray(styles[s])) {\r\n // support fallback value\r\n (styles[s] as string[]).forEach(val => {\r\n el.style[s] = val;\r\n });\r\n } else {\r\n el.style[s] = styles[s];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public static initEvent(e: DragEvent | MouseEvent, info: { type: string; target?: EventTarget }): T {\r\n const evt = { type: info.type };\r\n const obj = {\r\n button: 0,\r\n which: 0,\r\n buttons: 1,\r\n bubbles: true,\r\n cancelable: true,\r\n target: info.target ? info.target : e.target\r\n };\r\n // don't check for `instanceof DragEvent` as Safari use MouseEvent #1540\r\n if ((e as DragEvent).dataTransfer) {\r\n evt['dataTransfer'] = (e as DragEvent).dataTransfer; // workaround 'readonly' field.\r\n }\r\n ['altKey','ctrlKey','metaKey','shiftKey'].forEach(p => evt[p] = e[p]); // keys\r\n ['pageX','pageY','clientX','clientY','screenX','screenY'].forEach(p => evt[p] = e[p]); // point info\r\n return {...evt, ...obj} as unknown as T;\r\n }\r\n\r\n /** returns true if event is inside the given element rectangle */\r\n // Note: Safari Mac has null event.relatedTarget which causes #1684 so check if DragEvent is inside the coordinates instead\r\n // this.el.contains(event.relatedTarget as HTMLElement)\r\n // public static inside(e: MouseEvent, el: HTMLElement): boolean {\r\n // // srcElement, toElement, target: all set to placeholder when leaving simple grid, so we can't use that (Chrome)\r\n // let target: HTMLElement = e.relatedTarget || (e as any).fromElement;\r\n // if (!target) {\r\n // const { bottom, left, right, top } = el.getBoundingClientRect();\r\n // return (e.x < right && e.x > left && e.y < bottom && e.y > top);\r\n // }\r\n // return el.contains(target);\r\n // }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/dd-gridstack.ts b/src/dd-gridstack.ts index 1a7253955..6ac37799b 100644 --- a/src/dd-gridstack.ts +++ b/src/dd-gridstack.ts @@ -49,13 +49,15 @@ export class DDGridStack { const grid = dEl.el.gridstackNode.grid; let handles = dEl.el.getAttribute('gs-resize-handles') ? dEl.el.getAttribute('gs-resize-handles') : grid.opts.resizable.handles; let autoHide = !grid.opts.alwaysShowResizeHandle; + let fixedAspectRatio = dEl.el.getAttribute('gs-fixed-aspect-ratio') ? parseFloat(dEl.el.getAttribute('gs-fixed-aspect-ratio')) : undefined; dEl.setupResizable({ ...grid.opts.resizable, ...{ handles, autoHide }, ...{ start: opts.start, stop: opts.stop, - resize: opts.resize + resize: opts.resize, + fixedAspectRatio: fixedAspectRatio } }); } diff --git a/src/dd-resizable.ts b/src/dd-resizable.ts index d791425a0..bc25a778d 100644 --- a/src/dd-resizable.ts +++ b/src/dd-resizable.ts @@ -19,6 +19,7 @@ export interface DDResizableOpt { maxWidth?: number; minHeight?: number; minWidth?: number; + fixedAspectRatio?: number; start?: (event: Event, ui: DDUIData) => void; stop?: (event: Event) => void; resize?: (event: Event, ui: DDUIData) => void; @@ -187,7 +188,7 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt /** @internal */ protected _resizing(event: MouseEvent, dir: string): DDResizable { this.scrolled = this.scrollEl.scrollTop - this.scrollY; - this.temporalRect = this._getChange(event, dir); + this.temporalRect = this._getChange(event, dir, this.option.fixedAspectRatio); this._applyChange(); const ev = Utils.initEvent(event, { type: 'resize', target: this.el }); if (this.option.resize) { @@ -236,30 +237,91 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt } /** @internal */ - protected _getChange(event: MouseEvent, dir: string): Rect { + protected _getChange(event: MouseEvent, dir: string, fixedAspectRatio?: number): Rect { + const fixedAspect = typeof(fixedAspectRatio) !== 'undefined' && fixedAspectRatio != 0 && !isNaN(fixedAspectRatio) && isFinite(fixedAspectRatio); const oEvent = this.startEvent; const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out. width: this.originalRect.width, - height: this.originalRect.height + this.scrolled, + height: this.originalRect.height + (fixedAspect ? 0 : this.scrolled), left: this.originalRect.left, - top: this.originalRect.top - this.scrolled + top: this.originalRect.top - (fixedAspect ? 0 : this.scrolled) }; const offsetX = event.clientX - oEvent.clientX; const offsetY = event.clientY - oEvent.clientY; - if (dir.indexOf('e') > -1) { - newRect.width += offsetX; - } else if (dir.indexOf('w') > -1) { - newRect.width -= offsetX; - newRect.left += offsetX; + if (fixedAspect) + { + // If the window is being resized using the corner + if (dir.length > 1) { + + if (offsetX > offsetY) { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + } else { + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } + + + + } else { + if (dir.indexOf('e') > -1) { + newRect.width += offsetX; + newRect.height += Math.round(offsetX / fixedAspectRatio); + } else if (dir.indexOf('w') > -1) { + newRect.width -= offsetX; + newRect.left += offsetX; + + newRect.height -= Math.round(offsetX / fixedAspectRatio); + newRect.top += Math.round(offsetX / fixedAspectRatio); + } + + if (dir.indexOf('s') > -1) { + newRect.height += offsetY; + newRect.width += Math.round(offsetY * fixedAspectRatio); + } else if (dir.indexOf('n') > -1) { + newRect.height -= offsetY; + newRect.top += offsetY; + + newRect.width -= Math.round(offsetY * fixedAspectRatio); + newRect.left += Math.round(offsetY * fixedAspectRatio); + } + } } - if (dir.indexOf('s') > -1) { - newRect.height += offsetY; - } else if (dir.indexOf('n') > -1) { - newRect.height -= offsetY; - newRect.top += offsetY + else + { + if (dir.indexOf('e') > -1) { // East + newRect.width += offsetX; + } else if (dir.indexOf('w') > -1) { // West + newRect.width -= offsetX; + newRect.left += offsetX; + } + + if (dir.indexOf('s') > -1) { // South // HERE + newRect.height += offsetY; + } else if (dir.indexOf('n') > -1) { // North + newRect.height -= offsetY; + newRect.top += offsetY + } } + const constrain = this._constrainSize(newRect.width, newRect.height); if (Math.round(newRect.width) !== Math.round(constrain.width)) { // round to ignore slight round-off errors if (dir.indexOf('w') > -1) { diff --git a/src/gridstack.ts b/src/gridstack.ts index 6f98132a2..2ba5280d4 100644 --- a/src/gridstack.ts +++ b/src/gridstack.ts @@ -390,6 +390,10 @@ export class GridStack { this._updateWindowResizeEvent(); } + public change() { + this._triggerChangeEvent(); + } + /** * add a new widget and returns it. *