@themarioga/grid-editor 8.4.0 → 8.5.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 (36) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +27 -1
  3. package/dist/grideditor.bundle.min.js +3 -3
  4. package/dist/grideditor.d.ts +17 -1
  5. package/dist/grideditor.esm.js +13 -3
  6. package/dist/grideditor.js +13 -3
  7. package/dist/grideditor.min.js +2 -2
  8. package/dist/grideditor.min.js.map +2 -2
  9. package/dist/locales/grideditor.es.esm.js +1 -0
  10. package/dist/locales/grideditor.es.js +1 -0
  11. package/dist/locales/grideditor.es.min.js +1 -1
  12. package/dist/locales/grideditor.es.min.js.map +2 -2
  13. package/dist/plugins/grideditor.ckeditor.esm.js +1 -1
  14. package/dist/plugins/grideditor.ckeditor.js +1 -1
  15. package/dist/plugins/grideditor.ckeditor.min.js +1 -1
  16. package/dist/plugins/grideditor.ckeditor.min.js.map +2 -2
  17. package/dist/plugins/grideditor.elements.esm.js +72 -1
  18. package/dist/plugins/grideditor.elements.js +72 -1
  19. package/dist/plugins/grideditor.elements.min.js +1 -1
  20. package/dist/plugins/grideditor.elements.min.js.map +3 -3
  21. package/dist/plugins/grideditor.summernote.esm.js +1 -1
  22. package/dist/plugins/grideditor.summernote.js +1 -1
  23. package/dist/plugins/grideditor.summernote.min.js +1 -1
  24. package/dist/plugins/grideditor.summernote.min.js.map +2 -2
  25. package/dist/plugins/grideditor.tinymce.esm.js +1 -1
  26. package/dist/plugins/grideditor.tinymce.js +1 -1
  27. package/dist/plugins/grideditor.tinymce.min.js +1 -1
  28. package/dist/plugins/grideditor.tinymce.min.js.map +2 -2
  29. package/docs/locale-keys.md +2 -1
  30. package/docs/plugins.md +6 -5
  31. package/package.json +1 -1
  32. package/src/js/grideditor.js +6 -0
  33. package/src/js/locales/grideditor.es.js +1 -0
  34. package/src/js/plugins/grideditor.elements.js +94 -1
  35. package/src/js/text/grideditor.text.js +1 -1
  36. package/types/grideditor.d.ts +17 -1
@@ -123,11 +123,76 @@ Object.assign(GridEditor.locales.en, {
123
123
  var NOT_ELEMENTS = ".row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle";
124
124
  GridEditor.features.elements = function(ge) {
125
125
  var warnedIntoText = false;
126
+ var types = validTypes();
126
127
  function elementsEnabled() {
127
128
  if (ge.settings.elements.enabled !== "auto") {
128
129
  return !!ge.settings.elements.enabled;
129
130
  }
130
- return ge.settings.elements.auto || !!ge.canvas.querySelector(ge.settings.elements.selector);
131
+ return ge.settings.elements.auto || types.length > 0 || !!ge.canvas.querySelector(ge.settings.elements.selector);
132
+ }
133
+ function validTypes() {
134
+ return (ge.settings.elements.types || []).filter(function(type, index) {
135
+ var named = type && typeof type.type === "string" && type.type.trim() !== "";
136
+ var html = type && (typeof type.html === "function" || typeof type.html === "string" && type.html.trim() !== "");
137
+ if (!named || !html) {
138
+ ge.warn("elements.types[" + index + "]: a type needs a type name and its html, as a string or a function; it is left off the toolbar.");
139
+ }
140
+ return named && html;
141
+ });
142
+ }
143
+ function typeItem(type) {
144
+ var mismatched = false;
145
+ return {
146
+ // Asked again whenever the toolbar is built, so setLocale
147
+ // translates a labelKey
148
+ label: function() {
149
+ return labelOf(type);
150
+ },
151
+ iconClass: type.iconClass,
152
+ group: type.group || "elements",
153
+ kind: "element",
154
+ inColumn: true,
155
+ create: function() {
156
+ var element2 = makeElement(type);
157
+ if (element2 && !mismatched && !ge.settings.elements.auto && !element2.matches(ge.settings.elements.selector)) {
158
+ mismatched = true;
159
+ ge.warn('elements.types "' + type.type + '": what it makes does not match elements.selector "' + ge.settings.elements.selector + '", so it will not be an element once the editor looks again.');
160
+ }
161
+ return element2;
162
+ }
163
+ };
164
+ }
165
+ function labelOf(type) {
166
+ if (type.labelKey) {
167
+ return ge.t(type.labelKey);
168
+ }
169
+ return type.label || type.type;
170
+ }
171
+ function makeElement(type) {
172
+ var made;
173
+ try {
174
+ made = typeof type.html === "function" ? type.html() : type.html;
175
+ } catch (error) {
176
+ ge.warn('elements.types "' + type.type + '": its html function threw (' + error.message + "); nothing was added.");
177
+ return null;
178
+ }
179
+ var nodes = typeof made === "string" ? parse(made) : made && made.nodeType ? [made] : [];
180
+ nodes = nodes.filter(function(node) {
181
+ return node.nodeType !== 3 || node.textContent.trim() !== "";
182
+ });
183
+ if (!nodes.length) {
184
+ ge.warn('elements.types "' + type.type + '": its html came out empty; nothing was added.');
185
+ return null;
186
+ }
187
+ var element2 = nodes.length === 1 && nodes[0].nodeType === 1 ? nodes[0] : element("div");
188
+ if (element2 !== nodes[0] || nodes.length > 1) {
189
+ fill(element2, nodes);
190
+ }
191
+ element2.setAttribute("data-ge-element", type.type);
192
+ if (!element2.hasAttribute("data-ge-label")) {
193
+ element2.setAttribute("data-ge-label", labelOf(type));
194
+ }
195
+ return element2;
131
196
  }
132
197
  function isElement(node) {
133
198
  return ge.settings.elements.auto ? !node.matches(NOT_ELEMENTS) : node.matches(ge.settings.elements.selector);
@@ -204,6 +269,9 @@ GridEditor.features.elements = function(ge) {
204
269
  });
205
270
  return placed;
206
271
  }
272
+ function elementsOff() {
273
+ return ge.settings.elements.enabled === false;
274
+ }
207
275
  function nodeFrom(node) {
208
276
  if (typeof node === "string") {
209
277
  return document.querySelector(node);
@@ -242,6 +310,9 @@ GridEditor.features.elements = function(ge) {
242
310
  methods: {
243
311
  createElement: apiCreateElement
244
312
  },
313
+ // A button for each type the host offers, in the elements category
314
+ // unless the type names another
315
+ toolbar: elementsOff() ? [] : types.map(typeItem),
245
316
  /** A node this plugin marked is an element, whatever else it is. */
246
317
  kindOf: function(node) {
247
318
  return hasClass(node, "ge-element") ? "element" : null;
@@ -127,11 +127,76 @@
127
127
  var NOT_ELEMENTS = ".row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle";
128
128
  GridEditor.features.elements = function(ge) {
129
129
  var warnedIntoText = false;
130
+ var types = validTypes();
130
131
  function elementsEnabled() {
131
132
  if (ge.settings.elements.enabled !== "auto") {
132
133
  return !!ge.settings.elements.enabled;
133
134
  }
134
- return ge.settings.elements.auto || !!ge.canvas.querySelector(ge.settings.elements.selector);
135
+ return ge.settings.elements.auto || types.length > 0 || !!ge.canvas.querySelector(ge.settings.elements.selector);
136
+ }
137
+ function validTypes() {
138
+ return (ge.settings.elements.types || []).filter(function(type, index) {
139
+ var named = type && typeof type.type === "string" && type.type.trim() !== "";
140
+ var html = type && (typeof type.html === "function" || typeof type.html === "string" && type.html.trim() !== "");
141
+ if (!named || !html) {
142
+ ge.warn("elements.types[" + index + "]: a type needs a type name and its html, as a string or a function; it is left off the toolbar.");
143
+ }
144
+ return named && html;
145
+ });
146
+ }
147
+ function typeItem(type) {
148
+ var mismatched = false;
149
+ return {
150
+ // Asked again whenever the toolbar is built, so setLocale
151
+ // translates a labelKey
152
+ label: function() {
153
+ return labelOf(type);
154
+ },
155
+ iconClass: type.iconClass,
156
+ group: type.group || "elements",
157
+ kind: "element",
158
+ inColumn: true,
159
+ create: function() {
160
+ var element2 = makeElement(type);
161
+ if (element2 && !mismatched && !ge.settings.elements.auto && !element2.matches(ge.settings.elements.selector)) {
162
+ mismatched = true;
163
+ ge.warn('elements.types "' + type.type + '": what it makes does not match elements.selector "' + ge.settings.elements.selector + '", so it will not be an element once the editor looks again.');
164
+ }
165
+ return element2;
166
+ }
167
+ };
168
+ }
169
+ function labelOf(type) {
170
+ if (type.labelKey) {
171
+ return ge.t(type.labelKey);
172
+ }
173
+ return type.label || type.type;
174
+ }
175
+ function makeElement(type) {
176
+ var made;
177
+ try {
178
+ made = typeof type.html === "function" ? type.html() : type.html;
179
+ } catch (error) {
180
+ ge.warn('elements.types "' + type.type + '": its html function threw (' + error.message + "); nothing was added.");
181
+ return null;
182
+ }
183
+ var nodes = typeof made === "string" ? parse(made) : made && made.nodeType ? [made] : [];
184
+ nodes = nodes.filter(function(node) {
185
+ return node.nodeType !== 3 || node.textContent.trim() !== "";
186
+ });
187
+ if (!nodes.length) {
188
+ ge.warn('elements.types "' + type.type + '": its html came out empty; nothing was added.');
189
+ return null;
190
+ }
191
+ var element2 = nodes.length === 1 && nodes[0].nodeType === 1 ? nodes[0] : element("div");
192
+ if (element2 !== nodes[0] || nodes.length > 1) {
193
+ fill(element2, nodes);
194
+ }
195
+ element2.setAttribute("data-ge-element", type.type);
196
+ if (!element2.hasAttribute("data-ge-label")) {
197
+ element2.setAttribute("data-ge-label", labelOf(type));
198
+ }
199
+ return element2;
135
200
  }
136
201
  function isElement(node) {
137
202
  return ge.settings.elements.auto ? !node.matches(NOT_ELEMENTS) : node.matches(ge.settings.elements.selector);
@@ -208,6 +273,9 @@
208
273
  });
209
274
  return placed;
210
275
  }
276
+ function elementsOff() {
277
+ return ge.settings.elements.enabled === false;
278
+ }
211
279
  function nodeFrom(node) {
212
280
  if (typeof node === "string") {
213
281
  return document.querySelector(node);
@@ -246,6 +314,9 @@
246
314
  methods: {
247
315
  createElement: apiCreateElement
248
316
  },
317
+ // A button for each type the host offers, in the elements category
318
+ // unless the type names another
319
+ toolbar: elementsOff() ? [] : types.map(typeItem),
249
320
  /** A node this plugin marked is an element, whatever else it is. */
250
321
  kindOf: function(node) {
251
322
  return hasClass(node, "ge-element") ? "element" : null;
@@ -1 +1 @@
1
- (()=>{var s=window.GridEditor;if(!s||typeof s.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");function p(e,r){return e?Array.prototype.slice.call(e.querySelectorAll(r)):[]}function g(e,r){return e?Array.prototype.filter.call(e.children,function(o){return!r||o.matches(r)}):[]}function v(e,r){return g(e,r)[0]||null}function x(e,r){return!!e&&e.nodeType===1&&e.matches(r)}function y(e){var r=document.createElement("template");return r.innerHTML=e,Array.prototype.slice.call(r.content.childNodes)}function h(e,r,o){var u=document.createElement(e);return Object.keys(r||{}).forEach(function(a){var l=r[a];l!=null&&l!==!1&&u.setAttribute(a,l)}),o!=null&&(u.textContent=o),u}function E(e,r){return w(r).forEach(function(o){e.classList.add(o)}),e}function b(e,r){return w(r).forEach(function(o){e.classList.remove(o)}),e}function d(e,r){return!!e&&e.nodeType===1&&e.classList.contains(r)}function w(e){return String(e||"").split(/\s+/).filter(Boolean)}function C(e){return e.getAttribute("class")||e.removeAttribute("class"),e}function L(e){return e.style.display="none",e}function N(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}var O=400;function _(e,r,o,u){o=o===void 0?O:o;var a=function(){L(e),u&&u()};if(!N(e)||!e.animate||o<=0){window.setTimeout(a,0);return}var l=e.animate(r(getComputedStyle(e)),{duration:o,easing:"ease-in-out"}),f=!1,m=function(){f||(f=!0,a())};l.onfinish=m,l.oncancel=m}function T(e,r,o,u){e.style.overflow="hidden",_(e,function(a){var l={opacity:a.opacity,height:a.height},f={opacity:0,height:"0px"};return u&&(l.width=a.width,f.width="0px"),[l,f]},r,function(){e.style.removeProperty("overflow"),o&&o()})}Object.assign(s.locales.en,{"tool.delete_element":"Remove element","tool.element_info":"Element: {name}","confirm.delete_element":"Delete element?"});var H=".row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle";s.features.elements=function(e){var r=!1;function o(){return e.settings.elements.enabled!=="auto"?!!e.settings.elements.enabled:e.settings.elements.auto||!!e.canvas.querySelector(e.settings.elements.selector)}function u(t){return e.settings.elements.auto?!t.matches(H):t.matches(e.settings.elements.selector)}function a(){o()&&p(e.canvas,".column").forEach(function(t){g(t).forEach(function(n){!d(n,"ge-element")&&!u(n)||(E(n,"ge-element"),v(n,".ge-tools-drawer")||f(n))})})}function l(){p(e.canvas,".ge-element").forEach(function(t){b(t,"ge-element"),C(t)})}function f(t){var n=h("div",{class:"ge-tools-drawer ge-element-drawer"});t.insertBefore(n,t.firstChild),e.createMoveTool(n),e.createTool(n,e.t("tool.element_info",{name:m(t)}),"ge-element-info","bi bi-info-circle"),e.addSettingsTool(n,t,e.settings.element_classes),e.settings.element_tools.forEach(function(i){e.createTool(n,i.title||"",i.className||"",i.iconClass||"bi bi-wrench",i.on)}),e.createTool(n,e.t("tool.delete_element"),"ge-delete-element","bi bi-trash",function(){e.deleteNode("element",t,e.t("confirm.delete_element"),function(i){T(t,300,i)})})}function m(t){var n=t.getAttribute("data-ge-element"),i=t.getAttribute("data-ge-label");return i&&n?i+" ("+n+")":i||n||t.tagName.toLowerCase()}function A(t){var n=Object.assign({},t);return[["appendTo","insertAfter"],["prependTo","insertBefore"]].forEach(function(i){var c=t[i[0]]!==void 0?S(t[i[0]]):null;!c||!c.matches(".ge-content")||(r||(r=!0,e.warn("createElement: an element is a block of the column since 6.0, not part of a content area's text; it goes beside the content area. Place it in a column instead.")),delete n[i[0]],n[i[1]]=d(c.parentElement,"ge-text-block")?c.parentElement:c)}),n}function S(t){return typeof t=="string"?document.querySelector(t):t&&t.nodeType===1?t:null}function B(t,n){n!=null&&(typeof n=="string"?y(n).forEach(function(i){t.appendChild(i)}):n.nodeType?t.appendChild(n):typeof n.length=="number"&&Array.prototype.slice.call(n).forEach(function(i){t.appendChild(i)}))}function k(t,n){n=n||{};var i=h("div",{class:"ge-element","data-ge-element":n.type||"element"});return B(i,t),n.label!==void 0&&i.setAttribute("data-ge-label",n.label),e.place(i,"element",A(n))}return{methods:{createElement:k},kindOf:function(t){return d(t,"ge-element")?"element":null},cuts:function(){return o()?e.settings.elements.auto?"*":e.settings.elements.selector:null},blocks:".ge-element",accepts:function(t,n){return d(n,"ge-element")?x(t,".column"):!0},onInit:a,onDeinit:l}};})();
1
+ (()=>{var c=window.GridEditor;if(!c||typeof c.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");function g(e,i){return e?Array.prototype.slice.call(e.querySelectorAll(i)):[]}function v(e,i){return e?Array.prototype.filter.call(e.children,function(o){return!i||o.matches(i)}):[]}function b(e,i){return v(e,i)[0]||null}function E(e,i){return!!e&&e.nodeType===1&&e.matches(i)}function y(e){var i=document.createElement("template");return i.innerHTML=e,Array.prototype.slice.call(i.content.childNodes)}function h(e,i,o){var u=document.createElement(e);return Object.keys(i||{}).forEach(function(s){var a=i[s];a!=null&&a!==!1&&u.setAttribute(s,a)}),o!=null&&(u.textContent=o),u}function w(e,i){return T(i).forEach(function(o){e.classList.add(o)}),e}function C(e,i){return T(i).forEach(function(o){e.classList.remove(o)}),e}function m(e,i){return!!e&&e.nodeType===1&&e.classList.contains(i)}function T(e){return String(e||"").split(/\s+/).filter(Boolean)}function A(e){return e.getAttribute("class")||e.removeAttribute("class"),e}function I(e){return e.style.display="none",e}function R(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}var q=400;function M(e,i,o,u){o=o===void 0?q:o;var s=function(){I(e),u&&u()};if(!R(e)||!e.animate||o<=0){window.setTimeout(s,0);return}var a=e.animate(i(getComputedStyle(e)),{duration:o,easing:"ease-in-out"}),f=!1,d=function(){f||(f=!0,s())};a.onfinish=d,a.oncancel=d}function S(e,i,o,u){e.style.overflow="hidden",M(e,function(s){var a={opacity:s.opacity,height:s.height},f={opacity:0,height:"0px"};return u&&(a.width=s.width,f.width="0px"),[a,f]},i,function(){e.style.removeProperty("overflow"),o&&o()})}Object.assign(c.locales.en,{"tool.delete_element":"Remove element","tool.element_info":"Element: {name}","confirm.delete_element":"Delete element?"});var U=".row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle";c.features.elements=function(e){var i=!1,o=s();function u(){return e.settings.elements.enabled!=="auto"?!!e.settings.elements.enabled:e.settings.elements.auto||o.length>0||!!e.canvas.querySelector(e.settings.elements.selector)}function s(){return(e.settings.elements.types||[]).filter(function(t,n){var r=t&&typeof t.type=="string"&&t.type.trim()!=="",l=t&&(typeof t.html=="function"||typeof t.html=="string"&&t.html.trim()!=="");return(!r||!l)&&e.warn("elements.types["+n+"]: a type needs a type name and its html, as a string or a function; it is left off the toolbar."),r&&l})}function a(t){var n=!1;return{label:function(){return f(t)},iconClass:t.iconClass,group:t.group||"elements",kind:"element",inColumn:!0,create:function(){var r=d(t);return r&&!n&&!e.settings.elements.auto&&!r.matches(e.settings.elements.selector)&&(n=!0,e.warn('elements.types "'+t.type+'": what it makes does not match elements.selector "'+e.settings.elements.selector+'", so it will not be an element once the editor looks again.')),r}}}function f(t){return t.labelKey?e.t(t.labelKey):t.label||t.type}function d(t){var n;try{n=typeof t.html=="function"?t.html():t.html}catch(p){return e.warn('elements.types "'+t.type+'": its html function threw ('+p.message+"); nothing was added."),null}var r=typeof n=="string"?y(n):n&&n.nodeType?[n]:[];if(r=r.filter(function(p){return p.nodeType!==3||p.textContent.trim()!==""}),!r.length)return e.warn('elements.types "'+t.type+'": its html came out empty; nothing was added.'),null;var l=r.length===1&&r[0].nodeType===1?r[0]:h("div");return(l!==r[0]||r.length>1)&&x(l,r),l.setAttribute("data-ge-element",t.type),l.hasAttribute("data-ge-label")||l.setAttribute("data-ge-label",f(t)),l}function k(t){return e.settings.elements.auto?!t.matches(U):t.matches(e.settings.elements.selector)}function B(){u()&&g(e.canvas,".column").forEach(function(t){v(t).forEach(function(n){!m(n,"ge-element")&&!k(n)||(w(n,"ge-element"),b(n,".ge-tools-drawer")||O(n))})})}function L(){g(e.canvas,".ge-element").forEach(function(t){C(t,"ge-element"),A(t)})}function O(t){var n=h("div",{class:"ge-tools-drawer ge-element-drawer"});t.insertBefore(n,t.firstChild),e.createMoveTool(n),e.createTool(n,e.t("tool.element_info",{name:N(t)}),"ge-element-info","bi bi-info-circle"),e.addSettingsTool(n,t,e.settings.element_classes),e.settings.element_tools.forEach(function(r){e.createTool(n,r.title||"",r.className||"",r.iconClass||"bi bi-wrench",r.on)}),e.createTool(n,e.t("tool.delete_element"),"ge-delete-element","bi bi-trash",function(){e.deleteNode("element",t,e.t("confirm.delete_element"),function(r){S(t,300,r)})})}function N(t){var n=t.getAttribute("data-ge-element"),r=t.getAttribute("data-ge-label");return r&&n?r+" ("+n+")":r||n||t.tagName.toLowerCase()}function _(t){var n=Object.assign({},t);return[["appendTo","insertAfter"],["prependTo","insertBefore"]].forEach(function(r){var l=t[r[0]]!==void 0?H(t[r[0]]):null;!l||!l.matches(".ge-content")||(i||(i=!0,e.warn("createElement: an element is a block of the column since 6.0, not part of a content area's text; it goes beside the content area. Place it in a column instead.")),delete n[r[0]],n[r[1]]=m(l.parentElement,"ge-text-block")?l.parentElement:l)}),n}function j(){return e.settings.elements.enabled===!1}function H(t){return typeof t=="string"?document.querySelector(t):t&&t.nodeType===1?t:null}function x(t,n){n!=null&&(typeof n=="string"?y(n).forEach(function(r){t.appendChild(r)}):n.nodeType?t.appendChild(n):typeof n.length=="number"&&Array.prototype.slice.call(n).forEach(function(r){t.appendChild(r)}))}function D(t,n){n=n||{};var r=h("div",{class:"ge-element","data-ge-element":n.type||"element"});return x(r,t),n.label!==void 0&&r.setAttribute("data-ge-label",n.label),e.place(r,"element",_(n))}return{methods:{createElement:D},toolbar:j()?[]:o.map(a),kindOf:function(t){return m(t,"ge-element")?"element":null},cuts:function(){return u()?e.settings.elements.auto?"*":e.settings.elements.selector:null},blocks:".ge-element",accepts:function(t,n){return m(n,"ge-element")?E(t,".column"):!0},onInit:B,onDeinit:L}};})();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/js/register.js", "../../src/js/dom.js", "../../src/js/plugins/grideditor.elements.js"],
4
- "sourcesContent": ["/**\n * What a plugin's or a locale's classic script imports in place of the\n * editor: the GridEditor the page already loaded.\n *\n * The build points `import { GridEditor } from '../grideditor.js'` here for\n * the classic scripts, so each registers on the editor the page has rather\n * than bringing its own. Loaded before the editor there is nothing to\n * register on, and saying so is better than a TypeError three calls later.\n */\nvar GridEditor = window.GridEditor;\n\nif (!GridEditor || typeof GridEditor.get !== 'function') {\n throw new Error('grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, ' +\n 'its locales and grideditor.jquery.js');\n}\n\nexport { GridEditor };\nexport default GridEditor;\n", "/**\n * The DOM, the way grid-editor uses it.\n *\n * Small helpers over the browser's own API, for the core and the shipped\n * plugins. Not a public API: a plugin of a host's own is free to write its\n * DOM code however it likes, and this file makes no promise to it.\n *\n * Stateless on purpose. The build puts a copy of this file in each plugin's\n * classic script, so anything kept here would be kept once per copy; a\n * module that needs to remember something about a node keeps its own\n * WeakMap.\n */\n\n/** Every element under `root` matching `selector`, as an array. */\nexport function all(root, selector) {\n return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];\n}\n\n/** The first element under `root` matching `selector`, or null. */\nexport function one(root, selector) {\n return root ? root.querySelector(selector) : null;\n}\n\n/** `root` itself when it matches, then every element under it that does. */\nexport function selfAndAll(root, selector) {\n if (!root) { return []; }\n\n var found = all(root, selector);\n if (root.nodeType === 1 && root.matches(selector)) { found.unshift(root); }\n return found;\n}\n\n/** The element children of `node`, those matching `selector` if one is given. */\nexport function children(node, selector) {\n if (!node) { return []; }\n\n return Array.prototype.filter.call(node.children, function(each) {\n return !selector || each.matches(selector);\n });\n}\n\n/** The first element child matching `selector`, or null. */\nexport function child(node, selector) {\n return children(node, selector)[0] || null;\n}\n\n/** The nearest ancestor-or-self matching `selector` below `stopAt`, or null. */\nexport function closest(node, selector, stopAt) {\n var found = node && node.nodeType === 1 ? node.closest(selector) : null;\n\n if (found && stopAt && found !== stopAt && !stopAt.contains(found)) { return null; }\n return found;\n}\n\n/** Whether `node` is an element matching `selector`. */\nexport function is(node, selector) {\n return !!node && node.nodeType === 1 && node.matches(selector);\n}\n\n/** Whether `node` is in the document. */\nexport function attached(node) {\n return !!node && document.documentElement.contains(node);\n}\n\n/** The element siblings after `node` that match `selector`. */\nexport function nextAll(node, selector) {\n var found = [];\n\n for (var next = node.nextElementSibling; next; next = next.nextElementSibling) {\n if (!selector || next.matches(selector)) { found.push(next); }\n }\n return found;\n}\n\n/** The ancestors of `node` up to, and not including, `stop`, nearest first. */\nexport function parentsUntil(node, stop) {\n var found = [];\n\n for (var parent = node.parentElement; parent && parent !== stop; parent = parent.parentElement) {\n found.push(parent);\n }\n return found;\n}\n\n/**\n * The nodes the html parses into, detached. Parsed the way innerHTML parses,\n * so a <script> in it never runs, here or once it is in the page.\n */\nexport function parse(html) {\n var template = document.createElement('template');\n template.innerHTML = html;\n return Array.prototype.slice.call(template.content.childNodes);\n}\n\n/** The one element the html is, detached. */\nexport function create(html) {\n var nodes = parse(html.trim());\n\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i].nodeType === 1) { return nodes[i]; }\n }\n return null;\n}\n\n/** An element of `tag`, with `attributes` and `text`. */\nexport function element(tag, attributes, text) {\n var node = document.createElement(tag);\n\n Object.keys(attributes || {}).forEach(function(name) {\n var value = attributes[name];\n if (value !== null && value !== undefined && value !== false) { node.setAttribute(name, value); }\n });\n if (text !== undefined && text !== null) { node.textContent = text; }\n\n return node;\n}\n\n/** Replace what `node` holds with `html`. A <script> in it does not run. */\nexport function setHtml(node, html) {\n node.innerHTML = html === undefined || html === null ? '' : String(html);\n return node;\n}\n\n/** Add one or several space separated classes. */\nexport function addClass(node, names) {\n split(names).forEach(function(name) { node.classList.add(name); });\n return node;\n}\n\nexport function removeClass(node, names) {\n split(names).forEach(function(name) { node.classList.remove(name); });\n return node;\n}\n\n/** Each class on, or off, or flipped when `on` is not given. */\nexport function toggleClass(node, names, state) {\n split(names).forEach(function(name) {\n if (state === undefined) {\n node.classList.toggle(name);\n } else {\n node.classList.toggle(name, !!state);\n }\n });\n return node;\n}\n\nexport function hasClass(node, name) {\n return !!node && node.nodeType === 1 && node.classList.contains(name);\n}\n\nfunction split(names) {\n return String(names || '').split(/\\s+/).filter(Boolean);\n}\n\n/** Take the class attribute off when there is nothing left in it. */\nexport function dropEmptyClass(node) {\n if (!node.getAttribute('class')) { node.removeAttribute('class'); }\n return node;\n}\n\n/** Take the style attribute off when there is nothing left in it. */\nexport function dropEmptyStyle(node) {\n if (!node.getAttribute('style')) { node.removeAttribute('style'); }\n return node;\n}\n\n/** Set attributes; a null or undefined value takes the attribute off. */\nexport function attr(node, attributes) {\n Object.keys(attributes).forEach(function(name) {\n var value = attributes[name];\n\n if (value === null || value === undefined) {\n node.removeAttribute(name);\n } else {\n node.setAttribute(name, value);\n }\n });\n return node;\n}\n\n/**\n * Inline styles, by css property name. A number is pixels for the properties\n * that take a length, as jQuery had it; an empty string takes one off.\n */\nexport function css(node, styles) {\n Object.keys(styles).forEach(function(property) {\n var value = styles[property];\n\n if (typeof value === 'number' && !UNITLESS[property]) { value = value + 'px'; }\n node.style.setProperty(property, value === null || value === undefined ? '' : String(value));\n });\n return node;\n}\n\nvar UNITLESS = { opacity: true, 'z-index': true, 'flex-grow': true, 'flex-shrink': true, order: true };\n\n/** What an element of this tag shows as when nothing hides it. */\nvar defaultDisplays = {};\n\nfunction defaultDisplay(node) {\n var tag = node.nodeName;\n\n if (!defaultDisplays[tag]) {\n var probe = document.body.appendChild(document.createElement(tag));\n defaultDisplays[tag] = getComputedStyle(probe).display;\n probe.remove();\n if (defaultDisplays[tag] === 'none') { defaultDisplays[tag] = 'block'; }\n }\n return defaultDisplays[tag];\n}\n\n/** Show a node: its inline display:none off, and a display of its own if a stylesheet hides it. */\nexport function show(node) {\n node.style.removeProperty('display');\n if (getComputedStyle(node).display === 'none') { node.style.display = defaultDisplay(node); }\n return node;\n}\n\nexport function hide(node) {\n node.style.display = 'none';\n return node;\n}\n\n/** Show or hide; flip when `on` is not given. */\nexport function toggle(node, state) {\n if (state === undefined) { state = !visible(node); }\n return state ? show(node) : hide(node);\n}\n\n/** Whether a node takes up room: what jQuery's :visible meant. */\nexport function visible(node) {\n return !!(node.offsetWidth || node.offsetHeight || node.getClientRects().length);\n}\n\n/** The border box's width, fractions included. */\nexport function outerWidth(node) {\n return node.getBoundingClientRect().width;\n}\n\nexport function outerHeight(node) {\n return node.getBoundingClientRect().height;\n}\n\n/** The content box's height, which is what jQuery's height() gave. */\nexport function contentHeight(node) {\n var style = getComputedStyle(node);\n return node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);\n}\n\n/** Where a node is on the page, not in the window. */\nexport function offset(node) {\n var box = node.getBoundingClientRect();\n return { top: box.top + window.pageYOffset, left: box.left + window.pageXOffset };\n}\n\n/** Its index among its parent's element children, those matching `selector` if given. */\nexport function indexIn(node, selector) {\n return children(node.parentElement, selector).indexOf(node);\n}\n\n/** Put `node` right after `reference`. */\nexport function insertAfter(node, reference) {\n reference.parentNode.insertBefore(node, reference.nextSibling);\n return node;\n}\n\n/** Replace `node` with what it holds. */\nexport function unwrap(node) {\n var parent = node.parentNode;\n\n while (node.firstChild) { parent.insertBefore(node.firstChild, node); }\n node.remove();\n}\n\n/** Put `node` inside `wrapper`, where `node` was. */\nexport function wrap(node, wrapper) {\n node.parentNode.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\n/**\n * Listen on `root` for `types` (space separated) on descendants that match\n * `selector`, with `this` the matched element, as jQuery's delegated\n * handlers had it. Hands back the listener, for removeEventListener; a\n * signal in `options` removes it too.\n */\nexport function delegate(root, types, selector, handler, options) {\n var listener = function(event) {\n var match = closest(event.target, selector, root);\n if (match && root.contains(match)) { return handler.call(match, event); }\n return undefined;\n };\n\n split(types).forEach(function(type) { root.addEventListener(type, listener, options); });\n return listener;\n}\n\n/** Listen for several space separated event types with one handler. */\nexport function on(target, types, handler, options) {\n split(types).forEach(function(type) { target.addEventListener(type, handler, options); });\n return handler;\n}\n\nexport function off(target, types, handler, options) {\n split(types).forEach(function(type) { target.removeEventListener(type, handler, options); });\n}\n\n/** A mouse event of `type` sent to `node`, the way a pointer would. */\nexport function fire(node, type) {\n node.dispatchEvent(new MouseEvent(type, { bubbles: type !== 'mouseenter' && type !== 'mouseleave' }));\n}\n\n/* ------------------------------------------------------------------\n * Taking a node away, visibly.\n *\n * The durations are jQuery's: 400 ms unless the caller says otherwise. `done` runs once the node is out of sight, which is\n * when the caller removes it; a node that is already out of sight is done at\n * once, on the next task, as jQuery had it.\n * ------------------------------------------------------------------ */\n\nvar DEFAULT_DURATION = 400;\n\nfunction animateAway(node, frames, duration, done) {\n duration = duration === undefined ? DEFAULT_DURATION : duration;\n\n var finish = function() {\n hide(node);\n if (done) { done(); }\n };\n\n if (!visible(node) || !node.animate || duration <= 0) {\n window.setTimeout(finish, 0);\n return;\n }\n\n var animation = node.animate(frames(getComputedStyle(node)), {\n duration: duration,\n easing: 'ease-in-out',\n });\n var called = false;\n var once = function() {\n if (called) { return; }\n called = true;\n finish();\n };\n\n animation.onfinish = once;\n animation.oncancel = once;\n}\n\n/** Fold a node up to nothing, then hide it. */\nexport function slideUp(node, duration, done) {\n if (typeof duration === 'function') {\n done = duration;\n duration = undefined;\n }\n\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n return [\n {\n height: style.height,\n paddingTop: style.paddingTop,\n paddingBottom: style.paddingBottom,\n marginTop: style.marginTop,\n marginBottom: style.marginBottom,\n },\n { height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px' },\n ];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n\n/** Fade a node out, then hide it. */\nexport function fadeOut(node, duration, done) {\n animateAway(node, function(style) {\n return [{ opacity: style.opacity }, { opacity: 0 }];\n }, duration, done);\n}\n\n/** Fade and fold a node, in height and, with `width`, sideways too, then hide it. */\nexport function shrinkAway(node, duration, done, width) {\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n var from = { opacity: style.opacity, height: style.height };\n var to = { opacity: 0, height: '0px' };\n\n if (width) {\n from.width = style.width;\n to.width = '0px';\n }\n return [from, to];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n", "/**\n * Element level controls for grid-editor.\n *\n * A feature plugin: load this file after the editor and the nodes a host\n * marked become elements - one movable, deletable block each, in the column\n * beside the texts, instead of rich text. What it can ask the editor for is\n * the handle its factory is called with, described in docs/plugins.md.\n *\n * <script src=\"dist/grideditor.min.js\"></script>\n * <script src=\"dist/plugins/grideditor.elements.min.js\"></script>\n *\n * Up to 5.x an element lived inside a content area, among the text. Markup\n * saved that way still loads: the editor takes each element out of the text\n * it sits in, which is what `cuts` is for.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\n\nObject.assign(GridEditor.locales.en, {\n 'tool.delete_element': 'Remove element',\n 'tool.element_info': 'Element: {name}',\n 'confirm.delete_element': 'Delete element?',\n});\n\n/** A column's children that are something else than an element, whatever elements.auto says. */\nvar NOT_ELEMENTS = '.row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle';\n\nGridEditor.features.elements = function(ge) {\n\n var warnedIntoText = false;\n\n function elementsEnabled() {\n if (ge.settings.elements.enabled !== 'auto') { return !!ge.settings.elements.enabled; }\n\n return ge.settings.elements.auto || !!ge.canvas.querySelector(ge.settings.elements.selector);\n }\n\n /** Whether a child of a column is an element. */\n function isElement(node) {\n return ge.settings.elements.auto\n ? !node.matches(NOT_ELEMENTS)\n : node.matches(ge.settings.elements.selector);\n }\n\n function markElements() {\n if (!elementsEnabled()) { return; }\n\n dom.all(ge.canvas, '.column').forEach(function(column) {\n dom.children(column).forEach(function(element) {\n if (!dom.hasClass(element, 'ge-element') && !isElement(element)) { return; }\n\n dom.addClass(element, 'ge-element');\n if (!dom.child(element, '.ge-tools-drawer')) { createElementControls(element); }\n });\n });\n }\n\n function unmarkElements() {\n dom.all(ge.canvas, '.ge-element').forEach(function(element) {\n dom.removeClass(element, 'ge-element');\n\n // A host element that had no class of its own should not come\n // back from getHtml carrying an empty one\n dom.dropEmptyClass(element);\n });\n }\n\n function createElementControls(element) {\n var drawer = dom.element('div', { 'class': 'ge-tools-drawer ge-element-drawer' });\n element.insertBefore(drawer, element.firstChild);\n\n ge.createMoveTool(drawer);\n ge.createTool(drawer, ge.t('tool.element_info', { name: elementName(element) }),\n 'ge-element-info', 'bi bi-info-circle');\n ge.addSettingsTool(drawer, element, ge.settings.element_classes);\n\n ge.settings.element_tools.forEach(function(hostTool) {\n ge.createTool(drawer, hostTool.title || '', hostTool.className || '',\n hostTool.iconClass || 'bi bi-wrench', hostTool.on);\n });\n\n ge.createTool(drawer, ge.t('tool.delete_element'), 'ge-delete-element', 'bi bi-trash', function() {\n ge.deleteNode('element', element, ge.t('confirm.delete_element'), function(removed) {\n dom.shrinkAway(element, 300, removed);\n });\n });\n }\n\n function elementName(element) {\n var type = element.getAttribute('data-ge-element');\n var label = element.getAttribute('data-ge-label');\n\n if (label && type) { return label + ' (' + type + ')'; }\n\n return label || type || element.tagName.toLowerCase();\n }\n\n /**\n * Placed into a content area, as 5.x did, an element would be text\n * again, and the next init would cut it out. So it goes beside that\n * content area instead - after it for appendTo, before it for\n * prependTo - with a word to the host.\n */\n function placementBesideText(options) {\n var placed = Object.assign({}, options);\n\n [['appendTo', 'insertAfter'], ['prependTo', 'insertBefore']].forEach(function(pair) {\n var target = options[pair[0]] !== undefined ? nodeFrom(options[pair[0]]) : null;\n if (!target || !target.matches('.ge-content')) { return; }\n\n if (!warnedIntoText) {\n warnedIntoText = true;\n ge.warn('createElement: an element is a block of the column since 6.0, not part of a ' +\n 'content area\\'s text; it goes beside the content area. Place it in a column instead.');\n }\n\n delete placed[pair[0]];\n placed[pair[1]] = dom.hasClass(target.parentElement, 'ge-text-block') ? target.parentElement : target;\n });\n\n return placed;\n }\n\n /** A place a caller named: an element, or the first one a selector matches. */\n function nodeFrom(node) {\n if (typeof node === 'string') { return document.querySelector(node); }\n return node && node.nodeType === 1 ? node : null;\n }\n\n /**\n * What the element holds: html, which is parsed as innerHTML parses so\n * no <script> in it runs, or a node, or a list of nodes.\n */\n function fill(element, content) {\n if (content === undefined || content === null) { return; }\n\n if (typeof content === 'string') {\n dom.parse(content).forEach(function(node) { element.appendChild(node); });\n } else if (content.nodeType) {\n element.appendChild(content);\n } else if (typeof content.length === 'number') {\n Array.prototype.slice.call(content).forEach(function(node) { element.appendChild(node); });\n }\n }\n\n function apiCreateElement(content, options) {\n options = options || {};\n\n var element = dom.element('div', {\n 'class': 'ge-element',\n 'data-ge-element': options.type || 'element',\n });\n fill(element, content);\n if (options.label !== undefined) {\n element.setAttribute('data-ge-label', options.label);\n }\n\n return ge.place(element, 'element', placementBesideText(options));\n }\n\n return {\n methods: {\n createElement: apiCreateElement,\n },\n\n /** A node this plugin marked is an element, whatever else it is. */\n kindOf: function(node) {\n return dom.hasClass(node, 'ge-element') ? 'element' : null;\n },\n\n /**\n * An element cuts the text it sits in: 5.x's markup, or markup a host\n * wrote the same way, has it inside a content area, and it comes out.\n */\n cuts: function() {\n if (!elementsEnabled()) { return null; }\n\n return ge.settings.elements.auto ? '*' : ge.settings.elements.selector;\n },\n\n // A block the columns move, beside the texts, the rows and the\n // containers - and only the columns\n blocks: '.ge-element',\n accepts: function(region, node) {\n if (dom.hasClass(node, 'ge-element')) { return dom.is(region, '.column'); }\n\n return true;\n },\n\n onInit: markElements,\n onDeinit: unmarkElements,\n };\n};\n"],
5
- "mappings": "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",
6
- "names": ["GridEditor", "all", "root", "selector", "children", "node", "selector", "each", "child", "is", "node", "selector", "parse", "html", "template", "element", "tag", "attributes", "text", "node", "name", "value", "addClass", "node", "names", "split", "name", "removeClass", "hasClass", "node", "name", "split", "names", "dropEmptyClass", "hide", "node", "visible", "node", "DEFAULT_DURATION", "animateAway", "node", "frames", "duration", "done", "finish", "hide", "visible", "animation", "called", "once", "shrinkAway", "node", "duration", "done", "width", "animateAway", "style", "from", "to", "GridEditor", "NOT_ELEMENTS", "ge", "warnedIntoText", "elementsEnabled", "isElement", "node", "markElements", "all", "column", "children", "element", "hasClass", "addClass", "child", "createElementControls", "unmarkElements", "removeClass", "dropEmptyClass", "drawer", "elementName", "hostTool", "removed", "shrinkAway", "type", "label", "placementBesideText", "options", "placed", "pair", "target", "nodeFrom", "fill", "content", "parse", "apiCreateElement", "region", "is"]
4
+ "sourcesContent": ["/**\n * What a plugin's or a locale's classic script imports in place of the\n * editor: the GridEditor the page already loaded.\n *\n * The build points `import { GridEditor } from '../grideditor.js'` here for\n * the classic scripts, so each registers on the editor the page has rather\n * than bringing its own. Loaded before the editor there is nothing to\n * register on, and saying so is better than a TypeError three calls later.\n */\nvar GridEditor = window.GridEditor;\n\nif (!GridEditor || typeof GridEditor.get !== 'function') {\n throw new Error('grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, ' +\n 'its locales and grideditor.jquery.js');\n}\n\nexport { GridEditor };\nexport default GridEditor;\n", "/**\n * The DOM, the way grid-editor uses it.\n *\n * Small helpers over the browser's own API, for the core and the shipped\n * plugins. Not a public API: a plugin of a host's own is free to write its\n * DOM code however it likes, and this file makes no promise to it.\n *\n * Stateless on purpose. The build puts a copy of this file in each plugin's\n * classic script, so anything kept here would be kept once per copy; a\n * module that needs to remember something about a node keeps its own\n * WeakMap.\n */\n\n/** Every element under `root` matching `selector`, as an array. */\nexport function all(root, selector) {\n return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];\n}\n\n/** The first element under `root` matching `selector`, or null. */\nexport function one(root, selector) {\n return root ? root.querySelector(selector) : null;\n}\n\n/** `root` itself when it matches, then every element under it that does. */\nexport function selfAndAll(root, selector) {\n if (!root) { return []; }\n\n var found = all(root, selector);\n if (root.nodeType === 1 && root.matches(selector)) { found.unshift(root); }\n return found;\n}\n\n/** The element children of `node`, those matching `selector` if one is given. */\nexport function children(node, selector) {\n if (!node) { return []; }\n\n return Array.prototype.filter.call(node.children, function(each) {\n return !selector || each.matches(selector);\n });\n}\n\n/** The first element child matching `selector`, or null. */\nexport function child(node, selector) {\n return children(node, selector)[0] || null;\n}\n\n/** The nearest ancestor-or-self matching `selector` below `stopAt`, or null. */\nexport function closest(node, selector, stopAt) {\n var found = node && node.nodeType === 1 ? node.closest(selector) : null;\n\n if (found && stopAt && found !== stopAt && !stopAt.contains(found)) { return null; }\n return found;\n}\n\n/** Whether `node` is an element matching `selector`. */\nexport function is(node, selector) {\n return !!node && node.nodeType === 1 && node.matches(selector);\n}\n\n/** Whether `node` is in the document. */\nexport function attached(node) {\n return !!node && document.documentElement.contains(node);\n}\n\n/** The element siblings after `node` that match `selector`. */\nexport function nextAll(node, selector) {\n var found = [];\n\n for (var next = node.nextElementSibling; next; next = next.nextElementSibling) {\n if (!selector || next.matches(selector)) { found.push(next); }\n }\n return found;\n}\n\n/** The ancestors of `node` up to, and not including, `stop`, nearest first. */\nexport function parentsUntil(node, stop) {\n var found = [];\n\n for (var parent = node.parentElement; parent && parent !== stop; parent = parent.parentElement) {\n found.push(parent);\n }\n return found;\n}\n\n/**\n * The nodes the html parses into, detached. Parsed the way innerHTML parses,\n * so a <script> in it never runs, here or once it is in the page.\n */\nexport function parse(html) {\n var template = document.createElement('template');\n template.innerHTML = html;\n return Array.prototype.slice.call(template.content.childNodes);\n}\n\n/** The one element the html is, detached. */\nexport function create(html) {\n var nodes = parse(html.trim());\n\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i].nodeType === 1) { return nodes[i]; }\n }\n return null;\n}\n\n/** An element of `tag`, with `attributes` and `text`. */\nexport function element(tag, attributes, text) {\n var node = document.createElement(tag);\n\n Object.keys(attributes || {}).forEach(function(name) {\n var value = attributes[name];\n if (value !== null && value !== undefined && value !== false) { node.setAttribute(name, value); }\n });\n if (text !== undefined && text !== null) { node.textContent = text; }\n\n return node;\n}\n\n/** Replace what `node` holds with `html`. A <script> in it does not run. */\nexport function setHtml(node, html) {\n node.innerHTML = html === undefined || html === null ? '' : String(html);\n return node;\n}\n\n/** Add one or several space separated classes. */\nexport function addClass(node, names) {\n split(names).forEach(function(name) { node.classList.add(name); });\n return node;\n}\n\nexport function removeClass(node, names) {\n split(names).forEach(function(name) { node.classList.remove(name); });\n return node;\n}\n\n/** Each class on, or off, or flipped when `on` is not given. */\nexport function toggleClass(node, names, state) {\n split(names).forEach(function(name) {\n if (state === undefined) {\n node.classList.toggle(name);\n } else {\n node.classList.toggle(name, !!state);\n }\n });\n return node;\n}\n\nexport function hasClass(node, name) {\n return !!node && node.nodeType === 1 && node.classList.contains(name);\n}\n\nfunction split(names) {\n return String(names || '').split(/\\s+/).filter(Boolean);\n}\n\n/** Take the class attribute off when there is nothing left in it. */\nexport function dropEmptyClass(node) {\n if (!node.getAttribute('class')) { node.removeAttribute('class'); }\n return node;\n}\n\n/** Take the style attribute off when there is nothing left in it. */\nexport function dropEmptyStyle(node) {\n if (!node.getAttribute('style')) { node.removeAttribute('style'); }\n return node;\n}\n\n/** Set attributes; a null or undefined value takes the attribute off. */\nexport function attr(node, attributes) {\n Object.keys(attributes).forEach(function(name) {\n var value = attributes[name];\n\n if (value === null || value === undefined) {\n node.removeAttribute(name);\n } else {\n node.setAttribute(name, value);\n }\n });\n return node;\n}\n\n/**\n * Inline styles, by css property name. A number is pixels for the properties\n * that take a length, as jQuery had it; an empty string takes one off.\n */\nexport function css(node, styles) {\n Object.keys(styles).forEach(function(property) {\n var value = styles[property];\n\n if (typeof value === 'number' && !UNITLESS[property]) { value = value + 'px'; }\n node.style.setProperty(property, value === null || value === undefined ? '' : String(value));\n });\n return node;\n}\n\nvar UNITLESS = { opacity: true, 'z-index': true, 'flex-grow': true, 'flex-shrink': true, order: true };\n\n/** What an element of this tag shows as when nothing hides it. */\nvar defaultDisplays = {};\n\nfunction defaultDisplay(node) {\n var tag = node.nodeName;\n\n if (!defaultDisplays[tag]) {\n var probe = document.body.appendChild(document.createElement(tag));\n defaultDisplays[tag] = getComputedStyle(probe).display;\n probe.remove();\n if (defaultDisplays[tag] === 'none') { defaultDisplays[tag] = 'block'; }\n }\n return defaultDisplays[tag];\n}\n\n/** Show a node: its inline display:none off, and a display of its own if a stylesheet hides it. */\nexport function show(node) {\n node.style.removeProperty('display');\n if (getComputedStyle(node).display === 'none') { node.style.display = defaultDisplay(node); }\n return node;\n}\n\nexport function hide(node) {\n node.style.display = 'none';\n return node;\n}\n\n/** Show or hide; flip when `on` is not given. */\nexport function toggle(node, state) {\n if (state === undefined) { state = !visible(node); }\n return state ? show(node) : hide(node);\n}\n\n/** Whether a node takes up room: what jQuery's :visible meant. */\nexport function visible(node) {\n return !!(node.offsetWidth || node.offsetHeight || node.getClientRects().length);\n}\n\n/** The border box's width, fractions included. */\nexport function outerWidth(node) {\n return node.getBoundingClientRect().width;\n}\n\nexport function outerHeight(node) {\n return node.getBoundingClientRect().height;\n}\n\n/** The content box's height, which is what jQuery's height() gave. */\nexport function contentHeight(node) {\n var style = getComputedStyle(node);\n return node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);\n}\n\n/** Where a node is on the page, not in the window. */\nexport function offset(node) {\n var box = node.getBoundingClientRect();\n return { top: box.top + window.pageYOffset, left: box.left + window.pageXOffset };\n}\n\n/** Its index among its parent's element children, those matching `selector` if given. */\nexport function indexIn(node, selector) {\n return children(node.parentElement, selector).indexOf(node);\n}\n\n/** Put `node` right after `reference`. */\nexport function insertAfter(node, reference) {\n reference.parentNode.insertBefore(node, reference.nextSibling);\n return node;\n}\n\n/** Replace `node` with what it holds. */\nexport function unwrap(node) {\n var parent = node.parentNode;\n\n while (node.firstChild) { parent.insertBefore(node.firstChild, node); }\n node.remove();\n}\n\n/** Put `node` inside `wrapper`, where `node` was. */\nexport function wrap(node, wrapper) {\n node.parentNode.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\n/**\n * Listen on `root` for `types` (space separated) on descendants that match\n * `selector`, with `this` the matched element, as jQuery's delegated\n * handlers had it. Hands back the listener, for removeEventListener; a\n * signal in `options` removes it too.\n */\nexport function delegate(root, types, selector, handler, options) {\n var listener = function(event) {\n var match = closest(event.target, selector, root);\n if (match && root.contains(match)) { return handler.call(match, event); }\n return undefined;\n };\n\n split(types).forEach(function(type) { root.addEventListener(type, listener, options); });\n return listener;\n}\n\n/** Listen for several space separated event types with one handler. */\nexport function on(target, types, handler, options) {\n split(types).forEach(function(type) { target.addEventListener(type, handler, options); });\n return handler;\n}\n\nexport function off(target, types, handler, options) {\n split(types).forEach(function(type) { target.removeEventListener(type, handler, options); });\n}\n\n/** A mouse event of `type` sent to `node`, the way a pointer would. */\nexport function fire(node, type) {\n node.dispatchEvent(new MouseEvent(type, { bubbles: type !== 'mouseenter' && type !== 'mouseleave' }));\n}\n\n/* ------------------------------------------------------------------\n * Taking a node away, visibly.\n *\n * The durations are jQuery's: 400 ms unless the caller says otherwise. `done` runs once the node is out of sight, which is\n * when the caller removes it; a node that is already out of sight is done at\n * once, on the next task, as jQuery had it.\n * ------------------------------------------------------------------ */\n\nvar DEFAULT_DURATION = 400;\n\nfunction animateAway(node, frames, duration, done) {\n duration = duration === undefined ? DEFAULT_DURATION : duration;\n\n var finish = function() {\n hide(node);\n if (done) { done(); }\n };\n\n if (!visible(node) || !node.animate || duration <= 0) {\n window.setTimeout(finish, 0);\n return;\n }\n\n var animation = node.animate(frames(getComputedStyle(node)), {\n duration: duration,\n easing: 'ease-in-out',\n });\n var called = false;\n var once = function() {\n if (called) { return; }\n called = true;\n finish();\n };\n\n animation.onfinish = once;\n animation.oncancel = once;\n}\n\n/** Fold a node up to nothing, then hide it. */\nexport function slideUp(node, duration, done) {\n if (typeof duration === 'function') {\n done = duration;\n duration = undefined;\n }\n\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n return [\n {\n height: style.height,\n paddingTop: style.paddingTop,\n paddingBottom: style.paddingBottom,\n marginTop: style.marginTop,\n marginBottom: style.marginBottom,\n },\n { height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px' },\n ];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n\n/** Fade a node out, then hide it. */\nexport function fadeOut(node, duration, done) {\n animateAway(node, function(style) {\n return [{ opacity: style.opacity }, { opacity: 0 }];\n }, duration, done);\n}\n\n/** Fade and fold a node, in height and, with `width`, sideways too, then hide it. */\nexport function shrinkAway(node, duration, done, width) {\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n var from = { opacity: style.opacity, height: style.height };\n var to = { opacity: 0, height: '0px' };\n\n if (width) {\n from.width = style.width;\n to.width = '0px';\n }\n return [from, to];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n", "/**\n * Element level controls for grid-editor.\n *\n * A feature plugin: load this file after the editor and the nodes a host\n * marked become elements - one movable, deletable block each, in the column\n * beside the texts, instead of rich text. What it can ask the editor for is\n * the handle its factory is called with, described in docs/plugins.md.\n *\n * <script src=\"dist/grideditor.min.js\"></script>\n * <script src=\"dist/plugins/grideditor.elements.min.js\"></script>\n *\n * Up to 5.x an element lived inside a content area, among the text. Markup\n * saved that way still loads: the editor takes each element out of the text\n * it sits in, which is what `cuts` is for.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\n\nObject.assign(GridEditor.locales.en, {\n 'tool.delete_element': 'Remove element',\n 'tool.element_info': 'Element: {name}',\n 'confirm.delete_element': 'Delete element?',\n});\n\n/** A column's children that are something else than an element, whatever elements.auto says. */\nvar NOT_ELEMENTS = '.row, .ge-content, .ge-text-block, [data-ge-container], .ge-tools-drawer, .ge-resize-handle';\n\nGridEditor.features.elements = function(ge) {\n\n var warnedIntoText = false;\n var types = validTypes();\n\n function elementsEnabled() {\n if (ge.settings.elements.enabled !== 'auto') { return !!ge.settings.elements.enabled; }\n\n // A host that offers elements on the toolbar uses them, even on a\n // page that has none yet\n return ge.settings.elements.auto || types.length > 0 ||\n !!ge.canvas.querySelector(ge.settings.elements.selector);\n }\n\n /** The elements.types the toolbar can offer. One that can't be made is left out, with a word to the host. */\n function validTypes() {\n return (ge.settings.elements.types || []).filter(function(type, index) {\n var named = type && typeof type.type === 'string' && type.type.trim() !== '';\n var html = type && (typeof type.html === 'function' || (typeof type.html === 'string' && type.html.trim() !== ''));\n\n if (!named || !html) {\n ge.warn('elements.types[' + index + ']: a type needs a type name and its html, as a string or a ' +\n 'function; it is left off the toolbar.');\n }\n\n return named && html;\n });\n }\n\n /** A type's toolbar button. */\n function typeItem(type) {\n var mismatched = false;\n\n return {\n // Asked again whenever the toolbar is built, so setLocale\n // translates a labelKey\n label: function() { return labelOf(type); },\n iconClass: type.iconClass,\n group: type.group || 'elements',\n kind: 'element',\n inColumn: true,\n create: function() {\n var element = makeElement(type);\n\n if (element && !mismatched && !ge.settings.elements.auto && !element.matches(ge.settings.elements.selector)) {\n mismatched = true;\n ge.warn('elements.types \"' + type.type + '\": what it makes does not match elements.selector \"' +\n ge.settings.elements.selector + '\", so it will not be an element once the editor looks again.');\n }\n\n return element;\n },\n };\n }\n\n function labelOf(type) {\n if (type.labelKey) { return ge.t(type.labelKey); }\n\n return type.label || type.type;\n }\n\n /**\n * What a type's button makes: the root of its html, marked as the host\n * marks its own, or a div around it when it has no single root. Null,\n * with a word to the host, when there is nothing to make.\n */\n function makeElement(type) {\n var made;\n\n try {\n made = typeof type.html === 'function' ? type.html() : type.html;\n } catch (error) {\n ge.warn('elements.types \"' + type.type + '\": its html function threw (' + error.message + '); nothing was added.');\n return null;\n }\n\n var nodes = typeof made === 'string' ? dom.parse(made) : (made && made.nodeType ? [made] : []);\n // Whitespace between tags is not content\n nodes = nodes.filter(function(node) { return node.nodeType !== 3 || node.textContent.trim() !== ''; });\n\n if (!nodes.length) {\n ge.warn('elements.types \"' + type.type + '\": its html came out empty; nothing was added.');\n return null;\n }\n\n var element = nodes.length === 1 && nodes[0].nodeType === 1 ? nodes[0] : dom.element('div');\n if (element !== nodes[0] || nodes.length > 1) { fill(element, nodes); }\n\n element.setAttribute('data-ge-element', type.type);\n if (!element.hasAttribute('data-ge-label')) { element.setAttribute('data-ge-label', labelOf(type)); }\n\n return element;\n }\n\n /** Whether a child of a column is an element. */\n function isElement(node) {\n return ge.settings.elements.auto\n ? !node.matches(NOT_ELEMENTS)\n : node.matches(ge.settings.elements.selector);\n }\n\n function markElements() {\n if (!elementsEnabled()) { return; }\n\n dom.all(ge.canvas, '.column').forEach(function(column) {\n dom.children(column).forEach(function(element) {\n if (!dom.hasClass(element, 'ge-element') && !isElement(element)) { return; }\n\n dom.addClass(element, 'ge-element');\n if (!dom.child(element, '.ge-tools-drawer')) { createElementControls(element); }\n });\n });\n }\n\n function unmarkElements() {\n dom.all(ge.canvas, '.ge-element').forEach(function(element) {\n dom.removeClass(element, 'ge-element');\n\n // A host element that had no class of its own should not come\n // back from getHtml carrying an empty one\n dom.dropEmptyClass(element);\n });\n }\n\n function createElementControls(element) {\n var drawer = dom.element('div', { 'class': 'ge-tools-drawer ge-element-drawer' });\n element.insertBefore(drawer, element.firstChild);\n\n ge.createMoveTool(drawer);\n ge.createTool(drawer, ge.t('tool.element_info', { name: elementName(element) }),\n 'ge-element-info', 'bi bi-info-circle');\n ge.addSettingsTool(drawer, element, ge.settings.element_classes);\n\n ge.settings.element_tools.forEach(function(hostTool) {\n ge.createTool(drawer, hostTool.title || '', hostTool.className || '',\n hostTool.iconClass || 'bi bi-wrench', hostTool.on);\n });\n\n ge.createTool(drawer, ge.t('tool.delete_element'), 'ge-delete-element', 'bi bi-trash', function() {\n ge.deleteNode('element', element, ge.t('confirm.delete_element'), function(removed) {\n dom.shrinkAway(element, 300, removed);\n });\n });\n }\n\n function elementName(element) {\n var type = element.getAttribute('data-ge-element');\n var label = element.getAttribute('data-ge-label');\n\n if (label && type) { return label + ' (' + type + ')'; }\n\n return label || type || element.tagName.toLowerCase();\n }\n\n /**\n * Placed into a content area, as 5.x did, an element would be text\n * again, and the next init would cut it out. So it goes beside that\n * content area instead - after it for appendTo, before it for\n * prependTo - with a word to the host.\n */\n function placementBesideText(options) {\n var placed = Object.assign({}, options);\n\n [['appendTo', 'insertAfter'], ['prependTo', 'insertBefore']].forEach(function(pair) {\n var target = options[pair[0]] !== undefined ? nodeFrom(options[pair[0]]) : null;\n if (!target || !target.matches('.ge-content')) { return; }\n\n if (!warnedIntoText) {\n warnedIntoText = true;\n ge.warn('createElement: an element is a block of the column since 6.0, not part of a ' +\n 'content area\\'s text; it goes beside the content area. Place it in a column instead.');\n }\n\n delete placed[pair[0]];\n placed[pair[1]] = dom.hasClass(target.parentElement, 'ge-text-block') ? target.parentElement : target;\n });\n\n return placed;\n }\n\n /** enabled: false takes the toolbar's element buttons away too. */\n function elementsOff() {\n return ge.settings.elements.enabled === false;\n }\n\n /** A place a caller named: an element, or the first one a selector matches. */\n function nodeFrom(node) {\n if (typeof node === 'string') { return document.querySelector(node); }\n return node && node.nodeType === 1 ? node : null;\n }\n\n /**\n * What the element holds: html, which is parsed as innerHTML parses so\n * no <script> in it runs, or a node, or a list of nodes.\n */\n function fill(element, content) {\n if (content === undefined || content === null) { return; }\n\n if (typeof content === 'string') {\n dom.parse(content).forEach(function(node) { element.appendChild(node); });\n } else if (content.nodeType) {\n element.appendChild(content);\n } else if (typeof content.length === 'number') {\n Array.prototype.slice.call(content).forEach(function(node) { element.appendChild(node); });\n }\n }\n\n function apiCreateElement(content, options) {\n options = options || {};\n\n var element = dom.element('div', {\n 'class': 'ge-element',\n 'data-ge-element': options.type || 'element',\n });\n fill(element, content);\n if (options.label !== undefined) {\n element.setAttribute('data-ge-label', options.label);\n }\n\n return ge.place(element, 'element', placementBesideText(options));\n }\n\n return {\n methods: {\n createElement: apiCreateElement,\n },\n\n // A button for each type the host offers, in the elements category\n // unless the type names another\n toolbar: elementsOff() ? [] : types.map(typeItem),\n\n /** A node this plugin marked is an element, whatever else it is. */\n kindOf: function(node) {\n return dom.hasClass(node, 'ge-element') ? 'element' : null;\n },\n\n /**\n * An element cuts the text it sits in: 5.x's markup, or markup a host\n * wrote the same way, has it inside a content area, and it comes out.\n */\n cuts: function() {\n if (!elementsEnabled()) { return null; }\n\n return ge.settings.elements.auto ? '*' : ge.settings.elements.selector;\n },\n\n // A block the columns move, beside the texts, the rows and the\n // containers - and only the columns\n blocks: '.ge-element',\n accepts: function(region, node) {\n if (dom.hasClass(node, 'ge-element')) { return dom.is(region, '.column'); }\n\n return true;\n },\n\n onInit: markElements,\n onDeinit: unmarkElements,\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["GridEditor", "all", "root", "selector", "children", "node", "selector", "each", "child", "is", "node", "selector", "parse", "html", "template", "element", "tag", "attributes", "text", "node", "name", "value", "addClass", "node", "names", "split", "name", "removeClass", "hasClass", "node", "name", "split", "names", "dropEmptyClass", "hide", "node", "visible", "node", "DEFAULT_DURATION", "animateAway", "node", "frames", "duration", "done", "finish", "hide", "visible", "animation", "called", "once", "shrinkAway", "node", "duration", "done", "width", "animateAway", "style", "from", "to", "GridEditor", "NOT_ELEMENTS", "ge", "warnedIntoText", "types", "validTypes", "elementsEnabled", "type", "index", "named", "html", "typeItem", "mismatched", "labelOf", "element", "makeElement", "made", "error", "nodes", "parse", "node", "fill", "isElement", "markElements", "all", "column", "children", "hasClass", "addClass", "child", "createElementControls", "unmarkElements", "removeClass", "dropEmptyClass", "drawer", "elementName", "hostTool", "removed", "shrinkAway", "label", "placementBesideText", "options", "placed", "pair", "target", "nodeFrom", "elementsOff", "content", "apiCreateElement", "region", "is"]
7
7
  }
@@ -362,7 +362,7 @@ if (!GridEditor.features.text) {
362
362
  iconClass: TEXTS[type].iconClass,
363
363
  className: "ge-add-text-button",
364
364
  kind: "text",
365
- group: "content",
365
+ group: "elements",
366
366
  inColumn: true,
367
367
  create: function() {
368
368
  return makeText(type);
@@ -365,7 +365,7 @@
365
365
  iconClass: TEXTS[type].iconClass,
366
366
  className: "ge-add-text-button",
367
367
  kind: "text",
368
- group: "content",
368
+ group: "elements",
369
369
  inColumn: true,
370
370
  create: function() {
371
371
  return makeText(type);
@@ -1 +1 @@
1
- (()=>{var p=window.GridEditor;if(!p||typeof p.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");function _(e,i){return e?Array.prototype.slice.call(e.querySelectorAll(i)):[]}function X(e,i){return e?Array.prototype.filter.call(e.children,function(r){return!i||r.matches(i)}):[]}function b(e,i){return X(e,i)[0]||null}function Y(e,i,r){var o=e&&e.nodeType===1?e.closest(i):null;return o&&r&&o!==r&&!r.contains(o)?null:o}function w(e,i,r){var o=document.createElement(e);return Object.keys(i||{}).forEach(function(n){var u=i[n];u!=null&&u!==!1&&o.setAttribute(n,u)}),r!=null&&(o.textContent=r),o}function Q(e,i){return e.innerHTML=i==null?"":String(i),e}function A(e,i){return N(i).forEach(function(r){e.classList.add(r)}),e}function L(e,i){return N(i).forEach(function(r){e.classList.remove(r)}),e}function E(e,i){return!!e&&e.nodeType===1&&e.classList.contains(i)}function N(e){return String(e||"").split(/\s+/).filter(Boolean)}function J(e){return e.style.display="none",e}function H(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}function $(e,i,r,o,n){var u=function(s){var l=Y(s.target,r,e);if(l&&e.contains(l))return o.call(l,s)};return N(i).forEach(function(s){e.addEventListener(s,u,n)}),u}var V=400;function Z(e,i,r,o){r=r===void 0?V:r;var n=function(){J(e),o&&o()};if(!H(e)||!e.animate||r<=0){window.setTimeout(n,0);return}var u=e.animate(i(getComputedStyle(e)),{duration:r,easing:"ease-in-out"}),s=!1,l=function(){s||(s=!0,n())};u.onfinish=l,u.oncancel=l}function F(e,i,r){typeof i=="function"&&(r=i,i=void 0),e.style.overflow="hidden",Z(e,function(o){return[{height:o.height,paddingTop:o.paddingTop,paddingBottom:o.paddingBottom,marginTop:o.marginTop,marginBottom:o.marginBottom},{height:"0px",paddingTop:"0px",paddingBottom:"0px",marginTop:"0px",marginBottom:"0px"}]},i,function(){e.style.removeProperty("overflow"),r&&r()})}if(!p.features.text){let e=function(n){var u={};return Array.prototype.slice.call(n.attributes).forEach(function(s){u[s.name]=s.value}),u},i=function(n){return(n||"").split(/\s+/).filter(function(u){return u!==""&&!I.test(u)})},r=function(n,u,s,l){var m=Object.assign({},u);Object.keys(Object.assign({},s,l)).forEach(function(f){f==="class"||U.test(f)||s[f]===l[f]||(l[f]===void 0?delete m[f]:m[f]=l[f])});var v=i(s.class),T=i(l.class),x=i(u.class).filter(function(f){return T.indexOf(f)!==-1||v.indexOf(f)===-1});T.forEach(function(f){v.indexOf(f)===-1&&x.indexOf(f)===-1&&x.push(f)}),x.length?m.class=x.join(" "):delete m.class,Object.keys(e(n)).forEach(function(f){n.removeAttribute(f)}),Object.keys(m).forEach(function(f){n.setAttribute(f,m[f])})},o=function(n){var u=n.settings,s={},l={};Object.keys(p.texts).forEach(function(t){s[t]=p.texts[t](n)}),Array.isArray(u.content_types)||(u.content_types=Object.keys(s)),Array.isArray(u.text_tools)||(u.text_tools=[]),Array.isArray(u.text_classes)||(u.text_classes=[]);function m(){return u.content_types.filter(function(t){return!!s[t]})}function v(t){var a=s[t];return a&&a.labelKey?n.t(a.labelKey):t}function T(t,a){var c=s[t],d=w("div",{class:"ge-content ge-content-type-"+t,"data-ge-content-type":t});return a&&a.nodeType?d.appendChild(a):Q(d,a!==void 0?a:c&&c.initialContent||""),d}function x(t,a){return t&&typeof t=="object"&&(a=t,t=void 0),a=a||{},t=t||m()[0],!t||!s[t]?(l["createText:"+t]||(l["createText:"+t]=!0,n.warn('createText: no text editor "'+t+'" is loaded; load its plugin and name it in content_types')),null):n.place(T(t,a.content),"text",a)}function f(t){return!!s[t.getAttribute("data-ge-content-type")]}function K(t){if(!E(t,"ge-rte-active")&&H(t)){var a=s[t.getAttribute("data-ge-content-type")];if(a){if(a.available&&!a.available()){a.missingKey&&console.error(n.t(a.missingKey));return}j.set(t,e(t)),C.delete(t),A(t,"ge-rte-active"),a.start([t])}}}function D(){K(this)}function k(t){var a=s[t.getAttribute("data-ge-content-type")],c=j.get(t),d=c?e(t):null;a&&a.stop([t]),L(t,"ge-rte-active"),c&&(r(t,c,C.get(t)||c,d),j.delete(t),C.delete(t))}function B(t){var a=b(t,".ge-content"),c=a.getAttribute("data-ge-content-type"),d=w("div",{class:"ge-tools-drawer ge-text-drawer"});t.insertBefore(d,t.firstChild),n.createMoveTool(d);var O=n.addSettingsTool(d,a,u.text_classes),h=b(O,".ge-details-general"),S=w("div",{class:"ge-field ge-text-editor"});S.appendChild(w("span",{class:"ge-field-label"},n.t("panel.editor"))),S.appendChild(w("span",{class:"ge-field-value"},v(c))),h.insertBefore(S,h.firstChild),u.text_tools.forEach(function(y){n.createTool(d,y.title||"",y.className||"",y.iconClass||"bi bi-wrench",y.on)}),n.createTool(d,n.t("tool.delete_text"),"ge-delete-text","bi bi-trash",function(){n.deleteNode("text",a,n.t("confirm.delete_text"),function(y){k(a),F(t,function(){t.remove(),y()})})})}function z(){_(n.canvas,".ge-text-block").forEach(function(t){if(!b(t,".ge-tools-drawer")){var a=b(t,".ge-content");!a||!f(a)||B(t)}})}var P=m(),g=null;return{methods:{createText:x},textTypes:function(){var t=m(),a=Object.keys(s).filter(function(c){return t.indexOf(c)===-1});return t.concat(a).map(function(c){var d=s[c];return{type:c,label:v(c),offered:t.indexOf(c)!==-1,available:d.available?function(){return d.available()}:null,missingKey:d.missingKey,edit:function(O){var h=O.parentElement;E(h,"ge-text-block")&&!b(h,".ge-tools-drawer")&&B(h),K(O)}}})},toolbar:P.map(function(t){return{label:function(){return P.length>1?n.t("text.add_type",{editor:v(t)}):n.t("text.add")},iconClass:s[t].iconClass,className:"ge-add-text-button",kind:"text",group:"content",inColumn:!0,create:function(){return T(t)}}}),onInit:function(){z(),g&&n.canvas.removeEventListener("click",g),g=$(n.canvas,"click",".ge-content",D)},onBeforeDeinit:function(){_(n.canvas,".ge-content").forEach(function(t){f(t)&&k(t)})},onDeinit:function(){g&&n.canvas.removeEventListener("click",g),g=null},onContentReady:function(t){j.has(t)&&!C.has(t)&&C.set(t,e(t))}}};Object.assign(p.locales.en,{"text.add":"Text","text.add_type":"Text ({editor})","panel.editor":"Editor","panel.kind_text":"Text"}),j=new WeakMap,C=new WeakMap,I=/^(mce-|cke|ck-|note-)|^(ck|active|ge-rte-active)$/,U=/^(data-mce-|contenteditable$|spellcheck$)/,o.always=!0,p.features.text=o}var j,C,I,U;Object.assign(p.locales.en,{"text.summernote":"Summernote"});var W="<p>Lorem ipsum dolores</p>";function q(e){return!!e&&Object.prototype.toString.call(e)==="[object Object]"}function M(e){return Array.prototype.slice.call(arguments,1).forEach(function(i){Object.keys(i||{}).forEach(function(r){var o=i[r];o===void 0||o===e||(Array.isArray(o)?e[r]=M(Array.isArray(e[r])?e[r]:[],o):q(o)?e[r]=M(q(e[r])?e[r]:{},o):e[r]=o)})}),e}p.texts.summernote=function(e){return{labelKey:"text.summernote",initialContent:W,missingKey:"error.summernote_missing",available:function(){return!!(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.summernote)},start:function(i){var r=e.settings,o=window.jQuery;o.now||(o.now=Date.now),i.forEach(function(n){if(!E(n,"active")){n.innerHTML==W&&(n.innerHTML=""),A(n,"active");var u=M({},r.summernote&&r.summernote.config?r.summernote.config:{},{tabsize:2,airMode:!0,callbacks:{onInit:function(){var s;try{s=r.summernote.config.callbacks.onInit}catch(l){}s&&s.call(this),e.textReady(n),o(n).summernote("focus")}}});o(n).summernote(u)}})},stop:function(i){var r=window.jQuery;i.filter(function(o){return E(o,"active")}).forEach(function(o){r&&r.fn.summernote&&r(o).summernote("destroy"),L(o,"active"),["id","style","spellcheck"].forEach(function(n){o.removeAttribute(n)})})}}};})();
1
+ (()=>{var p=window.GridEditor;if(!p||typeof p.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");function _(e,i){return e?Array.prototype.slice.call(e.querySelectorAll(i)):[]}function X(e,i){return e?Array.prototype.filter.call(e.children,function(r){return!i||r.matches(i)}):[]}function b(e,i){return X(e,i)[0]||null}function Y(e,i,r){var o=e&&e.nodeType===1?e.closest(i):null;return o&&r&&o!==r&&!r.contains(o)?null:o}function w(e,i,r){var o=document.createElement(e);return Object.keys(i||{}).forEach(function(n){var s=i[n];s!=null&&s!==!1&&o.setAttribute(n,s)}),r!=null&&(o.textContent=r),o}function Q(e,i){return e.innerHTML=i==null?"":String(i),e}function A(e,i){return N(i).forEach(function(r){e.classList.add(r)}),e}function L(e,i){return N(i).forEach(function(r){e.classList.remove(r)}),e}function E(e,i){return!!e&&e.nodeType===1&&e.classList.contains(i)}function N(e){return String(e||"").split(/\s+/).filter(Boolean)}function J(e){return e.style.display="none",e}function H(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}function $(e,i,r,o,n){var s=function(u){var l=Y(u.target,r,e);if(l&&e.contains(l))return o.call(l,u)};return N(i).forEach(function(u){e.addEventListener(u,s,n)}),s}var V=400;function Z(e,i,r,o){r=r===void 0?V:r;var n=function(){J(e),o&&o()};if(!H(e)||!e.animate||r<=0){window.setTimeout(n,0);return}var s=e.animate(i(getComputedStyle(e)),{duration:r,easing:"ease-in-out"}),u=!1,l=function(){u||(u=!0,n())};s.onfinish=l,s.oncancel=l}function F(e,i,r){typeof i=="function"&&(r=i,i=void 0),e.style.overflow="hidden",Z(e,function(o){return[{height:o.height,paddingTop:o.paddingTop,paddingBottom:o.paddingBottom,marginTop:o.marginTop,marginBottom:o.marginBottom},{height:"0px",paddingTop:"0px",paddingBottom:"0px",marginTop:"0px",marginBottom:"0px"}]},i,function(){e.style.removeProperty("overflow"),r&&r()})}if(!p.features.text){let e=function(n){var s={};return Array.prototype.slice.call(n.attributes).forEach(function(u){s[u.name]=u.value}),s},i=function(n){return(n||"").split(/\s+/).filter(function(s){return s!==""&&!I.test(s)})},r=function(n,s,u,l){var m=Object.assign({},s);Object.keys(Object.assign({},u,l)).forEach(function(f){f==="class"||U.test(f)||u[f]===l[f]||(l[f]===void 0?delete m[f]:m[f]=l[f])});var v=i(u.class),T=i(l.class),x=i(s.class).filter(function(f){return T.indexOf(f)!==-1||v.indexOf(f)===-1});T.forEach(function(f){v.indexOf(f)===-1&&x.indexOf(f)===-1&&x.push(f)}),x.length?m.class=x.join(" "):delete m.class,Object.keys(e(n)).forEach(function(f){n.removeAttribute(f)}),Object.keys(m).forEach(function(f){n.setAttribute(f,m[f])})},o=function(n){var s=n.settings,u={},l={};Object.keys(p.texts).forEach(function(t){u[t]=p.texts[t](n)}),Array.isArray(s.content_types)||(s.content_types=Object.keys(u)),Array.isArray(s.text_tools)||(s.text_tools=[]),Array.isArray(s.text_classes)||(s.text_classes=[]);function m(){return s.content_types.filter(function(t){return!!u[t]})}function v(t){var a=u[t];return a&&a.labelKey?n.t(a.labelKey):t}function T(t,a){var c=u[t],d=w("div",{class:"ge-content ge-content-type-"+t,"data-ge-content-type":t});return a&&a.nodeType?d.appendChild(a):Q(d,a!==void 0?a:c&&c.initialContent||""),d}function x(t,a){return t&&typeof t=="object"&&(a=t,t=void 0),a=a||{},t=t||m()[0],!t||!u[t]?(l["createText:"+t]||(l["createText:"+t]=!0,n.warn('createText: no text editor "'+t+'" is loaded; load its plugin and name it in content_types')),null):n.place(T(t,a.content),"text",a)}function f(t){return!!u[t.getAttribute("data-ge-content-type")]}function K(t){if(!E(t,"ge-rte-active")&&H(t)){var a=u[t.getAttribute("data-ge-content-type")];if(a){if(a.available&&!a.available()){a.missingKey&&console.error(n.t(a.missingKey));return}j.set(t,e(t)),C.delete(t),A(t,"ge-rte-active"),a.start([t])}}}function D(){K(this)}function k(t){var a=u[t.getAttribute("data-ge-content-type")],c=j.get(t),d=c?e(t):null;a&&a.stop([t]),L(t,"ge-rte-active"),c&&(r(t,c,C.get(t)||c,d),j.delete(t),C.delete(t))}function B(t){var a=b(t,".ge-content"),c=a.getAttribute("data-ge-content-type"),d=w("div",{class:"ge-tools-drawer ge-text-drawer"});t.insertBefore(d,t.firstChild),n.createMoveTool(d);var O=n.addSettingsTool(d,a,s.text_classes),h=b(O,".ge-details-general"),S=w("div",{class:"ge-field ge-text-editor"});S.appendChild(w("span",{class:"ge-field-label"},n.t("panel.editor"))),S.appendChild(w("span",{class:"ge-field-value"},v(c))),h.insertBefore(S,h.firstChild),s.text_tools.forEach(function(y){n.createTool(d,y.title||"",y.className||"",y.iconClass||"bi bi-wrench",y.on)}),n.createTool(d,n.t("tool.delete_text"),"ge-delete-text","bi bi-trash",function(){n.deleteNode("text",a,n.t("confirm.delete_text"),function(y){k(a),F(t,function(){t.remove(),y()})})})}function z(){_(n.canvas,".ge-text-block").forEach(function(t){if(!b(t,".ge-tools-drawer")){var a=b(t,".ge-content");!a||!f(a)||B(t)}})}var P=m(),g=null;return{methods:{createText:x},textTypes:function(){var t=m(),a=Object.keys(u).filter(function(c){return t.indexOf(c)===-1});return t.concat(a).map(function(c){var d=u[c];return{type:c,label:v(c),offered:t.indexOf(c)!==-1,available:d.available?function(){return d.available()}:null,missingKey:d.missingKey,edit:function(O){var h=O.parentElement;E(h,"ge-text-block")&&!b(h,".ge-tools-drawer")&&B(h),K(O)}}})},toolbar:P.map(function(t){return{label:function(){return P.length>1?n.t("text.add_type",{editor:v(t)}):n.t("text.add")},iconClass:u[t].iconClass,className:"ge-add-text-button",kind:"text",group:"elements",inColumn:!0,create:function(){return T(t)}}}),onInit:function(){z(),g&&n.canvas.removeEventListener("click",g),g=$(n.canvas,"click",".ge-content",D)},onBeforeDeinit:function(){_(n.canvas,".ge-content").forEach(function(t){f(t)&&k(t)})},onDeinit:function(){g&&n.canvas.removeEventListener("click",g),g=null},onContentReady:function(t){j.has(t)&&!C.has(t)&&C.set(t,e(t))}}};Object.assign(p.locales.en,{"text.add":"Text","text.add_type":"Text ({editor})","panel.editor":"Editor","panel.kind_text":"Text"}),j=new WeakMap,C=new WeakMap,I=/^(mce-|cke|ck-|note-)|^(ck|active|ge-rte-active)$/,U=/^(data-mce-|contenteditable$|spellcheck$)/,o.always=!0,p.features.text=o}var j,C,I,U;Object.assign(p.locales.en,{"text.summernote":"Summernote"});var W="<p>Lorem ipsum dolores</p>";function q(e){return!!e&&Object.prototype.toString.call(e)==="[object Object]"}function M(e){return Array.prototype.slice.call(arguments,1).forEach(function(i){Object.keys(i||{}).forEach(function(r){var o=i[r];o===void 0||o===e||(Array.isArray(o)?e[r]=M(Array.isArray(e[r])?e[r]:[],o):q(o)?e[r]=M(q(e[r])?e[r]:{},o):e[r]=o)})}),e}p.texts.summernote=function(e){return{labelKey:"text.summernote",initialContent:W,missingKey:"error.summernote_missing",available:function(){return!!(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.summernote)},start:function(i){var r=e.settings,o=window.jQuery;o.now||(o.now=Date.now),i.forEach(function(n){if(!E(n,"active")){n.innerHTML==W&&(n.innerHTML=""),A(n,"active");var s=M({},r.summernote&&r.summernote.config?r.summernote.config:{},{tabsize:2,airMode:!0,callbacks:{onInit:function(){var u;try{u=r.summernote.config.callbacks.onInit}catch(l){}u&&u.call(this),e.textReady(n),o(n).summernote("focus")}}});o(n).summernote(s)}})},stop:function(i){var r=window.jQuery;i.filter(function(o){return E(o,"active")}).forEach(function(o){r&&r.fn.summernote&&r(o).summernote("destroy"),L(o,"active"),["id","style","spellcheck"].forEach(function(n){o.removeAttribute(n)})})}}};})();