gridstack 7.3.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/README.md +9 -2
  2. package/dist/dd-base-impl.d.ts +20 -20
  3. package/dist/dd-base-impl.js +31 -35
  4. package/dist/dd-base-impl.js.map +1 -1
  5. package/dist/dd-draggable.d.ts +28 -28
  6. package/dist/dd-draggable.js +336 -344
  7. package/dist/dd-draggable.js.map +1 -1
  8. package/dist/dd-droppable.d.ts +26 -26
  9. package/dist/dd-droppable.js +146 -148
  10. package/dist/dd-droppable.js.map +1 -1
  11. package/dist/dd-element.d.ts +27 -27
  12. package/dist/dd-element.js +90 -94
  13. package/dist/dd-element.js.map +1 -1
  14. package/dist/dd-gridstack.d.ts +34 -34
  15. package/dist/dd-gridstack.js +127 -124
  16. package/dist/dd-gridstack.js.map +1 -1
  17. package/dist/dd-manager.d.ts +22 -22
  18. package/dist/dd-manager.js +9 -13
  19. package/dist/dd-manager.js.map +1 -1
  20. package/dist/dd-resizable-handle.d.ts +14 -14
  21. package/dist/dd-resizable-handle.js +102 -105
  22. package/dist/dd-resizable-handle.js.map +1 -1
  23. package/dist/dd-resizable.d.ts +28 -28
  24. package/dist/dd-resizable.js +290 -296
  25. package/dist/dd-resizable.js.map +1 -1
  26. package/dist/dd-touch.d.ts +33 -33
  27. package/dist/dd-touch.js +173 -182
  28. package/dist/dd-touch.js.map +1 -1
  29. package/dist/es5/dd-base-impl.d.ts +20 -20
  30. package/dist/es5/dd-base-impl.js +40 -40
  31. package/dist/es5/dd-base-impl.js.map +1 -1
  32. package/dist/es5/dd-draggable.d.ts +28 -28
  33. package/dist/es5/dd-draggable.js +366 -367
  34. package/dist/es5/dd-draggable.js.map +1 -1
  35. package/dist/es5/dd-droppable.d.ts +26 -26
  36. package/dist/es5/dd-droppable.js +181 -179
  37. package/dist/es5/dd-droppable.js.map +1 -1
  38. package/dist/es5/dd-element.d.ts +27 -27
  39. package/dist/es5/dd-element.js +95 -95
  40. package/dist/es5/dd-element.js.map +1 -1
  41. package/dist/es5/dd-gridstack.d.ts +34 -34
  42. package/dist/es5/dd-gridstack.js +144 -144
  43. package/dist/es5/dd-gridstack.js.map +1 -1
  44. package/dist/es5/dd-manager.d.ts +22 -22
  45. package/dist/es5/dd-manager.js +16 -16
  46. package/dist/es5/dd-manager.js.map +1 -1
  47. package/dist/es5/dd-resizable-handle.d.ts +14 -14
  48. package/dist/es5/dd-resizable-handle.js +105 -106
  49. package/dist/es5/dd-resizable-handle.js.map +1 -1
  50. package/dist/es5/dd-resizable.d.ts +28 -28
  51. package/dist/es5/dd-resizable.js +317 -318
  52. package/dist/es5/dd-resizable.js.map +1 -1
  53. package/dist/es5/dd-touch.d.ts +33 -33
  54. package/dist/es5/dd-touch.js +185 -185
  55. package/dist/es5/dd-touch.js.map +1 -1
  56. package/dist/es5/gridstack-all.js +1 -1
  57. package/dist/es5/gridstack-all.js.LICENSE.txt +1 -1
  58. package/dist/es5/gridstack-all.js.map +1 -1
  59. package/dist/es5/gridstack-engine.d.ts +102 -102
  60. package/dist/es5/gridstack-engine.js +1000 -995
  61. package/dist/es5/gridstack-engine.js.map +1 -1
  62. package/dist/es5/gridstack-poly.js +1 -1
  63. package/dist/es5/gridstack.d.ts +392 -376
  64. package/dist/es5/gridstack.js +2254 -2233
  65. package/dist/es5/gridstack.js.map +1 -1
  66. package/dist/es5/types.d.ts +279 -284
  67. package/dist/es5/types.js +47 -35
  68. package/dist/es5/types.js.map +1 -1
  69. package/dist/es5/utils.d.ts +95 -93
  70. package/dist/es5/utils.js +600 -569
  71. package/dist/es5/utils.js.map +1 -1
  72. package/dist/gridstack-all.js +1 -1
  73. package/dist/gridstack-all.js.LICENSE.txt +1 -1
  74. package/dist/gridstack-all.js.map +1 -1
  75. package/dist/gridstack-engine.d.ts +102 -102
  76. package/dist/gridstack-engine.js +950 -954
  77. package/dist/gridstack-engine.js.map +1 -1
  78. package/dist/gridstack-extra.css +0 -390
  79. package/dist/gridstack-extra.min.css +1 -1
  80. package/dist/gridstack.css +19 -97
  81. package/dist/gridstack.d.ts +392 -376
  82. package/dist/gridstack.js +2155 -2157
  83. package/dist/gridstack.js.map +1 -1
  84. package/dist/gridstack.min.css +1 -1
  85. package/dist/ng/README.md +154 -0
  86. package/dist/ng/gridstack-item.component.d.ts +29 -0
  87. package/dist/ng/gridstack-item.component.js +65 -0
  88. package/dist/ng/gridstack-item.component.js.map +1 -0
  89. package/dist/ng/gridstack.component.d.ts +118 -0
  90. package/dist/ng/gridstack.component.js +245 -0
  91. package/dist/ng/gridstack.component.js.map +1 -0
  92. package/dist/src/gridstack-extra.scss +0 -2
  93. package/dist/src/gridstack.scss +14 -9
  94. package/dist/types.d.ts +279 -284
  95. package/dist/types.js +44 -35
  96. package/dist/types.js.map +1 -1
  97. package/dist/utils.d.ts +95 -93
  98. package/dist/utils.js +546 -527
  99. package/dist/utils.js.map +1 -1
  100. package/{dist → dist_save}/angular/gridstack-item.component.ts +5 -3
  101. package/{dist → dist_save}/angular/gridstack.component.ts +32 -18
  102. package/dist_save/dd-base-impl.d.ts +20 -0
  103. package/dist_save/dd-base-impl.js +36 -0
  104. package/dist_save/dd-base-impl.js.map +1 -0
  105. package/dist_save/dd-draggable.d.ts +28 -0
  106. package/dist_save/dd-draggable.js +343 -0
  107. package/dist_save/dd-draggable.js.map +1 -0
  108. package/dist_save/dd-droppable.d.ts +26 -0
  109. package/dist_save/dd-droppable.js +149 -0
  110. package/dist_save/dd-droppable.js.map +1 -0
  111. package/dist_save/dd-element.d.ts +27 -0
  112. package/dist_save/dd-element.js +95 -0
  113. package/dist_save/dd-element.js.map +1 -0
  114. package/dist_save/dd-gridstack.d.ts +34 -0
  115. package/dist_save/dd-gridstack.js +125 -0
  116. package/dist_save/dd-gridstack.js.map +1 -0
  117. package/dist_save/dd-manager.d.ts +22 -0
  118. package/dist_save/dd-manager.js +14 -0
  119. package/dist_save/dd-manager.js.map +1 -0
  120. package/dist_save/dd-resizable-handle.d.ts +14 -0
  121. package/dist_save/dd-resizable-handle.js +106 -0
  122. package/dist_save/dd-resizable-handle.js.map +1 -0
  123. package/dist_save/dd-resizable.d.ts +28 -0
  124. package/dist_save/dd-resizable.js +294 -0
  125. package/dist_save/dd-resizable.js.map +1 -0
  126. package/dist_save/dd-touch.d.ts +33 -0
  127. package/dist_save/dd-touch.js +183 -0
  128. package/dist_save/dd-touch.js.map +1 -0
  129. package/dist_save/es5/dd-base-impl.d.ts +20 -0
  130. package/dist_save/es5/dd-base-impl.js +41 -0
  131. package/dist_save/es5/dd-base-impl.js.map +1 -0
  132. package/dist_save/es5/dd-draggable.d.ts +28 -0
  133. package/dist_save/es5/dd-draggable.js +366 -0
  134. package/dist_save/es5/dd-draggable.js.map +1 -0
  135. package/dist_save/es5/dd-droppable.d.ts +26 -0
  136. package/dist_save/es5/dd-droppable.js +180 -0
  137. package/dist_save/es5/dd-droppable.js.map +1 -0
  138. package/dist_save/es5/dd-element.d.ts +27 -0
  139. package/dist_save/es5/dd-element.js +96 -0
  140. package/dist_save/es5/dd-element.js.map +1 -0
  141. package/dist_save/es5/dd-gridstack.d.ts +34 -0
  142. package/dist_save/es5/dd-gridstack.js +145 -0
  143. package/dist_save/es5/dd-gridstack.js.map +1 -0
  144. package/dist_save/es5/dd-manager.d.ts +22 -0
  145. package/dist_save/es5/dd-manager.js +17 -0
  146. package/dist_save/es5/dd-manager.js.map +1 -0
  147. package/dist_save/es5/dd-resizable-handle.d.ts +14 -0
  148. package/dist_save/es5/dd-resizable-handle.js +107 -0
  149. package/dist_save/es5/dd-resizable-handle.js.map +1 -0
  150. package/dist_save/es5/dd-resizable.d.ts +28 -0
  151. package/dist_save/es5/dd-resizable.js +316 -0
  152. package/dist_save/es5/dd-resizable.js.map +1 -0
  153. package/dist_save/es5/dd-touch.d.ts +33 -0
  154. package/dist_save/es5/dd-touch.js +186 -0
  155. package/dist_save/es5/dd-touch.js.map +1 -0
  156. package/dist_save/es5/gridstack-all.js +3 -0
  157. package/dist_save/es5/gridstack-all.js.LICENSE.txt +7 -0
  158. package/dist_save/es5/gridstack-all.js.map +1 -0
  159. package/dist_save/es5/gridstack-engine.d.ts +102 -0
  160. package/dist_save/es5/gridstack-engine.js +997 -0
  161. package/dist_save/es5/gridstack-engine.js.map +1 -0
  162. package/dist_save/es5/gridstack-poly.js +356 -0
  163. package/dist_save/es5/gridstack.d.ts +376 -0
  164. package/dist_save/es5/gridstack.js +2238 -0
  165. package/dist_save/es5/gridstack.js.map +1 -0
  166. package/dist_save/es5/types.d.ts +284 -0
  167. package/dist_save/es5/types.js +36 -0
  168. package/dist_save/es5/types.js.map +1 -0
  169. package/dist_save/es5/utils.d.ts +95 -0
  170. package/dist_save/es5/utils.js +590 -0
  171. package/dist_save/es5/utils.js.map +1 -0
  172. package/dist_save/gridstack-all.js +3 -0
  173. package/dist_save/gridstack-all.js.LICENSE.txt +7 -0
  174. package/dist_save/gridstack-all.js.map +1 -0
  175. package/dist_save/gridstack-engine.d.ts +102 -0
  176. package/dist_save/gridstack-engine.js +956 -0
  177. package/dist_save/gridstack-engine.js.map +1 -0
  178. package/dist_save/gridstack-extra.css +433 -0
  179. package/dist_save/gridstack-extra.min.css +1 -0
  180. package/dist_save/gridstack.css +226 -0
  181. package/dist_save/gridstack.d.ts +376 -0
  182. package/dist_save/gridstack.js +2162 -0
  183. package/dist_save/gridstack.js.map +1 -0
  184. package/dist_save/gridstack.min.css +1 -0
  185. package/dist_save/src/gridstack-extra.scss +27 -0
  186. package/dist_save/src/gridstack.scss +131 -0
  187. package/dist_save/types.d.ts +284 -0
  188. package/dist_save/types.js +36 -0
  189. package/dist_save/types.js.map +1 -0
  190. package/dist_save/utils.d.ts +95 -0
  191. package/dist_save/utils.js +548 -0
  192. package/dist_save/utils.js.map +1 -0
  193. package/doc/CHANGES.md +20 -0
  194. package/doc/README.md +21 -14
  195. package/package.json +25 -24
  196. /package/{dist → dist_save}/angular/README.md +0 -0
@@ -1,2234 +1,2255 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
16
- }) : (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- o[k2] = m[k];
19
- }));
20
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
22
- };
23
- var __spreadArrays = (this && this.__spreadArrays) || function () {
24
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
25
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
26
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
27
- r[k] = a[j];
28
- return r;
29
- };
30
- Object.defineProperty(exports, "__esModule", { value: true });
31
- exports.GridStack = void 0;
32
- /*!
33
- * GridStack 7.3.0
34
- * https://gridstackjs.com/
35
- *
36
- * Copyright (c) 2021-2022 Alain Dumesny
37
- * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE
38
- */
39
- var gridstack_engine_1 = require("./gridstack-engine");
40
- var utils_1 = require("./utils");
41
- var types_1 = require("./types");
42
- /*
43
- * and include D&D by default
44
- * TODO: while we could generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)
45
- * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts
46
- * also it caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039
47
- */
48
- var dd_gridstack_1 = require("./dd-gridstack");
49
- var dd_touch_1 = require("./dd-touch");
50
- var dd_manager_1 = require("./dd-manager");
51
- /** global instance */
52
- var dd = new dd_gridstack_1.DDGridStack;
53
- // export all dependent file as well to make it easier for users to just import the main file
54
- __exportStar(require("./types"), exports);
55
- __exportStar(require("./utils"), exports);
56
- __exportStar(require("./gridstack-engine"), exports);
57
- __exportStar(require("./dd-gridstack"), exports);
58
- /**
59
- * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.
60
- * Note: your grid elements MUST have the following classes for the CSS layout to work:
61
- * @example
62
- * <div class="grid-stack">
63
- * <div class="grid-stack-item">
64
- * <div class="grid-stack-item-content">Item 1</div>
65
- * </div>
66
- * </div>
67
- */
68
- var GridStack = /** @class */ (function () {
69
- /**
70
- * Construct a grid item from the given element and options
71
- * @param el
72
- * @param opts
73
- */
74
- function GridStack(el, opts) {
75
- var _this = this;
76
- if (opts === void 0) { opts = {}; }
77
- var _a, _b;
78
- /** @internal */
79
- this._gsEventHandler = {};
80
- /** @internal extra row added when dragging at the bottom of the grid */
81
- this._extraDragRow = 0;
82
- this.el = el; // exposed HTML element to the user
83
- opts = opts || {}; // handles null/undefined/0
84
- if (!el.classList.contains('grid-stack')) {
85
- this.el.classList.add('grid-stack');
86
- }
87
- // if row property exists, replace minRow and maxRow instead
88
- if (opts.row) {
89
- opts.minRow = opts.maxRow = opts.row;
90
- delete opts.row;
91
- }
92
- var rowAttr = utils_1.Utils.toNumber(el.getAttribute('gs-row'));
93
- // flag only valid in sub-grids (handled by parent, not here)
94
- if (opts.column === 'auto') {
95
- delete opts.column;
96
- }
97
- // 'minWidth' legacy support in 5.1
98
- /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
99
- var anyOpts = opts;
100
- if (anyOpts.minWidth !== undefined) {
101
- opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;
102
- delete anyOpts.minWidth;
103
- }
104
- // save original setting so we can restore on save
105
- if (opts.alwaysShowResizeHandle !== undefined) {
106
- opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;
107
- }
108
- // elements DOM attributes override any passed options (like CSS style) - merge the two together
109
- var defaults = __assign(__assign({}, utils_1.Utils.cloneDeep(types_1.gridDefaults)), { column: utils_1.Utils.toNumber(el.getAttribute('gs-column')) || types_1.gridDefaults.column, minRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-min-row')) || types_1.gridDefaults.minRow, maxRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-max-row')) || types_1.gridDefaults.maxRow, staticGrid: utils_1.Utils.toBool(el.getAttribute('gs-static')) || types_1.gridDefaults.staticGrid, draggable: {
110
- handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || types_1.gridDefaults.draggable.handle,
111
- }, removableOptions: {
112
- accept: opts.itemClass ? '.' + opts.itemClass : types_1.gridDefaults.removableOptions.accept,
113
- } });
114
- if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead
115
- defaults.animate = utils_1.Utils.toBool(el.getAttribute('gs-animate'));
116
- }
117
- this.opts = utils_1.Utils.defaults(opts, defaults);
118
- opts = null; // make sure we use this.opts instead
119
- this._initMargin(); // part of settings defaults...
120
- // 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)
121
- if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {
122
- this._prevColumn = this.getColumn();
123
- this.opts.column = 1;
124
- }
125
- if (this.opts.rtl === 'auto') {
126
- this.opts.rtl = (el.style.direction === 'rtl');
127
- }
128
- if (this.opts.rtl) {
129
- this.el.classList.add('grid-stack-rtl');
130
- }
131
- // check if we're been nested, and if so update our style and keep pointer around (used during save)
132
- var parentGridItem = (_a = utils_1.Utils.closestUpByClass(this.el, types_1.gridDefaults.itemClass)) === null || _a === void 0 ? void 0 : _a.gridstackNode;
133
- if (parentGridItem) {
134
- parentGridItem.subGrid = this;
135
- this.parentGridItem = parentGridItem;
136
- this.el.classList.add('grid-stack-nested');
137
- parentGridItem.el.classList.add('grid-stack-sub-grid');
138
- }
139
- this._isAutoCellHeight = (this.opts.cellHeight === 'auto');
140
- if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {
141
- // make the cell content square initially (will use resize/column event to keep it square)
142
- this.cellHeight(undefined, false);
143
- }
144
- else {
145
- // append unit if any are set
146
- if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== types_1.gridDefaults.cellHeightUnit) {
147
- this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;
148
- delete this.opts.cellHeightUnit;
149
- }
150
- this.cellHeight(this.opts.cellHeight, false);
151
- }
152
- // see if we need to adjust auto-hide
153
- if (this.opts.alwaysShowResizeHandle === 'mobile') {
154
- this.opts.alwaysShowResizeHandle = dd_touch_1.isTouch;
155
- }
156
- this._styleSheetClass = 'grid-stack-instance-' + gridstack_engine_1.GridStackEngine._idSeq++;
157
- this.el.classList.add(this._styleSheetClass);
158
- this._setStaticClass();
159
- var engineClass = this.opts.engineClass || GridStack.engineClass || gridstack_engine_1.GridStackEngine;
160
- this.engine = new engineClass({
161
- column: this.getColumn(),
162
- float: this.opts.float,
163
- maxRow: this.opts.maxRow,
164
- onChange: function (cbNodes) {
165
- var maxH = 0;
166
- _this.engine.nodes.forEach(function (n) { maxH = Math.max(maxH, n.y + n.h); });
167
- cbNodes.forEach(function (n) {
168
- var el = n.el;
169
- if (!el)
170
- return;
171
- if (n._removeDOM) {
172
- if (el)
173
- el.remove();
174
- delete n._removeDOM;
175
- }
176
- else {
177
- _this._writePosAttr(el, n);
178
- }
179
- });
180
- _this._updateStyles(false, maxH); // false = don't recreate, just append if need be
181
- }
182
- });
183
- if (this.opts.auto) {
184
- this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...
185
- this.getGridItems().forEach(function (el) { return _this._prepareElement(el); });
186
- this.batchUpdate(false);
187
- }
188
- // load any passed in children as well, which overrides any DOM layout done above
189
- if (this.opts.children) {
190
- var children = this.opts.children;
191
- delete this.opts.children;
192
- if (children.length)
193
- this.load(children); // don't load empty
194
- }
195
- this.setAnimation(this.opts.animate);
196
- this._updateStyles();
197
- if (this.opts.column != 12) {
198
- this.el.classList.add('grid-stack-' + this.opts.column);
199
- }
200
- // legacy support to appear 'per grid` options when really global.
201
- if (this.opts.dragIn)
202
- GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);
203
- delete this.opts.dragIn;
204
- delete this.opts.dragInOptions;
205
- // dynamic grids require pausing during drag to detect over to nest vs push
206
- if (this.opts.subGridDynamic && !dd_manager_1.DDManager.pauseDrag)
207
- dd_manager_1.DDManager.pauseDrag = true;
208
- if (((_b = this.opts.draggable) === null || _b === void 0 ? void 0 : _b.pause) !== undefined)
209
- dd_manager_1.DDManager.pauseDrag = this.opts.draggable.pause;
210
- this._setupRemoveDrop();
211
- this._setupAcceptWidget();
212
- this._updateWindowResizeEvent();
213
- }
214
- /**
215
- * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will
216
- * simply return the existing instance (ignore any passed options). There is also an initAll() version that support
217
- * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.
218
- * @param options grid options (optional)
219
- * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)
220
- *
221
- * @example
222
- * let grid = GridStack.init();
223
- *
224
- * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later
225
- * let grid = document.querySelector('.grid-stack').gridstack;
226
- */
227
- GridStack.init = function (options, elOrString) {
228
- if (options === void 0) { options = {}; }
229
- if (elOrString === void 0) { elOrString = '.grid-stack'; }
230
- var el = GridStack.getGridElement(elOrString);
231
- if (!el) {
232
- if (typeof elOrString === 'string') {
233
- console.error('GridStack.initAll() no grid was found with selector "' + elOrString + '" - element missing or wrong selector ?' +
234
- '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
235
- }
236
- else {
237
- console.error('GridStack.init() no grid element was passed.');
238
- }
239
- return null;
240
- }
241
- if (!el.gridstack) {
242
- el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
243
- }
244
- return el.gridstack;
245
- };
246
- /**
247
- * Will initialize a list of elements (given a selector) and return an array of grids.
248
- * @param options grid options (optional)
249
- * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)
250
- *
251
- * @example
252
- * let grids = GridStack.initAll();
253
- * grids.forEach(...)
254
- */
255
- GridStack.initAll = function (options, selector) {
256
- if (options === void 0) { options = {}; }
257
- if (selector === void 0) { selector = '.grid-stack'; }
258
- var grids = [];
259
- GridStack.getGridElements(selector).forEach(function (el) {
260
- if (!el.gridstack) {
261
- el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
262
- delete options.dragIn;
263
- delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)
264
- }
265
- grids.push(el.gridstack);
266
- });
267
- if (grids.length === 0) {
268
- console.error('GridStack.initAll() no grid was found with selector "' + selector + '" - element missing or wrong selector ?' +
269
- '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
270
- }
271
- return grids;
272
- };
273
- /**
274
- * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then
275
- * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from
276
- * JSON serialized data, including options.
277
- * @param parent HTML element parent to the grid
278
- * @param opt grids options used to initialize the grid, and list of children
279
- */
280
- GridStack.addGrid = function (parent, opt) {
281
- if (opt === void 0) { opt = {}; }
282
- if (!parent)
283
- return null;
284
- // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead
285
- var el = parent;
286
- var parentIsGrid = parent.classList.contains('grid-stack');
287
- if (!parentIsGrid || opt.addRemoveCB) {
288
- if (opt.addRemoveCB) {
289
- el = opt.addRemoveCB(parent, opt, true, true);
290
- }
291
- else {
292
- var doc = document.implementation.createHTMLDocument(''); // IE needs a param
293
- doc.body.innerHTML = "<div class=\"grid-stack " + (opt.class || '') + "\"></div>";
294
- el = doc.body.children[0];
295
- parent.appendChild(el);
296
- }
297
- }
298
- // create grid class and load any children
299
- var grid = GridStack.init(opt, el);
300
- return grid;
301
- };
302
- /** call this method to register your engine instead of the default one.
303
- * See instead `GridStackOptions.engineClass` if you only need to
304
- * replace just one instance.
305
- */
306
- GridStack.registerEngine = function (engineClass) {
307
- GridStack.engineClass = engineClass;
308
- };
309
- Object.defineProperty(GridStack.prototype, "placeholder", {
310
- /** @internal create placeholder DIV as needed */
311
- get: function () {
312
- if (!this._placeholder) {
313
- var placeholderChild = document.createElement('div'); // child so padding match item-content
314
- placeholderChild.className = 'placeholder-content';
315
- if (this.opts.placeholderText) {
316
- placeholderChild.innerHTML = this.opts.placeholderText;
317
- }
318
- this._placeholder = document.createElement('div');
319
- this._placeholder.classList.add(this.opts.placeholderClass, types_1.gridDefaults.itemClass, this.opts.itemClass);
320
- this.placeholder.appendChild(placeholderChild);
321
- }
322
- return this._placeholder;
323
- },
324
- enumerable: false,
325
- configurable: true
326
- });
327
- /**
328
- * add a new widget and returns it.
329
- *
330
- * Widget will be always placed even if result height is more than actual grid height.
331
- * You need to use `willItFit()` before calling addWidget for additional check.
332
- * See also `makeWidget()`.
333
- *
334
- * @example
335
- * let grid = GridStack.init();
336
- * grid.addWidget({w: 3, content: 'hello'});
337
- * grid.addWidget('<div class="grid-stack-item"><div class="grid-stack-item-content">hello</div></div>', {w: 3});
338
- *
339
- * @param el GridStackWidget (which can have content string as well), html element, or string definition to add
340
- * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget
341
- */
342
- GridStack.prototype.addWidget = function (els, options) {
343
- function isGridStackWidget(w) {
344
- return w.el !== undefined || w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;
345
- }
346
- var el;
347
- var node;
348
- if (typeof els === 'string') {
349
- var doc = document.implementation.createHTMLDocument(''); // IE needs a param
350
- doc.body.innerHTML = els;
351
- el = doc.body.children[0];
352
- }
353
- else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {
354
- node = options = els;
355
- if (node === null || node === void 0 ? void 0 : node.el) {
356
- el = node.el; // re-use element stored in the node
357
- }
358
- else if (this.opts.addRemoveCB) {
359
- el = this.opts.addRemoveCB(this.el, options, true, false);
360
- }
361
- else {
362
- var content = (options === null || options === void 0 ? void 0 : options.content) || '';
363
- var doc = document.implementation.createHTMLDocument(''); // IE needs a param
364
- doc.body.innerHTML = "<div class=\"grid-stack-item " + (this.opts.itemClass || '') + "\"><div class=\"grid-stack-item-content\">" + content + "</div></div>";
365
- el = doc.body.children[0];
366
- }
367
- }
368
- else {
369
- el = els;
370
- }
371
- if (!el)
372
- return;
373
- // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos
374
- // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz') before adding the node.
375
- // So make sure we load any DOM attributes that are not specified in passed in options (which override)
376
- var domAttr = this._readAttr(el);
377
- options = utils_1.Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it
378
- utils_1.Utils.defaults(options, domAttr);
379
- node = this.engine.prepareNode(options);
380
- this._writeAttr(el, options);
381
- if (this._insertNotAppend) {
382
- this.el.prepend(el);
383
- }
384
- else {
385
- this.el.appendChild(el);
386
- }
387
- // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id
388
- this._prepareElement(el, true, options);
389
- this._updateContainerHeight();
390
- // see if there is a sub-grid to create
391
- if (node.subGrid) {
392
- this.makeSubGrid(node.el, undefined, undefined, false); //node.subGrid will be used as option in method, no need to pass
393
- }
394
- // if we're adding an item into 1 column (_prevColumn is set only when going to 1) make sure
395
- // we don't override the larger 12 column layout that was already saved. #1985
396
- if (this._prevColumn && this.opts.column === 1) {
397
- this._ignoreLayoutsNodeChange = true;
398
- }
399
- this._triggerAddEvent();
400
- this._triggerChangeEvent();
401
- delete this._ignoreLayoutsNodeChange;
402
- return el;
403
- };
404
- /**
405
- * Convert an existing gridItem element into a sub-grid with the given (optional) options, else inherit them
406
- * from the parent's subGrid options.
407
- * @param el gridItem element to convert
408
- * @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults
409
- * @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)
410
- * @returns newly created grid
411
- */
412
- GridStack.prototype.makeSubGrid = function (el, ops, nodeToAdd, saveContent) {
413
- var _a, _b, _c;
414
- if (saveContent === void 0) { saveContent = true; }
415
- var node = el.gridstackNode;
416
- if (!node) {
417
- node = this.makeWidget(el).gridstackNode;
418
- }
419
- if ((_a = node.subGrid) === null || _a === void 0 ? void 0 : _a.el)
420
- return node.subGrid; // already done
421
- // find the template subGrid stored on a parent as fallback...
422
- var subGridTemplate; // eslint-disable-next-line @typescript-eslint/no-this-alias
423
- var grid = this;
424
- while (grid && !subGridTemplate) {
425
- subGridTemplate = (_b = grid.opts) === null || _b === void 0 ? void 0 : _b.subGrid;
426
- grid = (_c = grid.parentGridItem) === null || _c === void 0 ? void 0 : _c.grid;
427
- }
428
- //... and set the create options
429
- ops = utils_1.Utils.cloneDeep(__assign(__assign(__assign({}, (subGridTemplate || {})), { children: undefined }), (ops || node.subGrid)));
430
- node.subGrid = ops;
431
- // if column special case it set, remember that flag and set default
432
- var autoColumn;
433
- if (ops.column === 'auto') {
434
- autoColumn = true;
435
- ops.column = Math.max(node.w || 1, (nodeToAdd === null || nodeToAdd === void 0 ? void 0 : nodeToAdd.w) || 1);
436
- ops.disableOneColumnMode = true; // driven by parent
437
- }
438
- // if we're converting an existing full item, move over the content to be the first sub item in the new grid
439
- var content = node.el.querySelector('.grid-stack-item-content');
440
- var newItem;
441
- var newItemOpt;
442
- if (saveContent) {
443
- this._removeDD(node.el); // remove D&D since it's set on content div
444
- newItemOpt = __assign(__assign({}, node), { x: 0, y: 0 });
445
- utils_1.Utils.removeInternalForSave(newItemOpt);
446
- delete newItemOpt.subGrid;
447
- if (node.content) {
448
- newItemOpt.content = node.content;
449
- delete node.content;
450
- }
451
- if (this.opts.addRemoveCB) {
452
- newItem = this.opts.addRemoveCB(this.el, newItemOpt, true, false);
453
- }
454
- else {
455
- var doc = document.implementation.createHTMLDocument(''); // IE needs a param
456
- doc.body.innerHTML = "<div class=\"grid-stack-item\"></div>";
457
- newItem = doc.body.children[0];
458
- newItem.appendChild(content);
459
- doc.body.innerHTML = "<div class=\"grid-stack-item-content\"></div>";
460
- content = doc.body.children[0];
461
- node.el.appendChild(content);
462
- }
463
- this._prepareDragDropByNode(node); // ... and restore original D&D
464
- }
465
- // if we're adding an additional item, make the container large enough to have them both
466
- if (nodeToAdd) {
467
- var w = autoColumn ? ops.column : node.w;
468
- var h = node.h + nodeToAdd.h;
469
- var style_1 = node.el.style;
470
- style_1.transition = 'none'; // show up instantly so we don't see scrollbar with nodeToAdd
471
- this.update(node.el, { w: w, h: h });
472
- setTimeout(function () { return style_1.transition = null; }); // recover animation
473
- }
474
- if (this.opts.addRemoveCB) {
475
- ops.addRemoveCB = ops.addRemoveCB || this.opts.addRemoveCB;
476
- }
477
- var subGrid = node.subGrid = GridStack.addGrid(content, ops);
478
- if (nodeToAdd === null || nodeToAdd === void 0 ? void 0 : nodeToAdd._moving)
479
- subGrid._isTemp = true; // prevent re-nesting as we add over
480
- if (autoColumn)
481
- subGrid._autoColumn = true;
482
- // add the original content back as a child of hte newly created grid
483
- if (saveContent) {
484
- subGrid.addWidget(newItem, newItemOpt);
485
- }
486
- // now add any additional node
487
- if (nodeToAdd) {
488
- if (nodeToAdd._moving) {
489
- // create an artificial event even for the just created grid to receive this item
490
- window.setTimeout(function () { return utils_1.Utils.simulateMouseEvent(nodeToAdd._event, 'mouseenter', subGrid.el); }, 0);
491
- }
492
- else {
493
- subGrid.addWidget(node.el, node);
494
- }
495
- }
496
- return subGrid;
497
- };
498
- /**
499
- * called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back
500
- * to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)
501
- */
502
- GridStack.prototype.removeAsSubGrid = function (nodeThatRemoved) {
503
- var _this = this;
504
- var _a;
505
- var pGrid = (_a = this.parentGridItem) === null || _a === void 0 ? void 0 : _a.grid;
506
- if (!pGrid)
507
- return;
508
- pGrid.batchUpdate();
509
- pGrid.removeWidget(this.parentGridItem.el, true, true);
510
- this.engine.nodes.forEach(function (n) {
511
- // migrate any children over and offsetting by our location
512
- n.x += _this.parentGridItem.x;
513
- n.y += _this.parentGridItem.y;
514
- pGrid.addWidget(n.el, n);
515
- });
516
- pGrid.batchUpdate(false);
517
- if (this.parentGridItem)
518
- delete this.parentGridItem.subGrid;
519
- delete this.parentGridItem;
520
- // create an artificial event for the original grid now that this one is gone (got a leave, but won't get enter)
521
- if (nodeThatRemoved) {
522
- window.setTimeout(function () { return utils_1.Utils.simulateMouseEvent(nodeThatRemoved._event, 'mouseenter', pGrid.el); }, 0);
523
- }
524
- };
525
- /**
526
- /**
527
- * saves the current layout returning a list of widgets for serialization which might include any nested grids.
528
- * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will
529
- * be removed.
530
- * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()
531
- * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
532
- * @returns list of widgets or full grid option, including .children list of widgets
533
- */
534
- GridStack.prototype.save = function (saveContent, saveGridOpt) {
535
- if (saveContent === void 0) { saveContent = true; }
536
- if (saveGridOpt === void 0) { saveGridOpt = false; }
537
- // return copied nodes we can modify at will...
538
- var list = this.engine.save(saveContent);
539
- // check for HTML content and nested grids
540
- list.forEach(function (n) {
541
- var _a;
542
- if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content
543
- var sub = n.el.querySelector('.grid-stack-item-content');
544
- n.content = sub ? sub.innerHTML : undefined;
545
- if (!n.content)
546
- delete n.content;
547
- }
548
- else {
549
- if (!saveContent) {
550
- delete n.content;
551
- }
552
- // check for nested grid
553
- if ((_a = n.subGrid) === null || _a === void 0 ? void 0 : _a.el) {
554
- var listOrOpt = n.subGrid.save(saveContent, saveGridOpt);
555
- n.subGrid = (saveGridOpt ? listOrOpt : { children: listOrOpt });
556
- }
557
- }
558
- delete n.el;
559
- });
560
- // check if save entire grid options (needed for recursive) + children...
561
- if (saveGridOpt) {
562
- var o = utils_1.Utils.cloneDeep(this.opts);
563
- // delete default values that will be recreated on launch
564
- if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {
565
- o.margin = o.marginTop;
566
- delete o.marginTop;
567
- delete o.marginRight;
568
- delete o.marginBottom;
569
- delete o.marginLeft;
570
- }
571
- if (o.rtl === (this.el.style.direction === 'rtl')) {
572
- o.rtl = 'auto';
573
- }
574
- if (this._isAutoCellHeight) {
575
- o.cellHeight = 'auto';
576
- }
577
- if (this._autoColumn) {
578
- o.column = 'auto';
579
- delete o.disableOneColumnMode;
580
- }
581
- var origShow = o._alwaysShowResizeHandle;
582
- delete o._alwaysShowResizeHandle;
583
- if (origShow !== undefined) {
584
- o.alwaysShowResizeHandle = origShow;
585
- }
586
- else {
587
- delete o.alwaysShowResizeHandle;
588
- }
589
- utils_1.Utils.removeInternalAndSame(o, types_1.gridDefaults);
590
- o.children = list;
591
- return o;
592
- }
593
- return list;
594
- };
595
- /**
596
- * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.
597
- *
598
- * @param layout list of widgets definition to update/create
599
- * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving
600
- * the user control of insertion.
601
- *
602
- * @example
603
- * see http://gridstackjs.com/demo/serialization.html
604
- **/
605
- GridStack.prototype.load = function (layout, addRemove) {
606
- var _this = this;
607
- if (addRemove === void 0) { addRemove = this.opts.addRemoveCB || true; }
608
- var items = GridStack.Utils.sort(__spreadArrays(layout), -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort
609
- this._insertNotAppend = true; // since create in reverse order...
610
- // if we're loading a layout into for example 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save
611
- // the original wanted layout so we can scale back up correctly #1471
612
- if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(function (n) { return (n.x + n.w) > _this.opts.column; })) {
613
- this._ignoreLayoutsNodeChange = true; // skip layout update
614
- this.engine.cacheLayout(items, this._prevColumn, true);
615
- }
616
- // if given a different callback, temporally set it as global option to creating will use it
617
- var prevCB = this.opts.addRemoveCB;
618
- if (typeof (addRemove) === 'function')
619
- this.opts.addRemoveCB = addRemove;
620
- var removed = [];
621
- this.batchUpdate();
622
- // see if any items are missing from new layout and need to be removed first
623
- if (addRemove) {
624
- var copyNodes = __spreadArrays(this.engine.nodes); // don't loop through array you modify
625
- copyNodes.forEach(function (n) {
626
- var item = items.find(function (w) { return n.id === w.id; });
627
- if (!item) {
628
- if (_this.opts.addRemoveCB)
629
- _this.opts.addRemoveCB(_this.el, n, false, false);
630
- removed.push(n); // batch keep track
631
- _this.removeWidget(n.el, true, false);
632
- }
633
- });
634
- }
635
- // now add/update the widgets
636
- items.forEach(function (w) {
637
- var item = (w.id || w.id === 0) ? _this.engine.nodes.find(function (n) { return n.id === w.id; }) : undefined;
638
- if (item) {
639
- _this.update(item.el, w);
640
- if (w.subGrid && w.subGrid.children) { // update any sub grid as well
641
- var sub = item.el.querySelector('.grid-stack');
642
- if (sub && sub.gridstack) {
643
- sub.gridstack.load(w.subGrid.children); // TODO: support updating grid options ?
644
- _this._insertNotAppend = true; // got reset by above call
645
- }
646
- }
647
- }
648
- else if (addRemove) {
649
- _this.addWidget(w);
650
- }
651
- });
652
- this.engine.removedNodes = removed;
653
- this.batchUpdate(false);
654
- // after commit, clear that flag
655
- delete this._ignoreLayoutsNodeChange;
656
- delete this._insertNotAppend;
657
- prevCB ? this.opts.addRemoveCB = prevCB : delete this.opts.addRemoveCB;
658
- return this;
659
- };
660
- /**
661
- * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)
662
- * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.
663
- */
664
- GridStack.prototype.batchUpdate = function (flag) {
665
- if (flag === void 0) { flag = true; }
666
- this.engine.batchUpdate(flag);
667
- if (!flag) {
668
- this._triggerRemoveEvent();
669
- this._triggerAddEvent();
670
- this._triggerChangeEvent();
671
- }
672
- return this;
673
- };
674
- /**
675
- * Gets current cell height.
676
- */
677
- GridStack.prototype.getCellHeight = function (forcePixel) {
678
- if (forcePixel === void 0) { forcePixel = false; }
679
- if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&
680
- (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {
681
- return this.opts.cellHeight;
682
- }
683
- // else get first cell height
684
- var el = this.el.querySelector('.' + this.opts.itemClass);
685
- if (el) {
686
- var height = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
687
- return Math.round(el.offsetHeight / height);
688
- }
689
- // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)
690
- var rows = parseInt(this.el.getAttribute('gs-current-row'));
691
- return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight;
692
- };
693
- /**
694
- * Update current cell height - see `GridStackOptions.cellHeight` for format.
695
- * This method rebuilds an internal CSS style sheet.
696
- * Note: You can expect performance issues if call this method too often.
697
- *
698
- * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),
699
- * if pass 0 the CSS will be generated by the application instead.
700
- * @param update (Optional) if false, styles will not be updated
701
- *
702
- * @example
703
- * grid.cellHeight(100); // same as 100px
704
- * grid.cellHeight('70px');
705
- * grid.cellHeight(grid.cellWidth() * 1.2);
706
- */
707
- GridStack.prototype.cellHeight = function (val, update) {
708
- if (update === void 0) { update = true; }
709
- // if not called internally, check if we're changing mode
710
- if (update && val !== undefined) {
711
- if (this._isAutoCellHeight !== (val === 'auto')) {
712
- this._isAutoCellHeight = (val === 'auto');
713
- this._updateWindowResizeEvent();
714
- }
715
- }
716
- if (val === 'initial' || val === 'auto') {
717
- val = undefined;
718
- }
719
- // make item content be square
720
- if (val === undefined) {
721
- var marginDiff = -this.opts.marginRight - this.opts.marginLeft
722
- + this.opts.marginTop + this.opts.marginBottom;
723
- val = this.cellWidth() + marginDiff;
724
- }
725
- var data = utils_1.Utils.parseHeight(val);
726
- if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {
727
- return this;
728
- }
729
- this.opts.cellHeightUnit = data.unit;
730
- this.opts.cellHeight = data.h;
731
- if (update) {
732
- this._updateStyles(true); // true = force re-create for current # of rows
733
- }
734
- return this;
735
- };
736
- /** Gets current cell width. */
737
- GridStack.prototype.cellWidth = function () {
738
- return this._widthOrContainer() / this.getColumn();
739
- };
740
- /** return our expected width (or parent) for 1 column check */
741
- GridStack.prototype._widthOrContainer = function () {
742
- // use `offsetWidth` or `clientWidth` (no scrollbar) ?
743
- // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
744
- return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);
745
- };
746
- /** re-layout grid items to reclaim any empty space */
747
- GridStack.prototype.compact = function () {
748
- this.engine.compact();
749
- this._triggerChangeEvent();
750
- return this;
751
- };
752
- /**
753
- * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,
754
- * as well as cache the original layout so you can revert back to previous positions without loss.
755
- * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],
756
- * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)
757
- * @param column - Integer > 0 (default 12).
758
- * @param layout specify the type of re-layout that will happen (position, size, etc...).
759
- * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
760
- */
761
- GridStack.prototype.column = function (column, layout) {
762
- if (layout === void 0) { layout = 'moveScale'; }
763
- if (column < 1 || this.opts.column === column)
764
- return this;
765
- var oldColumn = this.getColumn();
766
- // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)
767
- // then remember the original columns so we can restore.
768
- if (column === 1) {
769
- this._prevColumn = oldColumn;
770
- }
771
- else {
772
- delete this._prevColumn;
773
- }
774
- this.el.classList.remove('grid-stack-' + oldColumn);
775
- this.el.classList.add('grid-stack-' + column);
776
- this.opts.column = this.engine.column = column;
777
- // update the items now - see if the dom order nodes should be passed instead (else default to current list)
778
- var domNodes;
779
- if (column === 1 && this.opts.oneColumnModeDomSort) {
780
- domNodes = [];
781
- this.getGridItems().forEach(function (el) {
782
- if (el.gridstackNode) {
783
- domNodes.push(el.gridstackNode);
784
- }
785
- });
786
- if (!domNodes.length) {
787
- domNodes = undefined;
788
- }
789
- }
790
- this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);
791
- if (this._isAutoCellHeight)
792
- this.cellHeight();
793
- // and trigger our event last...
794
- this._ignoreLayoutsNodeChange = true; // skip layout update
795
- this._triggerChangeEvent();
796
- delete this._ignoreLayoutsNodeChange;
797
- return this;
798
- };
799
- /**
800
- * get the number of columns in the grid (default 12)
801
- */
802
- GridStack.prototype.getColumn = function () {
803
- return this.opts.column;
804
- };
805
- /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */
806
- GridStack.prototype.getGridItems = function () {
807
- var _this = this;
808
- return Array.from(this.el.children)
809
- .filter(function (el) { return el.matches('.' + _this.opts.itemClass) && !el.matches('.' + _this.opts.placeholderClass); });
810
- };
811
- /**
812
- * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.
813
- * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).
814
- */
815
- GridStack.prototype.destroy = function (removeDOM) {
816
- if (removeDOM === void 0) { removeDOM = true; }
817
- if (!this.el)
818
- return; // prevent multiple calls
819
- this._updateWindowResizeEvent(true);
820
- this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)
821
- this.setAnimation(false);
822
- if (!removeDOM) {
823
- this.removeAll(removeDOM);
824
- this.el.classList.remove(this._styleSheetClass);
825
- }
826
- else {
827
- this.el.parentNode.removeChild(this.el);
828
- }
829
- this._removeStylesheet();
830
- this.el.removeAttribute('gs-current-row');
831
- if (this.parentGridItem)
832
- delete this.parentGridItem.subGrid;
833
- delete this.parentGridItem;
834
- delete this.opts;
835
- delete this._placeholder;
836
- delete this.engine;
837
- delete this.el.gridstack; // remove circular dependency that would prevent a freeing
838
- delete this.el;
839
- return this;
840
- };
841
- /**
842
- * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)
843
- */
844
- GridStack.prototype.float = function (val) {
845
- if (this.opts.float !== val) {
846
- this.opts.float = this.engine.float = val;
847
- this._triggerChangeEvent();
848
- }
849
- return this;
850
- };
851
- /**
852
- * get the current float mode
853
- */
854
- GridStack.prototype.getFloat = function () {
855
- return this.engine.float;
856
- };
857
- /**
858
- * Get the position of the cell under a pixel on screen.
859
- * @param position the position of the pixel to resolve in
860
- * absolute coordinates, as an object with top and left properties
861
- * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).
862
- * Useful when grid is within `position: relative` element
863
- *
864
- * Returns an object with properties `x` and `y` i.e. the column and row in the grid.
865
- */
866
- GridStack.prototype.getCellFromPixel = function (position, useDocRelative) {
867
- if (useDocRelative === void 0) { useDocRelative = false; }
868
- var box = this.el.getBoundingClientRect();
869
- // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)
870
- var containerPos;
871
- if (useDocRelative) {
872
- containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left };
873
- // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)
874
- }
875
- else {
876
- containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft };
877
- // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)
878
- }
879
- var relativeLeft = position.left - containerPos.left;
880
- var relativeTop = position.top - containerPos.top;
881
- var columnWidth = (box.width / this.getColumn());
882
- var rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));
883
- return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) };
884
- };
885
- /** returns the current number of rows, which will be at least `minRow` if set */
886
- GridStack.prototype.getRow = function () {
887
- return Math.max(this.engine.getRow(), this.opts.minRow);
888
- };
889
- /**
890
- * Checks if specified area is empty.
891
- * @param x the position x.
892
- * @param y the position y.
893
- * @param w the width of to check
894
- * @param h the height of to check
895
- */
896
- GridStack.prototype.isAreaEmpty = function (x, y, w, h) {
897
- return this.engine.isAreaEmpty(x, y, w, h);
898
- };
899
- /**
900
- * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.
901
- * If you want gridstack to add the elements for you, use `addWidget()` instead.
902
- * Makes the given element a widget and returns it.
903
- * @param els widget or single selector to convert.
904
- *
905
- * @example
906
- * let grid = GridStack.init();
907
- * grid.el.appendChild('<div id="gsi-1" gs-w="3"></div>');
908
- * grid.makeWidget('#gsi-1');
909
- */
910
- GridStack.prototype.makeWidget = function (els) {
911
- var el = GridStack.getElement(els);
912
- this._prepareElement(el, true);
913
- this._updateContainerHeight();
914
- this._triggerAddEvent();
915
- this._triggerChangeEvent();
916
- return el;
917
- };
918
- /**
919
- * Event handler that extracts our CustomEvent data out automatically for receiving custom
920
- * notifications (see doc for supported events)
921
- * @param name of the event (see possible values) or list of names space separated
922
- * @param callback function called with event and optional second/third param
923
- * (see README documentation for each signature).
924
- *
925
- * @example
926
- * grid.on('added', function(e, items) { log('added ', items)} );
927
- * or
928
- * grid.on('added removed change', function(e, items) { log(e.type, items)} );
929
- *
930
- * Note: in some cases it is the same as calling native handler and parsing the event.
931
- * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );
932
- *
933
- */
934
- GridStack.prototype.on = function (name, callback) {
935
- var _this = this;
936
- // check for array of names being passed instead
937
- if (name.indexOf(' ') !== -1) {
938
- var names = name.split(' ');
939
- names.forEach(function (name) { return _this.on(name, callback); });
940
- return this;
941
- }
942
- if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
943
- // native CustomEvent handlers - cash the generic handlers so we can easily remove
944
- var noData = (name === 'enable' || name === 'disable');
945
- if (noData) {
946
- this._gsEventHandler[name] = function (event) { return callback(event); };
947
- }
948
- else {
949
- this._gsEventHandler[name] = function (event) { return callback(event, event.detail); };
950
- }
951
- this.el.addEventListener(name, this._gsEventHandler[name]);
952
- }
953
- else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {
954
- // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.
955
- // do same for start event to make it easier...
956
- this._gsEventHandler[name] = callback;
957
- }
958
- else {
959
- console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');
960
- }
961
- return this;
962
- };
963
- /**
964
- * unsubscribe from the 'on' event below
965
- * @param name of the event (see possible values)
966
- */
967
- GridStack.prototype.off = function (name) {
968
- var _this = this;
969
- // check for array of names being passed instead
970
- if (name.indexOf(' ') !== -1) {
971
- var names = name.split(' ');
972
- names.forEach(function (name) { return _this.off(name); });
973
- return this;
974
- }
975
- if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
976
- // remove native CustomEvent handlers
977
- if (this._gsEventHandler[name]) {
978
- this.el.removeEventListener(name, this._gsEventHandler[name]);
979
- }
980
- }
981
- delete this._gsEventHandler[name];
982
- return this;
983
- };
984
- /**
985
- * Removes widget from the grid.
986
- * @param el widget or selector to modify
987
- * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).
988
- * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).
989
- */
990
- GridStack.prototype.removeWidget = function (els, removeDOM, triggerEvent) {
991
- var _this = this;
992
- if (removeDOM === void 0) { removeDOM = true; }
993
- if (triggerEvent === void 0) { triggerEvent = true; }
994
- GridStack.getElements(els).forEach(function (el) {
995
- if (el.parentElement && el.parentElement !== _this.el)
996
- return; // not our child!
997
- var node = el.gridstackNode;
998
- // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272
999
- if (!node) {
1000
- node = _this.engine.nodes.find(function (n) { return el === n.el; });
1001
- }
1002
- if (!node)
1003
- return;
1004
- // remove our DOM data (circular link) and drag&drop permanently
1005
- delete el.gridstackNode;
1006
- _this._removeDD(el);
1007
- _this.engine.removeNode(node, removeDOM, triggerEvent);
1008
- if (removeDOM && el.parentElement) {
1009
- el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM
1010
- }
1011
- });
1012
- if (triggerEvent) {
1013
- this._triggerRemoveEvent();
1014
- this._triggerChangeEvent();
1015
- }
1016
- return this;
1017
- };
1018
- /**
1019
- * Removes all widgets from the grid.
1020
- * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).
1021
- */
1022
- GridStack.prototype.removeAll = function (removeDOM) {
1023
- var _this = this;
1024
- if (removeDOM === void 0) { removeDOM = true; }
1025
- // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently
1026
- this.engine.nodes.forEach(function (n) {
1027
- delete n.el.gridstackNode;
1028
- _this._removeDD(n.el);
1029
- });
1030
- this.engine.removeAll(removeDOM);
1031
- this._triggerRemoveEvent();
1032
- return this;
1033
- };
1034
- /**
1035
- * Toggle the grid animation state. Toggles the `grid-stack-animate` class.
1036
- * @param doAnimate if true the grid will animate.
1037
- */
1038
- GridStack.prototype.setAnimation = function (doAnimate) {
1039
- if (doAnimate) {
1040
- this.el.classList.add('grid-stack-animate');
1041
- }
1042
- else {
1043
- this.el.classList.remove('grid-stack-animate');
1044
- }
1045
- return this;
1046
- };
1047
- /**
1048
- * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.
1049
- * Also toggle the grid-stack-static class.
1050
- * @param val if true the grid become static.
1051
- * @param updateClass true (default) if css class gets updated
1052
- * @param recurse true (default) if sub-grids also get updated
1053
- */
1054
- GridStack.prototype.setStatic = function (val, updateClass, recurse) {
1055
- var _this = this;
1056
- if (updateClass === void 0) { updateClass = true; }
1057
- if (recurse === void 0) { recurse = true; }
1058
- if (this.opts.staticGrid === val)
1059
- return this;
1060
- this.opts.staticGrid = val;
1061
- this._setupRemoveDrop();
1062
- this._setupAcceptWidget();
1063
- this.engine.nodes.forEach(function (n) {
1064
- _this._prepareDragDropByNode(n); // either delete or init Drag&drop
1065
- if (n.subGrid && recurse)
1066
- n.subGrid.setStatic(val, updateClass, recurse);
1067
- });
1068
- if (updateClass) {
1069
- this._setStaticClass();
1070
- }
1071
- return this;
1072
- };
1073
- /**
1074
- * 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.
1075
- * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)
1076
- * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.
1077
- */
1078
- GridStack.prototype.update = function (els, opt) {
1079
- var _this = this;
1080
- // support legacy call for now ?
1081
- if (arguments.length > 2) {
1082
- console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');
1083
- // eslint-disable-next-line prefer-rest-params
1084
- var a = arguments, i = 1;
1085
- opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] };
1086
- return this.update(els, opt);
1087
- }
1088
- GridStack.getElements(els).forEach(function (el) {
1089
- if (!el || !el.gridstackNode)
1090
- return;
1091
- var n = el.gridstackNode;
1092
- var w = utils_1.Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items
1093
- delete w.autoPosition;
1094
- // move/resize widget if anything changed
1095
- var keys = ['x', 'y', 'w', 'h'];
1096
- var m;
1097
- if (keys.some(function (k) { return w[k] !== undefined && w[k] !== n[k]; })) {
1098
- m = {};
1099
- keys.forEach(function (k) {
1100
- m[k] = (w[k] !== undefined) ? w[k] : n[k];
1101
- delete w[k];
1102
- });
1103
- }
1104
- // for a move as well IFF there is any min/max fields set
1105
- if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {
1106
- m = {}; // will use node position but validate values
1107
- }
1108
- // check for content changing
1109
- if (w.content) {
1110
- var sub = el.querySelector('.grid-stack-item-content');
1111
- if (sub && sub.innerHTML !== w.content) {
1112
- sub.innerHTML = w.content;
1113
- }
1114
- delete w.content;
1115
- }
1116
- // any remaining fields are assigned, but check for dragging changes, resize constrain
1117
- var changed = false;
1118
- var ddChanged = false;
1119
- for (var key in w) {
1120
- if (key[0] !== '_' && n[key] !== w[key]) {
1121
- n[key] = w[key];
1122
- changed = true;
1123
- ddChanged = ddChanged || (!_this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));
1124
- }
1125
- }
1126
- // finally move the widget
1127
- if (m) {
1128
- _this.engine.cleanNodes()
1129
- .beginUpdate(n)
1130
- .moveNode(n, m);
1131
- _this._updateContainerHeight();
1132
- _this._triggerChangeEvent();
1133
- _this.engine.endUpdate();
1134
- }
1135
- if (changed) { // move will only update x,y,w,h so update the rest too
1136
- _this._writeAttr(el, n);
1137
- }
1138
- if (ddChanged) {
1139
- _this._prepareDragDropByNode(n);
1140
- }
1141
- });
1142
- return this;
1143
- };
1144
- /**
1145
- * 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).
1146
- * @param value margin value
1147
- */
1148
- GridStack.prototype.margin = function (value) {
1149
- var isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);
1150
- // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)
1151
- if (!isMultiValue) {
1152
- var data = utils_1.Utils.parseHeight(value);
1153
- if (this.opts.marginUnit === data.unit && this.opts.margin === data.h)
1154
- return;
1155
- }
1156
- // re-use existing margin handling
1157
- this.opts.margin = value;
1158
- this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;
1159
- this._initMargin();
1160
- this._updateStyles(true); // true = force re-create
1161
- return this;
1162
- };
1163
- /** returns current margin number value (undefined if 4 sides don't match) */
1164
- GridStack.prototype.getMargin = function () { return this.opts.margin; };
1165
- /**
1166
- * Returns true if the height of the grid will be less than the vertical
1167
- * constraint. Always returns true if grid doesn't have height constraint.
1168
- * @param node contains x,y,w,h,auto-position options
1169
- *
1170
- * @example
1171
- * if (grid.willItFit(newWidget)) {
1172
- * grid.addWidget(newWidget);
1173
- * } else {
1174
- * alert('Not enough free space to place the widget');
1175
- * }
1176
- */
1177
- GridStack.prototype.willItFit = function (node) {
1178
- // support legacy call for now
1179
- if (arguments.length > 1) {
1180
- console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');
1181
- // eslint-disable-next-line prefer-rest-params
1182
- var a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] };
1183
- return this.willItFit(w);
1184
- }
1185
- return this.engine.willItFit(node);
1186
- };
1187
- /** @internal */
1188
- GridStack.prototype._triggerChangeEvent = function () {
1189
- if (this.engine.batchMode)
1190
- return this;
1191
- var elements = this.engine.getDirtyNodes(true); // verify they really changed
1192
- if (elements && elements.length) {
1193
- if (!this._ignoreLayoutsNodeChange) {
1194
- this.engine.layoutsNodesChange(elements);
1195
- }
1196
- this._triggerEvent('change', elements);
1197
- }
1198
- this.engine.saveInitial(); // we called, now reset initial values & dirty flags
1199
- return this;
1200
- };
1201
- /** @internal */
1202
- GridStack.prototype._triggerAddEvent = function () {
1203
- if (this.engine.batchMode)
1204
- return this;
1205
- if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {
1206
- if (!this._ignoreLayoutsNodeChange) {
1207
- this.engine.layoutsNodesChange(this.engine.addedNodes);
1208
- }
1209
- // prevent added nodes from also triggering 'change' event (which is called next)
1210
- this.engine.addedNodes.forEach(function (n) { delete n._dirty; });
1211
- this._triggerEvent('added', this.engine.addedNodes);
1212
- this.engine.addedNodes = [];
1213
- }
1214
- return this;
1215
- };
1216
- /** @internal */
1217
- GridStack.prototype._triggerRemoveEvent = function () {
1218
- if (this.engine.batchMode)
1219
- return this;
1220
- if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {
1221
- this._triggerEvent('removed', this.engine.removedNodes);
1222
- this.engine.removedNodes = [];
1223
- }
1224
- return this;
1225
- };
1226
- /** @internal */
1227
- GridStack.prototype._triggerEvent = function (type, data) {
1228
- var event = data ? new CustomEvent(type, { bubbles: false, detail: data }) : new Event(type);
1229
- this.el.dispatchEvent(event);
1230
- return this;
1231
- };
1232
- /** @internal called to delete the current dynamic style sheet used for our layout */
1233
- GridStack.prototype._removeStylesheet = function () {
1234
- if (this._styles) {
1235
- utils_1.Utils.removeStylesheet(this._styleSheetClass);
1236
- delete this._styles;
1237
- }
1238
- return this;
1239
- };
1240
- /** @internal updated/create the CSS styles for row based layout and initial margin setting */
1241
- GridStack.prototype._updateStyles = function (forceUpdate, maxH) {
1242
- if (forceUpdate === void 0) { forceUpdate = false; }
1243
- // call to delete existing one if we change cellHeight / margin
1244
- if (forceUpdate) {
1245
- this._removeStylesheet();
1246
- }
1247
- if (!maxH)
1248
- maxH = this.getRow();
1249
- this._updateContainerHeight();
1250
- // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
1251
- if (this.opts.cellHeight === 0) {
1252
- return this;
1253
- }
1254
- var cellHeight = this.opts.cellHeight;
1255
- var cellHeightUnit = this.opts.cellHeightUnit;
1256
- var prefix = "." + this._styleSheetClass + " > ." + this.opts.itemClass;
1257
- // create one as needed
1258
- if (!this._styles) {
1259
- // insert style to parent (instead of 'head' by default) to support WebComponent
1260
- var styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode;
1261
- this._styles = utils_1.Utils.createStylesheet(this._styleSheetClass, styleLocation, {
1262
- nonce: this.opts.nonce,
1263
- });
1264
- if (!this._styles)
1265
- return this;
1266
- this._styles._max = 0;
1267
- // these are done once only
1268
- utils_1.Utils.addCSSRule(this._styles, prefix, "min-height: " + cellHeight + cellHeightUnit);
1269
- // content margins
1270
- var top_1 = this.opts.marginTop + this.opts.marginUnit;
1271
- var bottom = this.opts.marginBottom + this.opts.marginUnit;
1272
- var right = this.opts.marginRight + this.opts.marginUnit;
1273
- var left = this.opts.marginLeft + this.opts.marginUnit;
1274
- var content = prefix + " > .grid-stack-item-content";
1275
- var placeholder = "." + this._styleSheetClass + " > .grid-stack-placeholder > .placeholder-content";
1276
- utils_1.Utils.addCSSRule(this._styles, content, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";");
1277
- utils_1.Utils.addCSSRule(this._styles, placeholder, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";");
1278
- // resize handles offset (to match margin)
1279
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-ne", "right: " + right);
1280
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-e", "right: " + right);
1281
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-se", "right: " + right + "; bottom: " + bottom);
1282
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-nw", "left: " + left);
1283
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-w", "left: " + left);
1284
- utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-sw", "left: " + left + "; bottom: " + bottom);
1285
- }
1286
- // now update the height specific fields
1287
- maxH = maxH || this._styles._max;
1288
- if (maxH > this._styles._max) {
1289
- var getHeight = function (rows) { return (cellHeight * rows) + cellHeightUnit; };
1290
- for (var i = this._styles._max + 1; i <= maxH; i++) { // start at 1
1291
- var h = getHeight(i);
1292
- utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-y=\"" + (i - 1) + "\"]", "top: " + getHeight(i - 1)); // start at 0
1293
- utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-h=\"" + i + "\"]", "height: " + h);
1294
- utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-min-h=\"" + i + "\"]", "min-height: " + h);
1295
- utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-max-h=\"" + i + "\"]", "max-height: " + h);
1296
- }
1297
- this._styles._max = maxH;
1298
- }
1299
- return this;
1300
- };
1301
- /** @internal */
1302
- GridStack.prototype._updateContainerHeight = function () {
1303
- if (!this.engine || this.engine.batchMode)
1304
- return this;
1305
- var row = this.getRow() + this._extraDragRow; // checks for minRow already
1306
- // check for css min height
1307
- // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary
1308
- // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.
1309
- // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);
1310
- // if (cssMinHeight > 0) {
1311
- // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));
1312
- // if (row < minRow) {
1313
- // row = minRow;
1314
- // }
1315
- // }
1316
- this.el.setAttribute('gs-current-row', String(row));
1317
- if (row === 0) {
1318
- this.el.style.removeProperty('min-height');
1319
- return this;
1320
- }
1321
- var cellHeight = this.opts.cellHeight;
1322
- var unit = this.opts.cellHeightUnit;
1323
- if (!cellHeight)
1324
- return this;
1325
- this.el.style.minHeight = row * cellHeight + unit;
1326
- return this;
1327
- };
1328
- /** @internal */
1329
- GridStack.prototype._prepareElement = function (el, triggerAddEvent, node) {
1330
- if (triggerAddEvent === void 0) { triggerAddEvent = false; }
1331
- el.classList.add(this.opts.itemClass);
1332
- node = node || this._readAttr(el);
1333
- el.gridstackNode = node;
1334
- node.el = el;
1335
- node.grid = this;
1336
- var copy = __assign({}, node);
1337
- node = this.engine.addNode(node, triggerAddEvent);
1338
- // write node attr back in case there was collision or we have to fix bad values during addNode()
1339
- if (!utils_1.Utils.same(node, copy)) {
1340
- this._writeAttr(el, node);
1341
- }
1342
- this._prepareDragDropByNode(node);
1343
- return this;
1344
- };
1345
- /** @internal call to write position x,y,w,h attributes back to element */
1346
- GridStack.prototype._writePosAttr = function (el, n) {
1347
- if (n.x !== undefined && n.x !== null) {
1348
- el.setAttribute('gs-x', String(n.x));
1349
- }
1350
- if (n.y !== undefined && n.y !== null) {
1351
- el.setAttribute('gs-y', String(n.y));
1352
- }
1353
- if (n.w) {
1354
- el.setAttribute('gs-w', String(n.w));
1355
- }
1356
- if (n.h) {
1357
- el.setAttribute('gs-h', String(n.h));
1358
- }
1359
- return this;
1360
- };
1361
- /** @internal call to write any default attributes back to element */
1362
- GridStack.prototype._writeAttr = function (el, node) {
1363
- if (!node)
1364
- return this;
1365
- this._writePosAttr(el, node);
1366
- var attrs /*: GridStackWidget but strings */ = {
1367
- autoPosition: 'gs-auto-position',
1368
- minW: 'gs-min-w',
1369
- minH: 'gs-min-h',
1370
- maxW: 'gs-max-w',
1371
- maxH: 'gs-max-h',
1372
- noResize: 'gs-no-resize',
1373
- noMove: 'gs-no-move',
1374
- locked: 'gs-locked',
1375
- id: 'gs-id',
1376
- };
1377
- for (var key in attrs) {
1378
- if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway
1379
- el.setAttribute(attrs[key], String(node[key]));
1380
- }
1381
- else {
1382
- el.removeAttribute(attrs[key]);
1383
- }
1384
- }
1385
- return this;
1386
- };
1387
- /** @internal call to read any default attributes from element */
1388
- GridStack.prototype._readAttr = function (el) {
1389
- var node = {};
1390
- node.x = utils_1.Utils.toNumber(el.getAttribute('gs-x'));
1391
- node.y = utils_1.Utils.toNumber(el.getAttribute('gs-y'));
1392
- node.w = utils_1.Utils.toNumber(el.getAttribute('gs-w'));
1393
- node.h = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
1394
- node.maxW = utils_1.Utils.toNumber(el.getAttribute('gs-max-w'));
1395
- node.minW = utils_1.Utils.toNumber(el.getAttribute('gs-min-w'));
1396
- node.maxH = utils_1.Utils.toNumber(el.getAttribute('gs-max-h'));
1397
- node.minH = utils_1.Utils.toNumber(el.getAttribute('gs-min-h'));
1398
- node.autoPosition = utils_1.Utils.toBool(el.getAttribute('gs-auto-position'));
1399
- node.noResize = utils_1.Utils.toBool(el.getAttribute('gs-no-resize'));
1400
- node.noMove = utils_1.Utils.toBool(el.getAttribute('gs-no-move'));
1401
- node.locked = utils_1.Utils.toBool(el.getAttribute('gs-locked'));
1402
- node.id = el.getAttribute('gs-id');
1403
- // remove any key not found (null or false which is default)
1404
- for (var key in node) {
1405
- if (!node.hasOwnProperty(key))
1406
- return;
1407
- if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)
1408
- delete node[key];
1409
- }
1410
- }
1411
- return node;
1412
- };
1413
- /** @internal */
1414
- GridStack.prototype._setStaticClass = function () {
1415
- var _a, _b;
1416
- var classes = ['grid-stack-static'];
1417
- if (this.opts.staticGrid) {
1418
- (_a = this.el.classList).add.apply(_a, classes);
1419
- this.el.setAttribute('gs-static', 'true');
1420
- }
1421
- else {
1422
- (_b = this.el.classList).remove.apply(_b, classes);
1423
- this.el.removeAttribute('gs-static');
1424
- }
1425
- return this;
1426
- };
1427
- /**
1428
- * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off
1429
- * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)
1430
- */
1431
- GridStack.prototype.onParentResize = function () {
1432
- var _this = this;
1433
- if (!this.el || !this.el.clientWidth)
1434
- return; // return if we're gone or no size yet (will get called again)
1435
- var changedColumn = false;
1436
- // see if we're nested and take our column count from our parent....
1437
- if (this._autoColumn && this.parentGridItem) {
1438
- if (this.opts.column !== this.parentGridItem.w) {
1439
- changedColumn = true;
1440
- this.column(this.parentGridItem.w, 'none');
1441
- }
1442
- }
1443
- else {
1444
- // else check for 1 column in/out behavior
1445
- var oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;
1446
- if ((this.opts.column === 1) !== oneColumn) {
1447
- changedColumn = true;
1448
- if (this.opts.animate) {
1449
- this.setAnimation(false);
1450
- } // 1 <-> 12 is too radical, turn off animation
1451
- this.column(oneColumn ? 1 : this._prevColumn);
1452
- if (this.opts.animate) {
1453
- this.setAnimation(true);
1454
- }
1455
- }
1456
- }
1457
- // make the cells content square again
1458
- if (this._isAutoCellHeight) {
1459
- if (!changedColumn && this.opts.cellHeightThrottle) {
1460
- if (!this._cellHeightThrottle) {
1461
- this._cellHeightThrottle = utils_1.Utils.throttle(function () { return _this.cellHeight(); }, this.opts.cellHeightThrottle);
1462
- }
1463
- this._cellHeightThrottle();
1464
- }
1465
- else {
1466
- // immediate update if we've changed column count or have no threshold
1467
- this.cellHeight();
1468
- }
1469
- }
1470
- // finally update any nested grids
1471
- this.engine.nodes.forEach(function (n) {
1472
- if (n.subGrid) {
1473
- n.subGrid.onParentResize();
1474
- }
1475
- });
1476
- return this;
1477
- };
1478
- /** add or remove the window size event handler */
1479
- GridStack.prototype._updateWindowResizeEvent = function (forceRemove) {
1480
- if (forceRemove === void 0) { forceRemove = false; }
1481
- // 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)
1482
- var workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.parentGridItem;
1483
- if (!forceRemove && workTodo && !this._windowResizeBind) {
1484
- this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later
1485
- window.addEventListener('resize', this._windowResizeBind);
1486
- }
1487
- else if ((forceRemove || !workTodo) && this._windowResizeBind) {
1488
- window.removeEventListener('resize', this._windowResizeBind);
1489
- delete this._windowResizeBind; // remove link to us so we can free
1490
- }
1491
- return this;
1492
- };
1493
- /** @internal convert a potential selector into actual element */
1494
- GridStack.getElement = function (els) {
1495
- if (els === void 0) { els = '.grid-stack-item'; }
1496
- return utils_1.Utils.getElement(els);
1497
- };
1498
- /** @internal */
1499
- GridStack.getElements = function (els) {
1500
- if (els === void 0) { els = '.grid-stack-item'; }
1501
- return utils_1.Utils.getElements(els);
1502
- };
1503
- /** @internal */
1504
- GridStack.getGridElement = function (els) { return GridStack.getElement(els); };
1505
- /** @internal */
1506
- GridStack.getGridElements = function (els) { return utils_1.Utils.getElements(els); };
1507
- /** @internal initialize margin top/bottom/left/right and units */
1508
- GridStack.prototype._initMargin = function () {
1509
- var data;
1510
- var margin = 0;
1511
- // support passing multiple values like CSS (ex: '5px 10px 0 20px')
1512
- var margins = [];
1513
- if (typeof this.opts.margin === 'string') {
1514
- margins = this.opts.margin.split(' ');
1515
- }
1516
- if (margins.length === 2) { // top/bot, left/right like CSS
1517
- this.opts.marginTop = this.opts.marginBottom = margins[0];
1518
- this.opts.marginLeft = this.opts.marginRight = margins[1];
1519
- }
1520
- else if (margins.length === 4) { // Clockwise like CSS
1521
- this.opts.marginTop = margins[0];
1522
- this.opts.marginRight = margins[1];
1523
- this.opts.marginBottom = margins[2];
1524
- this.opts.marginLeft = margins[3];
1525
- }
1526
- else {
1527
- data = utils_1.Utils.parseHeight(this.opts.margin);
1528
- this.opts.marginUnit = data.unit;
1529
- margin = this.opts.margin = data.h;
1530
- }
1531
- // see if top/bottom/left/right need to be set as well
1532
- if (this.opts.marginTop === undefined) {
1533
- this.opts.marginTop = margin;
1534
- }
1535
- else {
1536
- data = utils_1.Utils.parseHeight(this.opts.marginTop);
1537
- this.opts.marginTop = data.h;
1538
- delete this.opts.margin;
1539
- }
1540
- if (this.opts.marginBottom === undefined) {
1541
- this.opts.marginBottom = margin;
1542
- }
1543
- else {
1544
- data = utils_1.Utils.parseHeight(this.opts.marginBottom);
1545
- this.opts.marginBottom = data.h;
1546
- delete this.opts.margin;
1547
- }
1548
- if (this.opts.marginRight === undefined) {
1549
- this.opts.marginRight = margin;
1550
- }
1551
- else {
1552
- data = utils_1.Utils.parseHeight(this.opts.marginRight);
1553
- this.opts.marginRight = data.h;
1554
- delete this.opts.margin;
1555
- }
1556
- if (this.opts.marginLeft === undefined) {
1557
- this.opts.marginLeft = margin;
1558
- }
1559
- else {
1560
- data = utils_1.Utils.parseHeight(this.opts.marginLeft);
1561
- this.opts.marginLeft = data.h;
1562
- delete this.opts.margin;
1563
- }
1564
- this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...
1565
- if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {
1566
- this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()
1567
- }
1568
- return this;
1569
- };
1570
- /* ===========================================================================================
1571
- * drag&drop methods that used to be stubbed out and implemented in dd-gridstack.ts
1572
- * but caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039
1573
- * ===========================================================================================
1574
- */
1575
- /** get the global (but static to this code) DD implementation */
1576
- GridStack.getDD = function () {
1577
- return dd;
1578
- };
1579
- /**
1580
- * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.
1581
- * Called during GridStack.init() as options, but can also be called directly (last param are used) in case the toolbar
1582
- * is dynamically create and needs to be set later.
1583
- * @param dragIn string selector (ex: '.sidebar .grid-stack-item')
1584
- * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}
1585
- **/
1586
- GridStack.setupDragIn = function (dragIn, dragInOptions) {
1587
- if ((dragInOptions === null || dragInOptions === void 0 ? void 0 : dragInOptions.pause) !== undefined) {
1588
- dd_manager_1.DDManager.pauseDrag = dragInOptions.pause;
1589
- }
1590
- if (typeof dragIn === 'string') {
1591
- dragInOptions = __assign(__assign({}, types_1.dragInDefaultOptions), (dragInOptions || {}));
1592
- utils_1.Utils.getElements(dragIn).forEach(function (el) {
1593
- if (!dd.isDraggable(el))
1594
- dd.dragIn(el, dragInOptions);
1595
- });
1596
- }
1597
- };
1598
- /**
1599
- * 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.
1600
- * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.
1601
- * @param els widget or selector to modify.
1602
- * @param val if true widget will be draggable.
1603
- */
1604
- GridStack.prototype.movable = function (els, val) {
1605
- var _this = this;
1606
- if (this.opts.staticGrid)
1607
- return this; // can't move a static grid!
1608
- GridStack.getElements(els).forEach(function (el) {
1609
- var node = el.gridstackNode;
1610
- if (!node)
1611
- return;
1612
- if (val)
1613
- delete node.noMove;
1614
- else
1615
- node.noMove = true;
1616
- _this._prepareDragDropByNode(node); // init DD if need be, and adjust
1617
- });
1618
- return this;
1619
- };
1620
- /**
1621
- * 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.
1622
- * @param els widget or selector to modify
1623
- * @param val if true widget will be resizable.
1624
- */
1625
- GridStack.prototype.resizable = function (els, val) {
1626
- var _this = this;
1627
- if (this.opts.staticGrid)
1628
- return this; // can't resize a static grid!
1629
- GridStack.getElements(els).forEach(function (el) {
1630
- var node = el.gridstackNode;
1631
- if (!node)
1632
- return;
1633
- if (val)
1634
- delete node.noResize;
1635
- else
1636
- node.noResize = true;
1637
- _this._prepareDragDropByNode(node); // init DD if need be, and adjust
1638
- });
1639
- return this;
1640
- };
1641
- /**
1642
- * Temporarily disables widgets moving/resizing.
1643
- * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.
1644
- * Note: no-op for static grid
1645
- * This is a shortcut for:
1646
- * @example
1647
- * grid.enableMove(false);
1648
- * grid.enableResize(false);
1649
- * @param recurse true (default) if sub-grids also get updated
1650
- */
1651
- GridStack.prototype.disable = function (recurse) {
1652
- if (recurse === void 0) { recurse = true; }
1653
- if (this.opts.staticGrid)
1654
- return;
1655
- this.enableMove(false, recurse);
1656
- this.enableResize(false, recurse); // @ts-ignore
1657
- this._triggerEvent('disable');
1658
- return this;
1659
- };
1660
- /**
1661
- * Re-enables widgets moving/resizing - see disable().
1662
- * Note: no-op for static grid.
1663
- * This is a shortcut for:
1664
- * @example
1665
- * grid.enableMove(true);
1666
- * grid.enableResize(true);
1667
- * @param recurse true (default) if sub-grids also get updated
1668
- */
1669
- GridStack.prototype.enable = function (recurse) {
1670
- if (recurse === void 0) { recurse = true; }
1671
- if (this.opts.staticGrid)
1672
- return;
1673
- this.enableMove(true, recurse);
1674
- this.enableResize(true, recurse); // @ts-ignore
1675
- this._triggerEvent('enable');
1676
- return this;
1677
- };
1678
- /**
1679
- * Enables/disables widget moving. No-op for static grids.
1680
- * @param recurse true (default) if sub-grids also get updated
1681
- */
1682
- GridStack.prototype.enableMove = function (doEnable, recurse) {
1683
- var _this = this;
1684
- if (recurse === void 0) { recurse = true; }
1685
- if (this.opts.staticGrid)
1686
- return this; // can't move a static grid!
1687
- this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658
1688
- this.engine.nodes.forEach(function (n) {
1689
- _this.movable(n.el, doEnable);
1690
- if (n.subGrid && recurse)
1691
- n.subGrid.enableMove(doEnable, recurse);
1692
- });
1693
- return this;
1694
- };
1695
- /**
1696
- * Enables/disables widget resizing. No-op for static grids.
1697
- * @param recurse true (default) if sub-grids also get updated
1698
- */
1699
- GridStack.prototype.enableResize = function (doEnable, recurse) {
1700
- var _this = this;
1701
- if (recurse === void 0) { recurse = true; }
1702
- if (this.opts.staticGrid)
1703
- return this; // can't size a static grid!
1704
- this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658
1705
- this.engine.nodes.forEach(function (n) {
1706
- _this.resizable(n.el, doEnable);
1707
- if (n.subGrid && recurse)
1708
- n.subGrid.enableResize(doEnable, recurse);
1709
- });
1710
- return this;
1711
- };
1712
- /** @internal removes any drag&drop present (called during destroy) */
1713
- GridStack.prototype._removeDD = function (el) {
1714
- dd.draggable(el, 'destroy').resizable(el, 'destroy');
1715
- if (el.gridstackNode) {
1716
- delete el.gridstackNode._initDD; // reset our DD init flag
1717
- }
1718
- delete el.ddElement;
1719
- return this;
1720
- };
1721
- /** @internal called to add drag over to support widgets being added externally */
1722
- GridStack.prototype._setupAcceptWidget = function () {
1723
- var _this = this;
1724
- // check if we need to disable things
1725
- if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {
1726
- dd.droppable(this.el, 'destroy');
1727
- return this;
1728
- }
1729
- // vars shared across all methods
1730
- var cellHeight, cellWidth;
1731
- var onDrag = function (event, el, helper) {
1732
- var node = el.gridstackNode;
1733
- if (!node)
1734
- return;
1735
- helper = helper || el;
1736
- var parent = _this.el.getBoundingClientRect();
1737
- var _a = helper.getBoundingClientRect(), top = _a.top, left = _a.left;
1738
- left -= parent.left;
1739
- top -= parent.top;
1740
- var ui = { position: { top: top, left: left } };
1741
- if (node._temporaryRemoved) {
1742
- node.x = Math.max(0, Math.round(left / cellWidth));
1743
- node.y = Math.max(0, Math.round(top / cellHeight));
1744
- delete node.autoPosition;
1745
- _this.engine.nodeBoundFix(node);
1746
- // 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
1747
- if (!_this.engine.willItFit(node)) {
1748
- node.autoPosition = true; // ignore x,y and try for any slot...
1749
- if (!_this.engine.willItFit(node)) {
1750
- dd.off(el, 'drag'); // stop calling us
1751
- return; // full grid or can't grow
1752
- }
1753
- if (node._willFitPos) {
1754
- // use the auto position instead #1687
1755
- utils_1.Utils.copyPos(node, node._willFitPos);
1756
- delete node._willFitPos;
1757
- }
1758
- }
1759
- // re-use the existing node dragging method
1760
- _this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);
1761
- }
1762
- else {
1763
- // re-use the existing node dragging that does so much of the collision detection
1764
- _this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);
1765
- }
1766
- };
1767
- dd.droppable(this.el, {
1768
- accept: function (el) {
1769
- var node = el.gridstackNode;
1770
- // set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving
1771
- if ((node === null || node === void 0 ? void 0 : node.grid) === _this)
1772
- return true;
1773
- if (!_this.opts.acceptWidgets)
1774
- return false;
1775
- // check for accept method or class matching
1776
- var canAccept = true;
1777
- if (typeof _this.opts.acceptWidgets === 'function') {
1778
- canAccept = _this.opts.acceptWidgets(el);
1779
- }
1780
- else {
1781
- var selector = (_this.opts.acceptWidgets === true ? '.grid-stack-item' : _this.opts.acceptWidgets);
1782
- canAccept = el.matches(selector);
1783
- }
1784
- // finally check to make sure we actually have space left #1571
1785
- if (canAccept && node && _this.opts.maxRow) {
1786
- var n = { w: node.w, h: node.h, minW: node.minW, minH: node.minH }; // only width/height matters and autoPosition
1787
- canAccept = _this.engine.willItFit(n);
1788
- }
1789
- return canAccept;
1790
- }
1791
- })
1792
- /**
1793
- * entering our grid area
1794
- */
1795
- .on(this.el, 'dropover', function (event, el, helper) {
1796
- // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST
1797
- var node = el.gridstackNode;
1798
- // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item
1799
- if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._temporaryRemoved) {
1800
- // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)
1801
- return false; // prevent parent from receiving msg (which may be a grid as well)
1802
- }
1803
- // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now
1804
- if ((node === null || node === void 0 ? void 0 : node.grid) && node.grid !== _this && !node._temporaryRemoved) {
1805
- // console.log('dropover without leave'); // TEST
1806
- var otherGrid = node.grid;
1807
- otherGrid._leave(el, helper);
1808
- }
1809
- // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...
1810
- cellWidth = _this.cellWidth();
1811
- cellHeight = _this.getCellHeight(true);
1812
- // load any element attributes if we don't have a node
1813
- if (!node) { // @ts-ignore private read only on ourself
1814
- node = _this._readAttr(el);
1815
- }
1816
- if (!node.grid) {
1817
- node._isExternal = true;
1818
- el.gridstackNode = node;
1819
- }
1820
- // calculate the grid size based on element outer size
1821
- helper = helper || el;
1822
- var w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;
1823
- var h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;
1824
- // if the item came from another grid, make a copy and save the original info in case we go back there
1825
- if (node.grid && node.grid !== _this) {
1826
- // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific
1827
- // console.log('dropover cloning node'); // TEST
1828
- if (!el._gridstackNodeOrig)
1829
- el._gridstackNodeOrig = node; // shouldn't have multiple nested!
1830
- el.gridstackNode = node = __assign(__assign({}, node), { w: w, h: h, grid: _this });
1831
- _this.engine.cleanupNode(node)
1832
- .nodeBoundFix(node);
1833
- // restore some internal fields we need after clearing them all
1834
- node._initDD =
1835
- node._isExternal = // DOM needs to be re-parented on a drop
1836
- node._temporaryRemoved = true; // so it can be inserted onDrag below
1837
- }
1838
- else {
1839
- node.w = w;
1840
- node.h = h;
1841
- node._temporaryRemoved = true; // so we can insert it
1842
- }
1843
- // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)
1844
- _this._itemRemoving(node.el, false);
1845
- dd.on(el, 'drag', onDrag);
1846
- // make sure this is called at least once when going fast #1578
1847
- onDrag(event, el, helper);
1848
- return false; // prevent parent from receiving msg (which may be a grid as well)
1849
- })
1850
- /**
1851
- * Leaving our grid area...
1852
- */
1853
- .on(this.el, 'dropout', function (event, el, helper) {
1854
- // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST
1855
- var node = el.gridstackNode;
1856
- if (!node)
1857
- return false;
1858
- // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)
1859
- // so skip this one if we're not the active grid really..
1860
- if (!node.grid || node.grid === _this) {
1861
- _this._leave(el, helper);
1862
- // if we were created as temporary nested grid, go back to before state
1863
- if (_this._isTemp) {
1864
- _this.removeAsSubGrid(node);
1865
- }
1866
- }
1867
- return false; // prevent parent from receiving msg (which may be grid as well)
1868
- })
1869
- /**
1870
- * end - releasing the mouse
1871
- */
1872
- .on(this.el, 'drop', function (event, el, helper) {
1873
- var _a, _b;
1874
- var node = el.gridstackNode;
1875
- // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead
1876
- if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._isExternal)
1877
- return false;
1878
- var wasAdded = !!_this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419
1879
- _this.placeholder.remove();
1880
- // notify previous grid of removal
1881
- // console.log('drop delete _gridstackNodeOrig') // TEST
1882
- var origNode = el._gridstackNodeOrig;
1883
- delete el._gridstackNodeOrig;
1884
- if (wasAdded && (origNode === null || origNode === void 0 ? void 0 : origNode.grid) && origNode.grid !== _this) {
1885
- var oGrid = origNode.grid;
1886
- oGrid.engine.removedNodes.push(origNode);
1887
- oGrid._triggerRemoveEvent()._triggerChangeEvent();
1888
- // if it's an empty sub-grid that got auto-created, nuke it
1889
- if (oGrid.parentGridItem && !oGrid.engine.nodes.length && oGrid.opts.subGridDynamic) {
1890
- oGrid.removeAsSubGrid();
1891
- }
1892
- }
1893
- if (!node)
1894
- return false;
1895
- // use existing placeholder node as it's already in our list with drop location
1896
- if (wasAdded) {
1897
- _this.engine.cleanupNode(node); // removes all internal _xyz values
1898
- node.grid = _this;
1899
- }
1900
- dd.off(el, 'drag');
1901
- // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)
1902
- // as the helper will be nuked by jquery-ui otherwise. TODO: update old code path
1903
- if (helper !== el) {
1904
- helper.remove();
1905
- el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info
1906
- if (wasAdded) {
1907
- el = el.cloneNode(true);
1908
- }
1909
- }
1910
- else {
1911
- el.remove(); // reduce flicker as we change depth here, and size further down
1912
- _this._removeDD(el);
1913
- }
1914
- if (!wasAdded)
1915
- return false;
1916
- el.gridstackNode = node;
1917
- node.el = el;
1918
- var subGrid = (_b = (_a = node.subGrid) === null || _a === void 0 ? void 0 : _a.el) === null || _b === void 0 ? void 0 : _b.gridstack; // set when actual sub-grid present
1919
- // @ts-ignore
1920
- utils_1.Utils.copyPos(node, _this._readAttr(_this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578
1921
- utils_1.Utils.removePositioningStyles(el); // @ts-ignore
1922
- _this._writeAttr(el, node);
1923
- el.classList.add(types_1.gridDefaults.itemClass, _this.opts.itemClass);
1924
- _this.el.appendChild(el); // @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)
1925
- if (subGrid) {
1926
- subGrid.parentGridItem = node;
1927
- if (!subGrid.opts.styleInHead)
1928
- subGrid._updateStyles(true); // re-create sub-grid styles now that we've moved
1929
- }
1930
- _this._updateContainerHeight();
1931
- _this.engine.addedNodes.push(node); // @ts-ignore
1932
- _this._triggerAddEvent(); // @ts-ignore
1933
- _this._triggerChangeEvent();
1934
- _this.engine.endUpdate();
1935
- if (_this._gsEventHandler['dropped']) {
1936
- _this._gsEventHandler['dropped'](__assign(__assign({}, event), { type: 'dropped' }), origNode && origNode.grid ? origNode : undefined, node);
1937
- }
1938
- // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up
1939
- window.setTimeout(function () {
1940
- // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())
1941
- if (node.el && node.el.parentElement) {
1942
- _this._prepareDragDropByNode(node);
1943
- }
1944
- else {
1945
- _this.engine.removeNode(node);
1946
- }
1947
- delete node.grid._isTemp;
1948
- });
1949
- return false; // prevent parent from receiving msg (which may be grid as well)
1950
- });
1951
- return this;
1952
- };
1953
- /** @internal mark item for removal */
1954
- GridStack.prototype._itemRemoving = function (el, remove) {
1955
- var node = el ? el.gridstackNode : undefined;
1956
- if (!node || !node.grid)
1957
- return;
1958
- remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;
1959
- remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');
1960
- };
1961
- /** @internal called to setup a trash drop zone if the user specifies it */
1962
- GridStack.prototype._setupRemoveDrop = function () {
1963
- var _this = this;
1964
- if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {
1965
- var trashEl = document.querySelector(this.opts.removable);
1966
- if (!trashEl)
1967
- return this;
1968
- // only register ONE drop-over/dropout callback for the 'trash', and it will
1969
- // update the passed in item and parent grid because the 'trash' is a shared resource anyway,
1970
- // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)
1971
- if (!dd.isDroppable(trashEl)) {
1972
- dd.droppable(trashEl, this.opts.removableOptions)
1973
- .on(trashEl, 'dropover', function (event, el) { return _this._itemRemoving(el, true); })
1974
- .on(trashEl, 'dropout', function (event, el) { return _this._itemRemoving(el, false); });
1975
- }
1976
- }
1977
- return this;
1978
- };
1979
- /** @internal prepares the element for drag&drop **/
1980
- GridStack.prototype._prepareDragDropByNode = function (node) {
1981
- var _this = this;
1982
- var el = node.el;
1983
- var noMove = node.noMove || this.opts.disableDrag;
1984
- var noResize = node.noResize || this.opts.disableResize;
1985
- // check for disabled grid first
1986
- if (this.opts.staticGrid || (noMove && noResize)) {
1987
- if (node._initDD) {
1988
- this._removeDD(el); // nukes everything instead of just disable, will add some styles back next
1989
- delete node._initDD;
1990
- }
1991
- el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435
1992
- return this;
1993
- }
1994
- if (!node._initDD) {
1995
- // variables used/cashed between the 3 start/move/end methods, in addition to node passed above
1996
- var cellWidth_1;
1997
- var cellHeight_1;
1998
- /** called when item starts moving/resizing */
1999
- var onStartMoving = function (event, ui) {
2000
- // trigger any 'dragstart' / 'resizestart' manually
2001
- if (_this._gsEventHandler[event.type]) {
2002
- _this._gsEventHandler[event.type](event, event.target);
2003
- }
2004
- cellWidth_1 = _this.cellWidth();
2005
- cellHeight_1 = _this.getCellHeight(true); // force pixels for calculations
2006
- _this._onStartMoving(el, event, ui, node, cellWidth_1, cellHeight_1);
2007
- };
2008
- /** called when item is being dragged/resized */
2009
- var dragOrResize = function (event, ui) {
2010
- _this._dragOrResize(el, event, ui, node, cellWidth_1, cellHeight_1);
2011
- };
2012
- /** called when the item stops moving/resizing */
2013
- var onEndMoving = function (event) {
2014
- _this.placeholder.remove();
2015
- delete node._moving;
2016
- delete node._event;
2017
- delete node._lastTried;
2018
- // if the item has moved to another grid, we're done here
2019
- var target = event.target;
2020
- if (!target.gridstackNode || target.gridstackNode.grid !== _this)
2021
- return;
2022
- node.el = target;
2023
- if (node._isAboutToRemove) {
2024
- var gridToNotify = el.gridstackNode.grid;
2025
- if (gridToNotify._gsEventHandler[event.type]) {
2026
- gridToNotify._gsEventHandler[event.type](event, target);
2027
- }
2028
- _this._removeDD(el);
2029
- gridToNotify.engine.removedNodes.push(node);
2030
- gridToNotify._triggerRemoveEvent();
2031
- // break circular links and remove DOM
2032
- delete el.gridstackNode;
2033
- delete node.el;
2034
- el.remove();
2035
- }
2036
- else {
2037
- utils_1.Utils.removePositioningStyles(target);
2038
- if (node._temporaryRemoved) {
2039
- // got removed - restore item back to before dragging position
2040
- utils_1.Utils.copyPos(node, node._orig); // @ts-ignore
2041
- _this._writePosAttr(target, node);
2042
- _this.engine.addNode(node);
2043
- }
2044
- else {
2045
- // move to new placeholder location
2046
- _this._writePosAttr(target, node);
2047
- }
2048
- if (_this._gsEventHandler[event.type]) {
2049
- _this._gsEventHandler[event.type](event, target);
2050
- }
2051
- }
2052
- // @ts-ignore
2053
- _this._extraDragRow = 0; // @ts-ignore
2054
- _this._updateContainerHeight(); // @ts-ignore
2055
- _this._triggerChangeEvent();
2056
- _this.engine.endUpdate();
2057
- };
2058
- dd.draggable(el, {
2059
- start: onStartMoving,
2060
- stop: onEndMoving,
2061
- drag: dragOrResize
2062
- }).resizable(el, {
2063
- start: onStartMoving,
2064
- stop: onEndMoving,
2065
- resize: dragOrResize
2066
- });
2067
- node._initDD = true; // we've set DD support now
2068
- }
2069
- // finally fine tune move vs resize by disabling any part...
2070
- dd.draggable(el, noMove ? 'disable' : 'enable')
2071
- .resizable(el, noResize ? 'disable' : 'enable');
2072
- return this;
2073
- };
2074
- /** @internal handles actual drag/resize start **/
2075
- GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) {
2076
- this.engine.cleanNodes()
2077
- .beginUpdate(node);
2078
- // @ts-ignore
2079
- this._writePosAttr(this.placeholder, node);
2080
- this.el.appendChild(this.placeholder);
2081
- // console.log('_onStartMoving placeholder') // TEST
2082
- node.el = this.placeholder;
2083
- node._lastUiPosition = ui.position;
2084
- node._prevYPix = ui.position.top;
2085
- 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)
2086
- delete node._lastTried;
2087
- if (event.type === 'dropover' && node._temporaryRemoved) {
2088
- // console.log('engine.addNode x=' + node.x); // TEST
2089
- this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved
2090
- node._moving = true; // AFTER, mark as moving object (wanted fix location before)
2091
- }
2092
- // set the min/max resize info
2093
- this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop, this.opts.marginRight, this.opts.marginBottom, this.opts.marginLeft);
2094
- if (event.type === 'resizestart') {
2095
- dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))
2096
- .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));
2097
- if (node.maxW) {
2098
- dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW);
2099
- }
2100
- if (node.maxH) {
2101
- dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH);
2102
- }
2103
- }
2104
- };
2105
- /** @internal handles actual drag/resize **/
2106
- GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) {
2107
- 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)
2108
- var resizing;
2109
- var mLeft = this.opts.marginLeft, mRight = this.opts.marginRight, mTop = this.opts.marginTop, mBottom = this.opts.marginBottom;
2110
- // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855
2111
- var mHeight = Math.round(cellHeight * 0.1), mWidth = Math.round(cellWidth * 0.1);
2112
- mLeft = Math.min(mLeft, mWidth);
2113
- mRight = Math.min(mRight, mWidth);
2114
- mTop = Math.min(mTop, mHeight);
2115
- mBottom = Math.min(mBottom, mHeight);
2116
- if (event.type === 'drag') {
2117
- if (node._temporaryRemoved)
2118
- return; // handled by dropover
2119
- var distance = ui.position.top - node._prevYPix;
2120
- node._prevYPix = ui.position.top;
2121
- if (this.opts.draggable.scroll !== false) {
2122
- utils_1.Utils.updateScrollPosition(el, ui.position, distance);
2123
- }
2124
- // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)
2125
- var left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);
2126
- var top_2 = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);
2127
- p.x = Math.round(left / cellWidth);
2128
- p.y = Math.round(top_2 / cellHeight);
2129
- // @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
2130
- var prev = this._extraDragRow;
2131
- if (this.engine.collide(node, p)) {
2132
- var row = this.getRow();
2133
- var extra = Math.max(0, (p.y + node.h) - row);
2134
- if (this.opts.maxRow && row + extra > this.opts.maxRow) {
2135
- extra = Math.max(0, this.opts.maxRow - row);
2136
- } // @ts-ignore
2137
- this._extraDragRow = extra; // @ts-ignore
2138
- }
2139
- else
2140
- this._extraDragRow = 0; // @ts-ignore
2141
- if (this._extraDragRow !== prev)
2142
- this._updateContainerHeight();
2143
- if (node.x === p.x && node.y === p.y)
2144
- return; // skip same
2145
- // DON'T skip one we tried as we might have failed because of coverage <50% before
2146
- // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;
2147
- }
2148
- else if (event.type === 'resize') {
2149
- if (p.x < 0)
2150
- return;
2151
- // Scrolling page if needed
2152
- utils_1.Utils.updateScrollResize(event, el, cellHeight);
2153
- // get new size
2154
- p.w = Math.round((ui.size.width - mLeft) / cellWidth);
2155
- p.h = Math.round((ui.size.height - mTop) / cellHeight);
2156
- if (node.w === p.w && node.h === p.h)
2157
- return;
2158
- if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h)
2159
- return; // skip one we tried (but failed)
2160
- // if we size on left/top side this might move us, so get possible new position as well
2161
- var left = ui.position.left + mLeft;
2162
- var top_3 = ui.position.top + mTop;
2163
- p.x = Math.round(left / cellWidth);
2164
- p.y = Math.round(top_3 / cellHeight);
2165
- resizing = true;
2166
- }
2167
- node._event = event;
2168
- node._lastTried = p; // set as last tried (will nuke if we go there)
2169
- var rect = {
2170
- x: ui.position.left + mLeft,
2171
- y: ui.position.top + mTop,
2172
- w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,
2173
- h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom
2174
- };
2175
- if (this.engine.moveNodeCheck(node, __assign(__assign({}, p), { cellWidth: cellWidth, cellHeight: cellHeight, rect: rect, resizing: resizing }))) {
2176
- node._lastUiPosition = ui.position;
2177
- this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);
2178
- delete node._skipDown;
2179
- if (resizing && node.subGrid) {
2180
- node.subGrid.onParentResize();
2181
- } // @ts-ignore
2182
- this._extraDragRow = 0; // @ts-ignore
2183
- this._updateContainerHeight();
2184
- var target = event.target; // @ts-ignore
2185
- this._writePosAttr(target, node);
2186
- if (this._gsEventHandler[event.type]) {
2187
- this._gsEventHandler[event.type](event, target);
2188
- }
2189
- }
2190
- };
2191
- /** @internal called when item leaving our area by either cursor dropout event
2192
- * or shape is outside our boundaries. remove it from us, and mark temporary if this was
2193
- * our item to start with else restore prev node values from prev grid it came from.
2194
- **/
2195
- GridStack.prototype._leave = function (el, helper) {
2196
- var node = el.gridstackNode;
2197
- if (!node)
2198
- return;
2199
- dd.off(el, 'drag'); // no need to track while being outside
2200
- // this gets called when cursor leaves and shape is outside, so only do this once
2201
- if (node._temporaryRemoved)
2202
- return;
2203
- node._temporaryRemoved = true;
2204
- this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue
2205
- node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged
2206
- if (this.opts.removable === true) { // boolean vs a class string
2207
- // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so
2208
- this._itemRemoving(el, true);
2209
- }
2210
- // finally if item originally came from another grid, but left us, restore things back to prev info
2211
- if (el._gridstackNodeOrig) {
2212
- // console.log('leave delete _gridstackNodeOrig') // TEST
2213
- el.gridstackNode = el._gridstackNodeOrig;
2214
- delete el._gridstackNodeOrig;
2215
- }
2216
- else if (node._isExternal) {
2217
- // item came from outside (like a toolbar) so nuke any node info
2218
- delete node.el;
2219
- delete el.gridstackNode;
2220
- // and restore all nodes back to original
2221
- this.engine.restoreInitial();
2222
- }
2223
- };
2224
- // legacy method removed
2225
- GridStack.prototype.commit = function () { utils_1.obsolete(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; };
2226
- /** scoping so users can call GridStack.Utils.sort() for example */
2227
- GridStack.Utils = utils_1.Utils;
2228
- /** scoping so users can call new GridStack.Engine(12) for example */
2229
- GridStack.Engine = gridstack_engine_1.GridStackEngine;
2230
- GridStack.GDRev = '7.3.0';
2231
- return GridStack;
2232
- }());
2233
- exports.GridStack = GridStack;
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
25
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
26
+ };
27
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
28
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
29
+ if (ar || !(i in from)) {
30
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
31
+ ar[i] = from[i];
32
+ }
33
+ }
34
+ return to.concat(ar || Array.prototype.slice.call(from));
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.GridStack = void 0;
38
+ /*!
39
+ * GridStack 8.0.1
40
+ * https://gridstackjs.com/
41
+ *
42
+ * Copyright (c) 2021-2022 Alain Dumesny
43
+ * see root license https://github.com/gridstack/gridstack.js/tree/master/LICENSE
44
+ */
45
+ var gridstack_engine_1 = require("./gridstack-engine");
46
+ var utils_1 = require("./utils");
47
+ var types_1 = require("./types");
48
+ /*
49
+ * and include D&D by default
50
+ * TODO: while we could generate a gridstack-static.js at smaller size - saves about 31k (41k -> 72k)
51
+ * I don't know how to generate the DD only code at the remaining 31k to delay load as code depends on Gridstack.ts
52
+ * also it caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039
53
+ */
54
+ var dd_gridstack_1 = require("./dd-gridstack");
55
+ var dd_touch_1 = require("./dd-touch");
56
+ var dd_manager_1 = require("./dd-manager");
57
+ /** global instance */
58
+ var dd = new dd_gridstack_1.DDGridStack;
59
+ // export all dependent file as well to make it easier for users to just import the main file
60
+ __exportStar(require("./types"), exports);
61
+ __exportStar(require("./utils"), exports);
62
+ __exportStar(require("./gridstack-engine"), exports);
63
+ __exportStar(require("./dd-gridstack"), exports);
64
+ /**
65
+ * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.
66
+ * Note: your grid elements MUST have the following classes for the CSS layout to work:
67
+ * @example
68
+ * <div class="grid-stack">
69
+ * <div class="grid-stack-item">
70
+ * <div class="grid-stack-item-content">Item 1</div>
71
+ * </div>
72
+ * </div>
73
+ */
74
+ var GridStack = exports.GridStack = /** @class */ (function () {
75
+ /**
76
+ * Construct a grid item from the given element and options
77
+ * @param el
78
+ * @param opts
79
+ */
80
+ function GridStack(el, opts) {
81
+ if (opts === void 0) { opts = {}; }
82
+ var _this = this;
83
+ var _a, _b;
84
+ /** @internal */
85
+ this._gsEventHandler = {};
86
+ /** @internal extra row added when dragging at the bottom of the grid */
87
+ this._extraDragRow = 0;
88
+ this.el = el; // exposed HTML element to the user
89
+ opts = opts || {}; // handles null/undefined/0
90
+ if (!el.classList.contains('grid-stack')) {
91
+ this.el.classList.add('grid-stack');
92
+ }
93
+ // if row property exists, replace minRow and maxRow instead
94
+ if (opts.row) {
95
+ opts.minRow = opts.maxRow = opts.row;
96
+ delete opts.row;
97
+ }
98
+ var rowAttr = utils_1.Utils.toNumber(el.getAttribute('gs-row'));
99
+ // flag only valid in sub-grids (handled by parent, not here)
100
+ if (opts.column === 'auto') {
101
+ delete opts.column;
102
+ }
103
+ // 'minWidth' legacy support in 5.1
104
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
105
+ var anyOpts = opts;
106
+ if (anyOpts.minWidth !== undefined) {
107
+ opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;
108
+ delete anyOpts.minWidth;
109
+ }
110
+ // save original setting so we can restore on save
111
+ if (opts.alwaysShowResizeHandle !== undefined) {
112
+ opts._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;
113
+ }
114
+ // elements DOM attributes override any passed options (like CSS style) - merge the two together
115
+ var defaults = __assign(__assign({}, utils_1.Utils.cloneDeep(types_1.gridDefaults)), { column: utils_1.Utils.toNumber(el.getAttribute('gs-column')) || types_1.gridDefaults.column, minRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-min-row')) || types_1.gridDefaults.minRow, maxRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-max-row')) || types_1.gridDefaults.maxRow, staticGrid: utils_1.Utils.toBool(el.getAttribute('gs-static')) || types_1.gridDefaults.staticGrid, draggable: {
116
+ handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || types_1.gridDefaults.draggable.handle,
117
+ }, removableOptions: {
118
+ accept: opts.itemClass ? '.' + opts.itemClass : types_1.gridDefaults.removableOptions.accept,
119
+ } });
120
+ if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead
121
+ defaults.animate = utils_1.Utils.toBool(el.getAttribute('gs-animate'));
122
+ }
123
+ this.opts = utils_1.Utils.defaults(opts, defaults);
124
+ opts = null; // make sure we use this.opts instead
125
+ this._initMargin(); // part of settings defaults...
126
+ // 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)
127
+ if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.oneColumnSize) {
128
+ this._prevColumn = this.getColumn();
129
+ this.opts.column = 1;
130
+ }
131
+ if (this.opts.rtl === 'auto') {
132
+ this.opts.rtl = (el.style.direction === 'rtl');
133
+ }
134
+ if (this.opts.rtl) {
135
+ this.el.classList.add('grid-stack-rtl');
136
+ }
137
+ // check if we're been nested, and if so update our style and keep pointer around (used during save)
138
+ var parentGridItem = (_a = utils_1.Utils.closestUpByClass(this.el, types_1.gridDefaults.itemClass)) === null || _a === void 0 ? void 0 : _a.gridstackNode;
139
+ if (parentGridItem) {
140
+ parentGridItem.subGrid = this;
141
+ this.parentGridItem = parentGridItem;
142
+ this.el.classList.add('grid-stack-nested');
143
+ parentGridItem.el.classList.add('grid-stack-sub-grid');
144
+ }
145
+ this._isAutoCellHeight = (this.opts.cellHeight === 'auto');
146
+ if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {
147
+ // make the cell content square initially (will use resize/column event to keep it square)
148
+ this.cellHeight(undefined, false);
149
+ }
150
+ else {
151
+ // append unit if any are set
152
+ if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== types_1.gridDefaults.cellHeightUnit) {
153
+ this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;
154
+ delete this.opts.cellHeightUnit;
155
+ }
156
+ this.cellHeight(this.opts.cellHeight, false);
157
+ }
158
+ // see if we need to adjust auto-hide
159
+ if (this.opts.alwaysShowResizeHandle === 'mobile') {
160
+ this.opts.alwaysShowResizeHandle = dd_touch_1.isTouch;
161
+ }
162
+ this._styleSheetClass = 'grid-stack-instance-' + gridstack_engine_1.GridStackEngine._idSeq++;
163
+ this.el.classList.add(this._styleSheetClass);
164
+ this._setStaticClass();
165
+ var engineClass = this.opts.engineClass || GridStack.engineClass || gridstack_engine_1.GridStackEngine;
166
+ this.engine = new engineClass({
167
+ column: this.getColumn(),
168
+ float: this.opts.float,
169
+ maxRow: this.opts.maxRow,
170
+ onChange: function (cbNodes) {
171
+ var maxH = 0;
172
+ _this.engine.nodes.forEach(function (n) { maxH = Math.max(maxH, n.y + n.h); });
173
+ cbNodes.forEach(function (n) {
174
+ var el = n.el;
175
+ if (!el)
176
+ return;
177
+ if (n._removeDOM) {
178
+ if (el)
179
+ el.remove();
180
+ delete n._removeDOM;
181
+ }
182
+ else {
183
+ _this._writePosAttr(el, n);
184
+ }
185
+ });
186
+ _this._updateStyles(false, maxH); // false = don't recreate, just append if need be
187
+ }
188
+ });
189
+ if (this.opts.auto) {
190
+ this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...
191
+ this.getGridItems().forEach(function (el) { return _this._prepareElement(el); });
192
+ this.batchUpdate(false);
193
+ }
194
+ // load any passed in children as well, which overrides any DOM layout done above
195
+ if (this.opts.children) {
196
+ var children = this.opts.children;
197
+ delete this.opts.children;
198
+ if (children.length)
199
+ this.load(children); // don't load empty
200
+ }
201
+ this.setAnimation(this.opts.animate);
202
+ this._updateStyles();
203
+ if (this.opts.column != 12) {
204
+ this.el.classList.add('grid-stack-' + this.opts.column);
205
+ }
206
+ // dynamic grids require pausing during drag to detect over to nest vs push
207
+ if (this.opts.subGridDynamic && !dd_manager_1.DDManager.pauseDrag)
208
+ dd_manager_1.DDManager.pauseDrag = true;
209
+ if (((_b = this.opts.draggable) === null || _b === void 0 ? void 0 : _b.pause) !== undefined)
210
+ dd_manager_1.DDManager.pauseDrag = this.opts.draggable.pause;
211
+ this._setupRemoveDrop();
212
+ this._setupAcceptWidget();
213
+ this._updateWindowResizeEvent();
214
+ }
215
+ /**
216
+ * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will
217
+ * simply return the existing instance (ignore any passed options). There is also an initAll() version that support
218
+ * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.
219
+ * @param options grid options (optional)
220
+ * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)
221
+ *
222
+ * @example
223
+ * let grid = GridStack.init();
224
+ *
225
+ * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later
226
+ * let grid = document.querySelector('.grid-stack').gridstack;
227
+ */
228
+ GridStack.init = function (options, elOrString) {
229
+ if (options === void 0) { options = {}; }
230
+ if (elOrString === void 0) { elOrString = '.grid-stack'; }
231
+ var el = GridStack.getGridElement(elOrString);
232
+ if (!el) {
233
+ if (typeof elOrString === 'string') {
234
+ console.error('GridStack.initAll() no grid was found with selector "' + elOrString + '" - element missing or wrong selector ?' +
235
+ '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
236
+ }
237
+ else {
238
+ console.error('GridStack.init() no grid element was passed.');
239
+ }
240
+ return null;
241
+ }
242
+ if (!el.gridstack) {
243
+ el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
244
+ }
245
+ return el.gridstack;
246
+ };
247
+ /**
248
+ * Will initialize a list of elements (given a selector) and return an array of grids.
249
+ * @param options grid options (optional)
250
+ * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)
251
+ *
252
+ * @example
253
+ * let grids = GridStack.initAll();
254
+ * grids.forEach(...)
255
+ */
256
+ GridStack.initAll = function (options, selector) {
257
+ if (options === void 0) { options = {}; }
258
+ if (selector === void 0) { selector = '.grid-stack'; }
259
+ var grids = [];
260
+ GridStack.getGridElements(selector).forEach(function (el) {
261
+ if (!el.gridstack) {
262
+ el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
263
+ }
264
+ grids.push(el.gridstack);
265
+ });
266
+ if (grids.length === 0) {
267
+ console.error('GridStack.initAll() no grid was found with selector "' + selector + '" - element missing or wrong selector ?' +
268
+ '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
269
+ }
270
+ return grids;
271
+ };
272
+ /**
273
+ * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then
274
+ * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from
275
+ * JSON serialized data, including options.
276
+ * @param parent HTML element parent to the grid
277
+ * @param opt grids options used to initialize the grid, and list of children
278
+ */
279
+ GridStack.addGrid = function (parent, opt) {
280
+ if (opt === void 0) { opt = {}; }
281
+ if (!parent)
282
+ return null;
283
+ var el = parent;
284
+ if (el.gridstack) {
285
+ // already a grid - set option and load data
286
+ var grid_1 = el.gridstack;
287
+ if (opt)
288
+ grid_1.opts = __assign(__assign({}, grid_1.opts), opt);
289
+ if (opt.children !== undefined)
290
+ grid_1.load(opt.children);
291
+ return grid_1;
292
+ }
293
+ // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead
294
+ var parentIsGrid = parent.classList.contains('grid-stack');
295
+ if (!parentIsGrid || GridStack.addRemoveCB) {
296
+ if (GridStack.addRemoveCB) {
297
+ el = GridStack.addRemoveCB(parent, opt, true, true);
298
+ }
299
+ else {
300
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
301
+ doc.body.innerHTML = "<div class=\"grid-stack ".concat(opt.class || '', "\"></div>");
302
+ el = doc.body.children[0];
303
+ parent.appendChild(el);
304
+ }
305
+ }
306
+ // create grid class and load any children
307
+ var grid = GridStack.init(opt, el);
308
+ return grid;
309
+ };
310
+ /** call this method to register your engine instead of the default one.
311
+ * See instead `GridStackOptions.engineClass` if you only need to
312
+ * replace just one instance.
313
+ */
314
+ GridStack.registerEngine = function (engineClass) {
315
+ GridStack.engineClass = engineClass;
316
+ };
317
+ Object.defineProperty(GridStack.prototype, "placeholder", {
318
+ /** @internal create placeholder DIV as needed */
319
+ get: function () {
320
+ if (!this._placeholder) {
321
+ var placeholderChild = document.createElement('div'); // child so padding match item-content
322
+ placeholderChild.className = 'placeholder-content';
323
+ if (this.opts.placeholderText) {
324
+ placeholderChild.innerHTML = this.opts.placeholderText;
325
+ }
326
+ this._placeholder = document.createElement('div');
327
+ this._placeholder.classList.add(this.opts.placeholderClass, types_1.gridDefaults.itemClass, this.opts.itemClass);
328
+ this.placeholder.appendChild(placeholderChild);
329
+ }
330
+ return this._placeholder;
331
+ },
332
+ enumerable: false,
333
+ configurable: true
334
+ });
335
+ /**
336
+ * add a new widget and returns it.
337
+ *
338
+ * Widget will be always placed even if result height is more than actual grid height.
339
+ * You need to use `willItFit()` before calling addWidget for additional check.
340
+ * See also `makeWidget()`.
341
+ *
342
+ * @example
343
+ * let grid = GridStack.init();
344
+ * grid.addWidget({w: 3, content: 'hello'});
345
+ * grid.addWidget('<div class="grid-stack-item"><div class="grid-stack-item-content">hello</div></div>', {w: 3});
346
+ *
347
+ * @param el GridStackWidget (which can have content string as well), html element, or string definition to add
348
+ * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget
349
+ */
350
+ GridStack.prototype.addWidget = function (els, options) {
351
+ function isGridStackWidget(w) {
352
+ return w.el !== undefined || w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;
353
+ }
354
+ var el;
355
+ var node;
356
+ if (typeof els === 'string') {
357
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
358
+ doc.body.innerHTML = els;
359
+ el = doc.body.children[0];
360
+ }
361
+ else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {
362
+ node = options = els;
363
+ if (node === null || node === void 0 ? void 0 : node.el) {
364
+ el = node.el; // re-use element stored in the node
365
+ }
366
+ else if (GridStack.addRemoveCB) {
367
+ el = GridStack.addRemoveCB(this.el, options, true, false);
368
+ }
369
+ else {
370
+ var content = (options === null || options === void 0 ? void 0 : options.content) || '';
371
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
372
+ doc.body.innerHTML = "<div class=\"grid-stack-item ".concat(this.opts.itemClass || '', "\"><div class=\"grid-stack-item-content\">").concat(content, "</div></div>");
373
+ el = doc.body.children[0];
374
+ }
375
+ }
376
+ else {
377
+ el = els;
378
+ }
379
+ if (!el)
380
+ return;
381
+ // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos
382
+ // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz') before adding the node.
383
+ // So make sure we load any DOM attributes that are not specified in passed in options (which override)
384
+ var domAttr = this._readAttr(el);
385
+ options = utils_1.Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it
386
+ utils_1.Utils.defaults(options, domAttr);
387
+ node = this.engine.prepareNode(options);
388
+ this._writeAttr(el, options);
389
+ if (this._insertNotAppend) {
390
+ this.el.prepend(el);
391
+ }
392
+ else {
393
+ this.el.appendChild(el);
394
+ }
395
+ // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id
396
+ this._prepareElement(el, true, options);
397
+ this._updateContainerHeight();
398
+ // see if there is a sub-grid to create
399
+ if (node.subGridOpts) {
400
+ this.makeSubGrid(node.el, node.subGridOpts, undefined, false); // node.subGrid will be used as option in method, no need to pass
401
+ }
402
+ // if we're adding an item into 1 column (_prevColumn is set only when going to 1) make sure
403
+ // we don't override the larger 12 column layout that was already saved. #1985
404
+ if (this._prevColumn && this.opts.column === 1) {
405
+ this._ignoreLayoutsNodeChange = true;
406
+ }
407
+ this._triggerAddEvent();
408
+ this._triggerChangeEvent();
409
+ delete this._ignoreLayoutsNodeChange;
410
+ return el;
411
+ };
412
+ /**
413
+ * Convert an existing gridItem element into a sub-grid with the given (optional) options, else inherit them
414
+ * from the parent's subGrid options.
415
+ * @param el gridItem element to convert
416
+ * @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults
417
+ * @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)
418
+ * @returns newly created grid
419
+ */
420
+ GridStack.prototype.makeSubGrid = function (el, ops, nodeToAdd, saveContent) {
421
+ var _a, _b, _c;
422
+ if (saveContent === void 0) { saveContent = true; }
423
+ var node = el.gridstackNode;
424
+ if (!node) {
425
+ node = this.makeWidget(el).gridstackNode;
426
+ }
427
+ if ((_a = node.subGrid) === null || _a === void 0 ? void 0 : _a.el)
428
+ return node.subGrid; // already done
429
+ // find the template subGrid stored on a parent as fallback...
430
+ var subGridTemplate; // eslint-disable-next-line @typescript-eslint/no-this-alias
431
+ var grid = this;
432
+ while (grid && !subGridTemplate) {
433
+ subGridTemplate = (_b = grid.opts) === null || _b === void 0 ? void 0 : _b.subGridOpts;
434
+ grid = (_c = grid.parentGridItem) === null || _c === void 0 ? void 0 : _c.grid;
435
+ }
436
+ //... and set the create options
437
+ ops = utils_1.Utils.cloneDeep(__assign(__assign(__assign({}, (subGridTemplate || {})), { children: undefined }), (ops || node.subGridOpts)));
438
+ node.subGridOpts = ops;
439
+ // if column special case it set, remember that flag and set default
440
+ var autoColumn;
441
+ if (ops.column === 'auto') {
442
+ autoColumn = true;
443
+ ops.column = Math.max(node.w || 1, (nodeToAdd === null || nodeToAdd === void 0 ? void 0 : nodeToAdd.w) || 1);
444
+ ops.disableOneColumnMode = true; // driven by parent
445
+ }
446
+ // if we're converting an existing full item, move over the content to be the first sub item in the new grid
447
+ var content = node.el.querySelector('.grid-stack-item-content');
448
+ var newItem;
449
+ var newItemOpt;
450
+ if (saveContent) {
451
+ this._removeDD(node.el); // remove D&D since it's set on content div
452
+ newItemOpt = __assign(__assign({}, node), { x: 0, y: 0 });
453
+ utils_1.Utils.removeInternalForSave(newItemOpt);
454
+ delete newItemOpt.subGridOpts;
455
+ if (node.content) {
456
+ newItemOpt.content = node.content;
457
+ delete node.content;
458
+ }
459
+ if (GridStack.addRemoveCB) {
460
+ newItem = GridStack.addRemoveCB(this.el, newItemOpt, true, false);
461
+ }
462
+ else {
463
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
464
+ doc.body.innerHTML = "<div class=\"grid-stack-item\"></div>";
465
+ newItem = doc.body.children[0];
466
+ newItem.appendChild(content);
467
+ doc.body.innerHTML = "<div class=\"grid-stack-item-content\"></div>";
468
+ content = doc.body.children[0];
469
+ node.el.appendChild(content);
470
+ }
471
+ this._prepareDragDropByNode(node); // ... and restore original D&D
472
+ }
473
+ // if we're adding an additional item, make the container large enough to have them both
474
+ if (nodeToAdd) {
475
+ var w = autoColumn ? ops.column : node.w;
476
+ var h = node.h + nodeToAdd.h;
477
+ var style_1 = node.el.style;
478
+ style_1.transition = 'none'; // show up instantly so we don't see scrollbar with nodeToAdd
479
+ this.update(node.el, { w: w, h: h });
480
+ setTimeout(function () { return style_1.transition = null; }); // recover animation
481
+ }
482
+ var subGrid = node.subGrid = GridStack.addGrid(content, ops);
483
+ if (nodeToAdd === null || nodeToAdd === void 0 ? void 0 : nodeToAdd._moving)
484
+ subGrid._isTemp = true; // prevent re-nesting as we add over
485
+ if (autoColumn)
486
+ subGrid._autoColumn = true;
487
+ // add the original content back as a child of hte newly created grid
488
+ if (saveContent) {
489
+ subGrid.addWidget(newItem, newItemOpt);
490
+ }
491
+ // now add any additional node
492
+ if (nodeToAdd) {
493
+ if (nodeToAdd._moving) {
494
+ // create an artificial event even for the just created grid to receive this item
495
+ window.setTimeout(function () { return utils_1.Utils.simulateMouseEvent(nodeToAdd._event, 'mouseenter', subGrid.el); }, 0);
496
+ }
497
+ else {
498
+ subGrid.addWidget(node.el, node);
499
+ }
500
+ }
501
+ return subGrid;
502
+ };
503
+ /**
504
+ * called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back
505
+ * to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)
506
+ */
507
+ GridStack.prototype.removeAsSubGrid = function (nodeThatRemoved) {
508
+ var _this = this;
509
+ var _a;
510
+ var pGrid = (_a = this.parentGridItem) === null || _a === void 0 ? void 0 : _a.grid;
511
+ if (!pGrid)
512
+ return;
513
+ pGrid.batchUpdate();
514
+ pGrid.removeWidget(this.parentGridItem.el, true, true);
515
+ this.engine.nodes.forEach(function (n) {
516
+ // migrate any children over and offsetting by our location
517
+ n.x += _this.parentGridItem.x;
518
+ n.y += _this.parentGridItem.y;
519
+ pGrid.addWidget(n.el, n);
520
+ });
521
+ pGrid.batchUpdate(false);
522
+ if (this.parentGridItem)
523
+ delete this.parentGridItem.subGrid;
524
+ delete this.parentGridItem;
525
+ // create an artificial event for the original grid now that this one is gone (got a leave, but won't get enter)
526
+ if (nodeThatRemoved) {
527
+ window.setTimeout(function () { return utils_1.Utils.simulateMouseEvent(nodeThatRemoved._event, 'mouseenter', pGrid.el); }, 0);
528
+ }
529
+ };
530
+ /**
531
+ * saves the current layout returning a list of widgets for serialization which might include any nested grids.
532
+ * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will
533
+ * be removed.
534
+ * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()
535
+ * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
536
+ * @param saveCB callback for each node -> widget, so application can insert additional data to be saved into the widget data structure.
537
+ * @returns list of widgets or full grid option, including .children list of widgets
538
+ */
539
+ GridStack.prototype.save = function (saveContent, saveGridOpt, saveCB) {
540
+ if (saveContent === void 0) { saveContent = true; }
541
+ if (saveGridOpt === void 0) { saveGridOpt = false; }
542
+ if (saveCB === void 0) { saveCB = GridStack.saveCB; }
543
+ // return copied GridStackWidget (with optionally .el) we can modify at will...
544
+ var list = this.engine.save(saveContent, saveCB);
545
+ // check for HTML content and nested grids
546
+ list.forEach(function (n) {
547
+ var _a;
548
+ if (saveContent && n.el && !n.subGrid && !saveCB) { // sub-grid are saved differently, not plain content
549
+ var sub = n.el.querySelector('.grid-stack-item-content');
550
+ n.content = sub ? sub.innerHTML : undefined;
551
+ if (!n.content)
552
+ delete n.content;
553
+ }
554
+ else {
555
+ if (!saveContent && !saveCB) {
556
+ delete n.content;
557
+ }
558
+ // check for nested grid
559
+ if ((_a = n.subGrid) === null || _a === void 0 ? void 0 : _a.el) {
560
+ var listOrOpt = n.subGrid.save(saveContent, saveGridOpt, saveCB);
561
+ n.subGridOpts = (saveGridOpt ? listOrOpt : { children: listOrOpt });
562
+ delete n.subGrid;
563
+ }
564
+ }
565
+ delete n.el;
566
+ });
567
+ // check if save entire grid options (needed for recursive) + children...
568
+ if (saveGridOpt) {
569
+ var o = utils_1.Utils.cloneDeep(this.opts);
570
+ // delete default values that will be recreated on launch
571
+ if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {
572
+ o.margin = o.marginTop;
573
+ delete o.marginTop;
574
+ delete o.marginRight;
575
+ delete o.marginBottom;
576
+ delete o.marginLeft;
577
+ }
578
+ if (o.rtl === (this.el.style.direction === 'rtl')) {
579
+ o.rtl = 'auto';
580
+ }
581
+ if (this._isAutoCellHeight) {
582
+ o.cellHeight = 'auto';
583
+ }
584
+ if (this._autoColumn) {
585
+ o.column = 'auto';
586
+ delete o.disableOneColumnMode;
587
+ }
588
+ var origShow = o._alwaysShowResizeHandle;
589
+ delete o._alwaysShowResizeHandle;
590
+ if (origShow !== undefined) {
591
+ o.alwaysShowResizeHandle = origShow;
592
+ }
593
+ else {
594
+ delete o.alwaysShowResizeHandle;
595
+ }
596
+ utils_1.Utils.removeInternalAndSame(o, types_1.gridDefaults);
597
+ o.children = list;
598
+ return o;
599
+ }
600
+ return list;
601
+ };
602
+ /**
603
+ * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.
604
+ *
605
+ * @param layout list of widgets definition to update/create
606
+ * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving
607
+ * the user control of insertion.
608
+ *
609
+ * @example
610
+ * see http://gridstackjs.com/demo/serialization.html
611
+ **/
612
+ GridStack.prototype.load = function (layout, addRemove) {
613
+ var _this = this;
614
+ if (addRemove === void 0) { addRemove = GridStack.addRemoveCB || true; }
615
+ var items = GridStack.Utils.sort(__spreadArray([], layout, true), -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort
616
+ this._insertNotAppend = true; // since create in reverse order...
617
+ // if we're loading a layout into for example 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save
618
+ // the original wanted layout so we can scale back up correctly #1471
619
+ if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(function (n) { return (n.x + n.w) > _this.opts.column; })) {
620
+ this._ignoreLayoutsNodeChange = true; // skip layout update
621
+ this.engine.cacheLayout(items, this._prevColumn, true);
622
+ }
623
+ // if given a different callback, temporally set it as global option so creating will use it
624
+ var prevCB = GridStack.addRemoveCB;
625
+ if (typeof (addRemove) === 'function')
626
+ GridStack.addRemoveCB = addRemove;
627
+ var removed = [];
628
+ this.batchUpdate();
629
+ // see if any items are missing from new layout and need to be removed first
630
+ if (addRemove) {
631
+ var copyNodes = __spreadArray([], this.engine.nodes, true); // don't loop through array you modify
632
+ copyNodes.forEach(function (n) {
633
+ var item = items.find(function (w) { return n.id === w.id; });
634
+ if (!item) {
635
+ if (GridStack.addRemoveCB)
636
+ GridStack.addRemoveCB(_this.el, n, false, false);
637
+ removed.push(n); // batch keep track
638
+ _this.removeWidget(n.el, true, false);
639
+ }
640
+ });
641
+ }
642
+ // now add/update the widgets
643
+ items.forEach(function (w) {
644
+ var _a;
645
+ var item = (w.id || w.id === 0) ? _this.engine.nodes.find(function (n) { return n.id === w.id; }) : undefined;
646
+ if (item) {
647
+ _this.update(item.el, w);
648
+ if ((_a = w.subGridOpts) === null || _a === void 0 ? void 0 : _a.children) { // update any sub grid as well
649
+ var sub = item.el.querySelector('.grid-stack');
650
+ if (sub && sub.gridstack) {
651
+ sub.gridstack.load(w.subGridOpts.children); // TODO: support updating grid options ?
652
+ _this._insertNotAppend = true; // got reset by above call
653
+ }
654
+ }
655
+ }
656
+ else if (addRemove) {
657
+ _this.addWidget(w);
658
+ }
659
+ });
660
+ this.engine.removedNodes = removed;
661
+ this.batchUpdate(false);
662
+ // after commit, clear that flag
663
+ delete this._ignoreLayoutsNodeChange;
664
+ delete this._insertNotAppend;
665
+ prevCB ? GridStack.addRemoveCB = prevCB : delete GridStack.addRemoveCB;
666
+ return this;
667
+ };
668
+ /**
669
+ * use before calling a bunch of `addWidget()` to prevent un-necessary relayouts in between (more efficient)
670
+ * and get a single event callback. You will see no changes until `batchUpdate(false)` is called.
671
+ */
672
+ GridStack.prototype.batchUpdate = function (flag) {
673
+ if (flag === void 0) { flag = true; }
674
+ this.engine.batchUpdate(flag);
675
+ if (!flag) {
676
+ this._triggerRemoveEvent();
677
+ this._triggerAddEvent();
678
+ this._triggerChangeEvent();
679
+ }
680
+ return this;
681
+ };
682
+ /**
683
+ * Gets current cell height.
684
+ */
685
+ GridStack.prototype.getCellHeight = function (forcePixel) {
686
+ if (forcePixel === void 0) { forcePixel = false; }
687
+ if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&
688
+ (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {
689
+ return this.opts.cellHeight;
690
+ }
691
+ // else get first cell height
692
+ var el = this.el.querySelector('.' + this.opts.itemClass);
693
+ if (el) {
694
+ var height = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
695
+ return Math.round(el.offsetHeight / height);
696
+ }
697
+ // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)
698
+ var rows = parseInt(this.el.getAttribute('gs-current-row'));
699
+ return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight;
700
+ };
701
+ /**
702
+ * Update current cell height - see `GridStackOptions.cellHeight` for format.
703
+ * This method rebuilds an internal CSS style sheet.
704
+ * Note: You can expect performance issues if call this method too often.
705
+ *
706
+ * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),
707
+ * if pass 0 the CSS will be generated by the application instead.
708
+ * @param update (Optional) if false, styles will not be updated
709
+ *
710
+ * @example
711
+ * grid.cellHeight(100); // same as 100px
712
+ * grid.cellHeight('70px');
713
+ * grid.cellHeight(grid.cellWidth() * 1.2);
714
+ */
715
+ GridStack.prototype.cellHeight = function (val, update) {
716
+ if (update === void 0) { update = true; }
717
+ // if not called internally, check if we're changing mode
718
+ if (update && val !== undefined) {
719
+ if (this._isAutoCellHeight !== (val === 'auto')) {
720
+ this._isAutoCellHeight = (val === 'auto');
721
+ this._updateWindowResizeEvent();
722
+ }
723
+ }
724
+ if (val === 'initial' || val === 'auto') {
725
+ val = undefined;
726
+ }
727
+ // make item content be square
728
+ if (val === undefined) {
729
+ var marginDiff = -this.opts.marginRight - this.opts.marginLeft
730
+ + this.opts.marginTop + this.opts.marginBottom;
731
+ val = this.cellWidth() + marginDiff;
732
+ }
733
+ var data = utils_1.Utils.parseHeight(val);
734
+ if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {
735
+ return this;
736
+ }
737
+ this.opts.cellHeightUnit = data.unit;
738
+ this.opts.cellHeight = data.h;
739
+ if (update) {
740
+ this._updateStyles(true); // true = force re-create for current # of rows
741
+ }
742
+ return this;
743
+ };
744
+ /** Gets current cell width. */
745
+ GridStack.prototype.cellWidth = function () {
746
+ return this._widthOrContainer() / this.getColumn();
747
+ };
748
+ /** return our expected width (or parent) for 1 column check */
749
+ GridStack.prototype._widthOrContainer = function () {
750
+ // use `offsetWidth` or `clientWidth` (no scrollbar) ?
751
+ // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
752
+ return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);
753
+ };
754
+ /** re-layout grid items to reclaim any empty space */
755
+ GridStack.prototype.compact = function () {
756
+ this.engine.compact();
757
+ this._triggerChangeEvent();
758
+ return this;
759
+ };
760
+ /**
761
+ * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,
762
+ * as well as cache the original layout so you can revert back to previous positions without loss.
763
+ * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],
764
+ * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)
765
+ * @param column - Integer > 0 (default 12).
766
+ * @param layout specify the type of re-layout that will happen (position, size, etc...).
767
+ * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
768
+ */
769
+ GridStack.prototype.column = function (column, layout) {
770
+ if (layout === void 0) { layout = 'moveScale'; }
771
+ if (column < 1 || this.opts.column === column)
772
+ return this;
773
+ var oldColumn = this.getColumn();
774
+ // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)
775
+ // then remember the original columns so we can restore.
776
+ if (column === 1) {
777
+ this._prevColumn = oldColumn;
778
+ }
779
+ else {
780
+ delete this._prevColumn;
781
+ }
782
+ this.el.classList.remove('grid-stack-' + oldColumn);
783
+ this.el.classList.add('grid-stack-' + column);
784
+ this.opts.column = this.engine.column = column;
785
+ // update the items now - see if the dom order nodes should be passed instead (else default to current list)
786
+ var domNodes;
787
+ if (column === 1 && this.opts.oneColumnModeDomSort) {
788
+ domNodes = [];
789
+ this.getGridItems().forEach(function (el) {
790
+ if (el.gridstackNode) {
791
+ domNodes.push(el.gridstackNode);
792
+ }
793
+ });
794
+ if (!domNodes.length) {
795
+ domNodes = undefined;
796
+ }
797
+ }
798
+ this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);
799
+ if (this._isAutoCellHeight)
800
+ this.cellHeight();
801
+ // and trigger our event last...
802
+ this._ignoreLayoutsNodeChange = true; // skip layout update
803
+ this._triggerChangeEvent();
804
+ delete this._ignoreLayoutsNodeChange;
805
+ return this;
806
+ };
807
+ /**
808
+ * get the number of columns in the grid (default 12)
809
+ */
810
+ GridStack.prototype.getColumn = function () {
811
+ return this.opts.column;
812
+ };
813
+ /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */
814
+ GridStack.prototype.getGridItems = function () {
815
+ var _this = this;
816
+ return Array.from(this.el.children)
817
+ .filter(function (el) { return el.matches('.' + _this.opts.itemClass) && !el.matches('.' + _this.opts.placeholderClass); });
818
+ };
819
+ /**
820
+ * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.
821
+ * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).
822
+ */
823
+ GridStack.prototype.destroy = function (removeDOM) {
824
+ if (removeDOM === void 0) { removeDOM = true; }
825
+ if (!this.el)
826
+ return; // prevent multiple calls
827
+ this.offAll();
828
+ this._updateWindowResizeEvent(true);
829
+ this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)
830
+ this.setAnimation(false);
831
+ if (!removeDOM) {
832
+ this.removeAll(removeDOM);
833
+ this.el.classList.remove(this._styleSheetClass);
834
+ this.el.removeAttribute('gs-current-row');
835
+ }
836
+ else {
837
+ this.el.parentNode.removeChild(this.el);
838
+ }
839
+ this._removeStylesheet();
840
+ if (this.parentGridItem)
841
+ delete this.parentGridItem.subGrid;
842
+ delete this.parentGridItem;
843
+ delete this.opts;
844
+ delete this._placeholder;
845
+ delete this.engine;
846
+ delete this.el.gridstack; // remove circular dependency that would prevent a freeing
847
+ delete this.el;
848
+ return this;
849
+ };
850
+ /**
851
+ * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)
852
+ */
853
+ GridStack.prototype.float = function (val) {
854
+ if (this.opts.float !== val) {
855
+ this.opts.float = this.engine.float = val;
856
+ this._triggerChangeEvent();
857
+ }
858
+ return this;
859
+ };
860
+ /**
861
+ * get the current float mode
862
+ */
863
+ GridStack.prototype.getFloat = function () {
864
+ return this.engine.float;
865
+ };
866
+ /**
867
+ * Get the position of the cell under a pixel on screen.
868
+ * @param position the position of the pixel to resolve in
869
+ * absolute coordinates, as an object with top and left properties
870
+ * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).
871
+ * Useful when grid is within `position: relative` element
872
+ *
873
+ * Returns an object with properties `x` and `y` i.e. the column and row in the grid.
874
+ */
875
+ GridStack.prototype.getCellFromPixel = function (position, useDocRelative) {
876
+ if (useDocRelative === void 0) { useDocRelative = false; }
877
+ var box = this.el.getBoundingClientRect();
878
+ // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)
879
+ var containerPos;
880
+ if (useDocRelative) {
881
+ containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left };
882
+ // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)
883
+ }
884
+ else {
885
+ containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft };
886
+ // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)
887
+ }
888
+ var relativeLeft = position.left - containerPos.left;
889
+ var relativeTop = position.top - containerPos.top;
890
+ var columnWidth = (box.width / this.getColumn());
891
+ var rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));
892
+ return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) };
893
+ };
894
+ /** returns the current number of rows, which will be at least `minRow` if set */
895
+ GridStack.prototype.getRow = function () {
896
+ return Math.max(this.engine.getRow(), this.opts.minRow);
897
+ };
898
+ /**
899
+ * Checks if specified area is empty.
900
+ * @param x the position x.
901
+ * @param y the position y.
902
+ * @param w the width of to check
903
+ * @param h the height of to check
904
+ */
905
+ GridStack.prototype.isAreaEmpty = function (x, y, w, h) {
906
+ return this.engine.isAreaEmpty(x, y, w, h);
907
+ };
908
+ /**
909
+ * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.
910
+ * If you want gridstack to add the elements for you, use `addWidget()` instead.
911
+ * Makes the given element a widget and returns it.
912
+ * @param els widget or single selector to convert.
913
+ *
914
+ * @example
915
+ * let grid = GridStack.init();
916
+ * grid.el.appendChild('<div id="gsi-1" gs-w="3"></div>');
917
+ * grid.makeWidget('#gsi-1');
918
+ */
919
+ GridStack.prototype.makeWidget = function (els) {
920
+ var el = GridStack.getElement(els);
921
+ this._prepareElement(el, true);
922
+ this._updateContainerHeight();
923
+ this._triggerAddEvent();
924
+ this._triggerChangeEvent();
925
+ return el;
926
+ };
927
+ /**
928
+ * Event handler that extracts our CustomEvent data out automatically for receiving custom
929
+ * notifications (see doc for supported events)
930
+ * @param name of the event (see possible values) or list of names space separated
931
+ * @param callback function called with event and optional second/third param
932
+ * (see README documentation for each signature).
933
+ *
934
+ * @example
935
+ * grid.on('added', function(e, items) { log('added ', items)} );
936
+ * or
937
+ * grid.on('added removed change', function(e, items) { log(e.type, items)} );
938
+ *
939
+ * Note: in some cases it is the same as calling native handler and parsing the event.
940
+ * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );
941
+ *
942
+ */
943
+ GridStack.prototype.on = function (name, callback) {
944
+ var _this = this;
945
+ // check for array of names being passed instead
946
+ if (name.indexOf(' ') !== -1) {
947
+ var names = name.split(' ');
948
+ names.forEach(function (name) { return _this.on(name, callback); });
949
+ return this;
950
+ }
951
+ if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
952
+ // native CustomEvent handlers - cash the generic handlers so we can easily remove
953
+ var noData = (name === 'enable' || name === 'disable');
954
+ if (noData) {
955
+ this._gsEventHandler[name] = function (event) { return callback(event); };
956
+ }
957
+ else {
958
+ this._gsEventHandler[name] = function (event) { return callback(event, event.detail); };
959
+ }
960
+ this.el.addEventListener(name, this._gsEventHandler[name]);
961
+ }
962
+ else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {
963
+ // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.
964
+ // do same for start event to make it easier...
965
+ this._gsEventHandler[name] = callback;
966
+ }
967
+ else {
968
+ console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');
969
+ }
970
+ return this;
971
+ };
972
+ /**
973
+ * unsubscribe from the 'on' event below
974
+ * @param name of the event (see possible values)
975
+ */
976
+ GridStack.prototype.off = function (name) {
977
+ var _this = this;
978
+ // check for array of names being passed instead
979
+ if (name.indexOf(' ') !== -1) {
980
+ var names = name.split(' ');
981
+ names.forEach(function (name) { return _this.off(name); });
982
+ return this;
983
+ }
984
+ if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
985
+ // remove native CustomEvent handlers
986
+ if (this._gsEventHandler[name]) {
987
+ this.el.removeEventListener(name, this._gsEventHandler[name]);
988
+ }
989
+ }
990
+ delete this._gsEventHandler[name];
991
+ return this;
992
+ };
993
+ /** remove all event handlers */
994
+ GridStack.prototype.offAll = function () {
995
+ var _this = this;
996
+ Object.keys(this._gsEventHandler).forEach(function (key) { return _this.off(key); });
997
+ return this;
998
+ };
999
+ /**
1000
+ * Removes widget from the grid.
1001
+ * @param el widget or selector to modify
1002
+ * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).
1003
+ * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).
1004
+ */
1005
+ GridStack.prototype.removeWidget = function (els, removeDOM, triggerEvent) {
1006
+ var _this = this;
1007
+ if (removeDOM === void 0) { removeDOM = true; }
1008
+ if (triggerEvent === void 0) { triggerEvent = true; }
1009
+ GridStack.getElements(els).forEach(function (el) {
1010
+ if (el.parentElement && el.parentElement !== _this.el)
1011
+ return; // not our child!
1012
+ var node = el.gridstackNode;
1013
+ // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272
1014
+ if (!node) {
1015
+ node = _this.engine.nodes.find(function (n) { return el === n.el; });
1016
+ }
1017
+ if (!node)
1018
+ return;
1019
+ // remove our DOM data (circular link) and drag&drop permanently
1020
+ delete el.gridstackNode;
1021
+ _this._removeDD(el);
1022
+ _this.engine.removeNode(node, removeDOM, triggerEvent);
1023
+ if (removeDOM && el.parentElement) {
1024
+ el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM
1025
+ }
1026
+ });
1027
+ if (triggerEvent) {
1028
+ this._triggerRemoveEvent();
1029
+ this._triggerChangeEvent();
1030
+ }
1031
+ return this;
1032
+ };
1033
+ /**
1034
+ * Removes all widgets from the grid.
1035
+ * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).
1036
+ */
1037
+ GridStack.prototype.removeAll = function (removeDOM) {
1038
+ var _this = this;
1039
+ if (removeDOM === void 0) { removeDOM = true; }
1040
+ // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently
1041
+ this.engine.nodes.forEach(function (n) {
1042
+ delete n.el.gridstackNode;
1043
+ _this._removeDD(n.el);
1044
+ });
1045
+ this.engine.removeAll(removeDOM);
1046
+ this._triggerRemoveEvent();
1047
+ return this;
1048
+ };
1049
+ /**
1050
+ * Toggle the grid animation state. Toggles the `grid-stack-animate` class.
1051
+ * @param doAnimate if true the grid will animate.
1052
+ */
1053
+ GridStack.prototype.setAnimation = function (doAnimate) {
1054
+ if (doAnimate) {
1055
+ this.el.classList.add('grid-stack-animate');
1056
+ }
1057
+ else {
1058
+ this.el.classList.remove('grid-stack-animate');
1059
+ }
1060
+ return this;
1061
+ };
1062
+ /**
1063
+ * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.
1064
+ * Also toggle the grid-stack-static class.
1065
+ * @param val if true the grid become static.
1066
+ * @param updateClass true (default) if css class gets updated
1067
+ * @param recurse true (default) if sub-grids also get updated
1068
+ */
1069
+ GridStack.prototype.setStatic = function (val, updateClass, recurse) {
1070
+ var _this = this;
1071
+ if (updateClass === void 0) { updateClass = true; }
1072
+ if (recurse === void 0) { recurse = true; }
1073
+ if (this.opts.staticGrid === val)
1074
+ return this;
1075
+ this.opts.staticGrid = val;
1076
+ this._setupRemoveDrop();
1077
+ this._setupAcceptWidget();
1078
+ this.engine.nodes.forEach(function (n) {
1079
+ _this._prepareDragDropByNode(n); // either delete or init Drag&drop
1080
+ if (n.subGrid && recurse)
1081
+ n.subGrid.setStatic(val, updateClass, recurse);
1082
+ });
1083
+ if (updateClass) {
1084
+ this._setStaticClass();
1085
+ }
1086
+ return this;
1087
+ };
1088
+ /**
1089
+ * 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.
1090
+ * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)
1091
+ * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.
1092
+ */
1093
+ GridStack.prototype.update = function (els, opt) {
1094
+ var _this = this;
1095
+ // support legacy call for now ?
1096
+ if (arguments.length > 2) {
1097
+ console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');
1098
+ // eslint-disable-next-line prefer-rest-params
1099
+ var a = arguments, i = 1;
1100
+ opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] };
1101
+ return this.update(els, opt);
1102
+ }
1103
+ GridStack.getElements(els).forEach(function (el) {
1104
+ if (!el || !el.gridstackNode)
1105
+ return;
1106
+ var n = el.gridstackNode;
1107
+ var w = utils_1.Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items
1108
+ delete w.autoPosition;
1109
+ // move/resize widget if anything changed
1110
+ var keys = ['x', 'y', 'w', 'h'];
1111
+ var m;
1112
+ if (keys.some(function (k) { return w[k] !== undefined && w[k] !== n[k]; })) {
1113
+ m = {};
1114
+ keys.forEach(function (k) {
1115
+ m[k] = (w[k] !== undefined) ? w[k] : n[k];
1116
+ delete w[k];
1117
+ });
1118
+ }
1119
+ // for a move as well IFF there is any min/max fields set
1120
+ if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {
1121
+ m = {}; // will use node position but validate values
1122
+ }
1123
+ // check for content changing
1124
+ if (w.content) {
1125
+ var sub = el.querySelector('.grid-stack-item-content');
1126
+ if (sub && sub.innerHTML !== w.content) {
1127
+ sub.innerHTML = w.content;
1128
+ }
1129
+ delete w.content;
1130
+ }
1131
+ // any remaining fields are assigned, but check for dragging changes, resize constrain
1132
+ var changed = false;
1133
+ var ddChanged = false;
1134
+ for (var key in w) {
1135
+ if (key[0] !== '_' && n[key] !== w[key]) {
1136
+ n[key] = w[key];
1137
+ changed = true;
1138
+ ddChanged = ddChanged || (!_this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));
1139
+ }
1140
+ }
1141
+ utils_1.Utils.sanitizeMinMax(n);
1142
+ // finally move the widget
1143
+ if (m) {
1144
+ _this.engine.cleanNodes()
1145
+ .beginUpdate(n)
1146
+ .moveNode(n, m);
1147
+ _this._updateContainerHeight();
1148
+ _this._triggerChangeEvent();
1149
+ _this.engine.endUpdate();
1150
+ }
1151
+ if (changed) { // move will only update x,y,w,h so update the rest too
1152
+ _this._writeAttr(el, n);
1153
+ }
1154
+ if (ddChanged) {
1155
+ _this._prepareDragDropByNode(n);
1156
+ }
1157
+ });
1158
+ return this;
1159
+ };
1160
+ /**
1161
+ * 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).
1162
+ * @param value margin value
1163
+ */
1164
+ GridStack.prototype.margin = function (value) {
1165
+ var isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);
1166
+ // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)
1167
+ if (!isMultiValue) {
1168
+ var data = utils_1.Utils.parseHeight(value);
1169
+ if (this.opts.marginUnit === data.unit && this.opts.margin === data.h)
1170
+ return;
1171
+ }
1172
+ // re-use existing margin handling
1173
+ this.opts.margin = value;
1174
+ this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;
1175
+ this._initMargin();
1176
+ this._updateStyles(true); // true = force re-create
1177
+ return this;
1178
+ };
1179
+ /** returns current margin number value (undefined if 4 sides don't match) */
1180
+ GridStack.prototype.getMargin = function () { return this.opts.margin; };
1181
+ /**
1182
+ * Returns true if the height of the grid will be less than the vertical
1183
+ * constraint. Always returns true if grid doesn't have height constraint.
1184
+ * @param node contains x,y,w,h,auto-position options
1185
+ *
1186
+ * @example
1187
+ * if (grid.willItFit(newWidget)) {
1188
+ * grid.addWidget(newWidget);
1189
+ * } else {
1190
+ * alert('Not enough free space to place the widget');
1191
+ * }
1192
+ */
1193
+ GridStack.prototype.willItFit = function (node) {
1194
+ // support legacy call for now
1195
+ if (arguments.length > 1) {
1196
+ console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');
1197
+ // eslint-disable-next-line prefer-rest-params
1198
+ var a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] };
1199
+ return this.willItFit(w);
1200
+ }
1201
+ return this.engine.willItFit(node);
1202
+ };
1203
+ /** @internal */
1204
+ GridStack.prototype._triggerChangeEvent = function () {
1205
+ if (this.engine.batchMode)
1206
+ return this;
1207
+ var elements = this.engine.getDirtyNodes(true); // verify they really changed
1208
+ if (elements && elements.length) {
1209
+ if (!this._ignoreLayoutsNodeChange) {
1210
+ this.engine.layoutsNodesChange(elements);
1211
+ }
1212
+ this._triggerEvent('change', elements);
1213
+ }
1214
+ this.engine.saveInitial(); // we called, now reset initial values & dirty flags
1215
+ return this;
1216
+ };
1217
+ /** @internal */
1218
+ GridStack.prototype._triggerAddEvent = function () {
1219
+ var _a;
1220
+ if (this.engine.batchMode)
1221
+ return this;
1222
+ if ((_a = this.engine.addedNodes) === null || _a === void 0 ? void 0 : _a.length) {
1223
+ if (!this._ignoreLayoutsNodeChange) {
1224
+ this.engine.layoutsNodesChange(this.engine.addedNodes);
1225
+ }
1226
+ // prevent added nodes from also triggering 'change' event (which is called next)
1227
+ this.engine.addedNodes.forEach(function (n) { delete n._dirty; });
1228
+ this._triggerEvent('added', this.engine.addedNodes);
1229
+ this.engine.addedNodes = [];
1230
+ }
1231
+ return this;
1232
+ };
1233
+ /** @internal */
1234
+ GridStack.prototype._triggerRemoveEvent = function () {
1235
+ var _a;
1236
+ if (this.engine.batchMode)
1237
+ return this;
1238
+ if ((_a = this.engine.removedNodes) === null || _a === void 0 ? void 0 : _a.length) {
1239
+ this._triggerEvent('removed', this.engine.removedNodes);
1240
+ this.engine.removedNodes = [];
1241
+ }
1242
+ return this;
1243
+ };
1244
+ /** @internal */
1245
+ GridStack.prototype._triggerEvent = function (type, data) {
1246
+ var event = data ? new CustomEvent(type, { bubbles: false, detail: data }) : new Event(type);
1247
+ this.el.dispatchEvent(event);
1248
+ return this;
1249
+ };
1250
+ /** @internal called to delete the current dynamic style sheet used for our layout */
1251
+ GridStack.prototype._removeStylesheet = function () {
1252
+ if (this._styles) {
1253
+ utils_1.Utils.removeStylesheet(this._styleSheetClass);
1254
+ delete this._styles;
1255
+ }
1256
+ return this;
1257
+ };
1258
+ /** @internal updated/create the CSS styles for row based layout and initial margin setting */
1259
+ GridStack.prototype._updateStyles = function (forceUpdate, maxH) {
1260
+ if (forceUpdate === void 0) { forceUpdate = false; }
1261
+ // call to delete existing one if we change cellHeight / margin
1262
+ if (forceUpdate) {
1263
+ this._removeStylesheet();
1264
+ }
1265
+ if (!maxH)
1266
+ maxH = this.getRow();
1267
+ this._updateContainerHeight();
1268
+ // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
1269
+ if (this.opts.cellHeight === 0) {
1270
+ return this;
1271
+ }
1272
+ var cellHeight = this.opts.cellHeight;
1273
+ var cellHeightUnit = this.opts.cellHeightUnit;
1274
+ var prefix = ".".concat(this._styleSheetClass, " > .").concat(this.opts.itemClass);
1275
+ // create one as needed
1276
+ if (!this._styles) {
1277
+ // insert style to parent (instead of 'head' by default) to support WebComponent
1278
+ var styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode;
1279
+ this._styles = utils_1.Utils.createStylesheet(this._styleSheetClass, styleLocation, {
1280
+ nonce: this.opts.nonce,
1281
+ });
1282
+ if (!this._styles)
1283
+ return this;
1284
+ this._styles._max = 0;
1285
+ // these are done once only
1286
+ utils_1.Utils.addCSSRule(this._styles, prefix, "min-height: ".concat(cellHeight).concat(cellHeightUnit));
1287
+ // content margins
1288
+ var top_1 = this.opts.marginTop + this.opts.marginUnit;
1289
+ var bottom = this.opts.marginBottom + this.opts.marginUnit;
1290
+ var right = this.opts.marginRight + this.opts.marginUnit;
1291
+ var left = this.opts.marginLeft + this.opts.marginUnit;
1292
+ var content = "".concat(prefix, " > .grid-stack-item-content");
1293
+ var placeholder = ".".concat(this._styleSheetClass, " > .grid-stack-placeholder > .placeholder-content");
1294
+ utils_1.Utils.addCSSRule(this._styles, content, "top: ".concat(top_1, "; right: ").concat(right, "; bottom: ").concat(bottom, "; left: ").concat(left, ";"));
1295
+ utils_1.Utils.addCSSRule(this._styles, placeholder, "top: ".concat(top_1, "; right: ").concat(right, "; bottom: ").concat(bottom, "; left: ").concat(left, ";"));
1296
+ // resize handles offset (to match margin)
1297
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-ne"), "right: ".concat(right));
1298
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-e"), "right: ".concat(right));
1299
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-se"), "right: ".concat(right, "; bottom: ").concat(bottom));
1300
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-nw"), "left: ".concat(left));
1301
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-w"), "left: ".concat(left));
1302
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, " > .ui-resizable-sw"), "left: ".concat(left, "; bottom: ").concat(bottom));
1303
+ }
1304
+ // now update the height specific fields
1305
+ maxH = maxH || this._styles._max;
1306
+ if (maxH > this._styles._max) {
1307
+ var getHeight = function (rows) { return (cellHeight * rows) + cellHeightUnit; };
1308
+ for (var i = this._styles._max + 1; i <= maxH; i++) { // start at 1
1309
+ var h = getHeight(i);
1310
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, "[gs-y=\"").concat(i - 1, "\"]"), "top: ".concat(getHeight(i - 1))); // start at 0
1311
+ utils_1.Utils.addCSSRule(this._styles, "".concat(prefix, "[gs-h=\"").concat(i, "\"]"), "height: ".concat(h));
1312
+ }
1313
+ this._styles._max = maxH;
1314
+ }
1315
+ return this;
1316
+ };
1317
+ /** @internal */
1318
+ GridStack.prototype._updateContainerHeight = function () {
1319
+ if (!this.engine || this.engine.batchMode)
1320
+ return this;
1321
+ var row = this.getRow() + this._extraDragRow; // checks for minRow already
1322
+ // check for css min height
1323
+ // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary
1324
+ // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.
1325
+ // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);
1326
+ // if (cssMinHeight > 0) {
1327
+ // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));
1328
+ // if (row < minRow) {
1329
+ // row = minRow;
1330
+ // }
1331
+ // }
1332
+ this.el.setAttribute('gs-current-row', String(row));
1333
+ if (row === 0) {
1334
+ this.el.style.removeProperty('min-height');
1335
+ return this;
1336
+ }
1337
+ var cellHeight = this.opts.cellHeight;
1338
+ var unit = this.opts.cellHeightUnit;
1339
+ if (!cellHeight)
1340
+ return this;
1341
+ this.el.style.minHeight = row * cellHeight + unit;
1342
+ return this;
1343
+ };
1344
+ /** @internal */
1345
+ GridStack.prototype._prepareElement = function (el, triggerAddEvent, node) {
1346
+ if (triggerAddEvent === void 0) { triggerAddEvent = false; }
1347
+ el.classList.add(this.opts.itemClass);
1348
+ node = node || this._readAttr(el);
1349
+ el.gridstackNode = node;
1350
+ node.el = el;
1351
+ node.grid = this;
1352
+ var copy = __assign({}, node);
1353
+ node = this.engine.addNode(node, triggerAddEvent);
1354
+ // write node attr back in case there was collision or we have to fix bad values during addNode()
1355
+ if (!utils_1.Utils.same(node, copy)) {
1356
+ this._writeAttr(el, node);
1357
+ }
1358
+ this._prepareDragDropByNode(node);
1359
+ return this;
1360
+ };
1361
+ /** @internal call to write position x,y,w,h attributes back to element */
1362
+ GridStack.prototype._writePosAttr = function (el, n) {
1363
+ if (n.x !== undefined && n.x !== null) {
1364
+ el.setAttribute('gs-x', String(n.x));
1365
+ }
1366
+ if (n.y !== undefined && n.y !== null) {
1367
+ el.setAttribute('gs-y', String(n.y));
1368
+ }
1369
+ n.w > 1 ? el.setAttribute('gs-w', String(n.w)) : el.removeAttribute('gs-w');
1370
+ n.h > 1 ? el.setAttribute('gs-h', String(n.h)) : el.removeAttribute('gs-h');
1371
+ return this;
1372
+ };
1373
+ /** @internal call to write any default attributes back to element */
1374
+ GridStack.prototype._writeAttr = function (el, node) {
1375
+ if (!node)
1376
+ return this;
1377
+ this._writePosAttr(el, node);
1378
+ var attrs /*: GridStackWidget but strings */ = {
1379
+ autoPosition: 'gs-auto-position',
1380
+ noResize: 'gs-no-resize',
1381
+ noMove: 'gs-no-move',
1382
+ locked: 'gs-locked',
1383
+ id: 'gs-id',
1384
+ };
1385
+ for (var key in attrs) {
1386
+ if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway
1387
+ el.setAttribute(attrs[key], String(node[key]));
1388
+ }
1389
+ else {
1390
+ el.removeAttribute(attrs[key]);
1391
+ }
1392
+ }
1393
+ return this;
1394
+ };
1395
+ /** @internal call to read any default attributes from element */
1396
+ GridStack.prototype._readAttr = function (el) {
1397
+ var n = {};
1398
+ n.x = utils_1.Utils.toNumber(el.getAttribute('gs-x'));
1399
+ n.y = utils_1.Utils.toNumber(el.getAttribute('gs-y'));
1400
+ n.w = utils_1.Utils.toNumber(el.getAttribute('gs-w'));
1401
+ n.h = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
1402
+ if (!(n.w > 1))
1403
+ el.removeAttribute('gs-w');
1404
+ if (!(n.h > 1))
1405
+ el.removeAttribute('gs-h');
1406
+ n.autoPosition = utils_1.Utils.toBool(el.getAttribute('gs-auto-position'));
1407
+ n.noResize = utils_1.Utils.toBool(el.getAttribute('gs-no-resize'));
1408
+ n.noMove = utils_1.Utils.toBool(el.getAttribute('gs-no-move'));
1409
+ n.locked = utils_1.Utils.toBool(el.getAttribute('gs-locked'));
1410
+ n.id = el.getAttribute('gs-id');
1411
+ // read but never written out
1412
+ n.maxW = utils_1.Utils.toNumber(el.getAttribute('gs-max-w'));
1413
+ if (n.maxW)
1414
+ el.removeAttribute('gs-max-w');
1415
+ n.minW = utils_1.Utils.toNumber(el.getAttribute('gs-min-w'));
1416
+ if (n.minW)
1417
+ el.removeAttribute('gs-min-w');
1418
+ n.maxH = utils_1.Utils.toNumber(el.getAttribute('gs-max-h'));
1419
+ if (n.maxH)
1420
+ el.removeAttribute('gs-max-h');
1421
+ n.minH = utils_1.Utils.toNumber(el.getAttribute('gs-min-h'));
1422
+ if (n.minH)
1423
+ el.removeAttribute('gs-min-h');
1424
+ // remove any key not found (null or false which is default)
1425
+ for (var key in n) {
1426
+ if (!n.hasOwnProperty(key))
1427
+ return;
1428
+ if (!n[key] && n[key] !== 0) { // 0 can be valid value (x,y only really)
1429
+ delete n[key];
1430
+ }
1431
+ }
1432
+ return n;
1433
+ };
1434
+ /** @internal */
1435
+ GridStack.prototype._setStaticClass = function () {
1436
+ var _a, _b;
1437
+ var classes = ['grid-stack-static'];
1438
+ if (this.opts.staticGrid) {
1439
+ (_a = this.el.classList).add.apply(_a, classes);
1440
+ this.el.setAttribute('gs-static', 'true');
1441
+ }
1442
+ else {
1443
+ (_b = this.el.classList).remove.apply(_b, classes);
1444
+ this.el.removeAttribute('gs-static');
1445
+ }
1446
+ return this;
1447
+ };
1448
+ /**
1449
+ * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off
1450
+ * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)
1451
+ */
1452
+ GridStack.prototype.onParentResize = function () {
1453
+ var _this = this;
1454
+ if (!this.el || !this.el.clientWidth)
1455
+ return; // return if we're gone or no size yet (will get called again)
1456
+ var changedColumn = false;
1457
+ // see if we're nested and take our column count from our parent....
1458
+ if (this._autoColumn && this.parentGridItem) {
1459
+ if (this.opts.column !== this.parentGridItem.w) {
1460
+ changedColumn = true;
1461
+ this.column(this.parentGridItem.w, 'none');
1462
+ }
1463
+ }
1464
+ else {
1465
+ // else check for 1 column in/out behavior
1466
+ var oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.oneColumnSize;
1467
+ if ((this.opts.column === 1) !== oneColumn) {
1468
+ changedColumn = true;
1469
+ if (this.opts.animate) {
1470
+ this.setAnimation(false);
1471
+ } // 1 <-> 12 is too radical, turn off animation
1472
+ this.column(oneColumn ? 1 : this._prevColumn);
1473
+ if (this.opts.animate) {
1474
+ this.setAnimation(true);
1475
+ }
1476
+ }
1477
+ }
1478
+ // make the cells content square again
1479
+ if (this._isAutoCellHeight) {
1480
+ if (!changedColumn && this.opts.cellHeightThrottle) {
1481
+ if (!this._cellHeightThrottle) {
1482
+ this._cellHeightThrottle = utils_1.Utils.throttle(function () { return _this.cellHeight(); }, this.opts.cellHeightThrottle);
1483
+ }
1484
+ this._cellHeightThrottle();
1485
+ }
1486
+ else {
1487
+ // immediate update if we've changed column count or have no threshold
1488
+ this.cellHeight();
1489
+ }
1490
+ }
1491
+ // finally update any nested grids
1492
+ this.engine.nodes.forEach(function (n) {
1493
+ if (n.subGrid)
1494
+ n.subGrid.onParentResize();
1495
+ });
1496
+ return this;
1497
+ };
1498
+ /** add or remove the window size event handler */
1499
+ GridStack.prototype._updateWindowResizeEvent = function (forceRemove) {
1500
+ if (forceRemove === void 0) { forceRemove = false; }
1501
+ // 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)
1502
+ var workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.parentGridItem;
1503
+ if (!forceRemove && workTodo && !this._windowResizeBind) {
1504
+ this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later
1505
+ window.addEventListener('resize', this._windowResizeBind);
1506
+ }
1507
+ else if ((forceRemove || !workTodo) && this._windowResizeBind) {
1508
+ window.removeEventListener('resize', this._windowResizeBind);
1509
+ delete this._windowResizeBind; // remove link to us so we can free
1510
+ }
1511
+ return this;
1512
+ };
1513
+ /** @internal convert a potential selector into actual element */
1514
+ GridStack.getElement = function (els) {
1515
+ if (els === void 0) { els = '.grid-stack-item'; }
1516
+ return utils_1.Utils.getElement(els);
1517
+ };
1518
+ /** @internal */
1519
+ GridStack.getElements = function (els) {
1520
+ if (els === void 0) { els = '.grid-stack-item'; }
1521
+ return utils_1.Utils.getElements(els);
1522
+ };
1523
+ /** @internal */
1524
+ GridStack.getGridElement = function (els) { return GridStack.getElement(els); };
1525
+ /** @internal */
1526
+ GridStack.getGridElements = function (els) { return utils_1.Utils.getElements(els); };
1527
+ /** @internal initialize margin top/bottom/left/right and units */
1528
+ GridStack.prototype._initMargin = function () {
1529
+ var data;
1530
+ var margin = 0;
1531
+ // support passing multiple values like CSS (ex: '5px 10px 0 20px')
1532
+ var margins = [];
1533
+ if (typeof this.opts.margin === 'string') {
1534
+ margins = this.opts.margin.split(' ');
1535
+ }
1536
+ if (margins.length === 2) { // top/bot, left/right like CSS
1537
+ this.opts.marginTop = this.opts.marginBottom = margins[0];
1538
+ this.opts.marginLeft = this.opts.marginRight = margins[1];
1539
+ }
1540
+ else if (margins.length === 4) { // Clockwise like CSS
1541
+ this.opts.marginTop = margins[0];
1542
+ this.opts.marginRight = margins[1];
1543
+ this.opts.marginBottom = margins[2];
1544
+ this.opts.marginLeft = margins[3];
1545
+ }
1546
+ else {
1547
+ data = utils_1.Utils.parseHeight(this.opts.margin);
1548
+ this.opts.marginUnit = data.unit;
1549
+ margin = this.opts.margin = data.h;
1550
+ }
1551
+ // see if top/bottom/left/right need to be set as well
1552
+ if (this.opts.marginTop === undefined) {
1553
+ this.opts.marginTop = margin;
1554
+ }
1555
+ else {
1556
+ data = utils_1.Utils.parseHeight(this.opts.marginTop);
1557
+ this.opts.marginTop = data.h;
1558
+ delete this.opts.margin;
1559
+ }
1560
+ if (this.opts.marginBottom === undefined) {
1561
+ this.opts.marginBottom = margin;
1562
+ }
1563
+ else {
1564
+ data = utils_1.Utils.parseHeight(this.opts.marginBottom);
1565
+ this.opts.marginBottom = data.h;
1566
+ delete this.opts.margin;
1567
+ }
1568
+ if (this.opts.marginRight === undefined) {
1569
+ this.opts.marginRight = margin;
1570
+ }
1571
+ else {
1572
+ data = utils_1.Utils.parseHeight(this.opts.marginRight);
1573
+ this.opts.marginRight = data.h;
1574
+ delete this.opts.margin;
1575
+ }
1576
+ if (this.opts.marginLeft === undefined) {
1577
+ this.opts.marginLeft = margin;
1578
+ }
1579
+ else {
1580
+ data = utils_1.Utils.parseHeight(this.opts.marginLeft);
1581
+ this.opts.marginLeft = data.h;
1582
+ delete this.opts.margin;
1583
+ }
1584
+ this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...
1585
+ if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {
1586
+ this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()
1587
+ }
1588
+ return this;
1589
+ };
1590
+ /* ===========================================================================================
1591
+ * drag&drop methods that used to be stubbed out and implemented in dd-gridstack.ts
1592
+ * but caused loading issues in prod - see https://github.com/gridstack/gridstack.js/issues/2039
1593
+ * ===========================================================================================
1594
+ */
1595
+ /** get the global (but static to this code) DD implementation */
1596
+ GridStack.getDD = function () {
1597
+ return dd;
1598
+ };
1599
+ /**
1600
+ * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.
1601
+ * Called during GridStack.init() as options, but can also be called directly (last param are used) in case the toolbar
1602
+ * is dynamically create and needs to be set later.
1603
+ * @param dragIn string selector (ex: '.sidebar .grid-stack-item') or list of dom elements
1604
+ * @param dragInOptions options - see DDDragInOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}
1605
+ * @param root optional root which defaults to document (for shadow dom)
1606
+ **/
1607
+ GridStack.setupDragIn = function (dragIn, dragInOptions, root) {
1608
+ if (root === void 0) { root = document; }
1609
+ if ((dragInOptions === null || dragInOptions === void 0 ? void 0 : dragInOptions.pause) !== undefined) {
1610
+ dd_manager_1.DDManager.pauseDrag = dragInOptions.pause;
1611
+ }
1612
+ dragInOptions = __assign(__assign({}, types_1.dragInDefaultOptions), (dragInOptions || {}));
1613
+ var els = (typeof dragIn === 'string') ? utils_1.Utils.getElements(dragIn, root) : dragIn;
1614
+ if (els.length)
1615
+ els === null || els === void 0 ? void 0 : els.forEach(function (el) {
1616
+ if (!dd.isDraggable(el))
1617
+ dd.dragIn(el, dragInOptions);
1618
+ });
1619
+ };
1620
+ /**
1621
+ * 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.
1622
+ * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.
1623
+ * @param els widget or selector to modify.
1624
+ * @param val if true widget will be draggable.
1625
+ */
1626
+ GridStack.prototype.movable = function (els, val) {
1627
+ var _this = this;
1628
+ if (this.opts.staticGrid)
1629
+ return this; // can't move a static grid!
1630
+ GridStack.getElements(els).forEach(function (el) {
1631
+ var node = el.gridstackNode;
1632
+ if (!node)
1633
+ return;
1634
+ if (val)
1635
+ delete node.noMove;
1636
+ else
1637
+ node.noMove = true;
1638
+ _this._prepareDragDropByNode(node); // init DD if need be, and adjust
1639
+ });
1640
+ return this;
1641
+ };
1642
+ /**
1643
+ * 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.
1644
+ * @param els widget or selector to modify
1645
+ * @param val if true widget will be resizable.
1646
+ */
1647
+ GridStack.prototype.resizable = function (els, val) {
1648
+ var _this = this;
1649
+ if (this.opts.staticGrid)
1650
+ return this; // can't resize a static grid!
1651
+ GridStack.getElements(els).forEach(function (el) {
1652
+ var node = el.gridstackNode;
1653
+ if (!node)
1654
+ return;
1655
+ if (val)
1656
+ delete node.noResize;
1657
+ else
1658
+ node.noResize = true;
1659
+ _this._prepareDragDropByNode(node); // init DD if need be, and adjust
1660
+ });
1661
+ return this;
1662
+ };
1663
+ /**
1664
+ * Temporarily disables widgets moving/resizing.
1665
+ * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.
1666
+ * Note: no-op for static grid
1667
+ * This is a shortcut for:
1668
+ * @example
1669
+ * grid.enableMove(false);
1670
+ * grid.enableResize(false);
1671
+ * @param recurse true (default) if sub-grids also get updated
1672
+ */
1673
+ GridStack.prototype.disable = function (recurse) {
1674
+ if (recurse === void 0) { recurse = true; }
1675
+ if (this.opts.staticGrid)
1676
+ return;
1677
+ this.enableMove(false, recurse);
1678
+ this.enableResize(false, recurse); // @ts-ignore
1679
+ this._triggerEvent('disable');
1680
+ return this;
1681
+ };
1682
+ /**
1683
+ * Re-enables widgets moving/resizing - see disable().
1684
+ * Note: no-op for static grid.
1685
+ * This is a shortcut for:
1686
+ * @example
1687
+ * grid.enableMove(true);
1688
+ * grid.enableResize(true);
1689
+ * @param recurse true (default) if sub-grids also get updated
1690
+ */
1691
+ GridStack.prototype.enable = function (recurse) {
1692
+ if (recurse === void 0) { recurse = true; }
1693
+ if (this.opts.staticGrid)
1694
+ return;
1695
+ this.enableMove(true, recurse);
1696
+ this.enableResize(true, recurse); // @ts-ignore
1697
+ this._triggerEvent('enable');
1698
+ return this;
1699
+ };
1700
+ /**
1701
+ * Enables/disables widget moving. No-op for static grids.
1702
+ * @param recurse true (default) if sub-grids also get updated
1703
+ */
1704
+ GridStack.prototype.enableMove = function (doEnable, recurse) {
1705
+ var _this = this;
1706
+ if (recurse === void 0) { recurse = true; }
1707
+ if (this.opts.staticGrid)
1708
+ return this; // can't move a static grid!
1709
+ this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658
1710
+ this.engine.nodes.forEach(function (n) {
1711
+ _this.movable(n.el, doEnable);
1712
+ if (n.subGrid && recurse)
1713
+ n.subGrid.enableMove(doEnable, recurse);
1714
+ });
1715
+ return this;
1716
+ };
1717
+ /**
1718
+ * Enables/disables widget resizing. No-op for static grids.
1719
+ * @param recurse true (default) if sub-grids also get updated
1720
+ */
1721
+ GridStack.prototype.enableResize = function (doEnable, recurse) {
1722
+ var _this = this;
1723
+ if (recurse === void 0) { recurse = true; }
1724
+ if (this.opts.staticGrid)
1725
+ return this; // can't size a static grid!
1726
+ this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658
1727
+ this.engine.nodes.forEach(function (n) {
1728
+ _this.resizable(n.el, doEnable);
1729
+ if (n.subGrid && recurse)
1730
+ n.subGrid.enableResize(doEnable, recurse);
1731
+ });
1732
+ return this;
1733
+ };
1734
+ /** @internal removes any drag&drop present (called during destroy) */
1735
+ GridStack.prototype._removeDD = function (el) {
1736
+ dd.draggable(el, 'destroy').resizable(el, 'destroy');
1737
+ if (el.gridstackNode) {
1738
+ delete el.gridstackNode._initDD; // reset our DD init flag
1739
+ }
1740
+ delete el.ddElement;
1741
+ return this;
1742
+ };
1743
+ /** @internal called to add drag over to support widgets being added externally */
1744
+ GridStack.prototype._setupAcceptWidget = function () {
1745
+ var _this = this;
1746
+ // check if we need to disable things
1747
+ if (this.opts.staticGrid || (!this.opts.acceptWidgets && !this.opts.removable)) {
1748
+ dd.droppable(this.el, 'destroy');
1749
+ return this;
1750
+ }
1751
+ // vars shared across all methods
1752
+ var cellHeight, cellWidth;
1753
+ var onDrag = function (event, el, helper) {
1754
+ var _a;
1755
+ var node = el.gridstackNode;
1756
+ if (!node)
1757
+ return;
1758
+ helper = helper || el;
1759
+ var parent = _this.el.getBoundingClientRect();
1760
+ var top = (_a = helper.getBoundingClientRect(), _a.top), left = _a.left;
1761
+ left -= parent.left;
1762
+ top -= parent.top;
1763
+ var ui = { position: { top: top, left: left } };
1764
+ if (node._temporaryRemoved) {
1765
+ node.x = Math.max(0, Math.round(left / cellWidth));
1766
+ node.y = Math.max(0, Math.round(top / cellHeight));
1767
+ delete node.autoPosition;
1768
+ _this.engine.nodeBoundFix(node);
1769
+ // 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
1770
+ if (!_this.engine.willItFit(node)) {
1771
+ node.autoPosition = true; // ignore x,y and try for any slot...
1772
+ if (!_this.engine.willItFit(node)) {
1773
+ dd.off(el, 'drag'); // stop calling us
1774
+ return; // full grid or can't grow
1775
+ }
1776
+ if (node._willFitPos) {
1777
+ // use the auto position instead #1687
1778
+ utils_1.Utils.copyPos(node, node._willFitPos);
1779
+ delete node._willFitPos;
1780
+ }
1781
+ }
1782
+ // re-use the existing node dragging method
1783
+ _this._onStartMoving(helper, event, ui, node, cellWidth, cellHeight);
1784
+ }
1785
+ else {
1786
+ // re-use the existing node dragging that does so much of the collision detection
1787
+ _this._dragOrResize(helper, event, ui, node, cellWidth, cellHeight);
1788
+ }
1789
+ };
1790
+ dd.droppable(this.el, {
1791
+ accept: function (el) {
1792
+ var node = el.gridstackNode;
1793
+ // set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving
1794
+ if ((node === null || node === void 0 ? void 0 : node.grid) === _this)
1795
+ return true;
1796
+ if (!_this.opts.acceptWidgets)
1797
+ return false;
1798
+ // check for accept method or class matching
1799
+ var canAccept = true;
1800
+ if (typeof _this.opts.acceptWidgets === 'function') {
1801
+ canAccept = _this.opts.acceptWidgets(el);
1802
+ }
1803
+ else {
1804
+ var selector = (_this.opts.acceptWidgets === true ? '.grid-stack-item' : _this.opts.acceptWidgets);
1805
+ canAccept = el.matches(selector);
1806
+ }
1807
+ // finally check to make sure we actually have space left #1571
1808
+ if (canAccept && node && _this.opts.maxRow) {
1809
+ var n = { w: node.w, h: node.h, minW: node.minW, minH: node.minH }; // only width/height matters and autoPosition
1810
+ canAccept = _this.engine.willItFit(n);
1811
+ }
1812
+ return canAccept;
1813
+ }
1814
+ })
1815
+ /**
1816
+ * entering our grid area
1817
+ */
1818
+ .on(this.el, 'dropover', function (event, el, helper) {
1819
+ // console.log(`over ${this.el.gridstack.opts.id} ${count++}`); // TEST
1820
+ var node = el.gridstackNode;
1821
+ // ignore drop enter on ourself (unless we temporarily removed) which happens on a simple drag of our item
1822
+ if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._temporaryRemoved) {
1823
+ // delete node._added; // reset this to track placeholder again in case we were over other grid #1484 (dropout doesn't always clear)
1824
+ return false; // prevent parent from receiving msg (which may be a grid as well)
1825
+ }
1826
+ // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now
1827
+ if ((node === null || node === void 0 ? void 0 : node.grid) && node.grid !== _this && !node._temporaryRemoved) {
1828
+ // console.log('dropover without leave'); // TEST
1829
+ var otherGrid = node.grid;
1830
+ otherGrid._leave(el, helper);
1831
+ }
1832
+ // cache cell dimensions (which don't change), position can animate if we removed an item in otherGrid that affects us...
1833
+ cellWidth = _this.cellWidth();
1834
+ cellHeight = _this.getCellHeight(true);
1835
+ // load any element attributes if we don't have a node
1836
+ if (!node) { // @ts-ignore private read only on ourself
1837
+ node = _this._readAttr(el);
1838
+ }
1839
+ if (!node.grid) {
1840
+ node._isExternal = true;
1841
+ el.gridstackNode = node;
1842
+ }
1843
+ // calculate the grid size based on element outer size
1844
+ helper = helper || el;
1845
+ var w = node.w || Math.round(helper.offsetWidth / cellWidth) || 1;
1846
+ var h = node.h || Math.round(helper.offsetHeight / cellHeight) || 1;
1847
+ // if the item came from another grid, make a copy and save the original info in case we go back there
1848
+ if (node.grid && node.grid !== _this) {
1849
+ // copy the node original values (min/max/id/etc...) but override width/height/other flags which are this grid specific
1850
+ // console.log('dropover cloning node'); // TEST
1851
+ if (!el._gridstackNodeOrig)
1852
+ el._gridstackNodeOrig = node; // shouldn't have multiple nested!
1853
+ el.gridstackNode = node = __assign(__assign({}, node), { w: w, h: h, grid: _this });
1854
+ _this.engine.cleanupNode(node)
1855
+ .nodeBoundFix(node);
1856
+ // restore some internal fields we need after clearing them all
1857
+ node._initDD =
1858
+ node._isExternal = // DOM needs to be re-parented on a drop
1859
+ node._temporaryRemoved = true; // so it can be inserted onDrag below
1860
+ }
1861
+ else {
1862
+ node.w = w;
1863
+ node.h = h;
1864
+ node._temporaryRemoved = true; // so we can insert it
1865
+ }
1866
+ // clear any marked for complete removal (Note: don't check _isAboutToRemove as that is cleared above - just do it)
1867
+ _this._itemRemoving(node.el, false);
1868
+ dd.on(el, 'drag', onDrag);
1869
+ // make sure this is called at least once when going fast #1578
1870
+ onDrag(event, el, helper);
1871
+ return false; // prevent parent from receiving msg (which may be a grid as well)
1872
+ })
1873
+ /**
1874
+ * Leaving our grid area...
1875
+ */
1876
+ .on(this.el, 'dropout', function (event, el, helper) {
1877
+ // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST
1878
+ var node = el.gridstackNode;
1879
+ if (!node)
1880
+ return false;
1881
+ // fix #1578 when dragging fast, we might get leave after other grid gets enter (which calls us to clean)
1882
+ // so skip this one if we're not the active grid really..
1883
+ if (!node.grid || node.grid === _this) {
1884
+ _this._leave(el, helper);
1885
+ // if we were created as temporary nested grid, go back to before state
1886
+ if (_this._isTemp) {
1887
+ _this.removeAsSubGrid(node);
1888
+ }
1889
+ }
1890
+ return false; // prevent parent from receiving msg (which may be grid as well)
1891
+ })
1892
+ /**
1893
+ * end - releasing the mouse
1894
+ */
1895
+ .on(this.el, 'drop', function (event, el, helper) {
1896
+ var _a, _b;
1897
+ var node = el.gridstackNode;
1898
+ // ignore drop on ourself from ourself that didn't come from the outside - dragend will handle the simple move instead
1899
+ if ((node === null || node === void 0 ? void 0 : node.grid) === _this && !node._isExternal)
1900
+ return false;
1901
+ var wasAdded = !!_this.placeholder.parentElement; // skip items not actually added to us because of constrains, but do cleanup #1419
1902
+ _this.placeholder.remove();
1903
+ // notify previous grid of removal
1904
+ // console.log('drop delete _gridstackNodeOrig') // TEST
1905
+ var origNode = el._gridstackNodeOrig;
1906
+ delete el._gridstackNodeOrig;
1907
+ if (wasAdded && (origNode === null || origNode === void 0 ? void 0 : origNode.grid) && origNode.grid !== _this) {
1908
+ var oGrid = origNode.grid;
1909
+ oGrid.engine.removedNodes.push(origNode);
1910
+ oGrid._triggerRemoveEvent()._triggerChangeEvent();
1911
+ // if it's an empty sub-grid that got auto-created, nuke it
1912
+ if (oGrid.parentGridItem && !oGrid.engine.nodes.length && oGrid.opts.subGridDynamic) {
1913
+ oGrid.removeAsSubGrid();
1914
+ }
1915
+ }
1916
+ if (!node)
1917
+ return false;
1918
+ // use existing placeholder node as it's already in our list with drop location
1919
+ if (wasAdded) {
1920
+ _this.engine.cleanupNode(node); // removes all internal _xyz values
1921
+ node.grid = _this;
1922
+ }
1923
+ dd.off(el, 'drag');
1924
+ // if we made a copy ('helper' which is temp) of the original node then insert a copy, else we move the original node (#1102)
1925
+ // as the helper will be nuked by jquery-ui otherwise. TODO: update old code path
1926
+ if (helper !== el) {
1927
+ helper.remove();
1928
+ el.gridstackNode = origNode; // original item (left behind) is re-stored to pre dragging as the node now has drop info
1929
+ if (wasAdded) {
1930
+ el = el.cloneNode(true);
1931
+ }
1932
+ }
1933
+ else {
1934
+ el.remove(); // reduce flicker as we change depth here, and size further down
1935
+ _this._removeDD(el);
1936
+ }
1937
+ if (!wasAdded)
1938
+ return false;
1939
+ el.gridstackNode = node;
1940
+ node.el = el;
1941
+ var subGrid = (_b = (_a = node.subGrid) === null || _a === void 0 ? void 0 : _a.el) === null || _b === void 0 ? void 0 : _b.gridstack; // set when actual sub-grid present
1942
+ // @ts-ignore
1943
+ utils_1.Utils.copyPos(node, _this._readAttr(_this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578
1944
+ utils_1.Utils.removePositioningStyles(el); // @ts-ignore
1945
+ _this._writeAttr(el, node);
1946
+ el.classList.add(types_1.gridDefaults.itemClass, _this.opts.itemClass);
1947
+ _this.el.appendChild(el); // @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)
1948
+ if (subGrid) {
1949
+ subGrid.parentGridItem = node;
1950
+ if (!subGrid.opts.styleInHead)
1951
+ subGrid._updateStyles(true); // re-create sub-grid styles now that we've moved
1952
+ }
1953
+ _this._updateContainerHeight();
1954
+ _this.engine.addedNodes.push(node); // @ts-ignore
1955
+ _this._triggerAddEvent(); // @ts-ignore
1956
+ _this._triggerChangeEvent();
1957
+ _this.engine.endUpdate();
1958
+ if (_this._gsEventHandler['dropped']) {
1959
+ _this._gsEventHandler['dropped'](__assign(__assign({}, event), { type: 'dropped' }), origNode && origNode.grid ? origNode : undefined, node);
1960
+ }
1961
+ // wait till we return out of the drag callback to set the new drag&resize handler or they may get messed up
1962
+ window.setTimeout(function () {
1963
+ // IFF we are still there (some application will use as placeholder and insert their real widget instead and better call makeWidget())
1964
+ if (node.el && node.el.parentElement) {
1965
+ _this._prepareDragDropByNode(node);
1966
+ }
1967
+ else {
1968
+ _this.engine.removeNode(node);
1969
+ }
1970
+ delete node.grid._isTemp;
1971
+ });
1972
+ return false; // prevent parent from receiving msg (which may be grid as well)
1973
+ });
1974
+ return this;
1975
+ };
1976
+ /** @internal mark item for removal */
1977
+ GridStack.prototype._itemRemoving = function (el, remove) {
1978
+ var node = el ? el.gridstackNode : undefined;
1979
+ if (!node || !node.grid)
1980
+ return;
1981
+ remove ? node._isAboutToRemove = true : delete node._isAboutToRemove;
1982
+ remove ? el.classList.add('grid-stack-item-removing') : el.classList.remove('grid-stack-item-removing');
1983
+ };
1984
+ /** @internal called to setup a trash drop zone if the user specifies it */
1985
+ GridStack.prototype._setupRemoveDrop = function () {
1986
+ var _this = this;
1987
+ if (!this.opts.staticGrid && typeof this.opts.removable === 'string') {
1988
+ var trashEl = document.querySelector(this.opts.removable);
1989
+ if (!trashEl)
1990
+ return this;
1991
+ // only register ONE drop-over/dropout callback for the 'trash', and it will
1992
+ // update the passed in item and parent grid because the 'trash' is a shared resource anyway,
1993
+ // and Native DD only has 1 event CB (having a list and technically a per grid removableOptions complicates things greatly)
1994
+ if (!dd.isDroppable(trashEl)) {
1995
+ dd.droppable(trashEl, this.opts.removableOptions)
1996
+ .on(trashEl, 'dropover', function (event, el) { return _this._itemRemoving(el, true); })
1997
+ .on(trashEl, 'dropout', function (event, el) { return _this._itemRemoving(el, false); });
1998
+ }
1999
+ }
2000
+ return this;
2001
+ };
2002
+ /** @internal prepares the element for drag&drop **/
2003
+ GridStack.prototype._prepareDragDropByNode = function (node) {
2004
+ var _this = this;
2005
+ var el = node.el;
2006
+ var noMove = node.noMove || this.opts.disableDrag;
2007
+ var noResize = node.noResize || this.opts.disableResize;
2008
+ // check for disabled grid first
2009
+ if (this.opts.staticGrid || (noMove && noResize)) {
2010
+ if (node._initDD) {
2011
+ this._removeDD(el); // nukes everything instead of just disable, will add some styles back next
2012
+ delete node._initDD;
2013
+ }
2014
+ el.classList.add('ui-draggable-disabled', 'ui-resizable-disabled'); // add styles one might depend on #1435
2015
+ return this;
2016
+ }
2017
+ if (!node._initDD) {
2018
+ // variables used/cashed between the 3 start/move/end methods, in addition to node passed above
2019
+ var cellWidth_1;
2020
+ var cellHeight_1;
2021
+ /** called when item starts moving/resizing */
2022
+ var onStartMoving = function (event, ui) {
2023
+ // trigger any 'dragstart' / 'resizestart' manually
2024
+ if (_this._gsEventHandler[event.type]) {
2025
+ _this._gsEventHandler[event.type](event, event.target);
2026
+ }
2027
+ cellWidth_1 = _this.cellWidth();
2028
+ cellHeight_1 = _this.getCellHeight(true); // force pixels for calculations
2029
+ _this._onStartMoving(el, event, ui, node, cellWidth_1, cellHeight_1);
2030
+ };
2031
+ /** called when item is being dragged/resized */
2032
+ var dragOrResize = function (event, ui) {
2033
+ _this._dragOrResize(el, event, ui, node, cellWidth_1, cellHeight_1);
2034
+ };
2035
+ /** called when the item stops moving/resizing */
2036
+ var onEndMoving = function (event) {
2037
+ _this.placeholder.remove();
2038
+ delete node._moving;
2039
+ delete node._event;
2040
+ delete node._lastTried;
2041
+ // if the item has moved to another grid, we're done here
2042
+ var target = event.target;
2043
+ if (!target.gridstackNode || target.gridstackNode.grid !== _this)
2044
+ return;
2045
+ node.el = target;
2046
+ if (node._isAboutToRemove) {
2047
+ var gridToNotify = el.gridstackNode.grid;
2048
+ if (gridToNotify._gsEventHandler[event.type]) {
2049
+ gridToNotify._gsEventHandler[event.type](event, target);
2050
+ }
2051
+ _this._removeDD(el);
2052
+ gridToNotify.engine.removedNodes.push(node);
2053
+ gridToNotify._triggerRemoveEvent();
2054
+ // break circular links and remove DOM
2055
+ delete el.gridstackNode;
2056
+ delete node.el;
2057
+ el.remove();
2058
+ }
2059
+ else {
2060
+ utils_1.Utils.removePositioningStyles(target);
2061
+ if (node._temporaryRemoved) {
2062
+ // got removed - restore item back to before dragging position
2063
+ utils_1.Utils.copyPos(node, node._orig); // @ts-ignore
2064
+ _this._writePosAttr(target, node);
2065
+ _this.engine.addNode(node);
2066
+ }
2067
+ else {
2068
+ // move to new placeholder location
2069
+ _this._writePosAttr(target, node);
2070
+ }
2071
+ if (_this._gsEventHandler[event.type]) {
2072
+ _this._gsEventHandler[event.type](event, target);
2073
+ }
2074
+ }
2075
+ // @ts-ignore
2076
+ _this._extraDragRow = 0; // @ts-ignore
2077
+ _this._updateContainerHeight(); // @ts-ignore
2078
+ _this._triggerChangeEvent();
2079
+ _this.engine.endUpdate();
2080
+ };
2081
+ dd.draggable(el, {
2082
+ start: onStartMoving,
2083
+ stop: onEndMoving,
2084
+ drag: dragOrResize
2085
+ }).resizable(el, {
2086
+ start: onStartMoving,
2087
+ stop: onEndMoving,
2088
+ resize: dragOrResize
2089
+ });
2090
+ node._initDD = true; // we've set DD support now
2091
+ }
2092
+ // finally fine tune move vs resize by disabling any part...
2093
+ dd.draggable(el, noMove ? 'disable' : 'enable')
2094
+ .resizable(el, noResize ? 'disable' : 'enable');
2095
+ return this;
2096
+ };
2097
+ /** @internal handles actual drag/resize start **/
2098
+ GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) {
2099
+ this.engine.cleanNodes()
2100
+ .beginUpdate(node);
2101
+ // @ts-ignore
2102
+ this._writePosAttr(this.placeholder, node);
2103
+ this.el.appendChild(this.placeholder);
2104
+ // console.log('_onStartMoving placeholder') // TEST
2105
+ node.el = this.placeholder;
2106
+ node._lastUiPosition = ui.position;
2107
+ node._prevYPix = ui.position.top;
2108
+ 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)
2109
+ delete node._lastTried;
2110
+ if (event.type === 'dropover' && node._temporaryRemoved) {
2111
+ // console.log('engine.addNode x=' + node.x); // TEST
2112
+ this.engine.addNode(node); // will add, fix collisions, update attr and clear _temporaryRemoved
2113
+ node._moving = true; // AFTER, mark as moving object (wanted fix location before)
2114
+ }
2115
+ // set the min/max resize info
2116
+ this.engine.cacheRects(cellWidth, cellHeight, this.opts.marginTop, this.opts.marginRight, this.opts.marginBottom, this.opts.marginLeft);
2117
+ if (event.type === 'resizestart') {
2118
+ dd.resizable(el, 'option', 'minWidth', cellWidth * (node.minW || 1))
2119
+ .resizable(el, 'option', 'minHeight', cellHeight * (node.minH || 1));
2120
+ if (node.maxW) {
2121
+ dd.resizable(el, 'option', 'maxWidth', cellWidth * node.maxW);
2122
+ }
2123
+ if (node.maxH) {
2124
+ dd.resizable(el, 'option', 'maxHeight', cellHeight * node.maxH);
2125
+ }
2126
+ }
2127
+ };
2128
+ /** @internal handles actual drag/resize **/
2129
+ GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) {
2130
+ 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)
2131
+ var resizing;
2132
+ var mLeft = this.opts.marginLeft, mRight = this.opts.marginRight, mTop = this.opts.marginTop, mBottom = this.opts.marginBottom;
2133
+ // if margins (which are used to pass mid point by) are large relative to cell height/width, reduce them down #1855
2134
+ var mHeight = Math.round(cellHeight * 0.1), mWidth = Math.round(cellWidth * 0.1);
2135
+ mLeft = Math.min(mLeft, mWidth);
2136
+ mRight = Math.min(mRight, mWidth);
2137
+ mTop = Math.min(mTop, mHeight);
2138
+ mBottom = Math.min(mBottom, mHeight);
2139
+ if (event.type === 'drag') {
2140
+ if (node._temporaryRemoved)
2141
+ return; // handled by dropover
2142
+ var distance = ui.position.top - node._prevYPix;
2143
+ node._prevYPix = ui.position.top;
2144
+ if (this.opts.draggable.scroll !== false) {
2145
+ utils_1.Utils.updateScrollPosition(el, ui.position, distance);
2146
+ }
2147
+ // get new position taking into account the margin in the direction we are moving! (need to pass mid point by margin)
2148
+ var left = ui.position.left + (ui.position.left > node._lastUiPosition.left ? -mRight : mLeft);
2149
+ var top_2 = ui.position.top + (ui.position.top > node._lastUiPosition.top ? -mBottom : mTop);
2150
+ p.x = Math.round(left / cellWidth);
2151
+ p.y = Math.round(top_2 / cellHeight);
2152
+ // @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
2153
+ var prev = this._extraDragRow;
2154
+ if (this.engine.collide(node, p)) {
2155
+ var row = this.getRow();
2156
+ var extra = Math.max(0, (p.y + node.h) - row);
2157
+ if (this.opts.maxRow && row + extra > this.opts.maxRow) {
2158
+ extra = Math.max(0, this.opts.maxRow - row);
2159
+ } // @ts-ignore
2160
+ this._extraDragRow = extra; // @ts-ignore
2161
+ }
2162
+ else
2163
+ this._extraDragRow = 0; // @ts-ignore
2164
+ if (this._extraDragRow !== prev)
2165
+ this._updateContainerHeight();
2166
+ if (node.x === p.x && node.y === p.y)
2167
+ return; // skip same
2168
+ // DON'T skip one we tried as we might have failed because of coverage <50% before
2169
+ // if (node._lastTried && node._lastTried.x === x && node._lastTried.y === y) return;
2170
+ }
2171
+ else if (event.type === 'resize') {
2172
+ if (p.x < 0)
2173
+ return;
2174
+ // Scrolling page if needed
2175
+ utils_1.Utils.updateScrollResize(event, el, cellHeight);
2176
+ // get new size
2177
+ p.w = Math.round((ui.size.width - mLeft) / cellWidth);
2178
+ p.h = Math.round((ui.size.height - mTop) / cellHeight);
2179
+ if (node.w === p.w && node.h === p.h)
2180
+ return;
2181
+ if (node._lastTried && node._lastTried.w === p.w && node._lastTried.h === p.h)
2182
+ return; // skip one we tried (but failed)
2183
+ // if we size on left/top side this might move us, so get possible new position as well
2184
+ var left = ui.position.left + mLeft;
2185
+ var top_3 = ui.position.top + mTop;
2186
+ p.x = Math.round(left / cellWidth);
2187
+ p.y = Math.round(top_3 / cellHeight);
2188
+ resizing = true;
2189
+ }
2190
+ node._event = event;
2191
+ node._lastTried = p; // set as last tried (will nuke if we go there)
2192
+ var rect = {
2193
+ x: ui.position.left + mLeft,
2194
+ y: ui.position.top + mTop,
2195
+ w: (ui.size ? ui.size.width : node.w * cellWidth) - mLeft - mRight,
2196
+ h: (ui.size ? ui.size.height : node.h * cellHeight) - mTop - mBottom
2197
+ };
2198
+ if (this.engine.moveNodeCheck(node, __assign(__assign({}, p), { cellWidth: cellWidth, cellHeight: cellHeight, rect: rect, resizing: resizing }))) {
2199
+ node._lastUiPosition = ui.position;
2200
+ this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);
2201
+ delete node._skipDown;
2202
+ if (resizing && node.subGrid)
2203
+ node.subGrid.onParentResize();
2204
+ this._extraDragRow = 0; // @ts-ignore
2205
+ this._updateContainerHeight();
2206
+ var target = event.target; // @ts-ignore
2207
+ this._writePosAttr(target, node);
2208
+ if (this._gsEventHandler[event.type]) {
2209
+ this._gsEventHandler[event.type](event, target);
2210
+ }
2211
+ }
2212
+ };
2213
+ /** @internal called when item leaving our area by either cursor dropout event
2214
+ * or shape is outside our boundaries. remove it from us, and mark temporary if this was
2215
+ * our item to start with else restore prev node values from prev grid it came from.
2216
+ **/
2217
+ GridStack.prototype._leave = function (el, helper) {
2218
+ var node = el.gridstackNode;
2219
+ if (!node)
2220
+ return;
2221
+ dd.off(el, 'drag'); // no need to track while being outside
2222
+ // this gets called when cursor leaves and shape is outside, so only do this once
2223
+ if (node._temporaryRemoved)
2224
+ return;
2225
+ node._temporaryRemoved = true;
2226
+ this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue
2227
+ node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged
2228
+ if (this.opts.removable === true) { // boolean vs a class string
2229
+ // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so
2230
+ this._itemRemoving(el, true);
2231
+ }
2232
+ // finally if item originally came from another grid, but left us, restore things back to prev info
2233
+ if (el._gridstackNodeOrig) {
2234
+ // console.log('leave delete _gridstackNodeOrig') // TEST
2235
+ el.gridstackNode = el._gridstackNodeOrig;
2236
+ delete el._gridstackNodeOrig;
2237
+ }
2238
+ else if (node._isExternal) {
2239
+ // item came from outside (like a toolbar) so nuke any node info
2240
+ delete node.el;
2241
+ delete el.gridstackNode;
2242
+ // and restore all nodes back to original
2243
+ this.engine.restoreInitial();
2244
+ }
2245
+ };
2246
+ // legacy method removed
2247
+ GridStack.prototype.commit = function () { (0, utils_1.obsolete)(this, this.batchUpdate(false), 'commit', 'batchUpdate', '5.2'); return this; };
2248
+ /** scoping so users can call GridStack.Utils.sort() for example */
2249
+ GridStack.Utils = utils_1.Utils;
2250
+ /** scoping so users can call new GridStack.Engine(12) for example */
2251
+ GridStack.Engine = gridstack_engine_1.GridStackEngine;
2252
+ GridStack.GDRev = '8.0.1';
2253
+ return GridStack;
2254
+ }());
2234
2255
  //# sourceMappingURL=gridstack.js.map