@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
package/src/js/dom.js ADDED
@@ -0,0 +1,401 @@
1
+ /**
2
+ * The DOM, the way grid-editor uses it.
3
+ *
4
+ * Small helpers over the browser's own API, for the core and the shipped
5
+ * plugins. Not a public API: a plugin of a host's own is free to write its
6
+ * DOM code however it likes, and this file makes no promise to it.
7
+ *
8
+ * Stateless on purpose. The build puts a copy of this file in each plugin's
9
+ * classic script, so anything kept here would be kept once per copy; a
10
+ * module that needs to remember something about a node keeps its own
11
+ * WeakMap.
12
+ */
13
+
14
+ /** Every element under `root` matching `selector`, as an array. */
15
+ export function all(root, selector) {
16
+ return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];
17
+ }
18
+
19
+ /** The first element under `root` matching `selector`, or null. */
20
+ export function one(root, selector) {
21
+ return root ? root.querySelector(selector) : null;
22
+ }
23
+
24
+ /** `root` itself when it matches, then every element under it that does. */
25
+ export function selfAndAll(root, selector) {
26
+ if (!root) { return []; }
27
+
28
+ var found = all(root, selector);
29
+ if (root.nodeType === 1 && root.matches(selector)) { found.unshift(root); }
30
+ return found;
31
+ }
32
+
33
+ /** The element children of `node`, those matching `selector` if one is given. */
34
+ export function children(node, selector) {
35
+ if (!node) { return []; }
36
+
37
+ return Array.prototype.filter.call(node.children, function(each) {
38
+ return !selector || each.matches(selector);
39
+ });
40
+ }
41
+
42
+ /** The first element child matching `selector`, or null. */
43
+ export function child(node, selector) {
44
+ return children(node, selector)[0] || null;
45
+ }
46
+
47
+ /** The nearest ancestor-or-self matching `selector` below `stopAt`, or null. */
48
+ export function closest(node, selector, stopAt) {
49
+ var found = node && node.nodeType === 1 ? node.closest(selector) : null;
50
+
51
+ if (found && stopAt && found !== stopAt && !stopAt.contains(found)) { return null; }
52
+ return found;
53
+ }
54
+
55
+ /** Whether `node` is an element matching `selector`. */
56
+ export function is(node, selector) {
57
+ return !!node && node.nodeType === 1 && node.matches(selector);
58
+ }
59
+
60
+ /** Whether `node` is in the document. */
61
+ export function attached(node) {
62
+ return !!node && document.documentElement.contains(node);
63
+ }
64
+
65
+ /** The element siblings after `node` that match `selector`. */
66
+ export function nextAll(node, selector) {
67
+ var found = [];
68
+
69
+ for (var next = node.nextElementSibling; next; next = next.nextElementSibling) {
70
+ if (!selector || next.matches(selector)) { found.push(next); }
71
+ }
72
+ return found;
73
+ }
74
+
75
+ /** The ancestors of `node` up to, and not including, `stop`, nearest first. */
76
+ export function parentsUntil(node, stop) {
77
+ var found = [];
78
+
79
+ for (var parent = node.parentElement; parent && parent !== stop; parent = parent.parentElement) {
80
+ found.push(parent);
81
+ }
82
+ return found;
83
+ }
84
+
85
+ /**
86
+ * The nodes the html parses into, detached. Parsed the way innerHTML parses,
87
+ * so a <script> in it never runs, here or once it is in the page.
88
+ */
89
+ export function parse(html) {
90
+ var template = document.createElement('template');
91
+ template.innerHTML = html;
92
+ return Array.prototype.slice.call(template.content.childNodes);
93
+ }
94
+
95
+ /** The one element the html is, detached. */
96
+ export function create(html) {
97
+ var nodes = parse(html.trim());
98
+
99
+ for (var i = 0; i < nodes.length; i++) {
100
+ if (nodes[i].nodeType === 1) { return nodes[i]; }
101
+ }
102
+ return null;
103
+ }
104
+
105
+ /** An element of `tag`, with `attributes` and `text`. */
106
+ export function element(tag, attributes, text) {
107
+ var node = document.createElement(tag);
108
+
109
+ Object.keys(attributes || {}).forEach(function(name) {
110
+ var value = attributes[name];
111
+ if (value !== null && value !== undefined && value !== false) { node.setAttribute(name, value); }
112
+ });
113
+ if (text !== undefined && text !== null) { node.textContent = text; }
114
+
115
+ return node;
116
+ }
117
+
118
+ /** Replace what `node` holds with `html`. A <script> in it does not run. */
119
+ export function setHtml(node, html) {
120
+ node.innerHTML = html === undefined || html === null ? '' : String(html);
121
+ return node;
122
+ }
123
+
124
+ /** Add one or several space separated classes. */
125
+ export function addClass(node, names) {
126
+ split(names).forEach(function(name) { node.classList.add(name); });
127
+ return node;
128
+ }
129
+
130
+ export function removeClass(node, names) {
131
+ split(names).forEach(function(name) { node.classList.remove(name); });
132
+ return node;
133
+ }
134
+
135
+ /** Each class on, or off, or flipped when `on` is not given. */
136
+ export function toggleClass(node, names, state) {
137
+ split(names).forEach(function(name) {
138
+ if (state === undefined) {
139
+ node.classList.toggle(name);
140
+ } else {
141
+ node.classList.toggle(name, !!state);
142
+ }
143
+ });
144
+ return node;
145
+ }
146
+
147
+ export function hasClass(node, name) {
148
+ return !!node && node.nodeType === 1 && node.classList.contains(name);
149
+ }
150
+
151
+ function split(names) {
152
+ return String(names || '').split(/\s+/).filter(Boolean);
153
+ }
154
+
155
+ /** Take the class attribute off when there is nothing left in it. */
156
+ export function dropEmptyClass(node) {
157
+ if (!node.getAttribute('class')) { node.removeAttribute('class'); }
158
+ return node;
159
+ }
160
+
161
+ /** Take the style attribute off when there is nothing left in it. */
162
+ export function dropEmptyStyle(node) {
163
+ if (!node.getAttribute('style')) { node.removeAttribute('style'); }
164
+ return node;
165
+ }
166
+
167
+ /** Set attributes; a null or undefined value takes the attribute off. */
168
+ export function attr(node, attributes) {
169
+ Object.keys(attributes).forEach(function(name) {
170
+ var value = attributes[name];
171
+
172
+ if (value === null || value === undefined) {
173
+ node.removeAttribute(name);
174
+ } else {
175
+ node.setAttribute(name, value);
176
+ }
177
+ });
178
+ return node;
179
+ }
180
+
181
+ /**
182
+ * Inline styles, by css property name. A number is pixels for the properties
183
+ * that take a length, as jQuery had it; an empty string takes one off.
184
+ */
185
+ export function css(node, styles) {
186
+ Object.keys(styles).forEach(function(property) {
187
+ var value = styles[property];
188
+
189
+ if (typeof value === 'number' && !UNITLESS[property]) { value = value + 'px'; }
190
+ node.style.setProperty(property, value === null || value === undefined ? '' : String(value));
191
+ });
192
+ return node;
193
+ }
194
+
195
+ var UNITLESS = { opacity: true, 'z-index': true, 'flex-grow': true, 'flex-shrink': true, order: true };
196
+
197
+ /** What an element of this tag shows as when nothing hides it. */
198
+ var defaultDisplays = {};
199
+
200
+ function defaultDisplay(node) {
201
+ var tag = node.nodeName;
202
+
203
+ if (!defaultDisplays[tag]) {
204
+ var probe = document.body.appendChild(document.createElement(tag));
205
+ defaultDisplays[tag] = getComputedStyle(probe).display;
206
+ probe.remove();
207
+ if (defaultDisplays[tag] === 'none') { defaultDisplays[tag] = 'block'; }
208
+ }
209
+ return defaultDisplays[tag];
210
+ }
211
+
212
+ /** Show a node: its inline display:none off, and a display of its own if a stylesheet hides it. */
213
+ export function show(node) {
214
+ node.style.removeProperty('display');
215
+ if (getComputedStyle(node).display === 'none') { node.style.display = defaultDisplay(node); }
216
+ return node;
217
+ }
218
+
219
+ export function hide(node) {
220
+ node.style.display = 'none';
221
+ return node;
222
+ }
223
+
224
+ /** Show or hide; flip when `on` is not given. */
225
+ export function toggle(node, state) {
226
+ if (state === undefined) { state = !visible(node); }
227
+ return state ? show(node) : hide(node);
228
+ }
229
+
230
+ /** Whether a node takes up room: what jQuery's :visible meant. */
231
+ export function visible(node) {
232
+ return !!(node.offsetWidth || node.offsetHeight || node.getClientRects().length);
233
+ }
234
+
235
+ /** The border box's width, fractions included. */
236
+ export function outerWidth(node) {
237
+ return node.getBoundingClientRect().width;
238
+ }
239
+
240
+ export function outerHeight(node) {
241
+ return node.getBoundingClientRect().height;
242
+ }
243
+
244
+ /** The content box's height, which is what jQuery's height() gave. */
245
+ export function contentHeight(node) {
246
+ var style = getComputedStyle(node);
247
+ return node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);
248
+ }
249
+
250
+ /** Where a node is on the page, not in the window. */
251
+ export function offset(node) {
252
+ var box = node.getBoundingClientRect();
253
+ return { top: box.top + window.pageYOffset, left: box.left + window.pageXOffset };
254
+ }
255
+
256
+ /** Its index among its parent's element children, those matching `selector` if given. */
257
+ export function indexIn(node, selector) {
258
+ return children(node.parentElement, selector).indexOf(node);
259
+ }
260
+
261
+ /** Put `node` right after `reference`. */
262
+ export function insertAfter(node, reference) {
263
+ reference.parentNode.insertBefore(node, reference.nextSibling);
264
+ return node;
265
+ }
266
+
267
+ /** Replace `node` with what it holds. */
268
+ export function unwrap(node) {
269
+ var parent = node.parentNode;
270
+
271
+ while (node.firstChild) { parent.insertBefore(node.firstChild, node); }
272
+ node.remove();
273
+ }
274
+
275
+ /** Put `node` inside `wrapper`, where `node` was. */
276
+ export function wrap(node, wrapper) {
277
+ node.parentNode.insertBefore(wrapper, node);
278
+ wrapper.appendChild(node);
279
+ return wrapper;
280
+ }
281
+
282
+ /**
283
+ * Listen on `root` for `types` (space separated) on descendants that match
284
+ * `selector`, with `this` the matched element, as jQuery's delegated
285
+ * handlers had it. Hands back the listener, for removeEventListener; a
286
+ * signal in `options` removes it too.
287
+ */
288
+ export function delegate(root, types, selector, handler, options) {
289
+ var listener = function(event) {
290
+ var match = closest(event.target, selector, root);
291
+ if (match && root.contains(match)) { return handler.call(match, event); }
292
+ return undefined;
293
+ };
294
+
295
+ split(types).forEach(function(type) { root.addEventListener(type, listener, options); });
296
+ return listener;
297
+ }
298
+
299
+ /** Listen for several space separated event types with one handler. */
300
+ export function on(target, types, handler, options) {
301
+ split(types).forEach(function(type) { target.addEventListener(type, handler, options); });
302
+ return handler;
303
+ }
304
+
305
+ export function off(target, types, handler, options) {
306
+ split(types).forEach(function(type) { target.removeEventListener(type, handler, options); });
307
+ }
308
+
309
+ /** A mouse event of `type` sent to `node`, the way a pointer would. */
310
+ export function fire(node, type) {
311
+ node.dispatchEvent(new MouseEvent(type, { bubbles: type !== 'mouseenter' && type !== 'mouseleave' }));
312
+ }
313
+
314
+ /* ------------------------------------------------------------------
315
+ * Taking a node away, visibly.
316
+ *
317
+ * The durations are the ones 6.x had through jQuery: 400 ms unless the
318
+ * caller says otherwise. `done` runs once the node is out of sight, which is
319
+ * when the caller removes it; a node that is already out of sight is done at
320
+ * once, on the next task, as jQuery had it.
321
+ * ------------------------------------------------------------------ */
322
+
323
+ var DEFAULT_DURATION = 400;
324
+
325
+ function animateAway(node, frames, duration, done) {
326
+ duration = duration === undefined ? DEFAULT_DURATION : duration;
327
+
328
+ var finish = function() {
329
+ hide(node);
330
+ if (done) { done(); }
331
+ };
332
+
333
+ if (!visible(node) || !node.animate || duration <= 0) {
334
+ window.setTimeout(finish, 0);
335
+ return;
336
+ }
337
+
338
+ var animation = node.animate(frames(getComputedStyle(node)), {
339
+ duration: duration,
340
+ easing: 'ease-in-out',
341
+ });
342
+ var called = false;
343
+ var once = function() {
344
+ if (called) { return; }
345
+ called = true;
346
+ finish();
347
+ };
348
+
349
+ animation.onfinish = once;
350
+ animation.oncancel = once;
351
+ }
352
+
353
+ /** Fold a node up to nothing, then hide it. */
354
+ export function slideUp(node, duration, done) {
355
+ if (typeof duration === 'function') {
356
+ done = duration;
357
+ duration = undefined;
358
+ }
359
+
360
+ node.style.overflow = 'hidden';
361
+ animateAway(node, function(style) {
362
+ return [
363
+ {
364
+ height: style.height,
365
+ paddingTop: style.paddingTop,
366
+ paddingBottom: style.paddingBottom,
367
+ marginTop: style.marginTop,
368
+ marginBottom: style.marginBottom,
369
+ },
370
+ { height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px' },
371
+ ];
372
+ }, duration, function() {
373
+ node.style.removeProperty('overflow');
374
+ if (done) { done(); }
375
+ });
376
+ }
377
+
378
+ /** Fade a node out, then hide it. */
379
+ export function fadeOut(node, duration, done) {
380
+ animateAway(node, function(style) {
381
+ return [{ opacity: style.opacity }, { opacity: 0 }];
382
+ }, duration, done);
383
+ }
384
+
385
+ /** Fade and fold a node, in height and, with `width`, sideways too, then hide it. */
386
+ export function shrinkAway(node, duration, done, width) {
387
+ node.style.overflow = 'hidden';
388
+ animateAway(node, function(style) {
389
+ var from = { opacity: style.opacity, height: style.height };
390
+ var to = { opacity: 0, height: '0px' };
391
+
392
+ if (width) {
393
+ from.width = style.width;
394
+ to.width = '0px';
395
+ }
396
+ return [from, to];
397
+ }, duration, function() {
398
+ node.style.removeProperty('overflow');
399
+ if (done) { done(); }
400
+ });
401
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The classic script's entry: the editor as window.GridEditor, for a page
3
+ * that loads it with a <script> tag and its plugins after it.
4
+ *
5
+ * Loaded twice, the first copy is kept: its plugins registered on it, and
6
+ * the editors on the page are its.
7
+ */
8
+ import { GridEditor } from './grideditor.js';
9
+
10
+ if (window.GridEditor) {
11
+ if (window.console && window.console.warn) {
12
+ window.console.warn('grid-editor: ' + GridEditor.t({ locale: 'en' }, 'warning.duplicate_build'));
13
+ }
14
+ } else {
15
+ window.GridEditor = GridEditor;
16
+ }