@themarioga/grid-editor 8.3.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 (45) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +43 -1
  3. package/dist/grideditor.bundle.min.js +3 -3
  4. package/dist/grideditor.css +49 -0
  5. package/dist/grideditor.d.ts +21 -1
  6. package/dist/grideditor.esm.js +211 -9
  7. package/dist/grideditor.js +211 -9
  8. package/dist/grideditor.min.css +1 -1
  9. package/dist/grideditor.min.css.map +1 -1
  10. package/dist/grideditor.min.js +2 -2
  11. package/dist/grideditor.min.js.map +3 -3
  12. package/dist/locales/grideditor.es.esm.js +4 -0
  13. package/dist/locales/grideditor.es.js +4 -0
  14. package/dist/locales/grideditor.es.min.js +1 -1
  15. package/dist/locales/grideditor.es.min.js.map +2 -2
  16. package/dist/plugins/grideditor.ckeditor.esm.js +1 -0
  17. package/dist/plugins/grideditor.ckeditor.js +1 -0
  18. package/dist/plugins/grideditor.ckeditor.min.js +1 -1
  19. package/dist/plugins/grideditor.ckeditor.min.js.map +2 -2
  20. package/dist/plugins/grideditor.elements.esm.js +72 -1
  21. package/dist/plugins/grideditor.elements.js +72 -1
  22. package/dist/plugins/grideditor.elements.min.js +1 -1
  23. package/dist/plugins/grideditor.elements.min.js.map +3 -3
  24. package/dist/plugins/grideditor.sections.esm.js +1 -0
  25. package/dist/plugins/grideditor.sections.js +1 -0
  26. package/dist/plugins/grideditor.sections.min.js +1 -1
  27. package/dist/plugins/grideditor.sections.min.js.map +2 -2
  28. package/dist/plugins/grideditor.summernote.esm.js +1 -0
  29. package/dist/plugins/grideditor.summernote.js +1 -0
  30. package/dist/plugins/grideditor.summernote.min.js +1 -1
  31. package/dist/plugins/grideditor.summernote.min.js.map +2 -2
  32. package/dist/plugins/grideditor.tinymce.esm.js +1 -0
  33. package/dist/plugins/grideditor.tinymce.js +1 -0
  34. package/dist/plugins/grideditor.tinymce.min.js +1 -1
  35. package/dist/plugins/grideditor.tinymce.min.js.map +2 -2
  36. package/docs/locale-keys.md +5 -1
  37. package/docs/plugins.md +24 -1
  38. package/package.json +1 -1
  39. package/src/js/grideditor.js +252 -8
  40. package/src/js/locales/grideditor.es.js +4 -0
  41. package/src/js/plugins/grideditor.elements.js +94 -1
  42. package/src/js/plugins/grideditor.sections.js +1 -0
  43. package/src/js/text/grideditor.text.js +1 -0
  44. package/src/less/grideditor.less +58 -0
  45. package/types/grideditor.d.ts +21 -1
@@ -393,8 +393,10 @@
393
393
  // 'auto' turns them on when the page has any
394
394
  selector: "[data-ge-element]",
395
395
  // What the host marks an element with
396
- auto: false
396
+ auto: false,
397
397
  // Treat every child of a content area as an element
398
+ types: []
399
+ // The elements the toolbar offers: { type, html, label | labelKey, iconClass, group }
398
400
  },
399
401
  resize: {
400
402
  enabled: true,
@@ -445,6 +447,10 @@
445
447
  return params && params[name] !== void 0 ? params[name] : placeholder;
446
448
  });
447
449
  }
450
+ function hasString(settings, key) {
451
+ var locales = GridEditor.locales;
452
+ return (settings.locale_strings || {})[key] !== void 0 || (locales[settings.locale] || {})[key] !== void 0 || locales.en[key] !== void 0;
453
+ }
448
454
  function warn(message) {
449
455
  if (window.console && window.console.warn) {
450
456
  window.console.warn("grid-editor: " + message);
@@ -573,6 +579,10 @@
573
579
  // Drag the toolbar's buttons onto the canvas. 'auto' follows drag_handle
574
580
  "toolbar_overflow": "menu",
575
581
  // What doesn't fit on one line: 'menu' behind a button, 'wrap' onto another line
582
+ "drawer_overflow": "menu",
583
+ // The same for the drawers' tools: 'menu' behind a button, 'wrap' onto another line
584
+ "toolbar_groups": false,
585
+ // The add buttons in categories, one shown at a time, picked with tabs
576
586
  "active_target": false,
577
587
  // A click in a column makes it where the toolbar's buttons add
578
588
  "element_tools": [],
@@ -640,6 +650,10 @@
640
650
  var toolbarLifetime = null;
641
651
  var closeOverflowMenu = function() {
642
652
  };
653
+ var refitToolbar = function() {
654
+ };
655
+ var addButtons = [];
656
+ var toolbarGroup = null;
643
657
  var warnedHere = {};
644
658
  var sortables = [];
645
659
  var instanceId = ++editorCounter;
@@ -1036,6 +1050,7 @@
1036
1050
  htmlTextArea = element("textarea", { "class": "ge-html-output" });
1037
1051
  canvas.parentNode.insertBefore(htmlTextArea, canvas);
1038
1052
  createMainControls();
1053
+ watchDrawers();
1039
1054
  var signal = { signal: lifetime.signal };
1040
1055
  window.addEventListener("scroll", onScroll, signal);
1041
1056
  delegate(canvas, "click", ".ge-content", onContentClick, signal);
@@ -1059,6 +1074,10 @@
1059
1074
  return;
1060
1075
  }
1061
1076
  var region = closest(e.target, targetSelector());
1077
+ if (region && region === activeTarget && (e.target === region || e.target === child(region, ".ge-tools-drawer"))) {
1078
+ changeTarget(null);
1079
+ return;
1080
+ }
1062
1081
  changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
1063
1082
  }, signal);
1064
1083
  document.addEventListener("keydown", function(e) {
@@ -1090,6 +1109,7 @@
1090
1109
  addClass(wrapper, "ge-toolbar-menu");
1091
1110
  start = wrapper.appendChild(element("div", { "class": "ge-toolbar-start" }));
1092
1111
  }
1112
+ addButtons = [];
1093
1113
  addRowGroup = start.appendChild(element("div", { "class": "ge-addRowGroup btn-group" }));
1094
1114
  addContainerGroup = element("div", { "class": "ge-addContainerGroup btn-group ms-1" });
1095
1115
  settings.new_row_layouts.forEach(function(layout) {
@@ -1116,6 +1136,7 @@
1116
1136
  }
1117
1137
  });
1118
1138
  addRowGroup.appendChild(btn);
1139
+ addButtons.push({ button: btn, home: addRowGroup, group: "rows" });
1119
1140
  btn.appendChild(create('<i class="bi bi-plus"></i>'));
1120
1141
  var sizes = grouped ? rowColsIcon(layout) : layout;
1121
1142
  var icon = '<div class="row ge-row-icon">';
@@ -1147,6 +1168,7 @@
1147
1168
  }, { parent: canvas, source: "tool" });
1148
1169
  });
1149
1170
  addContainerGroup.appendChild(button);
1171
+ addButtons.push({ button, home: addContainerGroup, group: toolbarGroupOf(definition.group) || "content" });
1150
1172
  });
1151
1173
  var endItems = [];
1152
1174
  Object.keys(FEATURES).forEach(function(name) {
@@ -1156,6 +1178,7 @@
1156
1178
  endItems.push(button);
1157
1179
  } else {
1158
1180
  addContainerGroup.appendChild(button);
1181
+ addButtons.push({ button, home: addContainerGroup, group: toolbarGroupOf(item.group) || name });
1159
1182
  }
1160
1183
  });
1161
1184
  });
@@ -1209,11 +1232,82 @@
1209
1232
  end.appendChild(button);
1210
1233
  });
1211
1234
  }
1235
+ if (settings.toolbar_groups) {
1236
+ createGroupTabs(start);
1237
+ }
1212
1238
  if (overflowMenu) {
1213
1239
  createOverflowMenu(start);
1214
1240
  }
1215
1241
  makeToolbarDraggable();
1216
1242
  }
1243
+ var CORE_GROUPS = [
1244
+ { name: "rows", labelKey: "group.rows" },
1245
+ { name: "content", labelKey: "group.content" },
1246
+ { name: "elements", labelKey: "group.elements" }
1247
+ ];
1248
+ function toolbarGroupOf(value) {
1249
+ return typeof value === "string" && value.trim() !== "" ? value : null;
1250
+ }
1251
+ function createGroupTabs(start) {
1252
+ var names = CORE_GROUPS.map(function(group) {
1253
+ return group.name;
1254
+ });
1255
+ addButtons.forEach(function(entry) {
1256
+ if (names.indexOf(entry.group) < 0) {
1257
+ names.push(entry.group);
1258
+ }
1259
+ });
1260
+ names = names.filter(function(name) {
1261
+ return addButtons.some(function(entry) {
1262
+ return entry.group === name;
1263
+ });
1264
+ });
1265
+ if (names.length < 2) {
1266
+ return;
1267
+ }
1268
+ var tabs = element("div", { "class": "ge-toolbar-groups btn-group", role: "tablist", "aria-label": t("group.select") });
1269
+ start.insertBefore(tabs, start.firstChild);
1270
+ var stash = mainControls.appendChild(element("div", { "class": "ge-toolbar-stash", hidden: "hidden" }));
1271
+ names.forEach(function(name) {
1272
+ var tab = tabs.appendChild(element("button", {
1273
+ type: "button",
1274
+ "class": "btn btn-sm btn-outline-primary",
1275
+ role: "tab",
1276
+ "data-ge-group": name
1277
+ }, groupLabel(name)));
1278
+ tab.addEventListener("click", function() {
1279
+ showGroup(name);
1280
+ });
1281
+ });
1282
+ showGroup(names.indexOf(toolbarGroup) >= 0 ? toolbarGroup : names[0]);
1283
+ function showGroup(name) {
1284
+ toolbarGroup = name;
1285
+ addButtons.forEach(function(entry) {
1286
+ (entry.group === name ? entry.home : stash).appendChild(entry.button);
1287
+ });
1288
+ children(tabs).forEach(function(tab) {
1289
+ var chosen = tab.getAttribute("data-ge-group") === name;
1290
+ toggleClass(tab, "active", chosen);
1291
+ tab.setAttribute("aria-selected", chosen ? "true" : "false");
1292
+ });
1293
+ refitToolbar();
1294
+ }
1295
+ }
1296
+ function groupLabel(name) {
1297
+ var key = "group." + name;
1298
+ if (hasString(settings, key)) {
1299
+ return t(key);
1300
+ }
1301
+ var first = addButtons.filter(function(entry) {
1302
+ return entry.group === name;
1303
+ })[0];
1304
+ return first.button.getAttribute("title") || name;
1305
+ }
1306
+ function shownAddButtons() {
1307
+ return addButtons.filter(function(entry) {
1308
+ return !closest(entry.button, ".ge-toolbar-stash");
1309
+ });
1310
+ }
1217
1311
  function removeMainControls() {
1218
1312
  if (toolbarLifetime) {
1219
1313
  toolbarLifetime.abort();
@@ -1221,6 +1315,8 @@
1221
1315
  toolbarLifetime = null;
1222
1316
  closeOverflowMenu = function() {
1223
1317
  };
1318
+ refitToolbar = function() {
1319
+ };
1224
1320
  mainControls.remove();
1225
1321
  }
1226
1322
  function createOverflowMenu(start) {
@@ -1229,12 +1325,9 @@
1229
1325
  var toggle2 = one(more, "button");
1230
1326
  var panel = one(more, ".ge-toolbar-overflow");
1231
1327
  var spares = all(panel, ".btn-group");
1232
- var homes = [];
1233
- [addRowGroup, addContainerGroup].forEach(function(group, index) {
1234
- Array.prototype.slice.call(group.children).forEach(function(button) {
1235
- homes.push({ button, home: group, spare: spares[index] });
1236
- });
1237
- });
1328
+ function spareOf(home) {
1329
+ return home === addRowGroup ? spares[0] : spares[1];
1330
+ }
1238
1331
  toggle2.setAttribute("title", t("tool.more"));
1239
1332
  toggle2.setAttribute("aria-haspopup", "true");
1240
1333
  toggle2.setAttribute("aria-expanded", "false");
@@ -1261,6 +1354,7 @@
1261
1354
  closeOverflowMenu = function() {
1262
1355
  openOverflow(false);
1263
1356
  };
1357
+ refitToolbar = fit;
1264
1358
  fit();
1265
1359
  if (window.ResizeObserver) {
1266
1360
  var pending = false;
@@ -1288,6 +1382,7 @@
1288
1382
  toggle2.setAttribute("aria-expanded", open ? "true" : "false");
1289
1383
  }
1290
1384
  function fit() {
1385
+ var homes = shownAddButtons();
1291
1386
  homes.forEach(function(entry) {
1292
1387
  entry.home.appendChild(entry.button);
1293
1388
  });
@@ -1298,7 +1393,8 @@
1298
1393
  }
1299
1394
  addClass(more, "ge-needed");
1300
1395
  for (var i = homes.length - 1; i >= 0 && start.scrollWidth > start.clientWidth; i--) {
1301
- homes[i].spare.insertBefore(homes[i].button, homes[i].spare.firstChild);
1396
+ var into = spareOf(homes[i].home);
1397
+ into.insertBefore(homes[i].button, into.firstChild);
1302
1398
  }
1303
1399
  }
1304
1400
  }
@@ -1328,6 +1424,9 @@
1328
1424
  return;
1329
1425
  }
1330
1426
  var made = item.create();
1427
+ if (!made) {
1428
+ return;
1429
+ }
1331
1430
  var placed = item.inColumn ? inRowOfItsOwn(made) : made;
1332
1431
  var added = addNode(item.kind, made, function() {
1333
1432
  canvas.appendChild(placed);
@@ -1436,6 +1535,9 @@
1436
1535
  function insertFeatureFromToolbar(button, where, source) {
1437
1536
  var item = FEATURES[button.getAttribute("data-ge-feature")].toolbar[parseInt(button.getAttribute("data-ge-item"), 10)];
1438
1537
  var made = item.create();
1538
+ if (!made) {
1539
+ return null;
1540
+ }
1439
1541
  var placed = made;
1440
1542
  if (item.inColumn) {
1441
1543
  if (!is(where.region, ".column")) {
@@ -2825,6 +2927,102 @@
2825
2927
  }
2826
2928
  return createTool(drawer, t("tool.move"), "ge-move", "bi bi-arrows-move");
2827
2929
  }
2930
+ var FITTED_DRAWERS = ".ge-tools-drawer:not(.ge-text-drawer):not(.ge-pane-drawer):not(.ge-code-inline)";
2931
+ function watchDrawers() {
2932
+ if (settings.drawer_overflow === "wrap" || !window.ResizeObserver || !window.MutationObserver) {
2933
+ return;
2934
+ }
2935
+ var due = /* @__PURE__ */ new Set();
2936
+ var frame = null;
2937
+ function schedule(drawer) {
2938
+ due.add(drawer);
2939
+ if (frame === null) {
2940
+ frame = window.requestAnimationFrame(flush);
2941
+ }
2942
+ }
2943
+ function flush() {
2944
+ frame = null;
2945
+ var drawers = Array.from(due);
2946
+ due.clear();
2947
+ drawers.forEach(function(drawer) {
2948
+ if (!drawer.isConnected) {
2949
+ drawerResizes.unobserve(drawer);
2950
+ return;
2951
+ }
2952
+ fitDrawer(drawer);
2953
+ });
2954
+ }
2955
+ var drawerResizes = new window.ResizeObserver(function(entries) {
2956
+ entries.forEach(function(entry) {
2957
+ schedule(entry.target);
2958
+ });
2959
+ });
2960
+ var mutations = new window.MutationObserver(function(records) {
2961
+ records.forEach(function(record) {
2962
+ var target = record.target;
2963
+ if (record.type === "attributes") {
2964
+ var parent = target.parentNode;
2965
+ if (parent && parent.nodeType === 1 && parent.matches(FITTED_DRAWERS)) {
2966
+ schedule(parent);
2967
+ }
2968
+ return;
2969
+ }
2970
+ if (target.nodeType === 1 && target.matches(FITTED_DRAWERS)) {
2971
+ schedule(target);
2972
+ return;
2973
+ }
2974
+ record.addedNodes.forEach(function(node) {
2975
+ if (node.nodeType !== 1) {
2976
+ return;
2977
+ }
2978
+ selfAndAll(node, FITTED_DRAWERS).forEach(function(drawer) {
2979
+ addClass(drawer, "ge-drawer-fit");
2980
+ drawerResizes.observe(drawer);
2981
+ schedule(drawer);
2982
+ });
2983
+ });
2984
+ });
2985
+ });
2986
+ mutations.observe(canvas, { childList: true, subtree: true, attributes: true, attributeFilter: ["style"] });
2987
+ lifetime.signal.addEventListener("abort", function() {
2988
+ mutations.disconnect();
2989
+ drawerResizes.disconnect();
2990
+ if (frame !== null) {
2991
+ window.cancelAnimationFrame(frame);
2992
+ }
2993
+ });
2994
+ }
2995
+ function fitDrawer(drawer) {
2996
+ var tools = children(drawer, "a").filter(function(tool) {
2997
+ return !hasClass(tool, "ge-drawer-more");
2998
+ });
2999
+ var expanded = hasClass(drawer, "ge-drawer-expanded");
3000
+ removeClass(drawer, "ge-drawer-overflow ge-drawer-expanded");
3001
+ tools.forEach(function(tool) {
3002
+ removeClass(tool, "ge-tool-overflow");
3003
+ });
3004
+ if (!drawerOverflows(drawer, tools)) {
3005
+ return;
3006
+ }
3007
+ addClass(drawer, "ge-drawer-overflow");
3008
+ if (!child(drawer, ".ge-drawer-more")) {
3009
+ createTool(drawer, t("tool.more"), "ge-drawer-more", "bi bi-three-dots", function() {
3010
+ toggleClass(drawer, "ge-drawer-expanded");
3011
+ });
3012
+ }
3013
+ for (var i = tools.length - 1; i >= 0 && drawerOverflows(drawer, tools); i--) {
3014
+ addClass(tools[i], "ge-tool-overflow");
3015
+ }
3016
+ toggleClass(drawer, "ge-drawer-expanded", expanded);
3017
+ }
3018
+ function drawerOverflows(drawer, tools) {
3019
+ var style = window.getComputedStyle(drawer);
3020
+ var limit = drawer.getBoundingClientRect().right - parseFloat(style.borderRightWidth) - parseFloat(style.paddingRight);
3021
+ return tools.some(function(tool) {
3022
+ var rects = tool.getClientRects();
3023
+ return rects.length > 0 && rects[0].right > limit + 0.5;
3024
+ });
3025
+ }
2828
3026
  function createTool(drawer, title, className, iconClass, eventHandlers) {
2829
3027
  var tool = element("a", { title, "class": className });
2830
3028
  tool.appendChild(element("i", { "class": iconClass }));
@@ -4324,7 +4522,7 @@
4324
4522
  GridEditor._plainHtml = plainHtml;
4325
4523
  GridEditor.Sortable = null;
4326
4524
  GridEditor.bootstrap = null;
4327
- GridEditor.version = false ? "dev" : "8.3.0";
4525
+ GridEditor.version = false ? "dev" : "8.5.0";
4328
4526
  GridEditor.locales = {
4329
4527
  en: {
4330
4528
  "tool.move": "Move",
@@ -4350,6 +4548,10 @@
4350
4548
  "tool.edit_source": "Edit Source Code",
4351
4549
  "tool.preview": "Preview",
4352
4550
  "tool.more": "More",
4551
+ "group.rows": "Rows",
4552
+ "group.content": "Content",
4553
+ "group.elements": "Elements",
4554
+ "group.select": "Add",
4353
4555
  "panel.title": "{kind} settings",
4354
4556
  "panel.close": "Close",
4355
4557
  "panel.done": "Done",