@themarioga/grid-editor 6.0.0-beta.5 → 7.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 (147) hide show
  1. package/AUTO_SAVE.md +2 -2
  2. package/BUILDING.md +45 -29
  3. package/CHANGELOG.md +54 -0
  4. package/README.md +140 -89
  5. package/UPGRADING.md +146 -2
  6. package/dist/grideditor.bundle.min.js +14 -0
  7. package/dist/grideditor.d.ts +335 -0
  8. package/dist/grideditor.esm.js +3977 -0
  9. package/dist/grideditor.jquery.js +253 -0
  10. package/dist/grideditor.jquery.min.js +1 -0
  11. package/dist/grideditor.jquery.min.js.map +7 -0
  12. package/dist/grideditor.js +3983 -0
  13. package/dist/grideditor.min.js +6 -0
  14. package/dist/grideditor.min.js.map +7 -0
  15. package/dist/locales/grideditor.es.esm.js +158 -0
  16. package/dist/locales/grideditor.es.js +164 -170
  17. package/dist/locales/grideditor.es.min.js +6 -2
  18. package/dist/locales/grideditor.es.min.js.map +7 -1
  19. package/dist/plugins/grideditor.accordion.esm.js +294 -0
  20. package/dist/plugins/grideditor.accordion.js +286 -180
  21. package/dist/plugins/grideditor.accordion.min.js +1 -2
  22. package/dist/plugins/grideditor.accordion.min.js.map +7 -1
  23. package/dist/plugins/grideditor.alignment.esm.js +55 -0
  24. package/dist/plugins/grideditor.alignment.js +58 -77
  25. package/dist/plugins/grideditor.alignment.min.js +1 -2
  26. package/dist/plugins/grideditor.alignment.min.js.map +7 -1
  27. package/dist/plugins/grideditor.card.esm.js +73 -0
  28. package/dist/plugins/grideditor.card.js +74 -64
  29. package/dist/plugins/grideditor.card.min.js +1 -2
  30. package/dist/plugins/grideditor.card.min.js.map +7 -1
  31. package/dist/plugins/grideditor.ckeditor.esm.js +500 -0
  32. package/dist/plugins/grideditor.ckeditor.js +482 -493
  33. package/dist/plugins/grideditor.ckeditor.min.js +1 -2
  34. package/dist/plugins/grideditor.ckeditor.min.js.map +7 -1
  35. package/dist/plugins/grideditor.clipboard.esm.js +326 -0
  36. package/dist/plugins/grideditor.clipboard.js +298 -235
  37. package/dist/plugins/grideditor.clipboard.min.js +1 -2
  38. package/dist/plugins/grideditor.clipboard.min.js.map +7 -1
  39. package/dist/plugins/grideditor.codemirror-inline.esm.js +205 -0
  40. package/dist/plugins/grideditor.codemirror-inline.js +188 -168
  41. package/dist/plugins/grideditor.codemirror-inline.min.js +1 -2
  42. package/dist/plugins/grideditor.codemirror-inline.min.js.map +7 -1
  43. package/dist/plugins/grideditor.codemirror.esm.js +63 -0
  44. package/dist/plugins/grideditor.codemirror.js +60 -71
  45. package/dist/plugins/grideditor.codemirror.min.js +1 -2
  46. package/dist/plugins/grideditor.codemirror.min.js.map +7 -1
  47. package/dist/plugins/grideditor.elements.esm.js +271 -0
  48. package/dist/plugins/grideditor.elements.js +256 -149
  49. package/dist/plugins/grideditor.elements.min.js +1 -2
  50. package/dist/plugins/grideditor.elements.min.js.map +7 -1
  51. package/dist/plugins/grideditor.float.esm.js +34 -0
  52. package/dist/plugins/grideditor.float.js +37 -52
  53. package/dist/plugins/grideditor.float.min.js +1 -2
  54. package/dist/plugins/grideditor.float.min.js.map +7 -1
  55. package/dist/plugins/grideditor.gutters.esm.js +143 -0
  56. package/dist/plugins/grideditor.gutters.js +134 -131
  57. package/dist/plugins/grideditor.gutters.min.js +1 -2
  58. package/dist/plugins/grideditor.gutters.min.js.map +7 -1
  59. package/dist/plugins/grideditor.order.esm.js +189 -0
  60. package/dist/plugins/grideditor.order.js +170 -182
  61. package/dist/plugins/grideditor.order.min.js +1 -2
  62. package/dist/plugins/grideditor.order.min.js.map +7 -1
  63. package/dist/plugins/grideditor.popup.esm.js +187 -0
  64. package/dist/plugins/grideditor.popup.js +183 -134
  65. package/dist/plugins/grideditor.popup.min.js +1 -2
  66. package/dist/plugins/grideditor.popup.min.js.map +7 -1
  67. package/dist/plugins/grideditor.sections.esm.js +271 -0
  68. package/dist/plugins/grideditor.sections.js +250 -173
  69. package/dist/plugins/grideditor.sections.min.js +1 -2
  70. package/dist/plugins/grideditor.sections.min.js.map +7 -1
  71. package/dist/plugins/grideditor.spacing.esm.js +318 -0
  72. package/dist/plugins/grideditor.spacing.js +296 -272
  73. package/dist/plugins/grideditor.spacing.min.js +1 -2
  74. package/dist/plugins/grideditor.spacing.min.js.map +7 -1
  75. package/dist/plugins/grideditor.summernote.esm.js +509 -0
  76. package/dist/plugins/grideditor.summernote.js +491 -471
  77. package/dist/plugins/grideditor.summernote.min.js +1 -2
  78. package/dist/plugins/grideditor.summernote.min.js.map +7 -1
  79. package/dist/plugins/grideditor.tabs.esm.js +237 -0
  80. package/dist/plugins/grideditor.tabs.js +233 -139
  81. package/dist/plugins/grideditor.tabs.min.js +1 -2
  82. package/dist/plugins/grideditor.tabs.min.js.map +7 -1
  83. package/dist/plugins/grideditor.textalign.esm.js +40 -0
  84. package/dist/plugins/grideditor.textalign.js +43 -56
  85. package/dist/plugins/grideditor.textalign.min.js +1 -2
  86. package/dist/plugins/grideditor.textalign.min.js.map +7 -1
  87. package/dist/plugins/grideditor.tinymce.esm.js +519 -0
  88. package/dist/plugins/grideditor.tinymce.js +500 -534
  89. package/dist/plugins/grideditor.tinymce.min.js +1 -2
  90. package/dist/plugins/grideditor.tinymce.min.js.map +7 -1
  91. package/dist/plugins/grideditor.visibility.esm.js +158 -0
  92. package/dist/plugins/grideditor.visibility.js +140 -149
  93. package/dist/plugins/grideditor.visibility.min.js +1 -2
  94. package/dist/plugins/grideditor.visibility.min.js.map +7 -1
  95. package/docs/events.md +47 -21
  96. package/docs/locale-keys.md +7 -4
  97. package/docs/plugins.md +49 -27
  98. package/example/adapter.html +112 -0
  99. package/example/attributes.html +85 -61
  100. package/example/autocols.html +9 -9
  101. package/example/autosave.html +13 -14
  102. package/example/basic.html +4 -5
  103. package/example/breakpoints.html +5 -6
  104. package/example/ckeditor.html +4 -5
  105. package/example/clipboard.html +11 -10
  106. package/example/codemirror.html +9 -7
  107. package/example/containers.html +7 -8
  108. package/example/custom_editor.html +53 -34
  109. package/example/elements.html +10 -11
  110. package/example/index.html +16 -2
  111. package/example/locale.html +6 -7
  112. package/example/plugins.html +44 -29
  113. package/example/summernote.html +6 -5
  114. package/example/utilities.html +17 -13
  115. package/example/wrap_content.html +9 -9
  116. package/package.json +43 -12
  117. package/src/js/dom.js +401 -0
  118. package/src/js/grideditor.classic.js +16 -0
  119. package/src/js/grideditor.jquery.js +325 -0
  120. package/src/js/{jquery.grideditor.js → grideditor.js} +1284 -1124
  121. package/src/js/locales/grideditor.es.js +163 -158
  122. package/src/js/plugins/grideditor.accordion.js +97 -77
  123. package/src/js/plugins/grideditor.alignment.js +5 -7
  124. package/src/js/plugins/grideditor.card.js +23 -23
  125. package/src/js/plugins/grideditor.ckeditor.js +107 -106
  126. package/src/js/plugins/grideditor.clipboard.js +49 -37
  127. package/src/js/plugins/grideditor.codemirror-inline.js +50 -37
  128. package/src/js/plugins/grideditor.codemirror.js +9 -10
  129. package/src/js/plugins/grideditor.elements.js +57 -33
  130. package/src/js/plugins/grideditor.float.js +4 -6
  131. package/src/js/plugins/grideditor.gutters.js +20 -15
  132. package/src/js/plugins/grideditor.order.js +28 -25
  133. package/src/js/plugins/grideditor.popup.js +63 -51
  134. package/src/js/plugins/grideditor.sections.js +39 -32
  135. package/src/js/plugins/grideditor.spacing.js +42 -45
  136. package/src/js/plugins/grideditor.summernote.js +112 -76
  137. package/src/js/plugins/grideditor.tabs.js +65 -57
  138. package/src/js/plugins/grideditor.textalign.js +4 -6
  139. package/src/js/plugins/grideditor.tinymce.js +147 -139
  140. package/src/js/plugins/grideditor.visibility.js +24 -25
  141. package/src/js/register.js +18 -0
  142. package/src/js/text/grideditor.text.js +81 -106
  143. package/types/grideditor.d.ts +335 -0
  144. package/dist/jquery.grideditor.bundle.min.js +0 -10
  145. package/dist/jquery.grideditor.js +0 -4927
  146. package/dist/jquery.grideditor.min.js +0 -2
  147. package/dist/jquery.grideditor.min.js.map +0 -1
@@ -0,0 +1,3983 @@
1
+ (() => {
2
+ // src/js/dom.js
3
+ function all(root, selector) {
4
+ return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];
5
+ }
6
+ function one(root, selector) {
7
+ return root ? root.querySelector(selector) : null;
8
+ }
9
+ function selfAndAll(root, selector) {
10
+ if (!root) {
11
+ return [];
12
+ }
13
+ var found = all(root, selector);
14
+ if (root.nodeType === 1 && root.matches(selector)) {
15
+ found.unshift(root);
16
+ }
17
+ return found;
18
+ }
19
+ function children(node, selector) {
20
+ if (!node) {
21
+ return [];
22
+ }
23
+ return Array.prototype.filter.call(node.children, function(each) {
24
+ return !selector || each.matches(selector);
25
+ });
26
+ }
27
+ function child(node, selector) {
28
+ return children(node, selector)[0] || null;
29
+ }
30
+ function closest(node, selector, stopAt) {
31
+ var found = node && node.nodeType === 1 ? node.closest(selector) : null;
32
+ if (found && stopAt && found !== stopAt && !stopAt.contains(found)) {
33
+ return null;
34
+ }
35
+ return found;
36
+ }
37
+ function is(node, selector) {
38
+ return !!node && node.nodeType === 1 && node.matches(selector);
39
+ }
40
+ function attached(node) {
41
+ return !!node && document.documentElement.contains(node);
42
+ }
43
+ function nextAll(node, selector) {
44
+ var found = [];
45
+ for (var next = node.nextElementSibling; next; next = next.nextElementSibling) {
46
+ if (!selector || next.matches(selector)) {
47
+ found.push(next);
48
+ }
49
+ }
50
+ return found;
51
+ }
52
+ function parentsUntil(node, stop) {
53
+ var found = [];
54
+ for (var parent = node.parentElement; parent && parent !== stop; parent = parent.parentElement) {
55
+ found.push(parent);
56
+ }
57
+ return found;
58
+ }
59
+ function parse(html) {
60
+ var template = document.createElement("template");
61
+ template.innerHTML = html;
62
+ return Array.prototype.slice.call(template.content.childNodes);
63
+ }
64
+ function create(html) {
65
+ var nodes = parse(html.trim());
66
+ for (var i = 0; i < nodes.length; i++) {
67
+ if (nodes[i].nodeType === 1) {
68
+ return nodes[i];
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ function element(tag, attributes, text) {
74
+ var node = document.createElement(tag);
75
+ Object.keys(attributes || {}).forEach(function(name) {
76
+ var value = attributes[name];
77
+ if (value !== null && value !== void 0 && value !== false) {
78
+ node.setAttribute(name, value);
79
+ }
80
+ });
81
+ if (text !== void 0 && text !== null) {
82
+ node.textContent = text;
83
+ }
84
+ return node;
85
+ }
86
+ function setHtml(node, html) {
87
+ node.innerHTML = html === void 0 || html === null ? "" : String(html);
88
+ return node;
89
+ }
90
+ function addClass(node, names) {
91
+ split(names).forEach(function(name) {
92
+ node.classList.add(name);
93
+ });
94
+ return node;
95
+ }
96
+ function removeClass(node, names) {
97
+ split(names).forEach(function(name) {
98
+ node.classList.remove(name);
99
+ });
100
+ return node;
101
+ }
102
+ function toggleClass(node, names, state) {
103
+ split(names).forEach(function(name) {
104
+ if (state === void 0) {
105
+ node.classList.toggle(name);
106
+ } else {
107
+ node.classList.toggle(name, !!state);
108
+ }
109
+ });
110
+ return node;
111
+ }
112
+ function hasClass(node, name) {
113
+ return !!node && node.nodeType === 1 && node.classList.contains(name);
114
+ }
115
+ function split(names) {
116
+ return String(names || "").split(/\s+/).filter(Boolean);
117
+ }
118
+ function dropEmptyClass(node) {
119
+ if (!node.getAttribute("class")) {
120
+ node.removeAttribute("class");
121
+ }
122
+ return node;
123
+ }
124
+ function dropEmptyStyle(node) {
125
+ if (!node.getAttribute("style")) {
126
+ node.removeAttribute("style");
127
+ }
128
+ return node;
129
+ }
130
+ function attr(node, attributes) {
131
+ Object.keys(attributes).forEach(function(name) {
132
+ var value = attributes[name];
133
+ if (value === null || value === void 0) {
134
+ node.removeAttribute(name);
135
+ } else {
136
+ node.setAttribute(name, value);
137
+ }
138
+ });
139
+ return node;
140
+ }
141
+ function css(node, styles) {
142
+ Object.keys(styles).forEach(function(property) {
143
+ var value = styles[property];
144
+ if (typeof value === "number" && !UNITLESS[property]) {
145
+ value = value + "px";
146
+ }
147
+ node.style.setProperty(property, value === null || value === void 0 ? "" : String(value));
148
+ });
149
+ return node;
150
+ }
151
+ var UNITLESS = { opacity: true, "z-index": true, "flex-grow": true, "flex-shrink": true, order: true };
152
+ var defaultDisplays = {};
153
+ function defaultDisplay(node) {
154
+ var tag = node.nodeName;
155
+ if (!defaultDisplays[tag]) {
156
+ var probe = document.body.appendChild(document.createElement(tag));
157
+ defaultDisplays[tag] = getComputedStyle(probe).display;
158
+ probe.remove();
159
+ if (defaultDisplays[tag] === "none") {
160
+ defaultDisplays[tag] = "block";
161
+ }
162
+ }
163
+ return defaultDisplays[tag];
164
+ }
165
+ function show(node) {
166
+ node.style.removeProperty("display");
167
+ if (getComputedStyle(node).display === "none") {
168
+ node.style.display = defaultDisplay(node);
169
+ }
170
+ return node;
171
+ }
172
+ function hide(node) {
173
+ node.style.display = "none";
174
+ return node;
175
+ }
176
+ function toggle(node, state) {
177
+ if (state === void 0) {
178
+ state = !visible(node);
179
+ }
180
+ return state ? show(node) : hide(node);
181
+ }
182
+ function visible(node) {
183
+ return !!(node.offsetWidth || node.offsetHeight || node.getClientRects().length);
184
+ }
185
+ function outerWidth(node) {
186
+ return node.getBoundingClientRect().width;
187
+ }
188
+ function outerHeight(node) {
189
+ return node.getBoundingClientRect().height;
190
+ }
191
+ function contentHeight(node) {
192
+ var style = getComputedStyle(node);
193
+ return node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);
194
+ }
195
+ function offset(node) {
196
+ var box = node.getBoundingClientRect();
197
+ return { top: box.top + window.pageYOffset, left: box.left + window.pageXOffset };
198
+ }
199
+ function insertAfter(node, reference) {
200
+ reference.parentNode.insertBefore(node, reference.nextSibling);
201
+ return node;
202
+ }
203
+ function unwrap(node) {
204
+ var parent = node.parentNode;
205
+ while (node.firstChild) {
206
+ parent.insertBefore(node.firstChild, node);
207
+ }
208
+ node.remove();
209
+ }
210
+ function wrap(node, wrapper) {
211
+ node.parentNode.insertBefore(wrapper, node);
212
+ wrapper.appendChild(node);
213
+ return wrapper;
214
+ }
215
+ function delegate(root, types, selector, handler, options) {
216
+ var listener = function(event) {
217
+ var match = closest(event.target, selector, root);
218
+ if (match && root.contains(match)) {
219
+ return handler.call(match, event);
220
+ }
221
+ return void 0;
222
+ };
223
+ split(types).forEach(function(type) {
224
+ root.addEventListener(type, listener, options);
225
+ });
226
+ return listener;
227
+ }
228
+ function on(target, types, handler, options) {
229
+ split(types).forEach(function(type) {
230
+ target.addEventListener(type, handler, options);
231
+ });
232
+ return handler;
233
+ }
234
+ function off(target, types, handler, options) {
235
+ split(types).forEach(function(type) {
236
+ target.removeEventListener(type, handler, options);
237
+ });
238
+ }
239
+ var DEFAULT_DURATION = 400;
240
+ function animateAway(node, frames, duration, done) {
241
+ duration = duration === void 0 ? DEFAULT_DURATION : duration;
242
+ var finish = function() {
243
+ hide(node);
244
+ if (done) {
245
+ done();
246
+ }
247
+ };
248
+ if (!visible(node) || !node.animate || duration <= 0) {
249
+ window.setTimeout(finish, 0);
250
+ return;
251
+ }
252
+ var animation = node.animate(frames(getComputedStyle(node)), {
253
+ duration,
254
+ easing: "ease-in-out"
255
+ });
256
+ var called = false;
257
+ var once = function() {
258
+ if (called) {
259
+ return;
260
+ }
261
+ called = true;
262
+ finish();
263
+ };
264
+ animation.onfinish = once;
265
+ animation.oncancel = once;
266
+ }
267
+ function slideUp(node, duration, done) {
268
+ if (typeof duration === "function") {
269
+ done = duration;
270
+ duration = void 0;
271
+ }
272
+ node.style.overflow = "hidden";
273
+ animateAway(node, function(style) {
274
+ return [
275
+ {
276
+ height: style.height,
277
+ paddingTop: style.paddingTop,
278
+ paddingBottom: style.paddingBottom,
279
+ marginTop: style.marginTop,
280
+ marginBottom: style.marginBottom
281
+ },
282
+ { height: "0px", paddingTop: "0px", paddingBottom: "0px", marginTop: "0px", marginBottom: "0px" }
283
+ ];
284
+ }, duration, function() {
285
+ node.style.removeProperty("overflow");
286
+ if (done) {
287
+ done();
288
+ }
289
+ });
290
+ }
291
+ function shrinkAway(node, duration, done, width) {
292
+ node.style.overflow = "hidden";
293
+ animateAway(node, function(style) {
294
+ var from = { opacity: style.opacity, height: style.height };
295
+ var to = { opacity: 0, height: "0px" };
296
+ if (width) {
297
+ from.width = style.width;
298
+ to.width = "0px";
299
+ }
300
+ return [from, to];
301
+ }, duration, function() {
302
+ node.style.removeProperty("overflow");
303
+ if (done) {
304
+ done();
305
+ }
306
+ });
307
+ }
308
+
309
+ // src/js/grideditor.js
310
+ var METHODS = {
311
+ getHtml: { value: true },
312
+ getPlainHtml: { value: true },
313
+ init: {},
314
+ deinit: {},
315
+ reset: {},
316
+ destroy: {},
317
+ changeView: {},
318
+ getView: { value: true },
319
+ createRow: { value: true },
320
+ createColumn: { value: true },
321
+ createElement: { value: true },
322
+ createText: { value: true },
323
+ createSection: { value: true },
324
+ createContainer: { value: true },
325
+ addTab: { value: true },
326
+ addAccordionItem: { value: true },
327
+ setLocale: {},
328
+ getUtility: { value: true },
329
+ setUtility: { value: true }
330
+ };
331
+ var PLACEMENTS = ["appendTo", "prependTo", "insertAfter", "insertBefore"];
332
+ var BREAKPOINTS = [
333
+ { key: "xs", infix: "", colPrefix: "col-", offsetPrefix: "offset-", min: 0, preview: 400, labelKey: "view.xs" },
334
+ { key: "sm", infix: "sm", colPrefix: "col-sm-", offsetPrefix: "offset-sm-", min: 576, preview: 576, labelKey: "view.sm" },
335
+ { key: "md", infix: "md", colPrefix: "col-md-", offsetPrefix: "offset-md-", min: 768, preview: 768, labelKey: "view.md" },
336
+ { key: "lg", infix: "lg", colPrefix: "col-lg-", offsetPrefix: "offset-lg-", min: 992, preview: 992, labelKey: "view.lg" },
337
+ { key: "xl", infix: "xl", colPrefix: "col-xl-", offsetPrefix: "offset-xl-", min: 1200, preview: 1200, labelKey: "view.xl" },
338
+ { key: "xxl", infix: "xxl", colPrefix: "col-xxl-", offsetPrefix: "offset-xxl-", min: 1400, preview: null, labelKey: "view.xxl" }
339
+ ];
340
+ var ALL_VIEW = "all";
341
+ var ALL_VIEW_LABEL_KEY = "view.all";
342
+ var VIEW_KEYS = [ALL_VIEW].concat(BREAKPOINTS.map(function(tier) {
343
+ return tier.key;
344
+ }));
345
+ var LEGACY_VIEW_INDEXES = ["lg", "sm", "xs"];
346
+ var MAX_COL_SIZE = 12;
347
+ var MAX_COL_OFFSET = 11;
348
+ var FLEX_SIZES = ["equal", "auto"];
349
+ var ROW_COLS_VALUES = ["1", "2", "3", "4", "5", "6", "auto"];
350
+ function rowColsClass(tier, value) {
351
+ return "row-cols" + (tier.infix ? "-" + tier.infix : "") + "-" + value;
352
+ }
353
+ function isUnits(size) {
354
+ return typeof size === "number";
355
+ }
356
+ function sizeClass(tier, size) {
357
+ if (size === "equal") {
358
+ return tier.infix ? "col-" + tier.infix : "col";
359
+ }
360
+ return tier.colPrefix + size;
361
+ }
362
+ function breakpoint(key) {
363
+ for (var i = 0; i < BREAKPOINTS.length; i++) {
364
+ if (BREAKPOINTS[i].key === key) {
365
+ return BREAKPOINTS[i];
366
+ }
367
+ }
368
+ return null;
369
+ }
370
+ function tiersFor(view) {
371
+ if (view === ALL_VIEW) {
372
+ return [BREAKPOINTS[0]];
373
+ }
374
+ var tier = breakpoint(view);
375
+ return tier ? [tier] : [];
376
+ }
377
+ function labelKeyFor(view) {
378
+ var tier = breakpoint(view);
379
+ return tier ? tier.labelKey : ALL_VIEW_LABEL_KEY;
380
+ }
381
+ var NESTED_SETTINGS = {
382
+ add_column: {
383
+ size: 12,
384
+ // What a click on the add column tool adds
385
+ picker: true,
386
+ // Holding it offers the sizes instead
387
+ delay: 600
388
+ // How long to hold, in milliseconds
389
+ },
390
+ elements: {
391
+ enabled: "auto",
392
+ // 'auto' turns them on when the page has any
393
+ selector: "[data-ge-element]",
394
+ // What the host marks an element with
395
+ auto: false
396
+ // Treat every child of a content area as an element
397
+ },
398
+ resize: {
399
+ enabled: true,
400
+ handles: "e",
401
+ // Which edges carry a handle: 'e', 'w', or 'e, w'
402
+ balance: "next"
403
+ // 'next' takes the units out of the following column
404
+ },
405
+ drag: {
406
+ delay: 0,
407
+ // Milliseconds to hold before a drag starts
408
+ touch_delay: 100,
409
+ // The same for touch, where 0 eats the page's scrolling
410
+ threshold: 3,
411
+ // Pixels of movement before a gesture counts as a drag
412
+ animation: 150,
413
+ // Milliseconds of reordering animation, 0 for none
414
+ scroll: true
415
+ // Scroll the page when a drag reaches its edge
416
+ }
417
+ };
418
+ var REMOVED_SETTINGS = {
419
+ sortable_options: "drag",
420
+ resizable_options: "resize"
421
+ };
422
+ var warned = {};
423
+ var editorCounter = 0;
424
+ var instances = /* @__PURE__ */ new WeakMap();
425
+ function translate(settings, key, params) {
426
+ var locales = GridEditor.locales;
427
+ var locale = locales[settings.locale] || {};
428
+ var overrides = settings.locale_strings || {};
429
+ var string = overrides[key];
430
+ if (string === void 0) {
431
+ string = locale[key];
432
+ }
433
+ if (string === void 0) {
434
+ string = locales.en[key];
435
+ }
436
+ if (string === void 0) {
437
+ warnOnce("locale:" + key, 'no string for "' + key + '" in any locale, showing the key');
438
+ string = key;
439
+ }
440
+ return string.replace(/\{(\w+)\}/g, function(placeholder, name) {
441
+ return params && params[name] !== void 0 ? params[name] : placeholder;
442
+ });
443
+ }
444
+ function warn(message) {
445
+ if (window.console && window.console.warn) {
446
+ window.console.warn("grid-editor: " + message);
447
+ }
448
+ }
449
+ function warnOnce(key, message) {
450
+ if (warned[key]) {
451
+ return;
452
+ }
453
+ warned[key] = true;
454
+ warn(message);
455
+ }
456
+ function english(key, params) {
457
+ return translate({ locale: "en" }, key, params);
458
+ }
459
+ function targetElement(target) {
460
+ if (typeof target === "string") {
461
+ var found = document.querySelector(target);
462
+ if (!found) {
463
+ throw new TypeError("grid-editor: no element matches " + JSON.stringify(target));
464
+ }
465
+ return found;
466
+ }
467
+ if (target && target.nodeType === 1) {
468
+ return target;
469
+ }
470
+ throw new TypeError("grid-editor: the target is an element or a selector, not " + (target === null ? "null" : typeof target));
471
+ }
472
+ function nodeFrom(node) {
473
+ if (typeof node === "string") {
474
+ return document.querySelector(node);
475
+ }
476
+ return node && node.nodeType === 1 ? node : null;
477
+ }
478
+ function sortableLibrary() {
479
+ return GridEditor.Sortable || window.Sortable || null;
480
+ }
481
+ function modalLibrary() {
482
+ var bootstrap = GridEditor.bootstrap || window.bootstrap;
483
+ return bootstrap && bootstrap.Modal ? bootstrap.Modal : null;
484
+ }
485
+ function plainHtml(html) {
486
+ var root = document.implementation.createHTMLDocument("").body;
487
+ root.innerHTML = html;
488
+ var emptied = [];
489
+ all(root, "*").forEach(function(node) {
490
+ var marked = false;
491
+ Array.prototype.slice.call(node.attributes).forEach(function(attribute) {
492
+ if (attribute.name.indexOf("data-ge-") === 0) {
493
+ node.removeAttribute(attribute.name);
494
+ marked = true;
495
+ }
496
+ });
497
+ var classes = (node.getAttribute("class") || "").split(/\s+/).filter(Boolean);
498
+ var kept = classes.filter(function(name) {
499
+ return name !== "column" && name.indexOf("ge-") !== 0;
500
+ });
501
+ if (kept.length !== classes.length) {
502
+ marked = true;
503
+ }
504
+ if (kept.length) {
505
+ node.setAttribute("class", kept.join(" "));
506
+ } else {
507
+ node.removeAttribute("class");
508
+ }
509
+ if (marked && node.tagName === "DIV" && !node.attributes.length) {
510
+ emptied.push(node);
511
+ }
512
+ });
513
+ emptied.forEach(function(div) {
514
+ unwrap(div);
515
+ });
516
+ return root.innerHTML;
517
+ }
518
+ function GridEditor(target, options) {
519
+ var element2 = targetElement(target);
520
+ var existing = instances.get(element2);
521
+ if (existing) {
522
+ if (!doubleWarned.has(element2)) {
523
+ doubleWarned.add(element2);
524
+ warn(english("warning.already_editing"));
525
+ }
526
+ return existing;
527
+ }
528
+ if (!(this instanceof GridEditor)) {
529
+ return new GridEditor(element2, options);
530
+ }
531
+ build(this, element2, options || {});
532
+ }
533
+ var doubleWarned = /* @__PURE__ */ new WeakSet();
534
+ GridEditor.create = function(target, options) {
535
+ return new GridEditor(target, options);
536
+ };
537
+ GridEditor.get = function(target) {
538
+ var element2 = nodeFrom(target);
539
+ return element2 ? instances.get(element2) || null : null;
540
+ };
541
+ function build(instance, baseElem, optionsOrMethod) {
542
+ var settings = Object.assign({
543
+ "new_row_layouts": [
544
+ // Column layouts for add row buttons
545
+ [12],
546
+ [6, 6],
547
+ [4, 4, 4],
548
+ [3, 3, 3, 3],
549
+ [2, 2, 2, 2, 2, 2],
550
+ [2, 8, 2],
551
+ [4, 8],
552
+ [8, 4]
553
+ ],
554
+ "row_classes": [],
555
+ // Preset class toggles, on top of the classes field
556
+ "col_classes": [],
557
+ "col_tools": [],
558
+ /* Example:
559
+ [ {
560
+ title: 'Set background image',
561
+ iconClass: 'bi bi-image',
562
+ on: { click: function(event) {} }
563
+ } ]
564
+ */
565
+ "row_tools": [],
566
+ "drag_handle": "tool",
567
+ // 'tool' for the move tool, 'drawer' for the whole drawer
568
+ "toolbar_drag": "auto",
569
+ // Drag the toolbar's buttons onto the canvas. 'auto' follows drag_handle
570
+ "element_tools": [],
571
+ // Host tools on element drawers, same shape as row_tools
572
+ "element_classes": [],
573
+ // Preset class toggles on an element's settings panel
574
+ // content_types, text_tools and text_classes are the text editor
575
+ // plugins' settings since 6.0: see grideditor.text.js
576
+ "container_classes": [],
577
+ // The same, on a container's panel
578
+ "pane_classes": [],
579
+ // And on a tab's or an accordion item's
580
+ "container_tools": [],
581
+ // Host tools on container drawers
582
+ "tab_tools": [],
583
+ // Host tools on tab drawers
584
+ "accordion_tools": [],
585
+ // Host tools on accordion item drawers
586
+ "plugins": null,
587
+ // Plugins to use, of any kind; null means every one loaded
588
+ "row_cols": true,
589
+ // A row's "columns per row" field, row-cols-*
590
+ "utilities": {},
591
+ // Options for the utility plugins, by plugin name
592
+ "elements": NESTED_SETTINGS.elements,
593
+ // Element level controls, below the column
594
+ "custom_filter": "",
595
+ "valid_col_sizes": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "equal", "auto"],
596
+ "valid_col_offsets": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
597
+ "add_column": NESTED_SETTINGS.add_column,
598
+ // The add column tool
599
+ "layout_modes": VIEW_KEYS.slice(),
600
+ // Which views the dropdown offers
601
+ "default_view": ALL_VIEW,
602
+ "resize": NESTED_SETTINGS.resize,
603
+ // Resizing a column by dragging its edge
604
+ "source_textarea": "",
605
+ "edit_source": true,
606
+ // The toolbar's button to edit the canvas as html
607
+ "locale": "en",
608
+ // Code of a locale in GridEditor.locales
609
+ "locale_strings": {},
610
+ // Overrides for individual keys
611
+ "callbacks": {},
612
+ // before_*/after_* functions, the events by another route
613
+ "confirm_delete": true,
614
+ // Ask before deleting a row or a column
615
+ "settings_panel": "offcanvas",
616
+ // Where a node's settings open: 'offcanvas', 'popover', 'modal' or 'inline'
617
+ "drag": NESTED_SETTINGS.drag
618
+ // How a drag behaves, whatever drives it
619
+ }, optionsOrMethod);
620
+ Object.keys(NESTED_SETTINGS).forEach(function(name) {
621
+ settings[name] = Object.assign({}, NESTED_SETTINGS[name], settings[name]);
622
+ });
623
+ Object.keys(REMOVED_SETTINGS).forEach(function(name) {
624
+ if (optionsOrMethod && optionsOrMethod[name] !== void 0) {
625
+ warn(translate(settings, "warning.setting_removed", {
626
+ setting: name,
627
+ replacement: REMOVED_SETTINGS[name]
628
+ }));
629
+ }
630
+ });
631
+ var canvas, mainControls, wrapper, addRowGroup, addContainerGroup, layoutDropdown, htmlTextArea;
632
+ var curView = settings.default_view;
633
+ var confirmDialog = null;
634
+ var sizePicker = null;
635
+ var sourceOpen = false;
636
+ var dropMarker = null;
637
+ var warnedHere = {};
638
+ var sortables = [];
639
+ var instanceId = ++editorCounter;
640
+ var destroyed = false;
641
+ var detailsFor = /* @__PURE__ */ new WeakMap();
642
+ var moves = /* @__PURE__ */ new WeakMap();
643
+ var resizes = /* @__PURE__ */ new WeakMap();
644
+ var sectionNodes = /* @__PURE__ */ new WeakMap();
645
+ var editableLabels = /* @__PURE__ */ new WeakSet();
646
+ var lifetime = new AbortController();
647
+ canvas = addClass(baseElem, "ge-canvas");
648
+ function warnOnceHere(key, message) {
649
+ if (warnedHere[key]) {
650
+ return;
651
+ }
652
+ warnedHere[key] = true;
653
+ warn(message);
654
+ }
655
+ function t(key, params) {
656
+ return translate(settings, key, params);
657
+ }
658
+ function setLocale(code) {
659
+ settings.locale = code;
660
+ instance.settings = settingsCopy();
661
+ removeConfirmModal();
662
+ removeSettingsPanels();
663
+ mainControls.remove();
664
+ createMainControls();
665
+ reset();
666
+ }
667
+ var operationDepth = 0;
668
+ var deferredWork = [];
669
+ function payloadFor(kind, node, extra) {
670
+ return Object.assign({
671
+ kind,
672
+ node,
673
+ parent: node.parentElement,
674
+ canvas,
675
+ breakpoint: getView(),
676
+ source: "api"
677
+ }, extra || {});
678
+ }
679
+ function emit(name, payload) {
680
+ var names = [name];
681
+ var generic = name.replace(/^(before|after)-add-.+$/, "$1-add");
682
+ if (generic !== name) {
683
+ names.push(generic);
684
+ }
685
+ var canceled = false;
686
+ names.forEach(function(eventName) {
687
+ var event = new CustomEvent("grideditor:" + eventName, {
688
+ detail: payload,
689
+ bubbles: true,
690
+ cancelable: true
691
+ });
692
+ if (!canvas.dispatchEvent(event)) {
693
+ canceled = true;
694
+ }
695
+ });
696
+ names.forEach(function(eventName) {
697
+ var callback = settings.callbacks[eventName.replace(/-/g, "_")];
698
+ if (typeof callback == "function" && callback(payload) === false) {
699
+ canceled = true;
700
+ }
701
+ });
702
+ return !canceled;
703
+ }
704
+ function operate(body) {
705
+ operationDepth++;
706
+ try {
707
+ return body();
708
+ } finally {
709
+ operationDepth--;
710
+ if (operationDepth === 0) {
711
+ while (deferredWork.length) {
712
+ deferredWork.shift()();
713
+ }
714
+ }
715
+ }
716
+ }
717
+ function defer(work) {
718
+ if (operationDepth === 0) {
719
+ work();
720
+ return;
721
+ }
722
+ deferredWork.push(work);
723
+ }
724
+ function addNode(kind, node, insert, extra) {
725
+ var name = addEventName(kind);
726
+ return operate(function() {
727
+ var payload = payloadFor(kind, node, extra);
728
+ if (!emit("before-add-" + name, payload)) {
729
+ return null;
730
+ }
731
+ insert();
732
+ init();
733
+ emit("after-add-" + name, payload);
734
+ return node;
735
+ });
736
+ }
737
+ function addEventName(kind) {
738
+ return GridEditor.containers[kind] ? "container" : kind;
739
+ }
740
+ function askToDelete(message, whenConfirmed) {
741
+ if (!settings.confirm_delete) {
742
+ whenConfirmed();
743
+ return;
744
+ }
745
+ var Modal = modalLibrary();
746
+ if (!Modal) {
747
+ if (window.confirm(message)) {
748
+ whenConfirmed();
749
+ }
750
+ return;
751
+ }
752
+ var modal = confirmModal();
753
+ var confirmed = false;
754
+ one(modal, ".ge-confirm-message").textContent = message;
755
+ one(modal, ".ge-confirm-ok").onclick = function() {
756
+ confirmed = true;
757
+ Modal.getInstance(modal).hide();
758
+ };
759
+ confirmHandlers.hidden = function() {
760
+ if (confirmed) {
761
+ whenConfirmed();
762
+ }
763
+ };
764
+ confirmHandlers.shown = function() {
765
+ one(modal, ".ge-confirm-ok").focus();
766
+ };
767
+ Modal.getOrCreateInstance(modal).show();
768
+ }
769
+ var confirmHandlers = { hidden: null, shown: null };
770
+ function confirmModal() {
771
+ if (confirmDialog) {
772
+ return confirmDialog;
773
+ }
774
+ confirmDialog = create(
775
+ '<div class="modal fade ge-confirm" tabindex="-1" aria-hidden="true"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h5 class="modal-title"></h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body"><p class="ge-confirm-message"></p></div><div class="modal-footer"><button type="button" class="btn btn-secondary ge-confirm-cancel" data-bs-dismiss="modal"></button><button type="button" class="btn btn-danger ge-confirm-ok"></button></div></div></div></div>'
776
+ );
777
+ document.body.appendChild(confirmDialog);
778
+ one(confirmDialog, ".modal-title").textContent = t("confirm.title");
779
+ one(confirmDialog, ".btn-close").setAttribute("aria-label", t("confirm.cancel"));
780
+ one(confirmDialog, ".ge-confirm-cancel").textContent = t("confirm.cancel");
781
+ one(confirmDialog, ".ge-confirm-ok").textContent = t("confirm.ok");
782
+ trackModal(confirmDialog);
783
+ confirmDialog.addEventListener("hidden.bs.modal", function() {
784
+ if (confirmHandlers.hidden) {
785
+ confirmHandlers.hidden();
786
+ }
787
+ });
788
+ confirmDialog.addEventListener("shown.bs.modal", function() {
789
+ if (confirmHandlers.shown) {
790
+ confirmHandlers.shown();
791
+ }
792
+ });
793
+ return confirmDialog;
794
+ }
795
+ function removeConfirmModal() {
796
+ if (!confirmDialog) {
797
+ return;
798
+ }
799
+ confirmHandlers.hidden = null;
800
+ confirmHandlers.shown = null;
801
+ retireModal(confirmDialog);
802
+ confirmDialog = null;
803
+ }
804
+ function retireModal(panel) {
805
+ var Modal = modalLibrary();
806
+ var modal = Modal ? Modal.getInstance(panel) : null;
807
+ var gone = false;
808
+ var finish = function() {
809
+ if (gone) {
810
+ return;
811
+ }
812
+ gone = true;
813
+ if (modal) {
814
+ modal.dispose();
815
+ }
816
+ panel.remove();
817
+ };
818
+ if (!modal || !modalMoving.get(panel) && !hasClass(panel, "show")) {
819
+ finish();
820
+ return;
821
+ }
822
+ panel.addEventListener("hidden.bs.modal", finish, { once: true });
823
+ panel.addEventListener("shown.bs.modal", function() {
824
+ modal.hide();
825
+ }, { once: true });
826
+ modal.hide();
827
+ }
828
+ var modalMoving = /* @__PURE__ */ new WeakMap();
829
+ function trackModal(panel) {
830
+ on(panel, "show.bs.modal hide.bs.modal", function() {
831
+ modalMoving.set(panel, true);
832
+ });
833
+ on(panel, "shown.bs.modal hidden.bs.modal", function() {
834
+ modalMoving.set(panel, false);
835
+ });
836
+ }
837
+ function deleteNode(kind, node, message, animate) {
838
+ operate(function() {
839
+ var payload = payloadFor(kind, node, { source: "tool" });
840
+ if (!emit("before-delete", payload)) {
841
+ return;
842
+ }
843
+ askToDelete(message, function() {
844
+ operate(function() {
845
+ animate(function() {
846
+ node.remove();
847
+ operate(function() {
848
+ init();
849
+ emit("after-delete", payload);
850
+ });
851
+ });
852
+ });
853
+ });
854
+ });
855
+ }
856
+ function planSize(col, size, view) {
857
+ view = view || curView;
858
+ if (view !== ALL_VIEW) {
859
+ var tier = breakpoint(view);
860
+ var wanted = clamp({ size, offset: getEffectiveOffset(col, tier) || 0 });
861
+ if (wanted.refused || getSize(col, tier) === wanted.size) {
862
+ return null;
863
+ }
864
+ return { writes: [{ tier, size: wanted.size }], cleared: null, size: wanted.size };
865
+ }
866
+ var refused = BREAKPOINTS.some(function(each) {
867
+ return clamp({ size, offset: getEffectiveOffset(col, each) || 0 }).refused;
868
+ });
869
+ if (refused) {
870
+ return null;
871
+ }
872
+ var base = BREAKPOINTS[0];
873
+ var writes = [];
874
+ var cleared = [];
875
+ BREAKPOINTS.slice(1).forEach(function(each) {
876
+ var own2 = getSize(col, each);
877
+ if (own2 === null) {
878
+ return;
879
+ }
880
+ writes.push({ tier: each, size: null });
881
+ cleared.push({ breakpoint: each.key, value: own2 });
882
+ });
883
+ if (getSize(col, base) !== size) {
884
+ writes.unshift({ tier: base, size });
885
+ }
886
+ return writes.length ? { writes, cleared, size } : null;
887
+ }
888
+ function writeSize(col, plan) {
889
+ plan.writes.forEach(function(write) {
890
+ setSize(col, write.tier, write.size);
891
+ });
892
+ stripPixelWidths(col);
893
+ }
894
+ function withCleared(extra, cleared) {
895
+ if (cleared) {
896
+ extra.cleared = cleared;
897
+ }
898
+ return extra;
899
+ }
900
+ function resizeColumn(col, size, source, view) {
901
+ view = view || curView;
902
+ var from = currentSize(col);
903
+ var plan = planSize(col, size, view);
904
+ if (!plan) {
905
+ return false;
906
+ }
907
+ return operate(function() {
908
+ var payload = payloadFor("column", col, withCleared({
909
+ source,
910
+ breakpoint: view,
911
+ from,
912
+ to: plan.size
913
+ }, plan.cleared));
914
+ if (!emit("before-resize", payload)) {
915
+ refreshUtilities(col);
916
+ return false;
917
+ }
918
+ writeSize(col, plan);
919
+ refreshUtilities(col);
920
+ emit("after-resize", payload);
921
+ return true;
922
+ });
923
+ }
924
+ function indentColumn(col, offset2, source) {
925
+ var everywhere = curView === ALL_VIEW;
926
+ var tier = everywhere ? BREAKPOINTS[0] : breakpoint(curView);
927
+ var from = currentOffset(col);
928
+ offset2 = Math.min(Math.max(offset2, 0), MAX_COL_OFFSET);
929
+ var others = everywhere ? BREAKPOINTS.slice(1).filter(function(each) {
930
+ return getOffset(col, each) !== null;
931
+ }) : [];
932
+ if ((getOffset(col, tier) || 0) === offset2 && !others.length) {
933
+ return false;
934
+ }
935
+ return operate(function() {
936
+ var payload = payloadFor("column", col, withCleared({
937
+ source,
938
+ from,
939
+ to: offset2
940
+ }, everywhere ? others.map(function(each) {
941
+ return { breakpoint: each.key, value: getOffset(col, each) };
942
+ }) : null));
943
+ if (!emit("before-indent", payload)) {
944
+ return false;
945
+ }
946
+ setOffset(col, tier, offset2);
947
+ others.forEach(function(each) {
948
+ setOffset(col, each, 0);
949
+ });
950
+ (everywhere ? BREAKPOINTS : [tier]).forEach(function(each) {
951
+ var was = getEffectiveSize(col, each);
952
+ if (!isUnits(was)) {
953
+ return;
954
+ }
955
+ var wanted = clamp({ size: was, offset: offset2, leading: "offset" });
956
+ if (wanted.size !== was) {
957
+ setSize(col, each, wanted.size);
958
+ }
959
+ });
960
+ refreshUtilities(col);
961
+ emit("after-indent", payload);
962
+ return true;
963
+ });
964
+ }
965
+ function positionOf(node) {
966
+ var parent = node.parentElement;
967
+ return {
968
+ parent,
969
+ index: children(parent).filter(function(child2) {
970
+ return !hasClass(child2, "ge-tools-drawer");
971
+ }).indexOf(node)
972
+ };
973
+ }
974
+ function kindOf(node) {
975
+ var fromPlugin = null;
976
+ Object.keys(FEATURES).forEach(function(name) {
977
+ var feature = FEATURES[name];
978
+ if (!fromPlugin && feature.kindOf) {
979
+ fromPlugin = feature.kindOf(node);
980
+ }
981
+ });
982
+ if (fromPlugin) {
983
+ return fromPlugin;
984
+ }
985
+ if (node.getAttribute("data-ge-container")) {
986
+ return node.getAttribute("data-ge-container");
987
+ }
988
+ if (hasClass(node, "ge-tab")) {
989
+ return "tab";
990
+ }
991
+ if (hasClass(node, "ge-accordion-item")) {
992
+ return "accordion-item";
993
+ }
994
+ if (hasClass(node, "row")) {
995
+ return "row";
996
+ }
997
+ if (hasClass(node, "column")) {
998
+ return "column";
999
+ }
1000
+ if (hasClass(node, "ge-element")) {
1001
+ return "element";
1002
+ }
1003
+ if (hasClass(node, "ge-text-block")) {
1004
+ node = child(node, ".ge-content") || node;
1005
+ }
1006
+ if (hasClass(node, "ge-content")) {
1007
+ return node.getAttribute("data-ge-content-type") ? "text" : "plain";
1008
+ }
1009
+ return "node";
1010
+ }
1011
+ if (settings.source_textarea) {
1012
+ var sourceHtml = nodeFrom(settings.source_textarea).value;
1013
+ var probe = element("div");
1014
+ probe.innerHTML = sourceHtml;
1015
+ if (sourceHtml.length > 0 && !probe.querySelector(".row")) {
1016
+ sourceHtml = '<div class="row"><div class="col-lg-12">' + sourceHtml + "</div></div>";
1017
+ }
1018
+ setHtml(baseElem, sourceHtml);
1019
+ }
1020
+ if (baseElem.children.length && !baseElem.querySelector("div.row")) {
1021
+ var children2 = children(baseElem);
1022
+ var newRow = create('<div class="row"><div class="col-lg-12"></div></div>');
1023
+ baseElem.appendChild(newRow);
1024
+ children2.forEach(function(child2) {
1025
+ newRow.firstChild.appendChild(child2);
1026
+ });
1027
+ }
1028
+ function setup() {
1029
+ htmlTextArea = element("textarea", { "class": "ge-html-output" });
1030
+ canvas.parentNode.insertBefore(htmlTextArea, canvas);
1031
+ createMainControls();
1032
+ var signal = { signal: lifetime.signal };
1033
+ window.addEventListener("scroll", onScroll, signal);
1034
+ delegate(canvas, "click", ".ge-content", onContentClick, signal);
1035
+ delegate(canvas, "click", ".ge-popup-trigger, [data-ge-popup-target]", function(e) {
1036
+ if (hasClass(canvas, "ge-editing")) {
1037
+ e.preventDefault();
1038
+ }
1039
+ }, signal);
1040
+ }
1041
+ function textReady(block) {
1042
+ if (!is(block, ".ge-content") || !canvas.contains(block)) {
1043
+ return;
1044
+ }
1045
+ plugins("onContentReady", block);
1046
+ refreshPreviews(block);
1047
+ }
1048
+ function createMainControls() {
1049
+ mainControls = element("div", { "class": "ge-mainControls" });
1050
+ htmlTextArea.parentNode.insertBefore(mainControls, htmlTextArea);
1051
+ wrapper = mainControls.appendChild(element("div", { "class": "ge-wrapper ge-top" }));
1052
+ addRowGroup = wrapper.appendChild(element("div", { "class": "ge-addRowGroup btn-group" }));
1053
+ addContainerGroup = element("div", { "class": "ge-addContainerGroup btn-group ms-1" });
1054
+ settings.new_row_layouts.forEach(function(layout) {
1055
+ var grouped = !Array.isArray(layout);
1056
+ var btn = element("a", {
1057
+ "class": "btn btn-sm btn-primary",
1058
+ title: grouped ? t("row.add_row_cols", { columns: layout.columns, counts: rowColsText(layout.row_cols) }) : t("row.add", { layout: layout.join("-") }),
1059
+ // What this button makes, in the markup rather than in
1060
+ // memory: a drag works on a clone of it
1061
+ "data-ge-toolbar": "row",
1062
+ "data-ge-layout": grouped ? JSON.stringify(layout) : layout.join(",")
1063
+ });
1064
+ btn.addEventListener("click", function() {
1065
+ var row = rowFromLayoutValue(layout);
1066
+ var added = addNode("row", row, function() {
1067
+ canvas.appendChild(row);
1068
+ }, { parent: canvas, source: "tool" });
1069
+ if (added && row.scrollIntoView) {
1070
+ row.scrollIntoView({ behavior: "smooth" });
1071
+ }
1072
+ });
1073
+ addRowGroup.appendChild(btn);
1074
+ btn.appendChild(create('<i class="bi bi-plus"></i>'));
1075
+ var sizes = grouped ? rowColsIcon(layout) : layout;
1076
+ var icon = '<div class="row ge-row-icon">';
1077
+ sizes.forEach(function(size) {
1078
+ icon += '<div class="column ' + sizeClass(BREAKPOINTS[0], size) + '"></div>';
1079
+ });
1080
+ icon += "</div>";
1081
+ btn.appendChild(create(icon));
1082
+ });
1083
+ wrapper.appendChild(addContainerGroup);
1084
+ Object.keys(CONTAINERS).forEach(function(type) {
1085
+ var definition = CONTAINERS[type];
1086
+ var button = labelButton(
1087
+ element("a", { "class": "btn btn-sm btn-primary ge-add-container" }),
1088
+ t(definition.labelKey),
1089
+ definition.iconClass
1090
+ );
1091
+ attr(button, { "data-ge-toolbar": "container", "data-ge-container-type": type });
1092
+ button.addEventListener("click", function() {
1093
+ var row = createRow();
1094
+ var column = row.appendChild(createColumn(MAX_COL_SIZE));
1095
+ var container = column.appendChild(definition.create({}));
1096
+ addNode(type, container, function() {
1097
+ canvas.appendChild(row);
1098
+ }, { parent: canvas, source: "tool" });
1099
+ });
1100
+ addContainerGroup.appendChild(button);
1101
+ });
1102
+ var endItems = [];
1103
+ Object.keys(FEATURES).forEach(function(name) {
1104
+ (FEATURES[name].toolbar || []).forEach(function(item, index) {
1105
+ var button = featureButton(name, item, index);
1106
+ if (item.align === "end") {
1107
+ endItems.push(button);
1108
+ } else {
1109
+ addContainerGroup.appendChild(button);
1110
+ }
1111
+ });
1112
+ });
1113
+ layoutDropdown = create('<div class="dropdown pull-right ge-layout-mode"><button type="button" class="btn btn-sm btn-primary dropdown-toggle" data-bs-toggle="dropdown"></button><div class="dropdown-menu" role="menu"></div></div>');
1114
+ delegate(layoutDropdown, "click", "a", function() {
1115
+ changeView(this.getAttribute("data-ge-view"));
1116
+ });
1117
+ wrapper.appendChild(layoutDropdown);
1118
+ settings.layout_modes.forEach(function(view) {
1119
+ one(layoutDropdown, ".dropdown-menu").appendChild(element("a", {
1120
+ "class": "dropdown-item",
1121
+ "data-ge-view": view,
1122
+ title: t(labelKeyFor(view))
1123
+ }, t(labelKeyFor(view))));
1124
+ });
1125
+ one(layoutDropdown, "button").textContent = t(labelKeyFor(curView));
1126
+ var btnGroup = wrapper.appendChild(element("div", { "class": "btn-group pull-right" }));
1127
+ if (settings.edit_source) {
1128
+ var htmlButton = create('<button type="button" class="btn btn-sm btn-primary gm-edit-mode"><i class="bi bi-code-slash"></i></button>');
1129
+ htmlButton.setAttribute("title", t("tool.edit_source"));
1130
+ toggleClass(htmlButton, "active btn-danger", sourceOpen);
1131
+ htmlButton.addEventListener("click", function() {
1132
+ if (sourceOpen) {
1133
+ closeSource();
1134
+ } else {
1135
+ openSource();
1136
+ }
1137
+ toggleClass(htmlButton, "active btn-danger", sourceOpen);
1138
+ });
1139
+ btnGroup.appendChild(htmlButton);
1140
+ }
1141
+ var previewButton = create('<button type="button" class="btn btn-sm btn-primary gm-preview"><i class="bi bi-eye-fill"></i></button>');
1142
+ var endPreview = function() {
1143
+ if (!hasClass(previewButton, "active")) {
1144
+ addClass(canvas, "ge-editing");
1145
+ }
1146
+ };
1147
+ previewButton.setAttribute("title", t("tool.preview"));
1148
+ previewButton.addEventListener("mouseenter", function() {
1149
+ removeClass(canvas, "ge-editing");
1150
+ });
1151
+ previewButton.addEventListener("click", function() {
1152
+ toggleClass(previewButton, "active btn-danger");
1153
+ endPreview();
1154
+ });
1155
+ previewButton.addEventListener("mouseleave", endPreview);
1156
+ btnGroup.appendChild(previewButton);
1157
+ if (endItems.length) {
1158
+ var end = wrapper.appendChild(element("div", { "class": "pull-right ge-toolbar-end" }));
1159
+ endItems.forEach(function(button) {
1160
+ end.appendChild(button);
1161
+ });
1162
+ }
1163
+ makeToolbarDraggable();
1164
+ }
1165
+ function labelButton(button, label, iconClass) {
1166
+ button.setAttribute("title", label);
1167
+ if (iconClass) {
1168
+ button.appendChild(element("i", { "class": iconClass }));
1169
+ return button;
1170
+ }
1171
+ button.appendChild(create('<i class="bi bi-plus"></i>'));
1172
+ button.appendChild(element("span", {}, label));
1173
+ return button;
1174
+ }
1175
+ function featureButton(name, item, index) {
1176
+ var iconClass = item.iconClass || (item.align === "end" ? "bi bi-plus" : null);
1177
+ var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
1178
+ var button = labelButton(element("a", { "class": "btn btn-sm btn-primary ge-add-container ge-add-feature" }), label, iconClass);
1179
+ addClass(button, item.className || "");
1180
+ attr(button, {
1181
+ "data-ge-toolbar": "feature",
1182
+ "data-ge-feature": name,
1183
+ "data-ge-item": index
1184
+ });
1185
+ button.addEventListener("click", function() {
1186
+ var made = item.create();
1187
+ var placed = item.inColumn ? inRowOfItsOwn(made) : made;
1188
+ var added = addNode(item.kind, made, function() {
1189
+ canvas.appendChild(placed);
1190
+ }, { parent: canvas, source: item.source || "tool" });
1191
+ if (added && item.inColumn && placed.scrollIntoView) {
1192
+ placed.scrollIntoView({ behavior: "smooth" });
1193
+ }
1194
+ });
1195
+ return button;
1196
+ }
1197
+ function toolbarDrags() {
1198
+ if (settings.toolbar_drag === "auto") {
1199
+ return settings.drag_handle === "drawer";
1200
+ }
1201
+ return !!settings.toolbar_drag;
1202
+ }
1203
+ function makeToolbarDraggable() {
1204
+ var buttons = all(mainControls, "[data-ge-toolbar]");
1205
+ buttons.forEach(function(button) {
1206
+ removeClass(button, "ge-palette-button");
1207
+ button.removeEventListener("pointerdown", startToolbarDrag);
1208
+ });
1209
+ if (!toolbarDrags()) {
1210
+ return;
1211
+ }
1212
+ buttons.forEach(function(button) {
1213
+ addClass(button, "ge-palette-button");
1214
+ button.addEventListener("pointerdown", startToolbarDrag);
1215
+ });
1216
+ }
1217
+ function startToolbarDrag(e) {
1218
+ var button = e.currentTarget;
1219
+ var startX = e.pageX;
1220
+ var startY = e.pageY;
1221
+ var helper = null;
1222
+ if (e.button) {
1223
+ return;
1224
+ }
1225
+ function far(move) {
1226
+ return Math.abs(move.pageX - startX) + Math.abs(move.pageY - startY) > settings.drag.threshold;
1227
+ }
1228
+ function onMove(move) {
1229
+ if (!helper) {
1230
+ if (!far(move)) {
1231
+ return;
1232
+ }
1233
+ helper = addClass(button.cloneNode(true), "ge-toolbar-helper");
1234
+ document.body.appendChild(helper);
1235
+ addClass(canvas, "ge-dropping");
1236
+ }
1237
+ css(helper, { left: move.pageX - 14, top: move.pageY - 14 });
1238
+ showDropMarker(move.pageX, move.pageY);
1239
+ }
1240
+ function onUp(up) {
1241
+ document.removeEventListener("pointermove", onMove);
1242
+ off(document, "pointerup pointercancel", onUp);
1243
+ if (!helper) {
1244
+ return;
1245
+ }
1246
+ helper.remove();
1247
+ removeClass(canvas, "ge-dropping");
1248
+ hideDropMarker();
1249
+ var swallow = function(click) {
1250
+ if (click.target !== button && !button.contains(click.target)) {
1251
+ return;
1252
+ }
1253
+ click.preventDefault();
1254
+ click.stopImmediatePropagation();
1255
+ };
1256
+ window.addEventListener("click", swallow, { capture: true, once: true });
1257
+ window.setTimeout(function() {
1258
+ window.removeEventListener("click", swallow, { capture: true });
1259
+ }, 0);
1260
+ var where = dropPlaceAt(up.pageX, up.pageY);
1261
+ if (where) {
1262
+ insertFromToolbar(button, where);
1263
+ }
1264
+ }
1265
+ document.addEventListener("pointermove", onMove);
1266
+ on(document, "pointerup pointercancel", onUp);
1267
+ }
1268
+ function dropPlaceAt(pageX, pageY) {
1269
+ var x = pageX - window.scrollX;
1270
+ var y = pageY - window.scrollY;
1271
+ var under = document.elementFromPoint(x, y);
1272
+ if (!under) {
1273
+ return null;
1274
+ }
1275
+ var region = closest(under, [".column", ".ge-canvas"].concat(pluginHooks("regions")).join(", "));
1276
+ if (!region || region !== canvas && !canvas.contains(region)) {
1277
+ return null;
1278
+ }
1279
+ var before = null;
1280
+ children(region, blockSelector()).forEach(function(block) {
1281
+ if (before) {
1282
+ return;
1283
+ }
1284
+ var box = block.getBoundingClientRect();
1285
+ if (y < box.top + box.height / 2) {
1286
+ before = block;
1287
+ }
1288
+ });
1289
+ return { region, before };
1290
+ }
1291
+ function insertFeatureFromToolbar(button, where) {
1292
+ var item = FEATURES[button.getAttribute("data-ge-feature")].toolbar[parseInt(button.getAttribute("data-ge-item"), 10)];
1293
+ var made = item.create();
1294
+ var placed = made;
1295
+ if (item.inColumn) {
1296
+ if (!is(where.region, ".column")) {
1297
+ placed = inRowOfItsOwn(made);
1298
+ }
1299
+ } else if (!acceptsBlock(where.region, made)) {
1300
+ var ancestors = where.region === canvas ? [] : parentsUntil(where.region, canvas).reverse().concat([where.region]);
1301
+ var top = ancestors[0] || null;
1302
+ where = { region: canvas, before: top ? top.nextElementSibling : null };
1303
+ }
1304
+ return addNode(item.kind, made, function() {
1305
+ if (where.before) {
1306
+ where.before.parentNode.insertBefore(placed, where.before);
1307
+ } else {
1308
+ where.region.appendChild(placed);
1309
+ }
1310
+ }, { parent: where.region, source: item.source || "dragdrop" });
1311
+ }
1312
+ function inRowOfItsOwn(node) {
1313
+ var row = createRow();
1314
+ row.appendChild(createColumn(MAX_COL_SIZE)).appendChild(node);
1315
+ return row;
1316
+ }
1317
+ function showDropMarker(pageX, pageY) {
1318
+ var where = dropPlaceAt(pageX, pageY);
1319
+ if (!where) {
1320
+ return hideDropMarker();
1321
+ }
1322
+ if (!dropMarker) {
1323
+ dropMarker = element("div", { "class": "ge-drop-marker" });
1324
+ }
1325
+ if (where.before) {
1326
+ where.before.parentNode.insertBefore(dropMarker, where.before);
1327
+ } else {
1328
+ where.region.appendChild(dropMarker);
1329
+ }
1330
+ return void 0;
1331
+ }
1332
+ function hideDropMarker() {
1333
+ if (dropMarker) {
1334
+ dropMarker.remove();
1335
+ }
1336
+ }
1337
+ function insertFromToolbar(button, where) {
1338
+ if (button.getAttribute("data-ge-toolbar") === "feature") {
1339
+ return insertFeatureFromToolbar(button, where);
1340
+ }
1341
+ var container = button.getAttribute("data-ge-toolbar") === "container";
1342
+ var type = button.getAttribute("data-ge-container-type");
1343
+ var made = container ? CONTAINERS[type].create({}) : rowFromLayout(button.getAttribute("data-ge-layout"));
1344
+ var placed = made;
1345
+ if (container && !is(where.region, ".column")) {
1346
+ placed = inRowOfItsOwn(made);
1347
+ }
1348
+ return addNode(container ? type : "row", made, function() {
1349
+ if (where.before) {
1350
+ where.before.parentNode.insertBefore(placed, where.before);
1351
+ } else {
1352
+ where.region.appendChild(placed);
1353
+ }
1354
+ }, { parent: where.region, source: "dragdrop" });
1355
+ }
1356
+ function widthFamily() {
1357
+ var values = [];
1358
+ for (var units = 1; units <= MAX_COL_SIZE; units++) {
1359
+ values.push(String(units));
1360
+ }
1361
+ return {
1362
+ name: "col",
1363
+ values: values.concat(FLEX_SIZES),
1364
+ appliesTo: ["column"],
1365
+ labelKey: "utility.col_width",
1366
+ className: function(key, value) {
1367
+ return sizeClass(breakpoint(key), parseSize(value));
1368
+ },
1369
+ choices: function() {
1370
+ return settings.valid_col_sizes.map(String);
1371
+ },
1372
+ label: function(value) {
1373
+ if (value === "equal") {
1374
+ return t("utility.col_equal");
1375
+ }
1376
+ if (value === "auto") {
1377
+ return t("utility.col_auto");
1378
+ }
1379
+ return value;
1380
+ },
1381
+ write: function(col, value, view, source) {
1382
+ return resizeColumn(col, value === null ? null : parseSize(value), source, view);
1383
+ },
1384
+ // With no size of its own, a column in a row with row-cols
1385
+ // takes its share from the row, which the field says
1386
+ blank: function(col, view) {
1387
+ var winner = view === ALL_VIEW ? null : rowColsWinner(col, breakpoint(view));
1388
+ return winner ? t("utility.col_from_row", { count: rowColsLabel(winner.value) }) : null;
1389
+ }
1390
+ };
1391
+ }
1392
+ function parseSize(size) {
1393
+ return /^\d+$/.test(String(size)) ? parseInt(size, 10) : size;
1394
+ }
1395
+ function rowFromLayout(layout) {
1396
+ if (/^\s*\{/.test(layout || "")) {
1397
+ return rowFromLayoutValue(JSON.parse(layout));
1398
+ }
1399
+ return rowFromLayoutValue((layout || "").split(",").filter(function(size) {
1400
+ return size !== "";
1401
+ }).map(parseSize));
1402
+ }
1403
+ function rowFromLayoutValue(layout) {
1404
+ var row = createRow();
1405
+ if (Array.isArray(layout)) {
1406
+ layout.forEach(function(size) {
1407
+ row.appendChild(createColumn(size));
1408
+ });
1409
+ return row;
1410
+ }
1411
+ Object.keys(layout.row_cols || {}).forEach(function(key) {
1412
+ var value = layout.row_cols[key];
1413
+ var tier = breakpoint(key);
1414
+ if (tier && ROW_COLS_VALUES.indexOf(String(value)) !== -1) {
1415
+ addClass(row, rowColsClass(tier, value));
1416
+ }
1417
+ });
1418
+ for (var i = 0; i < (layout.columns || 0); i++) {
1419
+ row.appendChild(createColumn(null));
1420
+ }
1421
+ return row;
1422
+ }
1423
+ function rowColsText(counts) {
1424
+ return BREAKPOINTS.filter(function(tier) {
1425
+ return counts && counts[tier.key] !== void 0;
1426
+ }).map(function(tier) {
1427
+ return (tier.infix ? tier.key + ": " : "") + counts[tier.key];
1428
+ }).join(", ");
1429
+ }
1430
+ function rowColsIcon(layout) {
1431
+ var widest = 1;
1432
+ Object.keys(layout.row_cols || {}).forEach(function(key) {
1433
+ var value = layout.row_cols[key];
1434
+ if (value !== "auto") {
1435
+ widest = Math.max(widest, parseInt(value, 10) || 1);
1436
+ }
1437
+ });
1438
+ return Array.apply(null, Array(Math.min(widest, layout.columns || widest))).map(function() {
1439
+ return "equal";
1440
+ });
1441
+ }
1442
+ function onScroll() {
1443
+ var scrollTop = window.pageYOffset;
1444
+ if (scrollTop > offset(mainControls).top && scrollTop < offset(canvas).top + contentHeight(canvas)) {
1445
+ if (hasClass(wrapper, "ge-top")) {
1446
+ css(wrapper, {
1447
+ left: offset(wrapper).left,
1448
+ width: outerWidth(wrapper)
1449
+ });
1450
+ removeClass(wrapper, "ge-top");
1451
+ addClass(wrapper, "ge-fixed");
1452
+ }
1453
+ } else {
1454
+ if (hasClass(wrapper, "ge-fixed")) {
1455
+ css(wrapper, { left: "", width: "" });
1456
+ removeClass(wrapper, "ge-fixed");
1457
+ addClass(wrapper, "ge-top");
1458
+ }
1459
+ }
1460
+ }
1461
+ function onContentClick() {
1462
+ var block = this;
1463
+ if (block.getAttribute("data-ge-content-type")) {
1464
+ return;
1465
+ }
1466
+ if (closeSizePicker()) {
1467
+ return;
1468
+ }
1469
+ if (!visible(block)) {
1470
+ return;
1471
+ }
1472
+ var offers = textOffers();
1473
+ if (!offers.length) {
1474
+ return;
1475
+ }
1476
+ if (offers.length === 1) {
1477
+ convertPlain(block, offers[0]);
1478
+ } else {
1479
+ openConvertPicker(block, offers);
1480
+ }
1481
+ }
1482
+ function convertPlain(block, offer) {
1483
+ if (offer.available && !offer.available()) {
1484
+ if (offer.missingKey) {
1485
+ console.error(t(offer.missingKey));
1486
+ }
1487
+ return false;
1488
+ }
1489
+ return operate(function() {
1490
+ var payload = payloadFor("plain", block, { source: "tool", from: "plain", to: offer.type });
1491
+ if (!emit("before-convert", payload)) {
1492
+ return false;
1493
+ }
1494
+ addClass(block, "ge-content-type-" + offer.type);
1495
+ block.setAttribute("data-ge-content-type", offer.type);
1496
+ var textBlock = block.parentElement;
1497
+ if (hasClass(textBlock, "ge-text-block")) {
1498
+ removeClass(textBlock, "ge-plain-block");
1499
+ children(textBlock, ".ge-tools-drawer").forEach(function(drawer) {
1500
+ drawer.remove();
1501
+ });
1502
+ }
1503
+ emit("after-convert", payload);
1504
+ offer.edit(block);
1505
+ return true;
1506
+ });
1507
+ }
1508
+ function openConvertPicker(block, offers) {
1509
+ var textBlock = hasClass(block.parentElement, "ge-text-block") ? block.parentElement : null;
1510
+ if (!textBlock) {
1511
+ return;
1512
+ }
1513
+ openPicker(child(textBlock, ".ge-tools-drawer"), offers.map(function(offer) {
1514
+ return {
1515
+ label: offer.label,
1516
+ title: t("tool.convert_type", { editor: offer.label }),
1517
+ attributes: { "data-ge-content-type": offer.type },
1518
+ choose: function() {
1519
+ convertPlain(block, offer);
1520
+ }
1521
+ };
1522
+ }), "ge-text-picker ge-convert-picker", textBlock);
1523
+ }
1524
+ function openPicker(anchor, choices, className, hover) {
1525
+ closeSizePicker();
1526
+ if (!anchor) {
1527
+ return;
1528
+ }
1529
+ var drawer = closest(anchor, ".ge-tools-drawer");
1530
+ if (drawer) {
1531
+ addClass(drawer, "ge-picker-open");
1532
+ }
1533
+ sizePicker = anchor.appendChild(addClass(element("div", { "class": "ge-size-picker" }), className || ""));
1534
+ choices.forEach(function(choice) {
1535
+ var button = attr(element("a", { "class": "ge-size ge-size-flex" }), choice.attributes || {});
1536
+ button.setAttribute("title", choice.title || choice.label);
1537
+ button.textContent = choice.label;
1538
+ button.addEventListener("click", function(e) {
1539
+ e.preventDefault();
1540
+ e.stopPropagation();
1541
+ closeSizePicker();
1542
+ choice.choose();
1543
+ });
1544
+ sizePicker.appendChild(button);
1545
+ });
1546
+ withdrawOnLeave(hover || anchor);
1547
+ }
1548
+ function withdrawOnLeave(node) {
1549
+ node.addEventListener("mouseleave", function() {
1550
+ window.setTimeout(function() {
1551
+ if (sizePicker && !sizePicker.matches(":hover")) {
1552
+ closeSizePicker();
1553
+ }
1554
+ }, 400);
1555
+ }, { once: true });
1556
+ }
1557
+ function textTypes() {
1558
+ var owners = {};
1559
+ var entries = [];
1560
+ Object.keys(FEATURES).forEach(function(name) {
1561
+ var feature = FEATURES[name];
1562
+ if (!feature.textTypes) {
1563
+ return;
1564
+ }
1565
+ (feature.textTypes() || []).forEach(function(entry) {
1566
+ if (owners[entry.type]) {
1567
+ if (owners[entry.type] !== name) {
1568
+ warnOnceHere("text-type:" + entry.type, 'the "' + name + '" plugin declares the text type "' + entry.type + '", which the "' + owners[entry.type] + '" plugin already declares: ignored');
1569
+ }
1570
+ return;
1571
+ }
1572
+ owners[entry.type] = name;
1573
+ entries.push(entry);
1574
+ });
1575
+ });
1576
+ return entries;
1577
+ }
1578
+ function textOffers() {
1579
+ return textTypes().filter(function(entry) {
1580
+ return entry.offered !== false;
1581
+ });
1582
+ }
1583
+ function hasTextOwner(type) {
1584
+ return textTypes().some(function(entry) {
1585
+ return entry.type === type;
1586
+ });
1587
+ }
1588
+ function reset() {
1589
+ deinit();
1590
+ init();
1591
+ }
1592
+ function openSource() {
1593
+ deinit();
1594
+ htmlTextArea.style.height = 0.8 * document.documentElement.clientHeight + "px";
1595
+ htmlTextArea.value = canvas.innerHTML;
1596
+ show(htmlTextArea);
1597
+ hide(canvas);
1598
+ sourceOpen = true;
1599
+ plugins("onSourceOpen", htmlTextArea);
1600
+ }
1601
+ function closeSource() {
1602
+ plugins("onSourceClose", htmlTextArea);
1603
+ sourceOpen = false;
1604
+ setHtml(canvas, htmlTextArea.value);
1605
+ show(canvas);
1606
+ init();
1607
+ hide(htmlTextArea);
1608
+ }
1609
+ function init() {
1610
+ if (openSettingsState && !attached(openSettingsState.node)) {
1611
+ closeSettings();
1612
+ }
1613
+ runFilter(true);
1614
+ addClass(canvas, "ge-editing");
1615
+ toggleClass(canvas, "ge-drag-drawer", settings.drag_handle === "drawer");
1616
+ addAllColClasses();
1617
+ var cutter = textCutter();
1618
+ splitTexts(cutter);
1619
+ wrapContent(cutter);
1620
+ wrapTexts();
1621
+ createRowControls();
1622
+ createColControls();
1623
+ markContainers();
1624
+ plugins("onInit");
1625
+ makeSortable();
1626
+ makeResizable();
1627
+ switchLayout(curView);
1628
+ refreshPreviews(canvas);
1629
+ }
1630
+ function deinit() {
1631
+ closeSettings();
1632
+ removeClass(canvas, "ge-editing ge-drag-drawer ge-dropping");
1633
+ plugins("onBeforeDeinit");
1634
+ closeSizePicker();
1635
+ hideDropMarker();
1636
+ all(canvas, ".ge-tools-drawer").forEach(function(drawer) {
1637
+ drawer.remove();
1638
+ });
1639
+ unwrapTexts();
1640
+ plugins("onDeinit");
1641
+ clearPreviews(canvas);
1642
+ all(canvas, "[data-ge-row-cols]").forEach(function(row) {
1643
+ row.removeAttribute("data-ge-row-cols");
1644
+ });
1645
+ unmarkContainers();
1646
+ removeSortable();
1647
+ removeResizable();
1648
+ runFilter(false);
1649
+ }
1650
+ function getHtml() {
1651
+ deinit();
1652
+ stripPixelWidths(canvas);
1653
+ var html = canvas.innerHTML;
1654
+ init();
1655
+ return html;
1656
+ }
1657
+ function nodeHtml(node) {
1658
+ deinit();
1659
+ stripPixelWidths(node);
1660
+ var html = node.outerHTML;
1661
+ init();
1662
+ return html;
1663
+ }
1664
+ function getPlainHtml() {
1665
+ return plainHtml(getHtml());
1666
+ }
1667
+ function destroy() {
1668
+ if (sourceOpen) {
1669
+ closeSource();
1670
+ }
1671
+ deinit();
1672
+ removeConfirmModal();
1673
+ removeSettingsPanels();
1674
+ mainControls.remove();
1675
+ htmlTextArea.remove();
1676
+ lifetime.abort();
1677
+ instances.delete(canvas);
1678
+ destroyed = true;
1679
+ }
1680
+ function loadPlugins() {
1681
+ var api = pluginApi();
1682
+ registerFamily("grid", {}, widthFamily());
1683
+ if (settings.row_cols !== false) {
1684
+ registerFamily("grid", {}, rowColsFamily());
1685
+ }
1686
+ var wanted = function(name) {
1687
+ return !settings.plugins || settings.plugins.indexOf(name) !== -1;
1688
+ };
1689
+ var featureWanted = function(name, factory) {
1690
+ return factory.always === true || wanted(name);
1691
+ };
1692
+ Object.keys(GridEditor.containers).forEach(function(type) {
1693
+ if (wanted(type)) {
1694
+ CONTAINERS[type] = GridEditor.containers[type](api);
1695
+ }
1696
+ });
1697
+ Object.keys(GridEditor.features).forEach(function(name) {
1698
+ var factory = GridEditor.features[name];
1699
+ if (featureWanted(name, factory)) {
1700
+ FEATURES[name] = factory(api);
1701
+ }
1702
+ });
1703
+ Object.keys(GridEditor.utilities).forEach(function(name) {
1704
+ if (!wanted(name)) {
1705
+ return;
1706
+ }
1707
+ UTILITIES[name] = GridEditor.utilities[name](api);
1708
+ (UTILITIES[name].families || []).forEach(function(family) {
1709
+ registerFamily(name, UTILITIES[name], family);
1710
+ });
1711
+ });
1712
+ Object.keys(FEATURES).forEach(function(name) {
1713
+ var methods = FEATURES[name].methods || {};
1714
+ Object.keys(methods).forEach(function(method) {
1715
+ featureMethods[method] = methods[method];
1716
+ });
1717
+ });
1718
+ (settings.plugins || []).forEach(function(name) {
1719
+ if (CONTAINERS[name] || FEATURES[name] || UTILITIES[name]) {
1720
+ return;
1721
+ }
1722
+ warnOnceHere("plugin:" + name, 'the "' + name + '" plugin is not loaded: include dist/plugins/grideditor.' + name + ".js after the editor");
1723
+ });
1724
+ }
1725
+ function plugins(hook, argument) {
1726
+ [CONTAINERS, FEATURES, UTILITIES].forEach(function(registry) {
1727
+ Object.keys(registry).forEach(function(name) {
1728
+ if (registry[name][hook]) {
1729
+ registry[name][hook](argument);
1730
+ }
1731
+ });
1732
+ });
1733
+ }
1734
+ function pluginApi() {
1735
+ return {
1736
+ canvas,
1737
+ settings,
1738
+ t,
1739
+ warn,
1740
+ containerId,
1741
+ defaultRegion,
1742
+ createTool,
1743
+ createMoveTool,
1744
+ addSettingsTool,
1745
+ deleteNode,
1746
+ place,
1747
+ createPaneControls,
1748
+ makeLabelEditable,
1749
+ labelIn,
1750
+ unwrapLabels,
1751
+ suspendToggles,
1752
+ resumeToggles,
1753
+ emit,
1754
+ payloadFor,
1755
+ operate,
1756
+ kindOf,
1757
+ view: getView,
1758
+ viewTiers: function() {
1759
+ return tiersFor(curView).map(function(tier) {
1760
+ return tier.key;
1761
+ });
1762
+ },
1763
+ breakpoints: BREAKPOINTS.map(function(tier) {
1764
+ return tier.key;
1765
+ }),
1766
+ getUtility,
1767
+ setUtility,
1768
+ utilityField,
1769
+ bareStyle,
1770
+ rowFromLayout: rowFromLayoutValue,
1771
+ nodeHtml,
1772
+ // A text editor has rewritten a content area, so whatever the
1773
+ // editor and its plugins had put in there goes back in
1774
+ textReady,
1775
+ // A choice under a tool, offered by holding it
1776
+ attachPicker,
1777
+ openPicker,
1778
+ closePicker: closeSizePicker,
1779
+ // A node's settings panel, in its drawer or open outside it
1780
+ detailsOf,
1781
+ // A node's drawer: its first child, or for a content area the
1782
+ // one beside it in its text block
1783
+ drawerOf,
1784
+ toolbarItems: function(name) {
1785
+ return mainControls ? all(mainControls, '[data-ge-toolbar="feature"][data-ge-feature="' + name + '"]') : [];
1786
+ }
1787
+ };
1788
+ }
1789
+ function drawerOf(node) {
1790
+ if (hasClass(node, "ge-content")) {
1791
+ var textBlock = node.parentElement;
1792
+ return hasClass(textBlock, "ge-text-block") ? child(textBlock, ".ge-tools-drawer") : null;
1793
+ }
1794
+ return child(node, ".ge-tools-drawer");
1795
+ }
1796
+ var FAMILIES = {};
1797
+ var UTILITY_NODES = ".row, .column, .ge-content, .ge-element, [data-ge-container]";
1798
+ var PREVIEW_ATTR = "data-ge-preview";
1799
+ var utilitiesOpen = false;
1800
+ function registerFamily(pluginName, utility, family) {
1801
+ var name = family.name || family.prefix;
1802
+ if (FAMILIES[name]) {
1803
+ warn('the "' + pluginName + '" plugin declares the utility "' + name + '", which the "' + FAMILIES[name].plugin + '" plugin already declared: ignored');
1804
+ return;
1805
+ }
1806
+ FAMILIES[name] = {
1807
+ plugin: pluginName,
1808
+ family: Object.assign({}, family, {
1809
+ name,
1810
+ values: family.values.map(String),
1811
+ appliesTo: family.appliesTo || utility.appliesTo || ["row", "column"]
1812
+ })
1813
+ };
1814
+ }
1815
+ function familyNamed(name, method) {
1816
+ if (FAMILIES[name]) {
1817
+ return FAMILIES[name].family;
1818
+ }
1819
+ warnOnceHere("utility:" + name, method + "(" + JSON.stringify(name) + "): no loaded plugin declares that utility");
1820
+ return null;
1821
+ }
1822
+ function appliesTo(family, kind) {
1823
+ if (kind === "plain") {
1824
+ kind = "text";
1825
+ }
1826
+ if (family.appliesTo.indexOf(kind) !== -1) {
1827
+ return true;
1828
+ }
1829
+ return !!CONTAINERS[kind] && family.appliesTo.indexOf("container") !== -1;
1830
+ }
1831
+ function familiesFor(kind) {
1832
+ return Object.keys(FAMILIES).map(function(name) {
1833
+ return FAMILIES[name].family;
1834
+ }).filter(function(family) {
1835
+ return appliesTo(family, kind);
1836
+ });
1837
+ }
1838
+ function utilityClass(family, tier, value) {
1839
+ if (family.className) {
1840
+ return family.className(tier.key, value);
1841
+ }
1842
+ return family.prefix + (tier.infix ? "-" + tier.infix : "") + "-" + value;
1843
+ }
1844
+ function ownUtility(node, family, tier) {
1845
+ var classes = (node.getAttribute("class") || "").split(/\s+/);
1846
+ for (var i = 0; i < family.values.length; i++) {
1847
+ if (classes.indexOf(utilityClass(family, tier, family.values[i])) !== -1) {
1848
+ return family.values[i];
1849
+ }
1850
+ }
1851
+ return null;
1852
+ }
1853
+ function inheritedUtility(node, family, tier) {
1854
+ for (var i = BREAKPOINTS.indexOf(tier) - 1; i >= 0; i--) {
1855
+ var value = ownUtility(node, family, BREAKPOINTS[i]);
1856
+ if (value !== null) {
1857
+ return { tier: BREAKPOINTS[i], value };
1858
+ }
1859
+ }
1860
+ return null;
1861
+ }
1862
+ function effectiveUtility(node, family, tier) {
1863
+ var own2 = ownUtility(node, family, tier);
1864
+ if (own2 !== null) {
1865
+ return own2;
1866
+ }
1867
+ var inherited = inheritedUtility(node, family, tier);
1868
+ return inherited ? inherited.value : null;
1869
+ }
1870
+ function utilityTiers(node, family) {
1871
+ return BREAKPOINTS.map(function(tier) {
1872
+ return { tier, value: ownUtility(node, family, tier) };
1873
+ }).filter(function(entry) {
1874
+ return entry.value !== null;
1875
+ });
1876
+ }
1877
+ function writeUtility(node, family, tier, value) {
1878
+ family.values.forEach(function(candidate) {
1879
+ removeClass(node, utilityClass(family, tier, candidate));
1880
+ });
1881
+ if (value !== null) {
1882
+ addClass(node, utilityClass(family, tier, value));
1883
+ }
1884
+ dropEmptyClass(node);
1885
+ }
1886
+ function readUtility(node, family, view) {
1887
+ return view === ALL_VIEW ? ownUtility(node, family, BREAKPOINTS[0]) : effectiveUtility(node, family, breakpoint(view));
1888
+ }
1889
+ function planUtility(node, family, view, value) {
1890
+ if (view !== ALL_VIEW) {
1891
+ var tier = breakpoint(view);
1892
+ if (ownUtility(node, family, tier) === value) {
1893
+ return null;
1894
+ }
1895
+ return { writes: [{ tier, value }], cleared: [] };
1896
+ }
1897
+ var writes = [];
1898
+ var cleared = [];
1899
+ utilityTiers(node, family).forEach(function(entry) {
1900
+ if (entry.tier === BREAKPOINTS[0]) {
1901
+ return;
1902
+ }
1903
+ writes.push({ tier: entry.tier, value: null });
1904
+ cleared.push({ breakpoint: entry.tier.key, value: entry.value });
1905
+ });
1906
+ if (ownUtility(node, family, BREAKPOINTS[0]) !== value) {
1907
+ writes.unshift({ tier: BREAKPOINTS[0], value });
1908
+ }
1909
+ return writes.length ? { writes, cleared } : null;
1910
+ }
1911
+ function getUtility(node, name, view) {
1912
+ node = nodeFrom(node);
1913
+ var family = familyNamed(name, "getUtility");
1914
+ if (!family || !node) {
1915
+ return null;
1916
+ }
1917
+ var key = view === void 0 ? curView : viewKey(view);
1918
+ if (key === null) {
1919
+ warn("getUtility(" + JSON.stringify(view) + "): no such layout mode");
1920
+ return null;
1921
+ }
1922
+ return readUtility(node, family, key);
1923
+ }
1924
+ function setUtility(node, name, value, options) {
1925
+ options = typeof options == "string" ? { view: options } : options || {};
1926
+ node = nodeFrom(node);
1927
+ var family = familyNamed(name, "setUtility");
1928
+ if (!family || !node) {
1929
+ return false;
1930
+ }
1931
+ var view = options.view === void 0 ? curView : viewKey(options.view);
1932
+ if (view === null) {
1933
+ warn("setUtility(" + JSON.stringify(options.view) + "): no such layout mode");
1934
+ return false;
1935
+ }
1936
+ value = value === null || value === void 0 || value === "" ? null : String(value);
1937
+ if (value !== null && family.values.indexOf(value) === -1) {
1938
+ warn("setUtility: " + JSON.stringify(value) + ' is not a value of "' + name + '", which takes ' + JSON.stringify(family.values));
1939
+ return false;
1940
+ }
1941
+ var kind = kindOf(node);
1942
+ if (!appliesTo(family, kind)) {
1943
+ warn('setUtility: "' + name + '" does not apply to a ' + kind);
1944
+ return false;
1945
+ }
1946
+ if (family.write) {
1947
+ return family.write(node, value, view, options.source || "api");
1948
+ }
1949
+ var plan = planUtility(node, family, view, value);
1950
+ if (!plan) {
1951
+ return false;
1952
+ }
1953
+ return operate(function() {
1954
+ var payload = payloadFor(kind, node, {
1955
+ family: name,
1956
+ breakpoint: view,
1957
+ tiers: plan.writes.map(function(write) {
1958
+ return write.tier.key;
1959
+ }),
1960
+ from: readUtility(node, family, view),
1961
+ to: value,
1962
+ cleared: plan.cleared,
1963
+ source: options.source || "api"
1964
+ });
1965
+ if (!emit("before-utility", payload)) {
1966
+ refreshUtilities(node);
1967
+ return false;
1968
+ }
1969
+ plan.writes.forEach(function(write) {
1970
+ writeUtility(node, family, write.tier, write.value);
1971
+ });
1972
+ refreshUtilities(node);
1973
+ emit("after-utility", payload);
1974
+ return true;
1975
+ });
1976
+ }
1977
+ function bareStyle(node, name, property) {
1978
+ var family = familyNamed(name, "bareStyle");
1979
+ node = nodeFrom(node);
1980
+ if (!family || !node) {
1981
+ return null;
1982
+ }
1983
+ var original = node.getAttribute("class");
1984
+ BREAKPOINTS.forEach(function(tier) {
1985
+ writeUtility(node, family, tier, null);
1986
+ });
1987
+ var value = getComputedStyle(node).getPropertyValue(property);
1988
+ if (original === null) {
1989
+ node.removeAttribute("class");
1990
+ } else {
1991
+ node.setAttribute("class", original);
1992
+ }
1993
+ return value;
1994
+ }
1995
+ function refreshUtilities(node) {
1996
+ var details = detailsOf(node);
1997
+ if (details) {
1998
+ var classes = one(details, ".ge-classes");
1999
+ if (classes) {
2000
+ classes.value = hostClasses(node).join(" ");
2001
+ }
2002
+ children(details, ".ge-utilities").forEach(function(section) {
2003
+ renderUtilities(section);
2004
+ });
2005
+ }
2006
+ refreshPreviews(node);
2007
+ }
2008
+ function utilityNodes(scope) {
2009
+ return selfAndAll(scope, UTILITY_NODES);
2010
+ }
2011
+ function refreshPreviews(scope) {
2012
+ clearPreviews(scope);
2013
+ if (curView !== ALL_VIEW) {
2014
+ previewTier(scope, breakpoint(curView));
2015
+ }
2016
+ markRowCols(scope);
2017
+ plugins("onRefresh", scope);
2018
+ }
2019
+ function previewTier(scope, tier) {
2020
+ utilityNodes(scope).forEach(function(node) {
2021
+ var kind = kindOf(node);
2022
+ var styles = {};
2023
+ familiesFor(kind).forEach(function(family) {
2024
+ if (!family.preview || !utilityTiers(node, family).length) {
2025
+ return;
2026
+ }
2027
+ Object.assign(styles, family.preview(effectiveUtility(node, family, tier), node, kind));
2028
+ });
2029
+ if (kind === "column") {
2030
+ Object.assign(styles, rowColsPreview(node, tier));
2031
+ }
2032
+ Object.keys(UTILITIES).forEach(function(name) {
2033
+ var utility = UTILITIES[name];
2034
+ if (utility.preview) {
2035
+ Object.assign(styles, utility.preview(node, kind, tier.key));
2036
+ }
2037
+ });
2038
+ if (Object.keys(styles).length) {
2039
+ applyPreview(node, styles);
2040
+ }
2041
+ });
2042
+ }
2043
+ function applyPreview(node, styles) {
2044
+ var style = node.style;
2045
+ var was = {};
2046
+ Object.keys(styles).forEach(function(property) {
2047
+ was[property] = [style.getPropertyValue(property), style.getPropertyPriority(property)];
2048
+ style.setProperty(property, String(styles[property]), "important");
2049
+ });
2050
+ node.setAttribute(PREVIEW_ATTR, JSON.stringify(was));
2051
+ }
2052
+ function clearPreviews(scope) {
2053
+ selfAndAll(scope, "[" + PREVIEW_ATTR + "]").forEach(function(node) {
2054
+ var style = node.style;
2055
+ var was = {};
2056
+ try {
2057
+ was = JSON.parse(node.getAttribute(PREVIEW_ATTR)) || {};
2058
+ } catch (error) {
2059
+ }
2060
+ Object.keys(was).forEach(function(property) {
2061
+ var before = was[property];
2062
+ if (before && before[0]) {
2063
+ style.setProperty(property, before[0], before[1]);
2064
+ } else {
2065
+ style.removeProperty(property);
2066
+ }
2067
+ });
2068
+ node.removeAttribute(PREVIEW_ATTR);
2069
+ dropEmptyStyle(node);
2070
+ });
2071
+ }
2072
+ function createUtilitiesSection(node) {
2073
+ var kind = kindOf(node);
2074
+ var fields = familiesFor(kind).filter(function(family) {
2075
+ return family.panel !== false;
2076
+ }).map(function(family) {
2077
+ return createField(node, family);
2078
+ });
2079
+ Object.keys(UTILITIES).forEach(function(name) {
2080
+ var utility = UTILITIES[name];
2081
+ var own2 = utility.panel ? utility.panel(node, kind) : null;
2082
+ if (own2) {
2083
+ fields.push(own2);
2084
+ }
2085
+ });
2086
+ if (!fields.length) {
2087
+ return null;
2088
+ }
2089
+ var section = toggleClass(element("div", { "class": "ge-utilities" }), "ge-open", utilitiesOpen);
2090
+ sectionNodes.set(section, node);
2091
+ var toggle2 = section.appendChild(element("a", { "class": "ge-utilities-toggle" }));
2092
+ toggle2.addEventListener("click", function() {
2093
+ utilitiesOpen = !hasClass(section, "ge-open");
2094
+ settingsScope().forEach(function(scope) {
2095
+ all(scope, ".ge-utilities").forEach(function(each) {
2096
+ toggleClass(each, "ge-open", utilitiesOpen);
2097
+ });
2098
+ });
2099
+ });
2100
+ var body = section.appendChild(element("div", { "class": "ge-utilities-body" }));
2101
+ fields.forEach(function(field) {
2102
+ body.appendChild(field);
2103
+ });
2104
+ renderUtilities(section);
2105
+ return section;
2106
+ }
2107
+ function createField(node, family) {
2108
+ var field = element("label", { "class": "ge-utility", "data-ge-family": family.name });
2109
+ field.appendChild(element(
2110
+ "span",
2111
+ { "class": "ge-utility-label" },
2112
+ family.labelKey ? t(family.labelKey) : family.name
2113
+ ));
2114
+ var select = field.appendChild(element("select", { "class": "form-select form-select-sm" }));
2115
+ select.addEventListener("change", function() {
2116
+ setUtility(node, family.name, this.value, { source: "panel" });
2117
+ });
2118
+ field.appendChild(element("small", { "class": "ge-utility-note" }));
2119
+ return field;
2120
+ }
2121
+ function utilityField(node, name) {
2122
+ var family = familyNamed(name, "utilityField");
2123
+ if (!family) {
2124
+ return null;
2125
+ }
2126
+ var field = createField(node, family);
2127
+ renderField(field, node);
2128
+ return field;
2129
+ }
2130
+ function renderUtilities(section) {
2131
+ var node = sectionNodes.get(section);
2132
+ children(section, ".ge-utilities-toggle").forEach(function(toggle2) {
2133
+ toggle2.textContent = t("utility.section", { view: t(labelKeyFor(curView)) });
2134
+ });
2135
+ all(section, ".ge-utility").forEach(function(field) {
2136
+ renderField(field, node);
2137
+ });
2138
+ }
2139
+ function renderField(field, node) {
2140
+ var family = FAMILIES[field.getAttribute("data-ge-family")].family;
2141
+ var select = child(field, "select");
2142
+ var choices = family.choices ? family.choices(node, kindOf(node)) : family.values;
2143
+ var own2, blank, note = "";
2144
+ select.innerHTML = "";
2145
+ if (curView === ALL_VIEW) {
2146
+ own2 = ownUtility(node, family, BREAKPOINTS[0]);
2147
+ blank = t("utility.default");
2148
+ var varies = utilityTiers(node, family).filter(function(entry) {
2149
+ return entry.tier !== BREAKPOINTS[0];
2150
+ });
2151
+ if (varies.length) {
2152
+ note = t("utility.varies", {
2153
+ breakpoints: varies.map(function(entry) {
2154
+ return entry.tier.key;
2155
+ }).join(", ")
2156
+ });
2157
+ }
2158
+ } else {
2159
+ var tier = breakpoint(curView);
2160
+ var inherited = inheritedUtility(node, family, tier);
2161
+ own2 = ownUtility(node, family, tier);
2162
+ blank = inherited ? t("utility.inherit", { value: labelOf(family, inherited.value), breakpoint: inherited.tier.key }) : t("utility.default");
2163
+ var custom = family.blank ? family.blank(node, curView) : null;
2164
+ if (custom && own2 === null) {
2165
+ blank = custom;
2166
+ }
2167
+ }
2168
+ if (own2 !== null && choices.indexOf(own2) === -1) {
2169
+ choices = choices.concat([own2]);
2170
+ }
2171
+ select.appendChild(element("option", { value: "" }, blank));
2172
+ choices.forEach(function(value) {
2173
+ select.appendChild(element("option", { value }, labelOf(family, value)));
2174
+ });
2175
+ select.value = own2 === null ? "" : own2;
2176
+ var noteNode = child(field, ".ge-utility-note");
2177
+ noteNode.textContent = note;
2178
+ toggle(noteNode, note !== "");
2179
+ }
2180
+ function labelOf(family, value) {
2181
+ return family.label ? family.label(value) : value;
2182
+ }
2183
+ var CONTAINERS = {};
2184
+ var FEATURES = {};
2185
+ var UTILITIES = {};
2186
+ var featureMethods = {};
2187
+ var containerCounter = 0;
2188
+ function containerId(type) {
2189
+ containerCounter++;
2190
+ return "ge-" + type + "-" + containerCounter + "-" + Math.random().toString(36).slice(2, 6);
2191
+ }
2192
+ function defaultRegion() {
2193
+ var row = createRow();
2194
+ row.appendChild(createColumn(MAX_COL_SIZE));
2195
+ return row;
2196
+ }
2197
+ function containerTypeOf(container) {
2198
+ return container ? container.getAttribute("data-ge-container") : null;
2199
+ }
2200
+ function markContainers() {
2201
+ all(canvas, "[data-ge-container]").forEach(function(container) {
2202
+ var type = containerTypeOf(container);
2203
+ var definition = CONTAINERS[type];
2204
+ if (!definition) {
2205
+ warnOnceHere("container:" + type, 'unknown container type "' + type + '"');
2206
+ return;
2207
+ }
2208
+ addClass(container, "ge-container ge-container-" + type);
2209
+ definition.mark(container);
2210
+ if (!child(container, ".ge-tools-drawer")) {
2211
+ createContainerControls(container, type, definition);
2212
+ }
2213
+ });
2214
+ }
2215
+ function unmarkContainers() {
2216
+ all(canvas, "[data-ge-container]").forEach(function(container) {
2217
+ var definition = CONTAINERS[containerTypeOf(container)];
2218
+ if (definition) {
2219
+ definition.unmark(container);
2220
+ }
2221
+ removeClass(container, "ge-container ge-container-" + containerTypeOf(container));
2222
+ dropEmptyClass(container);
2223
+ });
2224
+ }
2225
+ function prependDrawer(node, className) {
2226
+ var drawer = element("div", { "class": className });
2227
+ node.insertBefore(drawer, node.firstChild);
2228
+ return drawer;
2229
+ }
2230
+ function hostTools(drawer, tools) {
2231
+ (tools || []).forEach(function(hostTool) {
2232
+ createTool(
2233
+ drawer,
2234
+ hostTool.title || "",
2235
+ hostTool.className || "",
2236
+ hostTool.iconClass || "bi bi-wrench",
2237
+ hostTool.on
2238
+ );
2239
+ });
2240
+ }
2241
+ function createContainerControls(container, type, definition) {
2242
+ var drawer = prependDrawer(container, "ge-tools-drawer ge-container-drawer");
2243
+ createMoveTool(drawer);
2244
+ addSettingsTool(drawer, container, settings.container_classes);
2245
+ hostTools(drawer, settings.container_tools);
2246
+ if (definition.tools) {
2247
+ definition.tools(drawer, container);
2248
+ }
2249
+ createTool(drawer, t("tool.delete_container"), "ge-delete-container", "bi bi-trash", function() {
2250
+ deleteNode(type, container, t("confirm.delete_container"), function(removed) {
2251
+ slideUp(container, removed);
2252
+ });
2253
+ });
2254
+ if (definition.addPane) {
2255
+ createTool(drawer, t(definition.addPaneKey), "ge-add-pane", "bi bi-plus-circle", function() {
2256
+ var pane = definition.addPane(container, {});
2257
+ addNode(definition.paneKind, pane, function() {
2258
+ }, {
2259
+ parent: container,
2260
+ source: "tool",
2261
+ container
2262
+ });
2263
+ });
2264
+ }
2265
+ }
2266
+ function createPaneControls(pane, kind, tools, confirmText, remove) {
2267
+ var drawer = prependDrawer(pane, "ge-tools-drawer ge-pane-drawer");
2268
+ createMoveTool(drawer);
2269
+ addSettingsTool(drawer, pane, settings.pane_classes);
2270
+ hostTools(drawer, tools);
2271
+ createTool(drawer, t("tool.delete_pane"), "ge-delete-pane", "bi bi-trash", function() {
2272
+ deleteNode(kind, pane, confirmText, function(removed) {
2273
+ remove(removed);
2274
+ });
2275
+ });
2276
+ return drawer;
2277
+ }
2278
+ function suspendToggles(scope) {
2279
+ if (!scope) {
2280
+ return;
2281
+ }
2282
+ selfAndAll(scope, "[data-bs-toggle], [data-bs-dismiss]").forEach(function(node) {
2283
+ ["toggle", "dismiss"].forEach(function(name) {
2284
+ var value = node.getAttribute("data-bs-" + name);
2285
+ if (value === null) {
2286
+ return;
2287
+ }
2288
+ node.setAttribute("data-ge-bs-" + name, value);
2289
+ node.removeAttribute("data-bs-" + name);
2290
+ });
2291
+ });
2292
+ }
2293
+ function resumeToggles(scope) {
2294
+ if (!scope) {
2295
+ return;
2296
+ }
2297
+ selfAndAll(scope, "[data-ge-bs-toggle], [data-ge-bs-dismiss]").forEach(function(node) {
2298
+ ["toggle", "dismiss"].forEach(function(name) {
2299
+ var value = node.getAttribute("data-ge-bs-" + name);
2300
+ if (value === null) {
2301
+ return;
2302
+ }
2303
+ node.setAttribute("data-bs-" + name, value);
2304
+ node.removeAttribute("data-ge-bs-" + name);
2305
+ });
2306
+ });
2307
+ }
2308
+ function makeLabelEditable(label) {
2309
+ if (editableLabels.has(label)) {
2310
+ return;
2311
+ }
2312
+ var toggle2 = closest(label, "[data-bs-toggle], [data-ge-bs-toggle]");
2313
+ editableLabels.add(label);
2314
+ label.setAttribute("title", t("tool.rename"));
2315
+ label.addEventListener("dblclick", function(e) {
2316
+ e.preventDefault();
2317
+ e.stopPropagation();
2318
+ suspendToggles(toggle2);
2319
+ label.setAttribute("contenteditable", "true");
2320
+ label.focus();
2321
+ window.getSelection().selectAllChildren(label);
2322
+ });
2323
+ label.addEventListener("keydown", function(e) {
2324
+ if (label.getAttribute("contenteditable") !== "true") {
2325
+ return;
2326
+ }
2327
+ if (e.key === "Enter") {
2328
+ e.preventDefault();
2329
+ label.blur();
2330
+ }
2331
+ });
2332
+ label.addEventListener("blur", function() {
2333
+ label.removeAttribute("contenteditable");
2334
+ resumeToggles(toggle2);
2335
+ });
2336
+ }
2337
+ function labelIn(button) {
2338
+ var label = child(button, ".ge-pane-label");
2339
+ if (!label) {
2340
+ label = element("span", { "class": "ge-pane-label" }, button.textContent.trim());
2341
+ button.innerHTML = "";
2342
+ button.appendChild(label);
2343
+ }
2344
+ return label;
2345
+ }
2346
+ function unwrapLabels(scope) {
2347
+ all(scope, ".ge-pane-label").forEach(function(label) {
2348
+ editableLabels.delete(label);
2349
+ unwrap(label);
2350
+ });
2351
+ }
2352
+ function addColumnTo(row, size) {
2353
+ var column = createColumn(size);
2354
+ return addNode("column", column, function() {
2355
+ row.appendChild(column);
2356
+ }, { parent: row, source: "tool" });
2357
+ }
2358
+ function attachSizePicker(tool, row) {
2359
+ if (!settings.add_column.picker || !tool) {
2360
+ return;
2361
+ }
2362
+ attachPicker(tool, function() {
2363
+ openSizePicker(tool, row);
2364
+ });
2365
+ }
2366
+ function attachPicker(tool, open) {
2367
+ var timer = null;
2368
+ var cancel = function() {
2369
+ window.clearTimeout(timer);
2370
+ timer = null;
2371
+ };
2372
+ on(tool, "mouseenter mousedown", function() {
2373
+ if (timer || sizePicker) {
2374
+ return;
2375
+ }
2376
+ timer = window.setTimeout(function() {
2377
+ timer = null;
2378
+ open();
2379
+ }, settings.add_column.delay);
2380
+ });
2381
+ on(tool, "mouseleave mouseup", cancel);
2382
+ }
2383
+ function openSizePicker(tool, row) {
2384
+ closeSizePicker();
2385
+ var room = spare(row, leadingTier());
2386
+ var drawer = closest(tool, ".ge-tools-drawer");
2387
+ if (drawer) {
2388
+ addClass(drawer, "ge-picker-open");
2389
+ }
2390
+ sizePicker = tool.appendChild(element("div", { "class": "ge-size-picker" }));
2391
+ settings.valid_col_sizes.forEach(function(size) {
2392
+ var choice = element("a", {
2393
+ "class": "ge-size",
2394
+ "data-ge-size": size,
2395
+ title: sizeTitle(size)
2396
+ }, isUnits(size) ? size : sizeClass(BREAKPOINTS[0], size));
2397
+ toggleClass(choice, "ge-size-tight", isUnits(size) && size > room);
2398
+ toggleClass(choice, "ge-size-flex", !isUnits(size));
2399
+ choice.addEventListener("click", function(e) {
2400
+ e.preventDefault();
2401
+ e.stopPropagation();
2402
+ closeSizePicker();
2403
+ addColumnTo(row, size);
2404
+ });
2405
+ sizePicker.appendChild(choice);
2406
+ });
2407
+ withdrawOnLeave(tool);
2408
+ }
2409
+ function sizeTitle(size) {
2410
+ if (size === "equal") {
2411
+ return t("tool.column_equal");
2412
+ }
2413
+ if (size === "auto") {
2414
+ return t("tool.column_auto");
2415
+ }
2416
+ return t("tool.column_size", { size });
2417
+ }
2418
+ function closeSizePicker() {
2419
+ if (!sizePicker) {
2420
+ return false;
2421
+ }
2422
+ var drawer = closest(sizePicker, ".ge-tools-drawer");
2423
+ if (drawer) {
2424
+ removeClass(drawer, "ge-picker-open");
2425
+ }
2426
+ sizePicker.remove();
2427
+ sizePicker = null;
2428
+ return true;
2429
+ }
2430
+ function createRowControls() {
2431
+ all(canvas, ".row").forEach(function(row) {
2432
+ if (child(row, ".ge-tools-drawer")) {
2433
+ return;
2434
+ }
2435
+ var drawer = prependDrawer(row, "ge-tools-drawer");
2436
+ createMoveTool(drawer);
2437
+ addSettingsTool(drawer, row, settings.row_classes);
2438
+ hostTools(drawer, settings.row_tools);
2439
+ createTool(drawer, t("tool.delete_row"), "ge-delete-row", "bi bi-trash", function() {
2440
+ deleteNode("row", row, t("confirm.delete_row"), function(removed) {
2441
+ slideUp(row, removed);
2442
+ });
2443
+ });
2444
+ createTool(drawer, t("tool.add_column"), "ge-add-column", "bi bi-plus-circle", function() {
2445
+ if (closeSizePicker()) {
2446
+ return;
2447
+ }
2448
+ addColumnTo(row, rowColsSource(row, leadingTier()) ? null : settings.add_column.size);
2449
+ });
2450
+ attachSizePicker(child(drawer, ".ge-add-column"), row);
2451
+ });
2452
+ }
2453
+ function createColControls() {
2454
+ all(canvas, ".column").forEach(function(col) {
2455
+ if (child(col, ".ge-tools-drawer")) {
2456
+ return;
2457
+ }
2458
+ var drawer = prependDrawer(col, "ge-tools-drawer");
2459
+ createMoveTool(drawer);
2460
+ createTool(drawer, t("tool.column_narrower"), "ge-decrease-col-width", "bi bi-dash-lg", function(e) {
2461
+ resizeColumn(
2462
+ col,
2463
+ e.shiftKey ? smallest(settings.valid_col_sizes) : stepThrough(settings.valid_col_sizes.filter(isUnits), currentUnits(col), -1),
2464
+ "tool"
2465
+ );
2466
+ });
2467
+ createTool(drawer, t("tool.column_wider"), "ge-increase-col-width", "bi bi-plus-lg", function(e) {
2468
+ resizeColumn(
2469
+ col,
2470
+ e.shiftKey ? widestFor(col) : stepThrough(settings.valid_col_sizes.filter(isUnits), currentUnits(col), 1),
2471
+ "tool"
2472
+ );
2473
+ });
2474
+ createTool(drawer, t("tool.indent_decrease"), "ge-decrease-col-offset", "bi bi-text-indent-right", function(e) {
2475
+ indentColumn(
2476
+ col,
2477
+ e.shiftKey ? smallest(settings.valid_col_offsets) : stepThrough(settings.valid_col_offsets, currentOffset(col), -1),
2478
+ "tool"
2479
+ );
2480
+ });
2481
+ createTool(drawer, t("tool.indent_increase"), "ge-increase-col-offset", "bi bi-text-indent-left", function(e) {
2482
+ indentColumn(col, e.shiftKey ? deepestFor(col) : stepThrough(settings.valid_col_offsets, currentOffset(col), 1), "tool");
2483
+ });
2484
+ addSettingsTool(drawer, col, settings.col_classes);
2485
+ hostTools(drawer, settings.col_tools);
2486
+ createTool(drawer, t("tool.delete_column"), "ge-delete-column", "bi bi-trash", function() {
2487
+ deleteNode("column", col, t("confirm.delete_column"), function(removed) {
2488
+ shrinkAway(col, 400, removed, true);
2489
+ });
2490
+ });
2491
+ createTool(drawer, t("tool.add_row"), "ge-add-row", "bi bi-plus-circle", function() {
2492
+ var row = createRow();
2493
+ addNode("row", row, function() {
2494
+ col.appendChild(row);
2495
+ }, { parent: col, source: "tool" });
2496
+ });
2497
+ });
2498
+ }
2499
+ function leadingTier() {
2500
+ return curView === ALL_VIEW ? BREAKPOINTS[BREAKPOINTS.length - 1] : breakpoint(curView);
2501
+ }
2502
+ function currentSize(col) {
2503
+ var tier = leadingTier();
2504
+ if (rowColsWinner(col, tier)) {
2505
+ return null;
2506
+ }
2507
+ var size = getEffectiveSize(col, tier);
2508
+ return size === null ? MAX_COL_SIZE : size;
2509
+ }
2510
+ function currentUnits(col) {
2511
+ var size = currentSize(col);
2512
+ if (isUnits(size)) {
2513
+ return size;
2514
+ }
2515
+ var units = Math.round(outerWidth(col) / rowContentWidth(col.parentElement) * MAX_COL_SIZE);
2516
+ return Math.min(Math.max(units, 1), MAX_COL_SIZE);
2517
+ }
2518
+ function rowContentWidth(row) {
2519
+ var style = window.getComputedStyle(row);
2520
+ return row.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
2521
+ }
2522
+ function currentOffset(col) {
2523
+ return getEffectiveOffset(col, leadingTier()) || 0;
2524
+ }
2525
+ function stepThrough(values, from, direction) {
2526
+ var index = values.indexOf(from);
2527
+ if (index === -1) {
2528
+ return values.reduce(function(best, value) {
2529
+ return Math.abs(value - from) < Math.abs(best - from) ? value : best;
2530
+ }, values[0]);
2531
+ }
2532
+ return values[Math.min(Math.max(index + direction, 0), values.length - 1)];
2533
+ }
2534
+ function smallest(values) {
2535
+ return values.filter(isUnits).reduce(function(a, b) {
2536
+ return Math.min(a, b);
2537
+ }, MAX_COL_SIZE);
2538
+ }
2539
+ function largest(values) {
2540
+ return values.filter(isUnits).reduce(function(a, b) {
2541
+ return Math.max(a, b);
2542
+ }, 0);
2543
+ }
2544
+ function widestFor(col) {
2545
+ var room = spare(col.parentElement, leadingTier(), col) - currentOffset(col);
2546
+ return Math.min(largest(settings.valid_col_sizes), Math.max(room, 1));
2547
+ }
2548
+ function deepestFor(col) {
2549
+ var room = spare(col.parentElement, leadingTier(), col) - currentUnits(col);
2550
+ return Math.min(largest(settings.valid_col_offsets), Math.max(room, 0));
2551
+ }
2552
+ function createMoveTool(drawer) {
2553
+ if (settings.drag_handle === "drawer") {
2554
+ return null;
2555
+ }
2556
+ return createTool(drawer, t("tool.move"), "ge-move", "bi bi-arrows-move");
2557
+ }
2558
+ function createTool(drawer, title, className, iconClass, eventHandlers) {
2559
+ var tool = element("a", { title, "class": className });
2560
+ tool.appendChild(element("i", { "class": iconClass }));
2561
+ drawer.appendChild(tool);
2562
+ if (typeof eventHandlers == "function") {
2563
+ tool.addEventListener("click", eventHandlers);
2564
+ }
2565
+ if (eventHandlers && typeof eventHandlers == "object") {
2566
+ Object.keys(eventHandlers).forEach(function(name) {
2567
+ on(tool, name, eventHandlers[name]);
2568
+ });
2569
+ }
2570
+ return tool;
2571
+ }
2572
+ function hostClasses(node) {
2573
+ return (node.getAttribute("class") || "").split(/\s+/).filter(function(name) {
2574
+ return name !== "" && !isEditorClass(name);
2575
+ });
2576
+ }
2577
+ function isEditorClass(name) {
2578
+ if (name === "row" || name === "column") {
2579
+ return true;
2580
+ }
2581
+ if (/^(ge-|ui-)/.test(name)) {
2582
+ return true;
2583
+ }
2584
+ if (/^col(-(sm|md|lg|xl|xxl))?(-auto)?$/.test(name)) {
2585
+ return true;
2586
+ }
2587
+ return BREAKPOINTS.some(function(tier) {
2588
+ return new RegExp("^(" + tier.colPrefix + "|" + tier.offsetPrefix + ")\\d+$").test(name);
2589
+ });
2590
+ }
2591
+ function setHostClasses(node, value) {
2592
+ hostClasses(node).forEach(function(name) {
2593
+ removeClass(node, name);
2594
+ });
2595
+ value.split(/\s+/).forEach(function(name) {
2596
+ if (name !== "") {
2597
+ addClass(node, name);
2598
+ }
2599
+ });
2600
+ dropEmptyClass(node);
2601
+ }
2602
+ function addSettingsTool(drawer, node, presets) {
2603
+ var details = createDetails(node, presets || []);
2604
+ detailsFor.set(node, details);
2605
+ createTool(drawer, t("tool.settings"), "ge-settings", "bi bi-gear-fill", function() {
2606
+ toggleSettings(node, details, this);
2607
+ });
2608
+ var kind = kindOf(node);
2609
+ Object.keys(UTILITIES).forEach(function(name) {
2610
+ if (UTILITIES[name].drawerTools) {
2611
+ UTILITIES[name].drawerTools(drawer, node, kind);
2612
+ }
2613
+ });
2614
+ Object.keys(FEATURES).forEach(function(name) {
2615
+ if (FEATURES[name].drawerTools) {
2616
+ FEATURES[name].drawerTools(drawer, node, kind);
2617
+ }
2618
+ });
2619
+ return drawer.appendChild(details);
2620
+ }
2621
+ function createDetails(container, cssClasses) {
2622
+ var detailsDiv = element("div", { "class": "ge-details" });
2623
+ var general = detailsDiv.appendChild(element("div", { "class": "ge-details-general" }));
2624
+ var field = function(label) {
2625
+ var holder = element("label", { "class": "ge-field" });
2626
+ holder.appendChild(element("span", { "class": "ge-field-label" }, label));
2627
+ return general.appendChild(holder);
2628
+ };
2629
+ var id = element("input", {
2630
+ "class": "ge-id form-control form-control-sm",
2631
+ placeholder: t("tool.id_placeholder"),
2632
+ title: t("tool.id_title")
2633
+ });
2634
+ id.value = container.getAttribute("id") || "";
2635
+ field(t("panel.id")).appendChild(id);
2636
+ id.addEventListener("change", function() {
2637
+ if (this.value === "") {
2638
+ container.removeAttribute("id");
2639
+ } else {
2640
+ container.setAttribute("id", this.value);
2641
+ }
2642
+ });
2643
+ var classes = element("input", {
2644
+ "class": "ge-classes form-control form-control-sm",
2645
+ placeholder: t("tool.classes_placeholder"),
2646
+ title: t("tool.classes_title")
2647
+ });
2648
+ classes.value = hostClasses(container).join(" ");
2649
+ field(t("panel.classes")).appendChild(classes);
2650
+ classes.addEventListener("change", function() {
2651
+ setHostClasses(container, this.value);
2652
+ refreshUtilities(container);
2653
+ });
2654
+ var classGroup = general.appendChild(element("div", { "class": "btn-group btn-group-sm ge-presets", role: "group" }));
2655
+ cssClasses.forEach(function(rowClass) {
2656
+ var on2 = hasClass(container, rowClass.cssClass);
2657
+ var btn = element("a", {
2658
+ role: "button",
2659
+ "class": "btn btn-sm btn-outline-secondary",
2660
+ title: rowClass.title ? rowClass.title : t("tool.toggle_class", { label: rowClass.label }),
2661
+ "aria-pressed": on2 ? "true" : "false"
2662
+ });
2663
+ btn.innerHTML = rowClass.label;
2664
+ toggleClass(btn, "active", on2);
2665
+ btn.addEventListener("click", function() {
2666
+ toggleClass(btn, "active");
2667
+ btn.setAttribute("aria-pressed", hasClass(btn, "active") ? "true" : "false");
2668
+ toggleClass(container, rowClass.cssClass, hasClass(btn, "active"));
2669
+ refreshUtilities(container);
2670
+ });
2671
+ classGroup.appendChild(btn);
2672
+ });
2673
+ var utilities = createUtilitiesSection(container);
2674
+ if (utilities) {
2675
+ detailsDiv.appendChild(utilities);
2676
+ }
2677
+ return detailsDiv;
2678
+ }
2679
+ var PANEL_MODES = ["offcanvas", "popover", "modal", "inline"];
2680
+ var settingsPanels = {};
2681
+ var openSettingsState = null;
2682
+ var modalState = /* @__PURE__ */ new WeakMap();
2683
+ function panelMode() {
2684
+ if (PANEL_MODES.indexOf(settings.settings_panel) !== -1) {
2685
+ return settings.settings_panel;
2686
+ }
2687
+ warnOnceHere("settings_panel", 'settings_panel "' + settings.settings_panel + '" is not one of ' + PANEL_MODES.join(", ") + ": using offcanvas");
2688
+ return "offcanvas";
2689
+ }
2690
+ function detailsOf(node) {
2691
+ return node && detailsFor.get(node) || null;
2692
+ }
2693
+ function settingsScope() {
2694
+ return openSettingsState && openSettingsState.mode !== "inline" ? [canvas, openSettingsState.details] : [canvas];
2695
+ }
2696
+ function toggleSettings(node, details, gear) {
2697
+ var mode = panelMode();
2698
+ if (mode === "inline") {
2699
+ toggle(details);
2700
+ return;
2701
+ }
2702
+ var same = openSettingsState && openSettingsState.details === details;
2703
+ closeSettings();
2704
+ if (!same) {
2705
+ openSettings(mode, node, details, gear);
2706
+ }
2707
+ }
2708
+ function openSettings(mode, node, details, gear) {
2709
+ var panel = settingsPanel(mode);
2710
+ var listening = new AbortController();
2711
+ openSettingsState = {
2712
+ mode,
2713
+ node,
2714
+ details,
2715
+ home: details.parentElement,
2716
+ next: details.nextElementSibling,
2717
+ gear,
2718
+ listening
2719
+ };
2720
+ one(panel, ".ge-settings-title").textContent = t("panel.title", { kind: kindLabel(node) });
2721
+ one(panel, ".ge-settings-body").appendChild(details);
2722
+ show(details);
2723
+ addClass(node, "ge-settings-target");
2724
+ var signal = { signal: listening.signal };
2725
+ document.addEventListener("keydown", function(e) {
2726
+ if (e.key === "Escape") {
2727
+ closeSettings();
2728
+ }
2729
+ }, signal);
2730
+ if (mode === "offcanvas") {
2731
+ var narrow = window.innerWidth < 576;
2732
+ toggleClass(panel, "offcanvas-end", !narrow);
2733
+ toggleClass(panel, "offcanvas-bottom", narrow);
2734
+ removeClass(panel, "hiding");
2735
+ panel.getBoundingClientRect();
2736
+ addClass(panel, "show");
2737
+ } else if (mode === "popover") {
2738
+ placePopover(panel, gear);
2739
+ on(window, "scroll resize", function() {
2740
+ placePopover(panel, gear);
2741
+ }, signal);
2742
+ if (window.ResizeObserver) {
2743
+ openSettingsState.observer = new window.ResizeObserver(function() {
2744
+ placePopover(panel, gear);
2745
+ });
2746
+ openSettingsState.observer.observe(details);
2747
+ }
2748
+ on(document, "mousedown touchstart", function(e) {
2749
+ if (!panel.contains(e.target) && !gear.contains(e.target)) {
2750
+ closeSettings();
2751
+ }
2752
+ }, signal);
2753
+ } else {
2754
+ showModal(panel);
2755
+ }
2756
+ }
2757
+ function closeSettings() {
2758
+ var open = openSettingsState;
2759
+ if (!open) {
2760
+ return;
2761
+ }
2762
+ openSettingsState = null;
2763
+ var panel = settingsPanels[open.mode];
2764
+ open.listening.abort();
2765
+ if (open.observer) {
2766
+ open.observer.disconnect();
2767
+ }
2768
+ if (open.mode === "offcanvas") {
2769
+ removeClass(panel, "show");
2770
+ addClass(panel, "hiding");
2771
+ window.setTimeout(function() {
2772
+ removeClass(panel, "hiding");
2773
+ }, 300);
2774
+ } else if (open.mode === "popover") {
2775
+ hide(panel);
2776
+ } else {
2777
+ hideModal(panel);
2778
+ }
2779
+ removeClass(open.node, "ge-settings-target");
2780
+ open.details.style.removeProperty("display");
2781
+ dropEmptyStyle(open.details);
2782
+ if (open.home && attached(open.home)) {
2783
+ if (open.next && open.next.parentElement === open.home) {
2784
+ open.home.insertBefore(open.details, open.next);
2785
+ } else {
2786
+ open.home.appendChild(open.details);
2787
+ }
2788
+ } else {
2789
+ open.details.remove();
2790
+ }
2791
+ }
2792
+ function settingsPanel(mode) {
2793
+ if (settingsPanels[mode]) {
2794
+ return settingsPanels[mode];
2795
+ }
2796
+ var closeButton = function() {
2797
+ return element("button", {
2798
+ type: "button",
2799
+ "class": "btn-close ge-settings-close",
2800
+ "aria-label": t("panel.close")
2801
+ });
2802
+ };
2803
+ var panel;
2804
+ if (mode === "offcanvas") {
2805
+ panel = create('<div class="offcanvas offcanvas-end ge-settings-panel ge-settings-offcanvas" tabindex="-1" role="dialog"><div class="offcanvas-header"><h5 class="offcanvas-title ge-settings-title"></h5></div><div class="offcanvas-body ge-settings-body"></div></div>');
2806
+ one(panel, ".offcanvas-header").appendChild(closeButton());
2807
+ } else if (mode === "popover") {
2808
+ panel = create('<div class="popover bs-popover-bottom ge-settings-panel ge-settings-popover" role="dialog"><div class="popover-arrow"></div><div class="popover-header"><span class="ge-settings-title"></span></div><div class="popover-body ge-settings-body"></div></div>');
2809
+ one(panel, ".popover-header").appendChild(closeButton());
2810
+ hide(panel);
2811
+ } else {
2812
+ panel = create('<div class="modal fade ge-settings-panel ge-settings-modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"><div class="modal-content"><div class="modal-header"><h5 class="modal-title ge-settings-title"></h5></div><div class="modal-body ge-settings-body"></div><div class="modal-footer"></div></div></div></div>');
2813
+ one(panel, ".modal-header").appendChild(closeButton());
2814
+ one(panel, ".modal-footer").appendChild(element("button", {
2815
+ type: "button",
2816
+ "class": "btn btn-primary ge-settings-close"
2817
+ }, t("panel.done")));
2818
+ }
2819
+ delegate(panel, "click", ".ge-settings-close", function(e) {
2820
+ e.preventDefault();
2821
+ closeSettings();
2822
+ });
2823
+ settingsPanels[mode] = document.body.appendChild(panel);
2824
+ return panel;
2825
+ }
2826
+ function removeSettingsPanels() {
2827
+ closeSettings();
2828
+ Object.keys(settingsPanels).forEach(function(mode) {
2829
+ if (mode === "modal") {
2830
+ retireModal(settingsPanels[mode]);
2831
+ } else {
2832
+ settingsPanels[mode].remove();
2833
+ }
2834
+ });
2835
+ if (settingsBackdrop) {
2836
+ settingsBackdrop.remove();
2837
+ settingsBackdrop = null;
2838
+ }
2839
+ settingsPanels = {};
2840
+ }
2841
+ function placePopover(panel, gear) {
2842
+ if (!attached(gear)) {
2843
+ return;
2844
+ }
2845
+ show(panel);
2846
+ var tool = gear.getBoundingClientRect();
2847
+ var gap = 8;
2848
+ var body = child(panel, ".popover-body");
2849
+ body.style.removeProperty("max-height");
2850
+ var width = outerWidth(panel);
2851
+ var height = outerHeight(panel);
2852
+ var roomBelow = window.innerHeight - tool.bottom - 2 * gap;
2853
+ var roomAbove = tool.top - 2 * gap;
2854
+ var below = height <= roomBelow || roomBelow >= roomAbove;
2855
+ var room = below ? roomBelow : roomAbove;
2856
+ if (height > room) {
2857
+ css(body, { "max-height": Math.max(120, room - (height - outerHeight(body))) });
2858
+ height = outerHeight(panel);
2859
+ }
2860
+ var top = below ? tool.bottom + gap : tool.top - gap - height;
2861
+ var left = Math.max(gap, Math.min(tool.left + tool.width / 2 - 24, window.innerWidth - width - gap));
2862
+ toggleClass(panel, "bs-popover-bottom", below);
2863
+ toggleClass(panel, "bs-popover-top", !below);
2864
+ css(panel, { top: top + window.pageYOffset, left: left + window.pageXOffset });
2865
+ css(child(panel, ".popover-arrow"), {
2866
+ left: Math.max(gap, Math.min(tool.left + tool.width / 2 - left - 8, width - 24))
2867
+ });
2868
+ }
2869
+ var settingsBackdrop = null;
2870
+ function showModal(panel) {
2871
+ var Modal = modalLibrary();
2872
+ if (!Modal) {
2873
+ settingsBackdrop = element("div", { "class": "modal-backdrop fade show ge-settings-backdrop" });
2874
+ settingsBackdrop.addEventListener("click", function() {
2875
+ closeSettings();
2876
+ });
2877
+ document.body.appendChild(settingsBackdrop);
2878
+ addClass(panel, "show");
2879
+ panel.style.display = "block";
2880
+ panel.removeAttribute("aria-hidden");
2881
+ return;
2882
+ }
2883
+ var modal = Modal.getOrCreateInstance(panel);
2884
+ var state = modalState.get(panel);
2885
+ if (!state) {
2886
+ state = { wanted: null, busy: false };
2887
+ modalState.set(panel, state);
2888
+ trackModal(panel);
2889
+ panel.addEventListener("hide.bs.modal", function() {
2890
+ if (state.wanted === "open") {
2891
+ state.wanted = "closed";
2892
+ state.busy = true;
2893
+ }
2894
+ });
2895
+ panel.addEventListener("shown.bs.modal", function() {
2896
+ state.busy = false;
2897
+ if (state.wanted === "closed") {
2898
+ hideModal(panel);
2899
+ }
2900
+ });
2901
+ panel.addEventListener("hidden.bs.modal", function() {
2902
+ state.busy = false;
2903
+ if (state.wanted === "open") {
2904
+ showModal(panel);
2905
+ } else if (openSettingsState && openSettingsState.mode === "modal") {
2906
+ closeSettings();
2907
+ }
2908
+ });
2909
+ }
2910
+ state.wanted = "open";
2911
+ if (!state.busy) {
2912
+ state.busy = true;
2913
+ modal.show();
2914
+ }
2915
+ }
2916
+ function hideModal(panel) {
2917
+ var Modal = modalLibrary();
2918
+ if (!Modal) {
2919
+ if (settingsBackdrop) {
2920
+ settingsBackdrop.remove();
2921
+ settingsBackdrop = null;
2922
+ }
2923
+ removeClass(panel, "show");
2924
+ panel.style.removeProperty("display");
2925
+ panel.setAttribute("aria-hidden", "true");
2926
+ return;
2927
+ }
2928
+ var state = modalState.get(panel) || { wanted: null, busy: false };
2929
+ state.wanted = "closed";
2930
+ if (!state.busy && hasClass(panel, "show")) {
2931
+ state.busy = true;
2932
+ Modal.getOrCreateInstance(panel).hide();
2933
+ }
2934
+ }
2935
+ function kindLabel(node) {
2936
+ var kind = kindOf(node);
2937
+ if (CONTAINERS[kind] && CONTAINERS[kind].labelKey) {
2938
+ return t(CONTAINERS[kind].labelKey);
2939
+ }
2940
+ switch (kind) {
2941
+ case "row":
2942
+ return t("panel.kind_row");
2943
+ case "column":
2944
+ return t("panel.kind_column");
2945
+ case "text":
2946
+ return t("panel.kind_text");
2947
+ case "element":
2948
+ return t("panel.kind_element");
2949
+ case "section":
2950
+ return t("panel.kind_section");
2951
+ case "tab":
2952
+ return t("panel.kind_tab");
2953
+ case "accordion-item":
2954
+ return t("panel.kind_accordion_item");
2955
+ default:
2956
+ return kind;
2957
+ }
2958
+ }
2959
+ function addAllColClasses() {
2960
+ all(canvas, '.column, div[class*="col-"], div.col').forEach(function(col) {
2961
+ addClass(col, "column");
2962
+ if (sizedTiers(col).length || hasRowCols(col.parentElement)) {
2963
+ return;
2964
+ }
2965
+ setSize(col, BREAKPOINTS[0], MAX_COL_SIZE);
2966
+ });
2967
+ }
2968
+ function hasRowCols(row) {
2969
+ return hasClass(row, "row") && BREAKPOINTS.some(function(tier) {
2970
+ return ROW_COLS_VALUES.some(function(value) {
2971
+ return hasClass(row, rowColsClass(tier, value));
2972
+ });
2973
+ });
2974
+ }
2975
+ function rowColsSource(row, tier) {
2976
+ if (!hasClass(row, "row")) {
2977
+ return null;
2978
+ }
2979
+ for (var i = BREAKPOINTS.indexOf(tier); i >= 0; i--) {
2980
+ for (var v = 0; v < ROW_COLS_VALUES.length; v++) {
2981
+ if (hasClass(row, rowColsClass(BREAKPOINTS[i], ROW_COLS_VALUES[v]))) {
2982
+ return { tier: i, value: ROW_COLS_VALUES[v] };
2983
+ }
2984
+ }
2985
+ }
2986
+ return null;
2987
+ }
2988
+ function columnSource(col, tier) {
2989
+ for (var i = BREAKPOINTS.indexOf(tier); i >= 0; i--) {
2990
+ var size = getSize(col, BREAKPOINTS[i]);
2991
+ if (size !== null) {
2992
+ return { tier: i, size };
2993
+ }
2994
+ }
2995
+ return null;
2996
+ }
2997
+ function rowColsWinner(col, tier) {
2998
+ var row = rowColsSource(col.parentElement, tier);
2999
+ if (!row) {
3000
+ return null;
3001
+ }
3002
+ var own2 = columnSource(col, tier);
3003
+ if (!own2 || row.tier > own2.tier) {
3004
+ return row;
3005
+ }
3006
+ return row.tier === own2.tier && own2.size === "equal" ? row : null;
3007
+ }
3008
+ function rowColsUnits(winner) {
3009
+ return winner.value === "auto" ? 0 : MAX_COL_SIZE / parseInt(winner.value, 10);
3010
+ }
3011
+ function rowColsPreview(col, tier) {
3012
+ var winner = rowColsWinner(col, tier);
3013
+ if (winner) {
3014
+ return {
3015
+ flex: "0 0 auto",
3016
+ width: winner.value === "auto" ? "auto" : 100 / parseInt(winner.value, 10) + "%",
3017
+ "max-width": "100%"
3018
+ };
3019
+ }
3020
+ if (hasRowCols(col.parentElement) && !columnSource(col, tier)) {
3021
+ return { flex: "0 0 auto", width: "100%", "max-width": "100%" };
3022
+ }
3023
+ return {};
3024
+ }
3025
+ function markRowCols(scope) {
3026
+ selfAndAll(scope, ".row").forEach(function(row) {
3027
+ var source = settings.row_cols === false ? null : curView === ALL_VIEW ? rowColsSource(row, BREAKPOINTS[0]) || null : rowColsSource(row, breakpoint(curView));
3028
+ if (!source) {
3029
+ row.removeAttribute("data-ge-row-cols");
3030
+ } else {
3031
+ row.setAttribute("data-ge-row-cols", rowColsLabel(source.value));
3032
+ }
3033
+ });
3034
+ }
3035
+ function rowColsLabel(value) {
3036
+ return value === "auto" ? t("badge.row_cols_auto") : t("badge.row_cols", { count: value });
3037
+ }
3038
+ function rowColsFamily() {
3039
+ return {
3040
+ name: "row-cols",
3041
+ prefix: "row-cols",
3042
+ values: ROW_COLS_VALUES,
3043
+ appliesTo: ["row"],
3044
+ labelKey: "utility.row_cols"
3045
+ };
3046
+ }
3047
+ function getSize(col, tier) {
3048
+ var units = readUnits(col, tier.colPrefix);
3049
+ if (units !== null) {
3050
+ return units;
3051
+ }
3052
+ if (hasClass(col, sizeClass(tier, "auto"))) {
3053
+ return "auto";
3054
+ }
3055
+ if (hasClass(col, sizeClass(tier, "equal"))) {
3056
+ return "equal";
3057
+ }
3058
+ return null;
3059
+ }
3060
+ function getOffset(col, tier) {
3061
+ return readUnits(col, tier.offsetPrefix);
3062
+ }
3063
+ function getEffectiveSize(col, tier) {
3064
+ return readEffective(col, tier, getSize);
3065
+ }
3066
+ function getEffectiveOffset(col, tier) {
3067
+ return readEffective(col, tier, getOffset);
3068
+ }
3069
+ function readEffective(col, tier, read) {
3070
+ for (var i = BREAKPOINTS.indexOf(tier); i >= 0; i--) {
3071
+ var units = read(col, BREAKPOINTS[i]);
3072
+ if (units !== null) {
3073
+ return units;
3074
+ }
3075
+ }
3076
+ return null;
3077
+ }
3078
+ function readUnits(col, prefix) {
3079
+ var match = new RegExp("(?:^|\\s)" + prefix + "(\\d+)(?:\\s|$)").exec(col.getAttribute("class") || "");
3080
+ return match ? parseInt(match[1], 10) : null;
3081
+ }
3082
+ function writeUnits(col, prefix, units) {
3083
+ var classes = (col.getAttribute("class") || "").split(/\s+/).filter(function(name) {
3084
+ return name !== "" && !new RegExp("^" + prefix + "\\d+$").test(name);
3085
+ });
3086
+ if (units !== null) {
3087
+ classes.push(prefix + units);
3088
+ }
3089
+ col.setAttribute("class", classes.join(" "));
3090
+ }
3091
+ function setSize(col, tier, size) {
3092
+ writeUnits(col, tier.colPrefix, null);
3093
+ FLEX_SIZES.forEach(function(flex) {
3094
+ removeClass(col, sizeClass(tier, flex));
3095
+ });
3096
+ if (size !== null && size !== void 0) {
3097
+ addClass(col, sizeClass(tier, size));
3098
+ }
3099
+ }
3100
+ function setOffset(col, tier, units) {
3101
+ writeUnits(col, tier.offsetPrefix, units ? units : null);
3102
+ }
3103
+ function sizedTiers(col) {
3104
+ return BREAKPOINTS.filter(function(tier) {
3105
+ return getSize(col, tier) !== null;
3106
+ });
3107
+ }
3108
+ function spare(row, tier, ignore) {
3109
+ var used = 0;
3110
+ children(row, ".column").forEach(function(sibling) {
3111
+ if (ignore && sibling === ignore) {
3112
+ return;
3113
+ }
3114
+ var winner = rowColsWinner(sibling, tier);
3115
+ var size = winner ? rowColsUnits(winner) : getEffectiveSize(sibling, tier);
3116
+ used += (isUnits(size) ? size : 0) + (getEffectiveOffset(sibling, tier) || 0);
3117
+ });
3118
+ return MAX_COL_SIZE - used;
3119
+ }
3120
+ function clamp(request) {
3121
+ var size = request.size === null || request.size === void 0 ? null : request.size;
3122
+ var offset2 = request.offset === null || request.offset === void 0 ? 0 : request.offset;
3123
+ offset2 = Math.min(Math.max(offset2, 0), MAX_COL_OFFSET);
3124
+ if (size === null || !isUnits(size)) {
3125
+ return { size, offset: offset2, refused: false };
3126
+ }
3127
+ size = Math.min(Math.max(size, 1), MAX_COL_SIZE);
3128
+ if (size + offset2 <= MAX_COL_SIZE) {
3129
+ return { size, offset: offset2, refused: false };
3130
+ }
3131
+ if (request.leading === "offset") {
3132
+ return { size: MAX_COL_SIZE - offset2, offset: offset2, refused: false };
3133
+ }
3134
+ return { size: null, offset: offset2, refused: true };
3135
+ }
3136
+ function stripPixelWidths(scope) {
3137
+ selfAndAll(scope, ".column").forEach(function(col) {
3138
+ css(col, { width: "", height: "", left: "", top: "" });
3139
+ dropEmptyStyle(col);
3140
+ });
3141
+ }
3142
+ function groupName(name) {
3143
+ return "ge-" + name + "-" + instanceId;
3144
+ }
3145
+ function blockSelector() {
3146
+ return [".row", ".ge-text-block", ".ge-content", "[data-ge-container]"].concat(pluginHooks("blocks")).join(", ");
3147
+ }
3148
+ function pluginHooks(name) {
3149
+ return Object.keys(FEATURES).map(function(key) {
3150
+ return FEATURES[key][name] || null;
3151
+ }).filter(function(hook) {
3152
+ return hook !== null;
3153
+ });
3154
+ }
3155
+ function acceptsBlock(region, node) {
3156
+ var accepted = true;
3157
+ Object.keys(FEATURES).forEach(function(name) {
3158
+ var feature = FEATURES[name];
3159
+ if (accepted && feature.accepts && feature.accepts(region, node) === false) {
3160
+ accepted = false;
3161
+ }
3162
+ });
3163
+ return accepted;
3164
+ }
3165
+ function dragCancelSelector() {
3166
+ return settings.drag_handle === "drawer" ? ".ge-tools-drawer > a:not(.ge-text-info):not(.ge-element-info), .ge-details, input, textarea, button, select, option" : "input, textarea, button, select, option";
3167
+ }
3168
+ function sortable(lists, options) {
3169
+ var Sortable = sortableLibrary();
3170
+ lists = Array.isArray(lists) ? lists : lists ? [lists] : [];
3171
+ if (!lists.length || !Sortable) {
3172
+ return;
3173
+ }
3174
+ var wholeDrawer = settings.drag_handle === "drawer";
3175
+ var cancel = dragCancelSelector();
3176
+ var soloGroup = 0;
3177
+ lists.forEach(function(list) {
3178
+ var group = options.group ? { name: groupName(options.group) } : { name: groupName(options.draggable + "-" + ++soloGroup), pull: false, put: false };
3179
+ if (options.group && options.accepts) {
3180
+ group.put = function(to, from, dragged) {
3181
+ return from.options.group.name === group.name && options.accepts(to.el, dragged);
3182
+ };
3183
+ }
3184
+ sortables.push(Sortable.create(list, Object.assign({
3185
+ group,
3186
+ draggable: options.draggable,
3187
+ handle: wholeDrawer ? ".ge-tools-drawer" : ".ge-tools-drawer .ge-move",
3188
+ /**
3189
+ * Two refusals in one, because SortableJS asks once.
3190
+ *
3191
+ * A tool or a form field never starts a drag, as the
3192
+ * cancel list said before. And only a direct child of
3193
+ * this list moves: the selector is matched against every
3194
+ * descendant, so without this the canvas would pick up a
3195
+ * row nested three columns down and drag that.
3196
+ */
3197
+ filter: function(e, item) {
3198
+ if (closest(e.target, cancel, list)) {
3199
+ return true;
3200
+ }
3201
+ return !item || item.parentNode !== list;
3202
+ },
3203
+ // A filtered pointerdown is still a click on a tool
3204
+ preventOnFilter: false,
3205
+ // The HTML5 drag and drop API cannot be driven by
3206
+ // synthetic events, so the tests could not exist without
3207
+ // this; it also gives one helper across browsers
3208
+ forceFallback: true,
3209
+ // The copy that follows the pointer is appended to the
3210
+ // list the drag started in rather than to the body: it is
3211
+ // positioned fixed either way, and inside the canvas it
3212
+ // looks like what it is a copy of. On the body none of the
3213
+ // editing styles reached it - its drawers came out
3214
+ // unstyled, their settings panels open.
3215
+ fallbackOnBody: false,
3216
+ ghostClass: "ge-drag-placeholder",
3217
+ chosenClass: "ge-drag-chosen",
3218
+ dragClass: "ge-drag-helper",
3219
+ fallbackClass: "ge-drag-helper",
3220
+ animation: settings.drag.animation,
3221
+ // One delay, which applies to both gestures or to touch
3222
+ // alone: a touch drag that starts instantly takes the
3223
+ // page's scrolling with it, a mouse drag has no such
3224
+ // problem, and asking for `delay` means asking for both
3225
+ delay: settings.drag.delay || settings.drag.touch_delay,
3226
+ delayOnTouchOnly: !settings.drag.delay,
3227
+ touchStartThreshold: settings.drag.threshold,
3228
+ scroll: settings.drag.scroll,
3229
+ onStart: sortStart,
3230
+ onEnd: sortEnd
3231
+ }, options.options || {})));
3232
+ });
3233
+ }
3234
+ function makeSortable() {
3235
+ if (!sortableLibrary()) {
3236
+ warnOnceHere("sortable_missing", t("error.sortable_missing"));
3237
+ return;
3238
+ }
3239
+ sortable(all(canvas, ".row"), {
3240
+ draggable: ".column",
3241
+ group: "column"
3242
+ });
3243
+ sortable([canvas].concat(all(canvas, ".column")), {
3244
+ draggable: blockSelector(),
3245
+ group: "block",
3246
+ accepts: acceptsBlock
3247
+ });
3248
+ var regions = pluginHooks("regions");
3249
+ if (regions.length) {
3250
+ sortable(all(canvas, regions.join(", ")), {
3251
+ draggable: ">" + blockSelector(),
3252
+ group: "block",
3253
+ accepts: acceptsBlock
3254
+ });
3255
+ }
3256
+ plugins("onSortable", sortable);
3257
+ }
3258
+ function sortStart(e) {
3259
+ var node = e.item;
3260
+ var from = positionOf(node);
3261
+ var subject = moveSubject(node);
3262
+ var move = { from, canceled: false };
3263
+ moves.set(node, move);
3264
+ operate(function() {
3265
+ var moving = emit("before-move", payloadFor(subject.kind, subject.node, {
3266
+ parent: from.parent,
3267
+ source: "dragdrop",
3268
+ from
3269
+ }));
3270
+ if (!moving) {
3271
+ move.canceled = true;
3272
+ }
3273
+ });
3274
+ }
3275
+ function moveSubject(item) {
3276
+ var node = hasClass(item, "ge-text-block") ? child(item, ".ge-content") || item : item;
3277
+ return { kind: kindOf(node), node };
3278
+ }
3279
+ function putBack(node, from) {
3280
+ var siblings = children(from.parent).filter(function(child2) {
3281
+ return child2 !== node && !hasClass(child2, "ge-tools-drawer");
3282
+ });
3283
+ if (!siblings.length || from.index >= siblings.length) {
3284
+ from.parent.appendChild(node);
3285
+ } else {
3286
+ from.parent.insertBefore(node, siblings[from.index]);
3287
+ }
3288
+ }
3289
+ function sortEnd(e) {
3290
+ var node = e.item;
3291
+ var move = moves.get(node);
3292
+ var from = move ? move.from : positionOf(node);
3293
+ moves.delete(node);
3294
+ if (move && move.canceled) {
3295
+ putBack(node, from);
3296
+ return;
3297
+ }
3298
+ var to = positionOf(node);
3299
+ if (to.parent === from.parent && to.index === from.index) {
3300
+ return;
3301
+ }
3302
+ var container = closest(node, "[data-ge-container]");
3303
+ var definition = CONTAINERS[containerTypeOf(container)];
3304
+ if (definition && definition.afterPaneMove) {
3305
+ definition.afterPaneMove(container, node, from);
3306
+ }
3307
+ var subject = moveSubject(node);
3308
+ operate(function() {
3309
+ emit("after-move", payloadFor(subject.kind, subject.node, {
3310
+ parent: to.parent,
3311
+ source: "dragdrop",
3312
+ from,
3313
+ to,
3314
+ container: container || void 0
3315
+ }));
3316
+ });
3317
+ }
3318
+ function makeResizable() {
3319
+ if (!settings.resize.enabled) {
3320
+ return;
3321
+ }
3322
+ all(canvas, ".column").forEach(function(col) {
3323
+ if (child(col, ".ge-resize-handle")) {
3324
+ return;
3325
+ }
3326
+ var drawer = child(col, ".ge-tools-drawer");
3327
+ if (drawer) {
3328
+ drawer.appendChild(element("span", { "class": "ge-resize-size" }));
3329
+ }
3330
+ resizeEdges().forEach(function(edge) {
3331
+ var handle = element("span", {
3332
+ "class": "ge-resize-handle ge-resize-" + edge,
3333
+ "data-ge-edge": edge
3334
+ });
3335
+ handle.addEventListener("pointerdown", startResizeDrag);
3336
+ col.appendChild(handle);
3337
+ });
3338
+ });
3339
+ }
3340
+ function resizeEdges() {
3341
+ return String(settings.resize.handles).split(",").map(function(edge) {
3342
+ return edge.trim();
3343
+ }).filter(function(edge) {
3344
+ return edge === "e" || edge === "w";
3345
+ });
3346
+ }
3347
+ function startResizeDrag(e) {
3348
+ var handle = e.currentTarget;
3349
+ var col = handle.parentElement;
3350
+ var west = handle.getAttribute("data-ge-edge") === "w";
3351
+ var startX = e.pageX;
3352
+ var startWidth = outerWidth(col);
3353
+ e.preventDefault();
3354
+ if (!resizeStart(col)) {
3355
+ return;
3356
+ }
3357
+ addClass(col, "ge-resizing");
3358
+ if (e.pointerId !== void 0 && handle.setPointerCapture) {
3359
+ handle.setPointerCapture(e.pointerId);
3360
+ }
3361
+ function widthAt(move) {
3362
+ var delta = move.pageX - startX;
3363
+ return Math.max(1, startWidth + (west ? -delta : delta));
3364
+ }
3365
+ function onMove(move) {
3366
+ col.style.width = widthAt(move) + "px";
3367
+ resizeMove(col, widthAt(move));
3368
+ }
3369
+ function onUp(up) {
3370
+ handle.removeEventListener("pointermove", onMove);
3371
+ off(handle, "pointerup pointercancel", onUp);
3372
+ removeClass(col, "ge-resizing");
3373
+ resizeStop(col, widthAt(up));
3374
+ }
3375
+ handle.addEventListener("pointermove", onMove);
3376
+ on(handle, "pointerup pointercancel", onUp);
3377
+ }
3378
+ function removeResizable() {
3379
+ all(canvas, ".ge-resize-handle").forEach(function(handle) {
3380
+ handle.remove();
3381
+ });
3382
+ all(canvas, ".ge-resize-size").forEach(function(readout) {
3383
+ readout.remove();
3384
+ });
3385
+ stripPixelWidths(canvas);
3386
+ }
3387
+ function snapUnits(col, pixels) {
3388
+ var units = Math.round(pixels / rowContentWidth(col.parentElement) * MAX_COL_SIZE);
3389
+ var next = balanceSibling(col);
3390
+ var nextSize = next ? currentSize(next) : null;
3391
+ var resize = resizes.get(col);
3392
+ var own2 = resize ? resize.units : currentUnits(col);
3393
+ var room = next && isUnits(nextSize) ? own2 + nextSize - smallest(settings.valid_col_sizes) : MAX_COL_SIZE - currentOffset(col);
3394
+ return Math.min(
3395
+ Math.max(units, smallest(settings.valid_col_sizes)),
3396
+ Math.max(room, smallest(settings.valid_col_sizes)),
3397
+ largest(settings.valid_col_sizes)
3398
+ );
3399
+ }
3400
+ function balanceSibling(col) {
3401
+ if (settings.resize.balance !== "next") {
3402
+ return null;
3403
+ }
3404
+ return nextAll(col, ".column")[0] || null;
3405
+ }
3406
+ function resizeReadout(col, text) {
3407
+ var drawer = child(col, ".ge-tools-drawer");
3408
+ var readout = drawer ? child(drawer, ".ge-resize-size") : null;
3409
+ if (readout) {
3410
+ readout.textContent = text;
3411
+ }
3412
+ }
3413
+ function sizeLabel(units) {
3414
+ return (curView === ALL_VIEW ? BREAKPOINTS[0].colPrefix : leadingTier().colPrefix) + units;
3415
+ }
3416
+ function resizeStart(col) {
3417
+ var from = currentSize(col);
3418
+ var allowed = operate(function() {
3419
+ return emit("before-resize", payloadFor("column", col, {
3420
+ source: "dragdrop",
3421
+ from,
3422
+ to: null
3423
+ // Not known until the pointer stops
3424
+ }));
3425
+ });
3426
+ if (!allowed) {
3427
+ return false;
3428
+ }
3429
+ var resize = { from, units: currentUnits(col) };
3430
+ resizes.set(col, resize);
3431
+ resizeReadout(col, sizeLabel(resize.units));
3432
+ return true;
3433
+ }
3434
+ function resizeMove(col, width) {
3435
+ resizeReadout(col, sizeLabel(snapUnits(col, width)));
3436
+ }
3437
+ function resizeStop(col, width) {
3438
+ var resize = resizes.get(col);
3439
+ var units = snapUnits(col, width);
3440
+ resizes.delete(col);
3441
+ resizeReadout(col, "");
3442
+ stripPixelWidths(col);
3443
+ if (!resize) {
3444
+ return;
3445
+ }
3446
+ if (units === resize.units) {
3447
+ return;
3448
+ }
3449
+ var plan = planSize(col, units);
3450
+ if (!plan) {
3451
+ return;
3452
+ }
3453
+ operate(function() {
3454
+ writeSize(col, plan);
3455
+ balanceAfterResize(col, units - resize.units);
3456
+ refreshUtilities(col);
3457
+ emit("after-resize", payloadFor("column", col, withCleared({
3458
+ source: "dragdrop",
3459
+ from: resize.from,
3460
+ to: plan.size
3461
+ }, plan.cleared)));
3462
+ });
3463
+ }
3464
+ function balanceAfterResize(col, delta) {
3465
+ var next = balanceSibling(col);
3466
+ if (!next || !delta) {
3467
+ return;
3468
+ }
3469
+ var size = currentSize(next);
3470
+ if (!isUnits(size)) {
3471
+ return;
3472
+ }
3473
+ var plan = planSize(next, size - delta);
3474
+ if (plan) {
3475
+ writeSize(next, plan);
3476
+ refreshUtilities(next);
3477
+ }
3478
+ }
3479
+ function removeSortable() {
3480
+ sortables.forEach(function(sortableInstance) {
3481
+ sortableInstance.destroy();
3482
+ });
3483
+ sortables = [];
3484
+ }
3485
+ function createRow() {
3486
+ return element("div", { "class": "row" });
3487
+ }
3488
+ function place(node, kind, options) {
3489
+ var placement = null;
3490
+ PLACEMENTS.forEach(function(name) {
3491
+ if (placement === null && options && options[name] !== void 0) {
3492
+ placement = name;
3493
+ }
3494
+ });
3495
+ if (placement === null) {
3496
+ return node;
3497
+ }
3498
+ var target = nodeFrom(options[placement]);
3499
+ if (!target) {
3500
+ warn(kind + ": " + placement + " matches no element; the " + kind + " is left detached");
3501
+ return node;
3502
+ }
3503
+ var parent = placement === "appendTo" || placement === "prependTo" ? target : target.parentElement;
3504
+ var add = function() {
3505
+ return addNode(kind, node, function() {
3506
+ if (placement === "appendTo") {
3507
+ target.appendChild(node);
3508
+ } else if (placement === "prependTo") {
3509
+ target.insertBefore(node, target.firstChild);
3510
+ } else if (placement === "insertBefore") {
3511
+ target.parentNode.insertBefore(node, target);
3512
+ } else {
3513
+ insertAfter(node, target);
3514
+ }
3515
+ }, { parent, source: options.source || "api" });
3516
+ };
3517
+ if (operationDepth > 0) {
3518
+ defer(add);
3519
+ return node;
3520
+ }
3521
+ return add();
3522
+ }
3523
+ function apiCreateRow(layout, options) {
3524
+ var row = createRow();
3525
+ if (layout !== void 0 && !Array.isArray(layout) && !(layout && layout.row_cols)) {
3526
+ warn("createRow: the layout is an array of column sizes, as in [8, 4], or { row_cols, columns }. Making an empty row instead.");
3527
+ layout = [];
3528
+ }
3529
+ if (layout && !Array.isArray(layout)) {
3530
+ row = rowFromLayoutValue(layout);
3531
+ }
3532
+ (Array.isArray(layout) ? layout : []).forEach(function(size) {
3533
+ row.appendChild(createColumn(size));
3534
+ });
3535
+ return place(row, "row", options);
3536
+ }
3537
+ function apiCreateColumn(size, options) {
3538
+ options = options || {};
3539
+ var into = nodeFrom(options.appendTo || options.prependTo || null);
3540
+ if (size === void 0 && into && rowColsSource(into, leadingTier())) {
3541
+ size = null;
3542
+ } else if (!isUnits(size) && FLEX_SIZES.indexOf(size) === -1) {
3543
+ warn("createColumn: no column size given, using " + MAX_COL_SIZE);
3544
+ size = MAX_COL_SIZE;
3545
+ }
3546
+ var column = createColumn(size, options.offset);
3547
+ if (options.content !== void 0) {
3548
+ column.appendChild(contentFor(options.content));
3549
+ }
3550
+ return place(column, "column", options);
3551
+ }
3552
+ function apiCreateContainer(type, options) {
3553
+ options = options || {};
3554
+ var definition = CONTAINERS[type];
3555
+ if (!definition) {
3556
+ warn('createContainer: no such container type "' + type + '"');
3557
+ return null;
3558
+ }
3559
+ return place(definition.create(options), type, options);
3560
+ }
3561
+ function addPaneTo(container, type, options) {
3562
+ container = nodeFrom(container);
3563
+ options = options || {};
3564
+ var definition = CONTAINERS[containerTypeOf(container)];
3565
+ if (!definition || containerTypeOf(container) !== type) {
3566
+ warn("this is not a " + type + " container");
3567
+ return null;
3568
+ }
3569
+ var pane = definition.addPane(container, options);
3570
+ return addNode(definition.paneKind, pane, function() {
3571
+ }, {
3572
+ parent: container,
3573
+ source: "api",
3574
+ container
3575
+ });
3576
+ }
3577
+ function settingsCopy() {
3578
+ var copy = {};
3579
+ Object.keys(settings).forEach(function(key) {
3580
+ var value = settings[key];
3581
+ copy[key] = Array.isArray(value) ? value.slice() : value;
3582
+ });
3583
+ return Object.freeze(copy);
3584
+ }
3585
+ function createColumn(size, offset2) {
3586
+ var column = element("div", { "class": "column" });
3587
+ var tier = tiersFor(curView)[0];
3588
+ var wanted = clamp({ size, offset: offset2 || 0, leading: "offset" });
3589
+ setSize(column, tier, wanted.size === null ? size : wanted.size);
3590
+ setOffset(column, tier, wanted.offset);
3591
+ return column;
3592
+ }
3593
+ function runFilter(isInit) {
3594
+ if (!settings.custom_filter || !settings.custom_filter.length) {
3595
+ return;
3596
+ }
3597
+ var filters = typeof settings.custom_filter === "string" || typeof settings.custom_filter === "function" ? [settings.custom_filter] : settings.custom_filter;
3598
+ Array.prototype.forEach.call(filters, function(func) {
3599
+ if (typeof func == "string") {
3600
+ func = window[func];
3601
+ }
3602
+ func(canvas, isInit);
3603
+ });
3604
+ }
3605
+ function textCutter() {
3606
+ var cuts = [".row", "[data-ge-container]"];
3607
+ Object.keys(FEATURES).forEach(function(name) {
3608
+ var feature = FEATURES[name];
3609
+ var cut = typeof feature.cuts === "function" ? feature.cuts() : feature.cuts;
3610
+ if (cut) {
3611
+ cuts.push(cut);
3612
+ }
3613
+ });
3614
+ return cuts.join(", ");
3615
+ }
3616
+ function splitTexts(cutter) {
3617
+ all(canvas, ".column > .ge-content, .column > .ge-text-block > .ge-content").forEach(function(area) {
3618
+ if (hasClass(area, "ge-rte-active") || !children(area, cutter).length) {
3619
+ return;
3620
+ }
3621
+ var type = area.getAttribute("data-ge-content-type");
3622
+ var anchor = hasClass(area.parentElement, "ge-text-block") ? area.parentElement : area;
3623
+ var pieces = [];
3624
+ var run = [];
3625
+ Array.prototype.slice.call(area.childNodes).forEach(function(node) {
3626
+ if (node.nodeType === 1 && node.matches(cutter)) {
3627
+ pieces.push({ text: run }, { block: node });
3628
+ run = [];
3629
+ } else {
3630
+ run.push(node);
3631
+ }
3632
+ });
3633
+ pieces.push({ text: run });
3634
+ while (area.firstChild) {
3635
+ area.removeChild(area.firstChild);
3636
+ }
3637
+ var kept = false;
3638
+ var last = anchor;
3639
+ pieces.forEach(function(piece) {
3640
+ var placed;
3641
+ if (piece.block) {
3642
+ placed = piece.block;
3643
+ } else if (!hasContent(piece.text)) {
3644
+ return;
3645
+ } else if (kept) {
3646
+ placed = createDefaultContentWrapper(type);
3647
+ piece.text.forEach(function(node) {
3648
+ placed.appendChild(node);
3649
+ });
3650
+ } else {
3651
+ piece.text.forEach(function(node) {
3652
+ area.appendChild(node);
3653
+ });
3654
+ placed = anchor;
3655
+ kept = true;
3656
+ }
3657
+ if (placed !== last) {
3658
+ insertAfter(placed, last);
3659
+ }
3660
+ last = placed;
3661
+ });
3662
+ if (!kept) {
3663
+ anchor.remove();
3664
+ }
3665
+ });
3666
+ }
3667
+ function hasContent(nodes) {
3668
+ return nodes.some(function(node) {
3669
+ return node.nodeType === 1 || node.nodeType === 3 && /\S/.test(node.nodeValue);
3670
+ });
3671
+ }
3672
+ function wrapContent(cutter) {
3673
+ all(canvas, ".column").forEach(function(col) {
3674
+ var contents = [];
3675
+ children(col).forEach(function(child2) {
3676
+ if (is(child2, ".ge-tools-drawer, .ge-resize-handle")) {
3677
+ return;
3678
+ }
3679
+ if (is(child2, ".ge-content, .ge-text-block") || child2.matches(cutter)) {
3680
+ contents = doWrap(contents);
3681
+ } else {
3682
+ contents.push(child2);
3683
+ }
3684
+ });
3685
+ doWrap(contents);
3686
+ });
3687
+ }
3688
+ function doWrap(contents) {
3689
+ if (contents.length) {
3690
+ var contentArea = insertAfter(createDefaultContentWrapper(), contents[contents.length - 1]);
3691
+ contents.forEach(function(node) {
3692
+ contentArea.appendChild(node);
3693
+ });
3694
+ }
3695
+ return [];
3696
+ }
3697
+ function createDefaultContentWrapper(type) {
3698
+ var contentArea = element("div", { "class": "ge-content" });
3699
+ if (type) {
3700
+ addClass(contentArea, "ge-content-type-" + type);
3701
+ contentArea.setAttribute("data-ge-content-type", type);
3702
+ }
3703
+ return contentArea;
3704
+ }
3705
+ function wrapTexts() {
3706
+ all(canvas, ".column > .ge-content").forEach(function(area) {
3707
+ wrap(area, element("div", { "class": "ge-text-block" }));
3708
+ });
3709
+ all(canvas, ".ge-text-block").forEach(function(textBlock) {
3710
+ if (child(textBlock, ".ge-tools-drawer")) {
3711
+ return;
3712
+ }
3713
+ var area = child(textBlock, ".ge-content");
3714
+ var type = area ? area.getAttribute("data-ge-content-type") : null;
3715
+ if (!type) {
3716
+ createPlainControls(textBlock);
3717
+ } else if (!hasTextOwner(type)) {
3718
+ createOrphanControls(textBlock, type);
3719
+ }
3720
+ });
3721
+ }
3722
+ function unwrapTexts() {
3723
+ all(canvas, ".ge-text-block").forEach(function(textBlock) {
3724
+ unwrap(textBlock);
3725
+ });
3726
+ }
3727
+ function createPlainControls(textBlock) {
3728
+ var block = child(textBlock, ".ge-content");
3729
+ var drawer = prependDrawer(textBlock, "ge-tools-drawer ge-text-drawer ge-plain-drawer");
3730
+ addClass(textBlock, "ge-plain-block");
3731
+ createMoveTool(drawer);
3732
+ Object.keys(FEATURES).forEach(function(name) {
3733
+ if (FEATURES[name].plainTools) {
3734
+ FEATURES[name].plainTools(drawer, block);
3735
+ }
3736
+ });
3737
+ createTool(drawer, t("tool.delete_plain"), "ge-delete-plain", "bi bi-trash", function() {
3738
+ deleteNode("plain", block, t("confirm.delete_plain"), function(removed) {
3739
+ slideUp(textBlock, function() {
3740
+ textBlock.remove();
3741
+ removed();
3742
+ });
3743
+ });
3744
+ });
3745
+ }
3746
+ function createOrphanControls(textBlock, type) {
3747
+ var block = child(textBlock, ".ge-content");
3748
+ var drawer = prependDrawer(textBlock, "ge-tools-drawer ge-text-drawer");
3749
+ createMoveTool(drawer);
3750
+ createTool(
3751
+ drawer,
3752
+ t("text.no_editor", { type }),
3753
+ "ge-text-info ge-text-missing",
3754
+ "bi bi-exclamation-triangle"
3755
+ );
3756
+ createTool(drawer, t("tool.delete_text"), "ge-delete-text", "bi bi-trash", function() {
3757
+ deleteNode("text", block, t("confirm.delete_text"), function(removed) {
3758
+ slideUp(textBlock, function() {
3759
+ textBlock.remove();
3760
+ removed();
3761
+ });
3762
+ });
3763
+ });
3764
+ }
3765
+ function contentFor(content) {
3766
+ var offers = textOffers();
3767
+ var area = createDefaultContentWrapper(offers.length ? offers[0].type : null);
3768
+ if (content && content.nodeType) {
3769
+ area.appendChild(content);
3770
+ } else {
3771
+ setHtml(area, content);
3772
+ }
3773
+ return area;
3774
+ }
3775
+ function switchLayout(view) {
3776
+ curView = view;
3777
+ VIEW_KEYS.forEach(function(key) {
3778
+ toggleClass(canvas, "ge-layout-" + key, key === view);
3779
+ });
3780
+ one(layoutDropdown, "button").textContent = t(labelKeyFor(view));
3781
+ }
3782
+ function viewKey(view) {
3783
+ if (typeof view == "number") {
3784
+ warnOnceHere("changeView-index", "changeView(" + view + "): layout modes are identified by breakpoint key now, so pass one of " + JSON.stringify(VIEW_KEYS) + ". Numeric indexes still work, but they mean what they meant in 2.x (" + LEGACY_VIEW_INDEXES.join(", ") + ") and will be dropped.");
3785
+ return LEGACY_VIEW_INDEXES[view] || null;
3786
+ }
3787
+ return VIEW_KEYS.indexOf(view) === -1 ? null : view;
3788
+ }
3789
+ function changeView(view) {
3790
+ var key = viewKey(view);
3791
+ if (key === null) {
3792
+ warn("changeView(" + JSON.stringify(view) + "): no such layout mode");
3793
+ return;
3794
+ }
3795
+ var from = curView;
3796
+ switchLayout(key);
3797
+ if (key === from) {
3798
+ return;
3799
+ }
3800
+ settingsScope().forEach(function(scope) {
3801
+ all(scope, ".ge-utilities").forEach(function(section) {
3802
+ renderUtilities(section);
3803
+ });
3804
+ });
3805
+ refreshPreviews(canvas);
3806
+ plugins("onViewChange", key);
3807
+ emit("view-change", { canvas, breakpoint: key, from, to: key });
3808
+ }
3809
+ function getView() {
3810
+ return curView;
3811
+ }
3812
+ function featureMethod(name, plugin, file) {
3813
+ return function() {
3814
+ if (!featureMethods[name]) {
3815
+ warnOnceHere("plugin:" + plugin, name + " needs the " + plugin + " plugin: include dist/plugins/grideditor." + file + ".js after the editor");
3816
+ return null;
3817
+ }
3818
+ return featureMethods[name].apply(null, arguments);
3819
+ };
3820
+ }
3821
+ var own = {
3822
+ getHtml,
3823
+ getPlainHtml,
3824
+ init: function() {
3825
+ defer(init);
3826
+ },
3827
+ reset: function() {
3828
+ defer(reset);
3829
+ },
3830
+ deinit,
3831
+ destroy,
3832
+ changeView,
3833
+ getView,
3834
+ createRow: apiCreateRow,
3835
+ createColumn: apiCreateColumn,
3836
+ createText: function(type, options) {
3837
+ if (!featureMethods.createText) {
3838
+ warnOnceHere("plugin:text", "createText needs a text editor plugin: include dist/plugins/grideditor.tinymce.js, or another editor's, after the editor");
3839
+ return null;
3840
+ }
3841
+ return featureMethods.createText(type, options);
3842
+ },
3843
+ createElement: featureMethod("createElement", "elements", "elements"),
3844
+ createSection: featureMethod("createSection", "sections", "sections"),
3845
+ createContainer: apiCreateContainer,
3846
+ addTab: function(container, options) {
3847
+ return addPaneTo(container, "tabs", options);
3848
+ },
3849
+ addAccordionItem: function(container, options) {
3850
+ return addPaneTo(container, "accordion", options);
3851
+ },
3852
+ setLocale,
3853
+ getUtility,
3854
+ setUtility
3855
+ };
3856
+ Object.keys(own).forEach(function(name) {
3857
+ var value = !!(METHODS[name] && METHODS[name].value);
3858
+ instance[name] = function() {
3859
+ if (destroyed) {
3860
+ warnOnceHere("destroyed:" + name, t("warning.destroyed", { method: name }));
3861
+ if (name === "getHtml") {
3862
+ return canvas.innerHTML;
3863
+ }
3864
+ if (name === "getPlainHtml") {
3865
+ return plainHtml(canvas.innerHTML);
3866
+ }
3867
+ return value ? null : instance;
3868
+ }
3869
+ var result = own[name].apply(instance, arguments);
3870
+ return value ? result : instance;
3871
+ };
3872
+ });
3873
+ instance.canvas = canvas;
3874
+ instance.settings = settingsCopy();
3875
+ instances.set(canvas, instance);
3876
+ loadPlugins();
3877
+ instance.settings = settingsCopy();
3878
+ setup();
3879
+ init();
3880
+ GridEditor._created.forEach(function(hook) {
3881
+ hook(instance);
3882
+ });
3883
+ }
3884
+ GridEditor._created = [];
3885
+ GridEditor.containers = {};
3886
+ GridEditor.features = {};
3887
+ GridEditor.utilities = {};
3888
+ GridEditor.texts = {};
3889
+ GridEditor.t = translate;
3890
+ GridEditor._plainHtml = plainHtml;
3891
+ GridEditor.Sortable = null;
3892
+ GridEditor.bootstrap = null;
3893
+ GridEditor.version = false ? "dev" : "7.0.0";
3894
+ GridEditor.locales = {
3895
+ en: {
3896
+ "tool.move": "Move",
3897
+ "tool.settings": "Settings",
3898
+ "tool.add_row": "Add row",
3899
+ "tool.delete_text": "Remove text",
3900
+ "tool.delete_plain": "Remove content",
3901
+ "tool.convert_type": "Edit as {editor} text",
3902
+ "text.no_editor": 'No text editor "{type}" is loaded: this text can be moved and deleted, not edited',
3903
+ "tool.add_column": "Add column\n(hold to choose the width)",
3904
+ "tool.column_size": "{size} of 12",
3905
+ "tool.column_equal": "Equal: shares what the row has left",
3906
+ "tool.column_auto": "Auto: as wide as its content",
3907
+ "tool.delete_row": "Remove row",
3908
+ "tool.delete_column": "Remove col",
3909
+ "tool.delete_container": "Remove container",
3910
+ "tool.delete_pane": "Remove pane",
3911
+ "tool.rename": "Double click to rename",
3912
+ "tool.column_narrower": "Make column narrower\n(hold shift for min)",
3913
+ "tool.column_wider": "Make column wider\n(hold shift for max)",
3914
+ "tool.indent_decrease": "Decrease indent\n(hold shift for none)",
3915
+ "tool.indent_increase": "Increase indent\n(hold shift for max)",
3916
+ "tool.edit_source": "Edit Source Code",
3917
+ "tool.preview": "Preview",
3918
+ "panel.title": "{kind} settings",
3919
+ "panel.close": "Close",
3920
+ "panel.done": "Done",
3921
+ "panel.id": "Id",
3922
+ "panel.classes": "Classes",
3923
+ "panel.kind_row": "Row",
3924
+ "panel.kind_column": "Column",
3925
+ "panel.kind_element": "Element",
3926
+ "panel.kind_section": "Section",
3927
+ "panel.kind_tab": "Tab",
3928
+ "panel.kind_accordion_item": "Accordion item",
3929
+ "tool.id_placeholder": "id",
3930
+ "tool.id_title": "Set a unique identifier",
3931
+ "tool.classes_placeholder": "classes",
3932
+ "tool.classes_title": "Css classes, separated by spaces",
3933
+ "tool.toggle_class": 'Toggle "{label}" styling',
3934
+ "row.add": "Add row {layout}",
3935
+ "row.add_row_cols": "Add a row of {columns} columns, {counts} per row",
3936
+ "confirm.title": "Confirm",
3937
+ "confirm.ok": "Delete",
3938
+ "confirm.cancel": "Cancel",
3939
+ "confirm.delete_row": "Delete row?",
3940
+ "confirm.delete_column": "Delete column?",
3941
+ "confirm.delete_text": "Delete this text?",
3942
+ "confirm.delete_plain": "Delete this content?",
3943
+ "confirm.delete_container": "Delete this container and everything in it?",
3944
+ "view.all": "All sizes",
3945
+ "view.xs": "Phone",
3946
+ "view.sm": "Tablet",
3947
+ "view.md": "Small desktop",
3948
+ "view.lg": "Desktop",
3949
+ "view.xl": "Large desktop",
3950
+ "view.xxl": "Widescreen",
3951
+ "utility.section": "Responsive: {view}",
3952
+ "utility.col_width": "Width",
3953
+ "utility.col_equal": "Equal",
3954
+ "utility.col_auto": "Auto",
3955
+ "utility.col_from_row": "From the row: {count}",
3956
+ "utility.row_cols": "Columns per row",
3957
+ "badge.row_cols": "{count} per row",
3958
+ "badge.row_cols_auto": "As wide as their content",
3959
+ "utility.default": "Default",
3960
+ "utility.inherit": "Inherit: {value} (from {breakpoint})",
3961
+ "utility.varies": "Changes at {breakpoints}; choosing here replaces that",
3962
+ "error.sortable_missing": "SortableJS not available! Make sure you loaded the Sortable js file; dragging is off without it.",
3963
+ "warning.setting_removed": "The {setting} setting was removed in 4.0. Use {replacement} instead.",
3964
+ "warning.already_editing": "This element already has an editor: that one is handed back, with the options it was made with.",
3965
+ "warning.destroyed": "{method}() was called on an editor that has been destroyed, and does nothing.",
3966
+ "warning.duplicate_build": "grideditor.js was loaded twice: the first GridEditor is kept.",
3967
+ "warning.plugin_6x": 'The "{name}" plugin is written for grid-editor 6 and is not loaded. Plugins register on GridEditor since 7.0: see UPGRADING.md.',
3968
+ "warning.adapter_no_jquery": "grideditor.jquery.js needs jQuery 4, and there is no jQuery on the page: the jQuery API is not there.",
3969
+ "error.tinymce_missing": "tinyMCE not available! Make sure you loaded the tinyMCE js file.",
3970
+ "error.ckeditor_missing": "CKEditor not available! Make sure you loaded the CKEditor js file.",
3971
+ "error.summernote_missing": "Summernote not available! Make sure you loaded jQuery and the Summernote js file."
3972
+ }
3973
+ };
3974
+
3975
+ // src/js/grideditor.classic.js
3976
+ if (window.GridEditor) {
3977
+ if (window.console && window.console.warn) {
3978
+ window.console.warn("grid-editor: " + GridEditor.t({ locale: "en" }, "warning.duplicate_build"));
3979
+ }
3980
+ } else {
3981
+ window.GridEditor = GridEditor;
3982
+ }
3983
+ })();