gridstack 4.3.0 → 5.0.0

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 (126) hide show
  1. package/README.md +22 -5
  2. package/dist/es5/gridstack-dd.d.ts +35 -0
  3. package/dist/es5/gridstack-dd.js +686 -0
  4. package/dist/es5/gridstack-dd.js.map +1 -0
  5. package/dist/es5/gridstack-ddi.d.ts +17 -0
  6. package/dist/es5/gridstack-ddi.js +31 -0
  7. package/dist/es5/gridstack-ddi.js.map +1 -0
  8. package/dist/es5/gridstack-engine.d.ts +93 -0
  9. package/dist/es5/gridstack-engine.js +955 -0
  10. package/dist/es5/gridstack-engine.js.map +1 -0
  11. package/dist/es5/gridstack-h5.d.ts +10 -0
  12. package/dist/es5/gridstack-h5.js +3 -0
  13. package/dist/es5/gridstack-h5.js.LICENSE.txt +7 -0
  14. package/dist/es5/gridstack-h5.js.map +1 -0
  15. package/dist/es5/gridstack-jq.d.ts +10 -0
  16. package/dist/es5/gridstack-jq.js +3 -0
  17. package/dist/es5/gridstack-jq.js.LICENSE.txt +99 -0
  18. package/dist/es5/gridstack-jq.js.map +1 -0
  19. package/dist/{gridstack-poly.js → es5/gridstack-poly.js} +154 -3
  20. package/dist/es5/gridstack-static.d.ts +9 -0
  21. package/dist/es5/gridstack-static.js +3 -0
  22. package/dist/es5/gridstack-static.js.LICENSE.txt +7 -0
  23. package/dist/es5/gridstack-static.js.map +1 -0
  24. package/dist/es5/gridstack.d.ts +346 -0
  25. package/dist/es5/gridstack.js +1517 -0
  26. package/dist/es5/gridstack.js.map +1 -0
  27. package/dist/es5/h5/dd-base-impl.d.ts +20 -0
  28. package/dist/es5/h5/dd-base-impl.js +43 -0
  29. package/dist/es5/h5/dd-base-impl.js.map +1 -0
  30. package/dist/es5/h5/dd-draggable.d.ts +29 -0
  31. package/dist/es5/h5/dd-draggable.js +329 -0
  32. package/dist/es5/h5/dd-draggable.js.map +1 -0
  33. package/dist/es5/h5/dd-droppable.d.ts +24 -0
  34. package/dist/es5/h5/dd-droppable.js +199 -0
  35. package/dist/es5/h5/dd-droppable.js.map +1 -0
  36. package/dist/es5/h5/dd-element.d.ts +27 -0
  37. package/dist/es5/h5/dd-element.js +96 -0
  38. package/dist/es5/h5/dd-element.js.map +1 -0
  39. package/dist/es5/h5/dd-manager.d.ts +8 -0
  40. package/dist/es5/h5/dd-manager.js +14 -0
  41. package/dist/es5/h5/dd-manager.js.map +1 -0
  42. package/dist/es5/h5/dd-resizable-handle.d.ts +14 -0
  43. package/dist/es5/h5/dd-resizable-handle.js +83 -0
  44. package/dist/es5/h5/dd-resizable-handle.js.map +1 -0
  45. package/dist/es5/h5/dd-resizable.d.ts +28 -0
  46. package/dist/es5/h5/dd-resizable.js +301 -0
  47. package/dist/es5/h5/dd-resizable.js.map +1 -0
  48. package/dist/es5/h5/dd-utils.d.ts +19 -0
  49. package/dist/es5/h5/dd-utils.js +111 -0
  50. package/dist/es5/h5/dd-utils.js.map +1 -0
  51. package/dist/es5/h5/gridstack-dd-native.d.ts +26 -0
  52. package/dist/es5/h5/gridstack-dd-native.js +175 -0
  53. package/dist/es5/h5/gridstack-dd-native.js.map +1 -0
  54. package/dist/es5/jq/gridstack-dd-jqueryui.d.ts +22 -0
  55. package/dist/es5/jq/gridstack-dd-jqueryui.js +162 -0
  56. package/dist/es5/jq/gridstack-dd-jqueryui.js.map +1 -0
  57. package/dist/es5/types.d.ts +263 -0
  58. package/dist/es5/types.js +7 -0
  59. package/dist/es5/types.js.map +1 -0
  60. package/dist/es5/utils.d.ts +73 -0
  61. package/dist/es5/utils.js +445 -0
  62. package/dist/es5/utils.js.map +1 -0
  63. package/dist/gridstack-dd.d.ts +1 -1
  64. package/dist/gridstack-dd.js +27 -16
  65. package/dist/gridstack-dd.js.map +1 -1
  66. package/dist/gridstack-ddi.d.ts +1 -1
  67. package/dist/gridstack-ddi.js +1 -1
  68. package/dist/gridstack-ddi.js.map +1 -1
  69. package/dist/gridstack-engine.d.ts +3 -2
  70. package/dist/gridstack-engine.js +83 -53
  71. package/dist/gridstack-engine.js.map +1 -1
  72. package/dist/gridstack-h5.d.ts +1 -1
  73. package/dist/gridstack-h5.js +1 -1
  74. package/dist/gridstack-h5.js.LICENSE.txt +1 -1
  75. package/dist/gridstack-h5.js.map +1 -1
  76. package/dist/gridstack-jq.d.ts +1 -1
  77. package/dist/gridstack-jq.js +1 -1
  78. package/dist/gridstack-jq.js.LICENSE.txt +1 -1
  79. package/dist/gridstack-jq.js.map +1 -1
  80. package/dist/gridstack-static.d.ts +1 -1
  81. package/dist/gridstack-static.js +1 -1
  82. package/dist/gridstack-static.js.LICENSE.txt +1 -1
  83. package/dist/gridstack-static.js.map +1 -1
  84. package/dist/gridstack.css +1 -5
  85. package/dist/gridstack.d.ts +2 -2
  86. package/dist/gridstack.js +81 -44
  87. package/dist/gridstack.js.map +1 -1
  88. package/dist/gridstack.min.css +1 -1
  89. package/dist/h5/dd-base-impl.d.ts +1 -1
  90. package/dist/h5/dd-base-impl.js +1 -1
  91. package/dist/h5/dd-base-impl.js.map +1 -1
  92. package/dist/h5/dd-draggable.d.ts +1 -2
  93. package/dist/h5/dd-draggable.js +26 -16
  94. package/dist/h5/dd-draggable.js.map +1 -1
  95. package/dist/h5/dd-droppable.d.ts +2 -1
  96. package/dist/h5/dd-droppable.js +42 -25
  97. package/dist/h5/dd-droppable.js.map +1 -1
  98. package/dist/h5/dd-element.d.ts +1 -1
  99. package/dist/h5/dd-element.js +1 -1
  100. package/dist/h5/dd-element.js.map +1 -1
  101. package/dist/h5/dd-manager.d.ts +1 -1
  102. package/dist/h5/dd-manager.js +1 -1
  103. package/dist/h5/dd-manager.js.map +1 -1
  104. package/dist/h5/dd-resizable-handle.d.ts +1 -1
  105. package/dist/h5/dd-resizable-handle.js +1 -1
  106. package/dist/h5/dd-resizable-handle.js.map +1 -1
  107. package/dist/h5/dd-resizable.d.ts +1 -2
  108. package/dist/h5/dd-resizable.js +3 -3
  109. package/dist/h5/dd-resizable.js.map +1 -1
  110. package/dist/h5/dd-utils.d.ts +3 -1
  111. package/dist/h5/dd-utils.js +13 -1
  112. package/dist/h5/dd-utils.js.map +1 -1
  113. package/dist/h5/gridstack-dd-native.d.ts +1 -1
  114. package/dist/h5/gridstack-dd-native.js +1 -1
  115. package/dist/h5/gridstack-dd-native.js.map +1 -1
  116. package/dist/jq/gridstack-dd-jqueryui.js.map +1 -1
  117. package/dist/src/gridstack.scss +6 -5
  118. package/dist/types.d.ts +12 -4
  119. package/dist/types.js +1 -1
  120. package/dist/types.js.map +1 -1
  121. package/dist/utils.d.ts +4 -2
  122. package/dist/utils.js +7 -6
  123. package/dist/utils.js.map +1 -1
  124. package/doc/CHANGES.md +24 -0
  125. package/doc/README.md +10 -5
  126. package/package.json +5 -3
@@ -0,0 +1,1517 @@
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 5.0
34
+ * https://gridstackjs.com/
35
+ *
36
+ * Copyright (c) 2021 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 gridstack_ddi_1 = require("./gridstack-ddi");
42
+ // export all dependent file as well to make it easier for users to just import the main file
43
+ __exportStar(require("./types"), exports);
44
+ __exportStar(require("./utils"), exports);
45
+ __exportStar(require("./gridstack-engine"), exports);
46
+ __exportStar(require("./gridstack-ddi"), exports);
47
+ // default values for grid options - used during init and when saving out
48
+ var GridDefaults = {
49
+ column: 12,
50
+ minRow: 0,
51
+ maxRow: 0,
52
+ itemClass: 'grid-stack-item',
53
+ placeholderClass: 'grid-stack-placeholder',
54
+ placeholderText: '',
55
+ handle: '.grid-stack-item-content',
56
+ handleClass: null,
57
+ styleInHead: false,
58
+ cellHeight: 'auto',
59
+ cellHeightThrottle: 100,
60
+ margin: 10,
61
+ auto: true,
62
+ minWidth: 768,
63
+ float: false,
64
+ staticGrid: false,
65
+ animate: true,
66
+ alwaysShowResizeHandle: false,
67
+ resizable: {
68
+ autoHide: true,
69
+ handles: 'se'
70
+ },
71
+ draggable: {
72
+ handle: '.grid-stack-item-content',
73
+ scroll: false,
74
+ appendTo: 'body'
75
+ },
76
+ disableDrag: false,
77
+ disableResize: false,
78
+ rtl: 'auto',
79
+ removable: false,
80
+ removableOptions: {
81
+ accept: '.grid-stack-item'
82
+ },
83
+ marginUnit: 'px',
84
+ cellHeightUnit: 'px',
85
+ disableOneColumnMode: false,
86
+ oneColumnModeDomSort: false
87
+ };
88
+ /**
89
+ * Main gridstack class - you will need to call `GridStack.init()` first to initialize your grid.
90
+ * Note: your grid elements MUST have the following classes for the CSS layout to work:
91
+ * @example
92
+ * <div class="grid-stack">
93
+ * <div class="grid-stack-item">
94
+ * <div class="grid-stack-item-content">Item 1</div>
95
+ * </div>
96
+ * </div>
97
+ */
98
+ var GridStack = /** @class */ (function () {
99
+ /**
100
+ * Construct a grid item from the given element and options
101
+ * @param el
102
+ * @param opts
103
+ */
104
+ function GridStack(el, opts) {
105
+ var _this = this;
106
+ if (opts === void 0) { opts = {}; }
107
+ /** @internal */
108
+ this._gsEventHandler = {};
109
+ /** @internal extra row added when dragging at the bottom of the grid */
110
+ this._extraDragRow = 0;
111
+ this.el = el; // exposed HTML element to the user
112
+ opts = opts || {}; // handles null/undefined/0
113
+ // if row property exists, replace minRow and maxRow instead
114
+ if (opts.row) {
115
+ opts.minRow = opts.maxRow = opts.row;
116
+ delete opts.row;
117
+ }
118
+ var rowAttr = utils_1.Utils.toNumber(el.getAttribute('gs-row'));
119
+ // flag only valid in sub-grids (handled by parent, not here)
120
+ if (opts.column === 'auto') {
121
+ delete opts.column;
122
+ }
123
+ // elements attributes override any passed options (like CSS style) - merge the two together
124
+ var defaults = __assign(__assign({}, utils_1.Utils.cloneDeep(GridDefaults)), { column: utils_1.Utils.toNumber(el.getAttribute('gs-column')) || 12, minRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-min-row')) || 0, maxRow: rowAttr ? rowAttr : utils_1.Utils.toNumber(el.getAttribute('gs-max-row')) || 0, staticGrid: utils_1.Utils.toBool(el.getAttribute('gs-static')) || false, _styleSheetClass: 'grid-stack-instance-' + (Math.random() * 10000).toFixed(0), alwaysShowResizeHandle: opts.alwaysShowResizeHandle || false, resizable: {
125
+ autoHide: !(opts.alwaysShowResizeHandle || false),
126
+ handles: 'se'
127
+ }, draggable: {
128
+ handle: (opts.handleClass ? '.' + opts.handleClass : (opts.handle ? opts.handle : '')) || '.grid-stack-item-content',
129
+ scroll: false,
130
+ appendTo: 'body'
131
+ }, removableOptions: {
132
+ accept: '.' + (opts.itemClass || 'grid-stack-item')
133
+ } });
134
+ if (el.getAttribute('gs-animate')) { // default to true, but if set to false use that instead
135
+ defaults.animate = utils_1.Utils.toBool(el.getAttribute('gs-animate'));
136
+ }
137
+ this.opts = utils_1.Utils.defaults(opts, defaults);
138
+ opts = null; // make sure we use this.opts instead
139
+ this.initMargin(); // part of settings defaults...
140
+ // 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)
141
+ if (this.opts.column !== 1 && !this.opts.disableOneColumnMode && this._widthOrContainer() <= this.opts.minWidth) {
142
+ this._prevColumn = this.getColumn();
143
+ this.opts.column = 1;
144
+ }
145
+ if (this.opts.rtl === 'auto') {
146
+ this.opts.rtl = (el.style.direction === 'rtl');
147
+ }
148
+ if (this.opts.rtl) {
149
+ this.el.classList.add('grid-stack-rtl');
150
+ }
151
+ // check if we're been nested, and if so update our style and keep pointer around (used during save)
152
+ var parentGridItemEl = utils_1.Utils.closestByClass(this.el, GridDefaults.itemClass);
153
+ if (parentGridItemEl && parentGridItemEl.gridstackNode) {
154
+ this.opts._isNested = parentGridItemEl.gridstackNode;
155
+ this.opts._isNested.subGrid = this;
156
+ parentGridItemEl.classList.add('grid-stack-nested');
157
+ this.el.classList.add('grid-stack-nested');
158
+ }
159
+ this._isAutoCellHeight = (this.opts.cellHeight === 'auto');
160
+ if (this._isAutoCellHeight || this.opts.cellHeight === 'initial') {
161
+ // make the cell content square initially (will use resize/column event to keep it square)
162
+ this.cellHeight(undefined, false);
163
+ }
164
+ else {
165
+ // append unit if any are set
166
+ if (typeof this.opts.cellHeight == 'number' && this.opts.cellHeightUnit && this.opts.cellHeightUnit !== GridDefaults.cellHeightUnit) {
167
+ this.opts.cellHeight = this.opts.cellHeight + this.opts.cellHeightUnit;
168
+ delete this.opts.cellHeightUnit;
169
+ }
170
+ this.cellHeight(this.opts.cellHeight, false);
171
+ }
172
+ this.el.classList.add(this.opts._styleSheetClass);
173
+ this._setStaticClass();
174
+ this.engine = new gridstack_engine_1.GridStackEngine({
175
+ column: this.getColumn(),
176
+ float: this.opts.float,
177
+ maxRow: this.opts.maxRow,
178
+ onChange: function (cbNodes) {
179
+ var maxH = 0;
180
+ _this.engine.nodes.forEach(function (n) { maxH = Math.max(maxH, n.y + n.h); });
181
+ cbNodes.forEach(function (n) {
182
+ var el = n.el;
183
+ if (!el)
184
+ return;
185
+ if (n._removeDOM) {
186
+ if (el)
187
+ el.remove();
188
+ delete n._removeDOM;
189
+ }
190
+ else {
191
+ _this._writePosAttr(el, n);
192
+ }
193
+ });
194
+ _this._updateStyles(false, maxH); // false = don't recreate, just append if need be
195
+ }
196
+ });
197
+ if (this.opts.auto) {
198
+ this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...
199
+ var elements_1 = [];
200
+ this.getGridItems().forEach(function (el) {
201
+ var x = parseInt(el.getAttribute('gs-x'));
202
+ var y = parseInt(el.getAttribute('gs-y'));
203
+ elements_1.push({
204
+ el: el,
205
+ // if x,y are missing (autoPosition) add them to end of list - but keep their respective DOM order
206
+ i: (Number.isNaN(x) ? 1000 : x) + (Number.isNaN(y) ? 1000 : y) * _this.getColumn()
207
+ });
208
+ });
209
+ elements_1.sort(function (a, b) { return a.i - b.i; }).forEach(function (e) { return _this._prepareElement(e.el); });
210
+ this.commit();
211
+ }
212
+ this.setAnimation(this.opts.animate);
213
+ this._updateStyles();
214
+ if (this.opts.column != 12) {
215
+ this.el.classList.add('grid-stack-' + this.opts.column);
216
+ }
217
+ // legacy support to appear 'per grid` options when really global.
218
+ if (this.opts.dragIn)
219
+ GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions);
220
+ delete this.opts.dragIn;
221
+ delete this.opts.dragInOptions;
222
+ this._setupRemoveDrop();
223
+ this._setupAcceptWidget();
224
+ this._updateWindowResizeEvent();
225
+ }
226
+ /**
227
+ * initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will
228
+ * simply return the existing instance (ignore any passed options). There is also an initAll() version that support
229
+ * multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.
230
+ * @param options grid options (optional)
231
+ * @param elOrString element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)
232
+ *
233
+ * @example
234
+ * let grid = GridStack.init();
235
+ *
236
+ * Note: the HTMLElement (of type GridHTMLElement) will store a `gridstack: GridStack` value that can be retrieve later
237
+ * let grid = document.querySelector('.grid-stack').gridstack;
238
+ */
239
+ GridStack.init = function (options, elOrString) {
240
+ if (options === void 0) { options = {}; }
241
+ if (elOrString === void 0) { elOrString = '.grid-stack'; }
242
+ var el = GridStack.getGridElement(elOrString);
243
+ if (!el) {
244
+ if (typeof elOrString === 'string') {
245
+ console.error('GridStack.initAll() no grid was found with selector "' + elOrString + '" - element missing or wrong selector ?' +
246
+ '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
247
+ }
248
+ else {
249
+ console.error('GridStack.init() no grid element was passed.');
250
+ }
251
+ return null;
252
+ }
253
+ if (!el.gridstack) {
254
+ el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
255
+ }
256
+ return el.gridstack;
257
+ };
258
+ /**
259
+ * Will initialize a list of elements (given a selector) and return an array of grids.
260
+ * @param options grid options (optional)
261
+ * @param selector elements selector to convert to grids (default to '.grid-stack' class selector)
262
+ *
263
+ * @example
264
+ * let grids = GridStack.initAll();
265
+ * grids.forEach(...)
266
+ */
267
+ GridStack.initAll = function (options, selector) {
268
+ if (options === void 0) { options = {}; }
269
+ if (selector === void 0) { selector = '.grid-stack'; }
270
+ var grids = [];
271
+ GridStack.getGridElements(selector).forEach(function (el) {
272
+ if (!el.gridstack) {
273
+ el.gridstack = new GridStack(el, utils_1.Utils.cloneDeep(options));
274
+ delete options.dragIn;
275
+ delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid)
276
+ }
277
+ grids.push(el.gridstack);
278
+ });
279
+ if (grids.length === 0) {
280
+ console.error('GridStack.initAll() no grid was found with selector "' + selector + '" - element missing or wrong selector ?' +
281
+ '\nNote: ".grid-stack" is required for proper CSS styling and drag/drop, and is the default selector.');
282
+ }
283
+ return grids;
284
+ };
285
+ /**
286
+ * call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then
287
+ * grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from
288
+ * JSON serialized data, including options.
289
+ * @param parent HTML element parent to the grid
290
+ * @param opt grids options used to initialize the grid, and list of children
291
+ */
292
+ GridStack.addGrid = function (parent, opt) {
293
+ if (opt === void 0) { opt = {}; }
294
+ if (!parent)
295
+ return null;
296
+ // create the grid element, but check if the passed 'parent' already has grid styling and should be used instead
297
+ var el = parent;
298
+ if (!parent.classList.contains('grid-stack')) {
299
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
300
+ doc.body.innerHTML = "<div class=\"grid-stack " + (opt.class || '') + "\"></div>";
301
+ el = doc.body.children[0];
302
+ parent.appendChild(el);
303
+ }
304
+ // create grid class and load any children
305
+ var grid = GridStack.init(opt, el);
306
+ if (grid.opts.children) {
307
+ var children = grid.opts.children;
308
+ delete grid.opts.children;
309
+ grid.load(children);
310
+ }
311
+ return grid;
312
+ };
313
+ Object.defineProperty(GridStack.prototype, "placeholder", {
314
+ /** @internal create placeholder DIV as needed */
315
+ get: function () {
316
+ if (!this._placeholder) {
317
+ var placeholderChild = document.createElement('div'); // child so padding match item-content
318
+ placeholderChild.className = 'placeholder-content';
319
+ if (this.opts.placeholderText) {
320
+ placeholderChild.innerHTML = this.opts.placeholderText;
321
+ }
322
+ this._placeholder = document.createElement('div');
323
+ this._placeholder.classList.add(this.opts.placeholderClass, GridDefaults.itemClass, this.opts.itemClass);
324
+ this.placeholder.appendChild(placeholderChild);
325
+ }
326
+ return this._placeholder;
327
+ },
328
+ enumerable: false,
329
+ configurable: true
330
+ });
331
+ /**
332
+ * add a new widget and returns it.
333
+ *
334
+ * Widget will be always placed even if result height is more than actual grid height.
335
+ * You need to use `willItFit()` before calling addWidget for additional check.
336
+ * See also `makeWidget()`.
337
+ *
338
+ * @example
339
+ * let grid = GridStack.init();
340
+ * grid.addWidget({w: 3, content: 'hello'});
341
+ * grid.addWidget('<div class="grid-stack-item"><div class="grid-stack-item-content">hello</div></div>', {w: 3});
342
+ *
343
+ * @param el GridStackWidget (which can have content string as well), html element, or string definition to add
344
+ * @param options widget position/size options (optional, and ignore if first param is already option) - see GridStackWidget
345
+ */
346
+ GridStack.prototype.addWidget = function (els, options) {
347
+ // support legacy call for now ?
348
+ if (arguments.length > 2) {
349
+ console.warn('gridstack.ts: `addWidget(el, x, y, width...)` is deprecated. Use `addWidget({x, y, w, content, ...})`. It will be removed soon');
350
+ // eslint-disable-next-line prefer-rest-params
351
+ var a = arguments, i = 1, opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++],
352
+ minW: a[i++], maxW: a[i++], minH: a[i++], maxH: a[i++], id: a[i++] };
353
+ return this.addWidget(els, opt);
354
+ }
355
+ function isGridStackWidget(w) {
356
+ return w.x !== undefined || w.y !== undefined || w.w !== undefined || w.h !== undefined || w.content !== undefined ? true : false;
357
+ }
358
+ var el;
359
+ if (typeof els === 'string') {
360
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
361
+ doc.body.innerHTML = els;
362
+ el = doc.body.children[0];
363
+ }
364
+ else if (arguments.length === 0 || arguments.length === 1 && isGridStackWidget(els)) {
365
+ var content = els ? els.content || '' : '';
366
+ options = els;
367
+ var doc = document.implementation.createHTMLDocument(''); // IE needs a param
368
+ doc.body.innerHTML = "<div class=\"grid-stack-item " + (this.opts.itemClass || '') + "\"><div class=\"grid-stack-item-content\">" + content + "</div></div>";
369
+ el = doc.body.children[0];
370
+ }
371
+ else {
372
+ el = els;
373
+ }
374
+ // Tempting to initialize the passed in opt with default and valid values, but this break knockout demos
375
+ // as the actual value are filled in when _prepareElement() calls el.getAttribute('gs-xyz) before adding the node.
376
+ // So make sure we load any DOM attributes that are not specified in passed in options (which override)
377
+ var domAttr = this._readAttr(el);
378
+ options = utils_1.Utils.cloneDeep(options) || {}; // make a copy before we modify in case caller re-uses it
379
+ utils_1.Utils.defaults(options, domAttr);
380
+ var node = this.engine.prepareNode(options);
381
+ this._writeAttr(el, options);
382
+ if (this._insertNotAppend) {
383
+ this.el.prepend(el);
384
+ }
385
+ else {
386
+ this.el.appendChild(el);
387
+ }
388
+ // similar to makeWidget() that doesn't read attr again and worse re-create a new node and loose any _id
389
+ this._prepareElement(el, true, options);
390
+ this._updateContainerHeight();
391
+ // check if nested grid definition is present
392
+ if (node.subGrid && !node.subGrid.el) { // see if there is a sub-grid to create too
393
+ // if column special case it set, remember that flag and set default
394
+ var autoColumn = void 0;
395
+ var ops = node.subGrid;
396
+ if (ops.column === 'auto') {
397
+ ops.column = node.w;
398
+ ops.disableOneColumnMode = true; // driven by parent
399
+ autoColumn = true;
400
+ }
401
+ var content = node.el.querySelector('.grid-stack-item-content');
402
+ node.subGrid = GridStack.addGrid(content, node.subGrid);
403
+ if (autoColumn) {
404
+ node.subGrid._autoColumn = true;
405
+ }
406
+ }
407
+ this._triggerAddEvent();
408
+ this._triggerChangeEvent();
409
+ return el;
410
+ };
411
+ /**
412
+ /**
413
+ * saves the current layout returning a list of widgets for serialization which might include any nested grids.
414
+ * @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will
415
+ * be removed.
416
+ * @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()
417
+ * to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
418
+ * @returns list of widgets or full grid option, including .children list of widgets
419
+ */
420
+ GridStack.prototype.save = function (saveContent, saveGridOpt) {
421
+ if (saveContent === void 0) { saveContent = true; }
422
+ if (saveGridOpt === void 0) { saveGridOpt = false; }
423
+ // return copied nodes we can modify at will...
424
+ var list = this.engine.save(saveContent);
425
+ // check for HTML content and nested grids
426
+ list.forEach(function (n) {
427
+ if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content
428
+ var sub = n.el.querySelector('.grid-stack-item-content');
429
+ n.content = sub ? sub.innerHTML : undefined;
430
+ if (!n.content)
431
+ delete n.content;
432
+ }
433
+ else {
434
+ if (!saveContent) {
435
+ delete n.content;
436
+ }
437
+ // check for nested grid
438
+ if (n.subGrid) {
439
+ n.subGrid = n.subGrid.save(saveContent, true);
440
+ }
441
+ }
442
+ delete n.el;
443
+ });
444
+ // check if save entire grid options (needed for recursive) + children...
445
+ if (saveGridOpt) {
446
+ var o = utils_1.Utils.cloneDeep(this.opts);
447
+ // delete default values that will be recreated on launch
448
+ if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {
449
+ o.margin = o.marginTop;
450
+ delete o.marginTop;
451
+ delete o.marginRight;
452
+ delete o.marginBottom;
453
+ delete o.marginLeft;
454
+ }
455
+ if (o.rtl === (this.el.style.direction === 'rtl')) {
456
+ o.rtl = 'auto';
457
+ }
458
+ if (this._isAutoCellHeight) {
459
+ o.cellHeight = 'auto';
460
+ }
461
+ if (this._autoColumn) {
462
+ o.column = 'auto';
463
+ delete o.disableOneColumnMode;
464
+ }
465
+ utils_1.Utils.removeInternalAndSame(o, GridDefaults);
466
+ o.children = list;
467
+ return o;
468
+ }
469
+ return list;
470
+ };
471
+ /**
472
+ * load the widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.
473
+ *
474
+ * @param layout list of widgets definition to update/create
475
+ * @param addAndRemove boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving
476
+ * the user control of insertion.
477
+ *
478
+ * @example
479
+ * see http://gridstackjs.com/demo/serialization.html
480
+ **/
481
+ GridStack.prototype.load = function (layout, addAndRemove) {
482
+ var _this = this;
483
+ if (addAndRemove === void 0) { addAndRemove = true; }
484
+ var items = GridStack.Utils.sort(__spreadArrays(layout), -1, this._prevColumn || this.getColumn()); // make copy before we mod/sort
485
+ this._insertNotAppend = true; // since create in reverse order...
486
+ // if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save
487
+ // the original wanted layout so we can scale back up correctly #1471
488
+ if (this._prevColumn && this._prevColumn !== this.opts.column && items.some(function (n) { return (n.x + n.w) > _this.opts.column; })) {
489
+ this._ignoreLayoutsNodeChange = true; // skip layout update
490
+ this.engine.cacheLayout(items, this._prevColumn, true);
491
+ }
492
+ var removed = [];
493
+ this.batchUpdate();
494
+ // see if any items are missing from new layout and need to be removed first
495
+ if (addAndRemove) {
496
+ var copyNodes = __spreadArrays(this.engine.nodes); // don't loop through array you modify
497
+ copyNodes.forEach(function (n) {
498
+ var item = items.find(function (w) { return n.id === w.id; });
499
+ if (!item) {
500
+ if (typeof (addAndRemove) === 'function') {
501
+ addAndRemove(_this, n, false);
502
+ }
503
+ else {
504
+ removed.push(n); // batch keep track
505
+ _this.removeWidget(n.el, true, false);
506
+ }
507
+ }
508
+ });
509
+ }
510
+ // now add/update the widgets
511
+ items.forEach(function (w) {
512
+ var item = (w.id || w.id === 0) ? _this.engine.nodes.find(function (n) { return n.id === w.id; }) : undefined;
513
+ if (item) {
514
+ _this.update(item.el, w);
515
+ if (w.subGrid && w.subGrid.children) { // update any sub grid as well
516
+ var sub = item.el.querySelector('.grid-stack');
517
+ if (sub && sub.gridstack) {
518
+ sub.gridstack.load(w.subGrid.children); // TODO: support updating grid options ?
519
+ _this._insertNotAppend = true; // got reset by above call
520
+ }
521
+ }
522
+ }
523
+ else if (addAndRemove) {
524
+ if (typeof (addAndRemove) === 'function') {
525
+ w = addAndRemove(_this, w, true).gridstackNode;
526
+ }
527
+ else {
528
+ w = _this.addWidget(w).gridstackNode;
529
+ }
530
+ }
531
+ });
532
+ this.engine.removedNodes = removed;
533
+ this.commit();
534
+ // after commit, clear that flag
535
+ delete this._ignoreLayoutsNodeChange;
536
+ delete this._insertNotAppend;
537
+ return this;
538
+ };
539
+ /**
540
+ * Initializes batch updates. You will see no changes until `commit()` method is called.
541
+ */
542
+ GridStack.prototype.batchUpdate = function () {
543
+ this.engine.batchUpdate();
544
+ return this;
545
+ };
546
+ /**
547
+ * Gets current cell height.
548
+ */
549
+ GridStack.prototype.getCellHeight = function (forcePixel) {
550
+ if (forcePixel === void 0) { forcePixel = false; }
551
+ if (this.opts.cellHeight && this.opts.cellHeight !== 'auto' &&
552
+ (!forcePixel || !this.opts.cellHeightUnit || this.opts.cellHeightUnit === 'px')) {
553
+ return this.opts.cellHeight;
554
+ }
555
+ // else get first cell height
556
+ var el = this.el.querySelector('.' + this.opts.itemClass);
557
+ if (el) {
558
+ var height = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
559
+ return Math.round(el.offsetHeight / height);
560
+ }
561
+ // else do entire grid and # of rows (but doesn't work if min-height is the actual constrain)
562
+ var rows = parseInt(this.el.getAttribute('gs-current-row'));
563
+ return rows ? Math.round(this.el.getBoundingClientRect().height / rows) : this.opts.cellHeight;
564
+ };
565
+ /**
566
+ * Update current cell height - see `GridStackOptions.cellHeight` for format.
567
+ * This method rebuilds an internal CSS style sheet.
568
+ * Note: You can expect performance issues if call this method too often.
569
+ *
570
+ * @param val the cell height. If not passed (undefined), cells content will be made square (match width minus margin),
571
+ * if pass 0 the CSS will be generated by the application instead.
572
+ * @param update (Optional) if false, styles will not be updated
573
+ *
574
+ * @example
575
+ * grid.cellHeight(100); // same as 100px
576
+ * grid.cellHeight('70px');
577
+ * grid.cellHeight(grid.cellWidth() * 1.2);
578
+ */
579
+ GridStack.prototype.cellHeight = function (val, update) {
580
+ if (update === void 0) { update = true; }
581
+ // if not called internally, check if we're changing mode
582
+ if (update && val !== undefined) {
583
+ if (this._isAutoCellHeight !== (val === 'auto')) {
584
+ this._isAutoCellHeight = (val === 'auto');
585
+ this._updateWindowResizeEvent();
586
+ }
587
+ }
588
+ if (val === 'initial' || val === 'auto') {
589
+ val = undefined;
590
+ }
591
+ // make item content be square
592
+ if (val === undefined) {
593
+ var marginDiff = -this.opts.marginRight - this.opts.marginLeft
594
+ + this.opts.marginTop + this.opts.marginBottom;
595
+ val = this.cellWidth() + marginDiff;
596
+ }
597
+ var data = utils_1.Utils.parseHeight(val);
598
+ if (this.opts.cellHeightUnit === data.unit && this.opts.cellHeight === data.h) {
599
+ return this;
600
+ }
601
+ this.opts.cellHeightUnit = data.unit;
602
+ this.opts.cellHeight = data.h;
603
+ if (update) {
604
+ this._updateStyles(true, this.getRow()); // true = force re-create, for that # of rows
605
+ }
606
+ return this;
607
+ };
608
+ /** Gets current cell width. */
609
+ GridStack.prototype.cellWidth = function () {
610
+ return this._widthOrContainer() / this.getColumn();
611
+ };
612
+ /** return our expected width (or parent) for 1 column check */
613
+ GridStack.prototype._widthOrContainer = function () {
614
+ // use `offsetWidth` or `clientWidth` (no scrollbar) ?
615
+ // https://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
616
+ return (this.el.clientWidth || this.el.parentElement.clientWidth || window.innerWidth);
617
+ };
618
+ /**
619
+ * Finishes batch updates. Updates DOM nodes. You must call it after batchUpdate.
620
+ */
621
+ GridStack.prototype.commit = function () {
622
+ this.engine.commit();
623
+ this._triggerRemoveEvent();
624
+ this._triggerAddEvent();
625
+ this._triggerChangeEvent();
626
+ return this;
627
+ };
628
+ /** re-layout grid items to reclaim any empty space */
629
+ GridStack.prototype.compact = function () {
630
+ this.engine.compact();
631
+ this._triggerChangeEvent();
632
+ return this;
633
+ };
634
+ /**
635
+ * set the number of columns in the grid. Will update existing widgets to conform to new number of columns,
636
+ * as well as cache the original layout so you can revert back to previous positions without loss.
637
+ * Requires `gridstack-extra.css` or `gridstack-extra.min.css` for [2-11],
638
+ * else you will need to generate correct CSS (see https://github.com/gridstack/gridstack.js#change-grid-columns)
639
+ * @param column - Integer > 0 (default 12).
640
+ * @param layout specify the type of re-layout that will happen (position, size, etc...).
641
+ * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
642
+ */
643
+ GridStack.prototype.column = function (column, layout) {
644
+ if (layout === void 0) { layout = 'moveScale'; }
645
+ if (column < 1 || this.opts.column === column)
646
+ return this;
647
+ var oldColumn = this.getColumn();
648
+ // if we go into 1 column mode (which happens if we're sized less than minW unless disableOneColumnMode is on)
649
+ // then remember the original columns so we can restore.
650
+ if (column === 1) {
651
+ this._prevColumn = oldColumn;
652
+ }
653
+ else {
654
+ delete this._prevColumn;
655
+ }
656
+ this.el.classList.remove('grid-stack-' + oldColumn);
657
+ this.el.classList.add('grid-stack-' + column);
658
+ this.opts.column = this.engine.column = column;
659
+ // update the items now - see if the dom order nodes should be passed instead (else default to current list)
660
+ var domNodes;
661
+ if (column === 1 && this.opts.oneColumnModeDomSort) {
662
+ domNodes = [];
663
+ this.getGridItems().forEach(function (el) {
664
+ if (el.gridstackNode) {
665
+ domNodes.push(el.gridstackNode);
666
+ }
667
+ });
668
+ if (!domNodes.length) {
669
+ domNodes = undefined;
670
+ }
671
+ }
672
+ this.engine.updateNodeWidths(oldColumn, column, domNodes, layout);
673
+ if (this._isAutoCellHeight)
674
+ this.cellHeight();
675
+ // and trigger our event last...
676
+ this._ignoreLayoutsNodeChange = true; // skip layout update
677
+ this._triggerChangeEvent();
678
+ delete this._ignoreLayoutsNodeChange;
679
+ return this;
680
+ };
681
+ /**
682
+ * get the number of columns in the grid (default 12)
683
+ */
684
+ GridStack.prototype.getColumn = function () {
685
+ return this.opts.column;
686
+ };
687
+ /** returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order */
688
+ GridStack.prototype.getGridItems = function () {
689
+ var _this = this;
690
+ return Array.from(this.el.children)
691
+ .filter(function (el) { return el.matches('.' + _this.opts.itemClass) && !el.matches('.' + _this.opts.placeholderClass); });
692
+ };
693
+ /**
694
+ * Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.
695
+ * @param removeDOM if `false` grid and items HTML elements will not be removed from the DOM (Optional. Default `true`).
696
+ */
697
+ GridStack.prototype.destroy = function (removeDOM) {
698
+ if (removeDOM === void 0) { removeDOM = true; }
699
+ if (!this.el)
700
+ return; // prevent multiple calls
701
+ this._updateWindowResizeEvent(true);
702
+ this.setStatic(true, false); // permanently removes DD but don't set CSS class (we're going away)
703
+ this.setAnimation(false);
704
+ if (!removeDOM) {
705
+ this.removeAll(removeDOM);
706
+ this.el.classList.remove(this.opts._styleSheetClass);
707
+ }
708
+ else {
709
+ this.el.parentNode.removeChild(this.el);
710
+ }
711
+ this._removeStylesheet();
712
+ this.el.removeAttribute('gs-current-row');
713
+ delete this.opts._isNested;
714
+ delete this.opts;
715
+ delete this._placeholder;
716
+ delete this.engine;
717
+ delete this.el.gridstack; // remove circular dependency that would prevent a freeing
718
+ delete this.el;
719
+ return this;
720
+ };
721
+ /**
722
+ * enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html)
723
+ */
724
+ GridStack.prototype.float = function (val) {
725
+ this.engine.float = val;
726
+ this._triggerChangeEvent();
727
+ return this;
728
+ };
729
+ /**
730
+ * get the current float mode
731
+ */
732
+ GridStack.prototype.getFloat = function () {
733
+ return this.engine.float;
734
+ };
735
+ /**
736
+ * Get the position of the cell under a pixel on screen.
737
+ * @param position the position of the pixel to resolve in
738
+ * absolute coordinates, as an object with top and left properties
739
+ * @param useDocRelative if true, value will be based on document position vs parent position (Optional. Default false).
740
+ * Useful when grid is within `position: relative` element
741
+ *
742
+ * Returns an object with properties `x` and `y` i.e. the column and row in the grid.
743
+ */
744
+ GridStack.prototype.getCellFromPixel = function (position, useDocRelative) {
745
+ if (useDocRelative === void 0) { useDocRelative = false; }
746
+ var box = this.el.getBoundingClientRect();
747
+ // console.log(`getBoundingClientRect left: ${box.left} top: ${box.top} w: ${box.w} h: ${box.h}`)
748
+ var containerPos;
749
+ if (useDocRelative) {
750
+ containerPos = { top: box.top + document.documentElement.scrollTop, left: box.left };
751
+ // console.log(`getCellFromPixel scrollTop: ${document.documentElement.scrollTop}`)
752
+ }
753
+ else {
754
+ containerPos = { top: this.el.offsetTop, left: this.el.offsetLeft };
755
+ // console.log(`getCellFromPixel offsetTop: ${containerPos.left} offsetLeft: ${containerPos.top}`)
756
+ }
757
+ var relativeLeft = position.left - containerPos.left;
758
+ var relativeTop = position.top - containerPos.top;
759
+ var columnWidth = (box.width / this.getColumn());
760
+ var rowHeight = (box.height / parseInt(this.el.getAttribute('gs-current-row')));
761
+ return { x: Math.floor(relativeLeft / columnWidth), y: Math.floor(relativeTop / rowHeight) };
762
+ };
763
+ /** returns the current number of rows, which will be at least `minRow` if set */
764
+ GridStack.prototype.getRow = function () {
765
+ return Math.max(this.engine.getRow(), this.opts.minRow);
766
+ };
767
+ /**
768
+ * Checks if specified area is empty.
769
+ * @param x the position x.
770
+ * @param y the position y.
771
+ * @param w the width of to check
772
+ * @param h the height of to check
773
+ */
774
+ GridStack.prototype.isAreaEmpty = function (x, y, w, h) {
775
+ return this.engine.isAreaEmpty(x, y, w, h);
776
+ };
777
+ /**
778
+ * If you add elements to your grid by hand, you have to tell gridstack afterwards to make them widgets.
779
+ * If you want gridstack to add the elements for you, use `addWidget()` instead.
780
+ * Makes the given element a widget and returns it.
781
+ * @param els widget or single selector to convert.
782
+ *
783
+ * @example
784
+ * let grid = GridStack.init();
785
+ * grid.el.appendChild('<div id="gsi-1" gs-w="3"></div>');
786
+ * grid.makeWidget('#gsi-1');
787
+ */
788
+ GridStack.prototype.makeWidget = function (els) {
789
+ var el = GridStack.getElement(els);
790
+ this._prepareElement(el, true);
791
+ this._updateContainerHeight();
792
+ this._triggerAddEvent();
793
+ this._triggerChangeEvent();
794
+ return el;
795
+ };
796
+ /**
797
+ * Event handler that extracts our CustomEvent data out automatically for receiving custom
798
+ * notifications (see doc for supported events)
799
+ * @param name of the event (see possible values) or list of names space separated
800
+ * @param callback function called with event and optional second/third param
801
+ * (see README documentation for each signature).
802
+ *
803
+ * @example
804
+ * grid.on('added', function(e, items) { log('added ', items)} );
805
+ * or
806
+ * grid.on('added removed change', function(e, items) { log(e.type, items)} );
807
+ *
808
+ * Note: in some cases it is the same as calling native handler and parsing the event.
809
+ * grid.el.addEventListener('added', function(event) { log('added ', event.detail)} );
810
+ *
811
+ */
812
+ GridStack.prototype.on = function (name, callback) {
813
+ var _this = this;
814
+ // check for array of names being passed instead
815
+ if (name.indexOf(' ') !== -1) {
816
+ var names = name.split(' ');
817
+ names.forEach(function (name) { return _this.on(name, callback); });
818
+ return this;
819
+ }
820
+ if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
821
+ // native CustomEvent handlers - cash the generic handlers so we can easily remove
822
+ var noData = (name === 'enable' || name === 'disable');
823
+ if (noData) {
824
+ this._gsEventHandler[name] = function (event) { return callback(event); };
825
+ }
826
+ else {
827
+ this._gsEventHandler[name] = function (event) { return callback(event, event.detail); };
828
+ }
829
+ this.el.addEventListener(name, this._gsEventHandler[name]);
830
+ }
831
+ else if (name === 'drag' || name === 'dragstart' || name === 'dragstop' || name === 'resizestart' || name === 'resize' || name === 'resizestop' || name === 'dropped') {
832
+ // drag&drop stop events NEED to be call them AFTER we update node attributes so handle them ourself.
833
+ // do same for start event to make it easier...
834
+ this._gsEventHandler[name] = callback;
835
+ }
836
+ else {
837
+ console.log('GridStack.on(' + name + ') event not supported, but you can still use $(".grid-stack").on(...) while jquery-ui is still used internally.');
838
+ }
839
+ return this;
840
+ };
841
+ /**
842
+ * unsubscribe from the 'on' event below
843
+ * @param name of the event (see possible values)
844
+ */
845
+ GridStack.prototype.off = function (name) {
846
+ var _this = this;
847
+ // check for array of names being passed instead
848
+ if (name.indexOf(' ') !== -1) {
849
+ var names = name.split(' ');
850
+ names.forEach(function (name) { return _this.off(name); });
851
+ return this;
852
+ }
853
+ if (name === 'change' || name === 'added' || name === 'removed' || name === 'enable' || name === 'disable') {
854
+ // remove native CustomEvent handlers
855
+ if (this._gsEventHandler[name]) {
856
+ this.el.removeEventListener(name, this._gsEventHandler[name]);
857
+ }
858
+ }
859
+ delete this._gsEventHandler[name];
860
+ return this;
861
+ };
862
+ /**
863
+ * Removes widget from the grid.
864
+ * @param el widget or selector to modify
865
+ * @param removeDOM if `false` DOM element won't be removed from the tree (Default? true).
866
+ * @param triggerEvent if `false` (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).
867
+ */
868
+ GridStack.prototype.removeWidget = function (els, removeDOM, triggerEvent) {
869
+ var _this = this;
870
+ if (removeDOM === void 0) { removeDOM = true; }
871
+ if (triggerEvent === void 0) { triggerEvent = true; }
872
+ GridStack.getElements(els).forEach(function (el) {
873
+ if (el.parentElement !== _this.el)
874
+ return; // not our child!
875
+ var node = el.gridstackNode;
876
+ // For Meteor support: https://github.com/gridstack/gridstack.js/pull/272
877
+ if (!node) {
878
+ node = _this.engine.nodes.find(function (n) { return el === n.el; });
879
+ }
880
+ if (!node)
881
+ return;
882
+ // remove our DOM data (circular link) and drag&drop permanently
883
+ delete el.gridstackNode;
884
+ gridstack_ddi_1.GridStackDDI.get().remove(el);
885
+ _this.engine.removeNode(node, removeDOM, triggerEvent);
886
+ if (removeDOM && el.parentElement) {
887
+ el.remove(); // in batch mode engine.removeNode doesn't call back to remove DOM
888
+ }
889
+ });
890
+ if (triggerEvent) {
891
+ this._triggerRemoveEvent();
892
+ this._triggerChangeEvent();
893
+ }
894
+ return this;
895
+ };
896
+ /**
897
+ * Removes all widgets from the grid.
898
+ * @param removeDOM if `false` DOM elements won't be removed from the tree (Default? `true`).
899
+ */
900
+ GridStack.prototype.removeAll = function (removeDOM) {
901
+ if (removeDOM === void 0) { removeDOM = true; }
902
+ // always remove our DOM data (circular link) before list gets emptied and drag&drop permanently
903
+ this.engine.nodes.forEach(function (n) {
904
+ delete n.el.gridstackNode;
905
+ gridstack_ddi_1.GridStackDDI.get().remove(n.el);
906
+ });
907
+ this.engine.removeAll(removeDOM);
908
+ this._triggerRemoveEvent();
909
+ return this;
910
+ };
911
+ /**
912
+ * Toggle the grid animation state. Toggles the `grid-stack-animate` class.
913
+ * @param doAnimate if true the grid will animate.
914
+ */
915
+ GridStack.prototype.setAnimation = function (doAnimate) {
916
+ if (doAnimate) {
917
+ this.el.classList.add('grid-stack-animate');
918
+ }
919
+ else {
920
+ this.el.classList.remove('grid-stack-animate');
921
+ }
922
+ return this;
923
+ };
924
+ /**
925
+ * Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.
926
+ * Also toggle the grid-stack-static class.
927
+ * @param val if true the grid become static.
928
+ */
929
+ GridStack.prototype.setStatic = function (val, updateClass) {
930
+ var _this = this;
931
+ if (updateClass === void 0) { updateClass = true; }
932
+ if (this.opts.staticGrid === val)
933
+ return this;
934
+ this.opts.staticGrid = val;
935
+ this._setupRemoveDrop();
936
+ this._setupAcceptWidget();
937
+ this.engine.nodes.forEach(function (n) { return _this._prepareDragDropByNode(n); }); // either delete or init Drag&drop
938
+ if (updateClass) {
939
+ this._setStaticClass();
940
+ }
941
+ return this;
942
+ };
943
+ /**
944
+ * 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.
945
+ * @param els widget or selector of objects to modify (note: setting the same x,y for multiple items will be indeterministic and likely unwanted)
946
+ * @param opt new widget options (x,y,w,h, etc..). Only those set will be updated.
947
+ */
948
+ GridStack.prototype.update = function (els, opt) {
949
+ var _this = this;
950
+ // support legacy call for now ?
951
+ if (arguments.length > 2) {
952
+ console.warn('gridstack.ts: `update(el, x, y, w, h)` is deprecated. Use `update(el, {x, w, content, ...})`. It will be removed soon');
953
+ // eslint-disable-next-line prefer-rest-params
954
+ var a = arguments, i = 1;
955
+ opt = { x: a[i++], y: a[i++], w: a[i++], h: a[i++] };
956
+ return this.update(els, opt);
957
+ }
958
+ GridStack.getElements(els).forEach(function (el) {
959
+ if (!el || !el.gridstackNode)
960
+ return;
961
+ var n = el.gridstackNode;
962
+ var w = utils_1.Utils.cloneDeep(opt); // make a copy we can modify in case they re-use it or multiple items
963
+ delete w.autoPosition;
964
+ // move/resize widget if anything changed
965
+ var keys = ['x', 'y', 'w', 'h'];
966
+ var m;
967
+ if (keys.some(function (k) { return w[k] !== undefined && w[k] !== n[k]; })) {
968
+ m = {};
969
+ keys.forEach(function (k) {
970
+ m[k] = (w[k] !== undefined) ? w[k] : n[k];
971
+ delete w[k];
972
+ });
973
+ }
974
+ // for a move as well IFF there is any min/max fields set
975
+ if (!m && (w.minW || w.minH || w.maxW || w.maxH)) {
976
+ m = {}; // will use node position but validate values
977
+ }
978
+ // check for content changing
979
+ if (w.content) {
980
+ var sub = el.querySelector('.grid-stack-item-content');
981
+ if (sub && sub.innerHTML !== w.content) {
982
+ sub.innerHTML = w.content;
983
+ }
984
+ delete w.content;
985
+ }
986
+ // any remaining fields are assigned, but check for dragging changes, resize constrain
987
+ var changed = false;
988
+ var ddChanged = false;
989
+ for (var key in w) {
990
+ if (key[0] !== '_' && n[key] !== w[key]) {
991
+ n[key] = w[key];
992
+ changed = true;
993
+ ddChanged = ddChanged || (!_this.opts.staticGrid && (key === 'noResize' || key === 'noMove' || key === 'locked'));
994
+ }
995
+ }
996
+ // finally move the widget
997
+ if (m) {
998
+ _this.engine.cleanNodes()
999
+ .beginUpdate(n)
1000
+ .moveNode(n, m);
1001
+ _this._updateContainerHeight();
1002
+ _this._triggerChangeEvent();
1003
+ _this.engine.endUpdate();
1004
+ }
1005
+ if (changed) { // move will only update x,y,w,h so update the rest too
1006
+ _this._writeAttr(el, n);
1007
+ }
1008
+ if (ddChanged) {
1009
+ _this._prepareDragDropByNode(n);
1010
+ }
1011
+ });
1012
+ return this;
1013
+ };
1014
+ /**
1015
+ * 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).
1016
+ * @param value margin value
1017
+ */
1018
+ GridStack.prototype.margin = function (value) {
1019
+ var isMultiValue = (typeof value === 'string' && value.split(' ').length > 1);
1020
+ // check if we can skip re-creating our CSS file... won't check if multi values (too much hassle)
1021
+ if (!isMultiValue) {
1022
+ var data = utils_1.Utils.parseHeight(value);
1023
+ if (this.opts.marginUnit === data.unit && this.opts.margin === data.h)
1024
+ return;
1025
+ }
1026
+ // re-use existing margin handling
1027
+ this.opts.margin = value;
1028
+ this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined;
1029
+ this.initMargin();
1030
+ this._updateStyles(true); // true = force re-create
1031
+ return this;
1032
+ };
1033
+ /** returns current margin number value (undefined if 4 sides don't match) */
1034
+ GridStack.prototype.getMargin = function () { return this.opts.margin; };
1035
+ /**
1036
+ * Returns true if the height of the grid will be less than the vertical
1037
+ * constraint. Always returns true if grid doesn't have height constraint.
1038
+ * @param node contains x,y,w,h,auto-position options
1039
+ *
1040
+ * @example
1041
+ * if (grid.willItFit(newWidget)) {
1042
+ * grid.addWidget(newWidget);
1043
+ * } else {
1044
+ * alert('Not enough free space to place the widget');
1045
+ * }
1046
+ */
1047
+ GridStack.prototype.willItFit = function (node) {
1048
+ // support legacy call for now
1049
+ if (arguments.length > 1) {
1050
+ console.warn('gridstack.ts: `willItFit(x,y,w,h,autoPosition)` is deprecated. Use `willItFit({x, y,...})`. It will be removed soon');
1051
+ // eslint-disable-next-line prefer-rest-params
1052
+ var a = arguments, i = 0, w = { x: a[i++], y: a[i++], w: a[i++], h: a[i++], autoPosition: a[i++] };
1053
+ return this.willItFit(w);
1054
+ }
1055
+ return this.engine.willItFit(node);
1056
+ };
1057
+ /** @internal */
1058
+ GridStack.prototype._triggerChangeEvent = function () {
1059
+ if (this.engine.batchMode)
1060
+ return this;
1061
+ var elements = this.engine.getDirtyNodes(true); // verify they really changed
1062
+ if (elements && elements.length) {
1063
+ if (!this._ignoreLayoutsNodeChange) {
1064
+ this.engine.layoutsNodesChange(elements);
1065
+ }
1066
+ this._triggerEvent('change', elements);
1067
+ }
1068
+ this.engine.saveInitial(); // we called, now reset initial values & dirty flags
1069
+ return this;
1070
+ };
1071
+ /** @internal */
1072
+ GridStack.prototype._triggerAddEvent = function () {
1073
+ if (this.engine.batchMode)
1074
+ return this;
1075
+ if (this.engine.addedNodes && this.engine.addedNodes.length > 0) {
1076
+ if (!this._ignoreLayoutsNodeChange) {
1077
+ this.engine.layoutsNodesChange(this.engine.addedNodes);
1078
+ }
1079
+ // prevent added nodes from also triggering 'change' event (which is called next)
1080
+ this.engine.addedNodes.forEach(function (n) { delete n._dirty; });
1081
+ this._triggerEvent('added', this.engine.addedNodes);
1082
+ this.engine.addedNodes = [];
1083
+ }
1084
+ return this;
1085
+ };
1086
+ /** @internal */
1087
+ GridStack.prototype._triggerRemoveEvent = function () {
1088
+ if (this.engine.batchMode)
1089
+ return this;
1090
+ if (this.engine.removedNodes && this.engine.removedNodes.length > 0) {
1091
+ this._triggerEvent('removed', this.engine.removedNodes);
1092
+ this.engine.removedNodes = [];
1093
+ }
1094
+ return this;
1095
+ };
1096
+ /** @internal */
1097
+ GridStack.prototype._triggerEvent = function (name, data) {
1098
+ var event = data ? new CustomEvent(name, { bubbles: false, detail: data }) : new Event(name);
1099
+ this.el.dispatchEvent(event);
1100
+ return this;
1101
+ };
1102
+ /** @internal called to delete the current dynamic style sheet used for our layout */
1103
+ GridStack.prototype._removeStylesheet = function () {
1104
+ if (this._styles) {
1105
+ utils_1.Utils.removeStylesheet(this._styles._id);
1106
+ delete this._styles;
1107
+ }
1108
+ return this;
1109
+ };
1110
+ /** @internal updated/create the CSS styles for row based layout and initial margin setting */
1111
+ GridStack.prototype._updateStyles = function (forceUpdate, maxH) {
1112
+ if (forceUpdate === void 0) { forceUpdate = false; }
1113
+ // call to delete existing one if we change cellHeight / margin
1114
+ if (forceUpdate) {
1115
+ this._removeStylesheet();
1116
+ }
1117
+ this._updateContainerHeight();
1118
+ // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
1119
+ if (this.opts.cellHeight === 0) {
1120
+ return this;
1121
+ }
1122
+ var cellHeight = this.opts.cellHeight;
1123
+ var cellHeightUnit = this.opts.cellHeightUnit;
1124
+ var prefix = "." + this.opts._styleSheetClass + " > ." + this.opts.itemClass;
1125
+ // create one as needed
1126
+ if (!this._styles) {
1127
+ var id = 'gridstack-style-' + (Math.random() * 100000).toFixed();
1128
+ // insert style to parent (instead of 'head' by default) to support WebComponent
1129
+ var styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode;
1130
+ this._styles = utils_1.Utils.createStylesheet(id, styleLocation);
1131
+ if (!this._styles)
1132
+ return this;
1133
+ this._styles._id = id;
1134
+ this._styles._max = 0;
1135
+ // these are done once only
1136
+ utils_1.Utils.addCSSRule(this._styles, prefix, "min-height: " + cellHeight + cellHeightUnit);
1137
+ // content margins
1138
+ var top_1 = this.opts.marginTop + this.opts.marginUnit;
1139
+ var bottom = this.opts.marginBottom + this.opts.marginUnit;
1140
+ var right = this.opts.marginRight + this.opts.marginUnit;
1141
+ var left = this.opts.marginLeft + this.opts.marginUnit;
1142
+ var content = prefix + " > .grid-stack-item-content";
1143
+ var placeholder = "." + this.opts._styleSheetClass + " > .grid-stack-placeholder > .placeholder-content";
1144
+ utils_1.Utils.addCSSRule(this._styles, content, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";");
1145
+ utils_1.Utils.addCSSRule(this._styles, placeholder, "top: " + top_1 + "; right: " + right + "; bottom: " + bottom + "; left: " + left + ";");
1146
+ // resize handles offset (to match margin)
1147
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-ne", "right: " + right);
1148
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-e", "right: " + right);
1149
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-se", "right: " + right + "; bottom: " + bottom);
1150
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-nw", "left: " + left);
1151
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-w", "left: " + left);
1152
+ utils_1.Utils.addCSSRule(this._styles, prefix + " > .ui-resizable-sw", "left: " + left + "; bottom: " + bottom);
1153
+ }
1154
+ // now update the height specific fields
1155
+ maxH = maxH || this._styles._max;
1156
+ if (maxH > this._styles._max) {
1157
+ var getHeight = function (rows) { return (cellHeight * rows) + cellHeightUnit; };
1158
+ for (var i = this._styles._max + 1; i <= maxH; i++) { // start at 1
1159
+ var h = getHeight(i);
1160
+ utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-y=\"" + (i - 1) + "\"]", "top: " + getHeight(i - 1)); // start at 0
1161
+ utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-h=\"" + i + "\"]", "height: " + h);
1162
+ utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-min-h=\"" + i + "\"]", "min-height: " + h);
1163
+ utils_1.Utils.addCSSRule(this._styles, prefix + "[gs-max-h=\"" + i + "\"]", "max-height: " + h);
1164
+ }
1165
+ this._styles._max = maxH;
1166
+ }
1167
+ return this;
1168
+ };
1169
+ /** @internal */
1170
+ GridStack.prototype._updateContainerHeight = function () {
1171
+ if (!this.engine || this.engine.batchMode)
1172
+ return this;
1173
+ var row = this.getRow() + this._extraDragRow; // checks for minRow already
1174
+ // check for css min height
1175
+ // Note: we don't handle %,rem correctly so comment out, beside we don't need need to create un-necessary
1176
+ // rows as the CSS will make us bigger than our set height if needed... not sure why we had this.
1177
+ // let cssMinHeight = parseInt(getComputedStyle(this.el)['min-height']);
1178
+ // if (cssMinHeight > 0) {
1179
+ // let minRow = Math.round(cssMinHeight / this.getCellHeight(true));
1180
+ // if (row < minRow) {
1181
+ // row = minRow;
1182
+ // }
1183
+ // }
1184
+ this.el.setAttribute('gs-current-row', String(row));
1185
+ if (row === 0) {
1186
+ this.el.style.removeProperty('height');
1187
+ return this;
1188
+ }
1189
+ var cellHeight = this.opts.cellHeight;
1190
+ var unit = this.opts.cellHeightUnit;
1191
+ if (!cellHeight)
1192
+ return this;
1193
+ this.el.style.height = row * cellHeight + unit;
1194
+ return this;
1195
+ };
1196
+ /** @internal */
1197
+ GridStack.prototype._prepareElement = function (el, triggerAddEvent, node) {
1198
+ if (triggerAddEvent === void 0) { triggerAddEvent = false; }
1199
+ if (!node) {
1200
+ el.classList.add(this.opts.itemClass);
1201
+ node = this._readAttr(el);
1202
+ }
1203
+ el.gridstackNode = node;
1204
+ node.el = el;
1205
+ node.grid = this;
1206
+ var copy = __assign({}, node);
1207
+ node = this.engine.addNode(node, triggerAddEvent);
1208
+ // write node attr back in case there was collision or we have to fix bad values during addNode()
1209
+ if (!utils_1.Utils.same(node, copy)) {
1210
+ this._writeAttr(el, node);
1211
+ }
1212
+ this._prepareDragDropByNode(node);
1213
+ return this;
1214
+ };
1215
+ /** @internal call to write position x,y,w,h attributes back to element */
1216
+ GridStack.prototype._writePosAttr = function (el, n) {
1217
+ if (n.x !== undefined && n.x !== null) {
1218
+ el.setAttribute('gs-x', String(n.x));
1219
+ }
1220
+ if (n.y !== undefined && n.y !== null) {
1221
+ el.setAttribute('gs-y', String(n.y));
1222
+ }
1223
+ if (n.w) {
1224
+ el.setAttribute('gs-w', String(n.w));
1225
+ }
1226
+ if (n.h) {
1227
+ el.setAttribute('gs-h', String(n.h));
1228
+ }
1229
+ return this;
1230
+ };
1231
+ /** @internal call to write any default attributes back to element */
1232
+ GridStack.prototype._writeAttr = function (el, node) {
1233
+ if (!node)
1234
+ return this;
1235
+ this._writePosAttr(el, node);
1236
+ var attrs /*: GridStackWidget but strings */ = {
1237
+ autoPosition: 'gs-auto-position',
1238
+ minW: 'gs-min-w',
1239
+ minH: 'gs-min-h',
1240
+ maxW: 'gs-max-w',
1241
+ maxH: 'gs-max-h',
1242
+ noResize: 'gs-no-resize',
1243
+ noMove: 'gs-no-move',
1244
+ locked: 'gs-locked',
1245
+ id: 'gs-id',
1246
+ resizeHandles: 'gs-resize-handles'
1247
+ };
1248
+ for (var key in attrs) {
1249
+ if (node[key]) { // 0 is valid for x,y only but done above already and not in list anyway
1250
+ el.setAttribute(attrs[key], String(node[key]));
1251
+ }
1252
+ else {
1253
+ el.removeAttribute(attrs[key]);
1254
+ }
1255
+ }
1256
+ return this;
1257
+ };
1258
+ /** @internal call to read any default attributes from element */
1259
+ GridStack.prototype._readAttr = function (el) {
1260
+ var node = {};
1261
+ node.x = utils_1.Utils.toNumber(el.getAttribute('gs-x'));
1262
+ node.y = utils_1.Utils.toNumber(el.getAttribute('gs-y'));
1263
+ node.w = utils_1.Utils.toNumber(el.getAttribute('gs-w'));
1264
+ node.h = utils_1.Utils.toNumber(el.getAttribute('gs-h'));
1265
+ node.maxW = utils_1.Utils.toNumber(el.getAttribute('gs-max-w'));
1266
+ node.minW = utils_1.Utils.toNumber(el.getAttribute('gs-min-w'));
1267
+ node.maxH = utils_1.Utils.toNumber(el.getAttribute('gs-max-h'));
1268
+ node.minH = utils_1.Utils.toNumber(el.getAttribute('gs-min-h'));
1269
+ node.autoPosition = utils_1.Utils.toBool(el.getAttribute('gs-auto-position'));
1270
+ node.noResize = utils_1.Utils.toBool(el.getAttribute('gs-no-resize'));
1271
+ node.noMove = utils_1.Utils.toBool(el.getAttribute('gs-no-move'));
1272
+ node.locked = utils_1.Utils.toBool(el.getAttribute('gs-locked'));
1273
+ node.resizeHandles = el.getAttribute('gs-resize-handles');
1274
+ node.id = el.getAttribute('gs-id');
1275
+ // remove any key not found (null or false which is default)
1276
+ for (var key in node) {
1277
+ if (!node.hasOwnProperty(key))
1278
+ return;
1279
+ if (!node[key] && node[key] !== 0) { // 0 can be valid value (x,y only really)
1280
+ delete node[key];
1281
+ }
1282
+ }
1283
+ return node;
1284
+ };
1285
+ /** @internal */
1286
+ GridStack.prototype._setStaticClass = function () {
1287
+ var _a, _b;
1288
+ var classes = ['grid-stack-static'];
1289
+ if (this.opts.staticGrid) {
1290
+ (_a = this.el.classList).add.apply(_a, classes);
1291
+ this.el.setAttribute('gs-static', 'true');
1292
+ }
1293
+ else {
1294
+ (_b = this.el.classList).remove.apply(_b, classes);
1295
+ this.el.removeAttribute('gs-static');
1296
+ }
1297
+ return this;
1298
+ };
1299
+ /**
1300
+ * called when we are being resized by the window - check if the one Column Mode needs to be turned on/off
1301
+ * and remember the prev columns we used, or get our count from parent, as well as check for auto cell height (square)
1302
+ */
1303
+ GridStack.prototype.onParentResize = function () {
1304
+ var _this = this;
1305
+ if (!this.el || !this.el.clientWidth)
1306
+ return; // return if we're gone or no size yet (will get called again)
1307
+ var changedColumn = false;
1308
+ // see if we're nested and take our column count from our parent....
1309
+ if (this._autoColumn && this.opts._isNested) {
1310
+ if (this.opts.column !== this.opts._isNested.w) {
1311
+ changedColumn = true;
1312
+ this.column(this.opts._isNested.w, 'none');
1313
+ }
1314
+ }
1315
+ else {
1316
+ // else check for 1 column in/out behavior
1317
+ var oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.minWidth;
1318
+ if ((this.opts.column === 1) !== oneColumn) {
1319
+ changedColumn = true;
1320
+ if (this.opts.animate) {
1321
+ this.setAnimation(false);
1322
+ } // 1 <-> 12 is too radical, turn off animation
1323
+ this.column(oneColumn ? 1 : this._prevColumn);
1324
+ if (this.opts.animate) {
1325
+ this.setAnimation(true);
1326
+ }
1327
+ }
1328
+ }
1329
+ // make the cells content square again
1330
+ if (this._isAutoCellHeight) {
1331
+ if (!changedColumn && this.opts.cellHeightThrottle) {
1332
+ if (!this._cellHeightThrottle) {
1333
+ this._cellHeightThrottle = utils_1.Utils.throttle(function () { return _this.cellHeight(); }, this.opts.cellHeightThrottle);
1334
+ }
1335
+ this._cellHeightThrottle();
1336
+ }
1337
+ else {
1338
+ // immediate update if we've changed column count or have no threshold
1339
+ this.cellHeight();
1340
+ }
1341
+ }
1342
+ // finally update any nested grids
1343
+ this.engine.nodes.forEach(function (n) {
1344
+ if (n.subGrid) {
1345
+ n.subGrid.onParentResize();
1346
+ }
1347
+ });
1348
+ return this;
1349
+ };
1350
+ /** add or remove the window size event handler */
1351
+ GridStack.prototype._updateWindowResizeEvent = function (forceRemove) {
1352
+ if (forceRemove === void 0) { forceRemove = false; }
1353
+ // 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)
1354
+ var workTodo = (this._isAutoCellHeight || !this.opts.disableOneColumnMode) && !this.opts._isNested;
1355
+ if (!forceRemove && workTodo && !this._windowResizeBind) {
1356
+ this._windowResizeBind = this.onParentResize.bind(this); // so we can properly remove later
1357
+ window.addEventListener('resize', this._windowResizeBind);
1358
+ }
1359
+ else if ((forceRemove || !workTodo) && this._windowResizeBind) {
1360
+ window.removeEventListener('resize', this._windowResizeBind);
1361
+ delete this._windowResizeBind; // remove link to us so we can free
1362
+ }
1363
+ return this;
1364
+ };
1365
+ /** @internal convert a potential selector into actual element */
1366
+ GridStack.getElement = function (els) {
1367
+ if (els === void 0) { els = '.grid-stack-item'; }
1368
+ return utils_1.Utils.getElement(els);
1369
+ };
1370
+ /** @internal */
1371
+ GridStack.getElements = function (els) {
1372
+ if (els === void 0) { els = '.grid-stack-item'; }
1373
+ return utils_1.Utils.getElements(els);
1374
+ };
1375
+ /** @internal */
1376
+ GridStack.getGridElement = function (els) { return GridStack.getElement(els); };
1377
+ /** @internal */
1378
+ GridStack.getGridElements = function (els) { return utils_1.Utils.getElements(els); };
1379
+ /** @internal initialize margin top/bottom/left/right and units */
1380
+ GridStack.prototype.initMargin = function () {
1381
+ var data;
1382
+ var margin = 0;
1383
+ // support passing multiple values like CSS (ex: '5px 10px 0 20px')
1384
+ var margins = [];
1385
+ if (typeof this.opts.margin === 'string') {
1386
+ margins = this.opts.margin.split(' ');
1387
+ }
1388
+ if (margins.length === 2) { // top/bot, left/right like CSS
1389
+ this.opts.marginTop = this.opts.marginBottom = margins[0];
1390
+ this.opts.marginLeft = this.opts.marginRight = margins[1];
1391
+ }
1392
+ else if (margins.length === 4) { // Clockwise like CSS
1393
+ this.opts.marginTop = margins[0];
1394
+ this.opts.marginRight = margins[1];
1395
+ this.opts.marginBottom = margins[2];
1396
+ this.opts.marginLeft = margins[3];
1397
+ }
1398
+ else {
1399
+ data = utils_1.Utils.parseHeight(this.opts.margin);
1400
+ this.opts.marginUnit = data.unit;
1401
+ margin = this.opts.margin = data.h;
1402
+ }
1403
+ // see if top/bottom/left/right need to be set as well
1404
+ if (this.opts.marginTop === undefined) {
1405
+ this.opts.marginTop = margin;
1406
+ }
1407
+ else {
1408
+ data = utils_1.Utils.parseHeight(this.opts.marginTop);
1409
+ this.opts.marginTop = data.h;
1410
+ delete this.opts.margin;
1411
+ }
1412
+ if (this.opts.marginBottom === undefined) {
1413
+ this.opts.marginBottom = margin;
1414
+ }
1415
+ else {
1416
+ data = utils_1.Utils.parseHeight(this.opts.marginBottom);
1417
+ this.opts.marginBottom = data.h;
1418
+ delete this.opts.margin;
1419
+ }
1420
+ if (this.opts.marginRight === undefined) {
1421
+ this.opts.marginRight = margin;
1422
+ }
1423
+ else {
1424
+ data = utils_1.Utils.parseHeight(this.opts.marginRight);
1425
+ this.opts.marginRight = data.h;
1426
+ delete this.opts.margin;
1427
+ }
1428
+ if (this.opts.marginLeft === undefined) {
1429
+ this.opts.marginLeft = margin;
1430
+ }
1431
+ else {
1432
+ data = utils_1.Utils.parseHeight(this.opts.marginLeft);
1433
+ this.opts.marginLeft = data.h;
1434
+ delete this.opts.margin;
1435
+ }
1436
+ this.opts.marginUnit = data.unit; // in case side were spelled out, use those units instead...
1437
+ if (this.opts.marginTop === this.opts.marginBottom && this.opts.marginLeft === this.opts.marginRight && this.opts.marginTop === this.opts.marginRight) {
1438
+ this.opts.margin = this.opts.marginTop; // makes it easier to check for no-ops in setMargin()
1439
+ }
1440
+ return this;
1441
+ };
1442
+ /*
1443
+ * drag&drop empty stubs that will be implemented in gridstack-dd.ts for non static grid
1444
+ * so we don't incur the load unless needed.
1445
+ * NOTE: had to make those methods public in order to define them else as
1446
+ * GridStack.prototype._setupAcceptWidget = function()
1447
+ * maybe there is a better way ????
1448
+ */
1449
+ /* eslint-disable @typescript-eslint/no-unused-vars */
1450
+ /**
1451
+ * call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.
1452
+ * Called during GridStack.init() as options, but can also be called directly (last param are cached) in case the toolbar
1453
+ * is dynamically create and needs to change later.
1454
+ * @param dragIn string selector (ex: '.sidebar .grid-stack-item')
1455
+ * @param dragInOptions options - see DDDragInOpt. (default: {revert: 'invalid', handle: '.grid-stack-item-content', scroll: false, appendTo: 'body'}
1456
+ **/
1457
+ GridStack.setupDragIn = function (dragIn, dragInOptions) { };
1458
+ /**
1459
+ * 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.
1460
+ * IF you are looking to prevent an item from moving (due to being pushed around by another during collision) use locked property instead.
1461
+ * @param els widget or selector to modify.
1462
+ * @param val if true widget will be draggable.
1463
+ */
1464
+ GridStack.prototype.movable = function (els, val) { return this; };
1465
+ /**
1466
+ * 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.
1467
+ * @param els widget or selector to modify
1468
+ * @param val if true widget will be resizable.
1469
+ */
1470
+ GridStack.prototype.resizable = function (els, val) { return this; };
1471
+ /**
1472
+ * Temporarily disables widgets moving/resizing.
1473
+ * If you want a more permanent way (which freezes up resources) use `setStatic(true)` instead.
1474
+ * Note: no-op for static grid
1475
+ * This is a shortcut for:
1476
+ * @example
1477
+ * grid.enableMove(false);
1478
+ * grid.enableResize(false);
1479
+ */
1480
+ GridStack.prototype.disable = function () { return this; };
1481
+ /**
1482
+ * Re-enables widgets moving/resizing - see disable().
1483
+ * Note: no-op for static grid.
1484
+ * This is a shortcut for:
1485
+ * @example
1486
+ * grid.enableMove(true);
1487
+ * grid.enableResize(true);
1488
+ */
1489
+ GridStack.prototype.enable = function () { return this; };
1490
+ /**
1491
+ * Enables/disables widget moving. No-op for static grids.
1492
+ */
1493
+ GridStack.prototype.enableMove = function (doEnable) { return this; };
1494
+ /**
1495
+ * Enables/disables widget resizing. No-op for static grids.
1496
+ */
1497
+ GridStack.prototype.enableResize = function (doEnable) { return this; };
1498
+ /** @internal called to add drag over support to support widgets */
1499
+ GridStack.prototype._setupAcceptWidget = function () { return this; };
1500
+ /** @internal called to setup a trash drop zone if the user specifies it */
1501
+ GridStack.prototype._setupRemoveDrop = function () { return this; };
1502
+ /** @internal prepares the element for drag&drop **/
1503
+ GridStack.prototype._prepareDragDropByNode = function (node) { return this; };
1504
+ /** @internal handles actual drag/resize start **/
1505
+ GridStack.prototype._onStartMoving = function (el, event, ui, node, cellWidth, cellHeight) { return; };
1506
+ /** @internal handles actual drag/resize **/
1507
+ GridStack.prototype._dragOrResize = function (el, event, ui, node, cellWidth, cellHeight) { return; };
1508
+ /** @internal called when a node leaves our area (mouse out or shape outside) **/
1509
+ GridStack.prototype._leave = function (el, helper) { return; };
1510
+ /** scoping so users can call GridStack.Utils.sort() for example */
1511
+ GridStack.Utils = utils_1.Utils;
1512
+ /** scoping so users can call new GridStack.Engine(12) for example */
1513
+ GridStack.Engine = gridstack_engine_1.GridStackEngine;
1514
+ return GridStack;
1515
+ }());
1516
+ exports.GridStack = GridStack;
1517
+ //# sourceMappingURL=gridstack.js.map