@themarioga/grid-editor 8.1.0 → 8.3.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.
@@ -326,7 +326,9 @@
326
326
  addAccordionItem: { value: true },
327
327
  setLocale: {},
328
328
  getUtility: { value: true },
329
- setUtility: { value: true }
329
+ setUtility: { value: true },
330
+ getActiveTarget: { value: true },
331
+ setActiveTarget: {}
330
332
  };
331
333
  var PLACEMENTS = ["appendTo", "prependTo", "insertAfter", "insertBefore"];
332
334
  var BREAKPOINTS = [
@@ -569,6 +571,10 @@
569
571
  // 'tool' for the move tool, 'drawer' for the whole drawer
570
572
  "toolbar_drag": "auto",
571
573
  // Drag the toolbar's buttons onto the canvas. 'auto' follows drag_handle
574
+ "toolbar_overflow": "menu",
575
+ // What doesn't fit on one line: 'menu' behind a button, 'wrap' onto another line
576
+ "active_target": false,
577
+ // A click in a column makes it where the toolbar's buttons add
572
578
  "element_tools": [],
573
579
  // Host tools on element drawers, same shape as row_tools
574
580
  "element_classes": [],
@@ -630,6 +636,10 @@
630
636
  var sizePicker = null;
631
637
  var sourceOpen = false;
632
638
  var dropMarker = null;
639
+ var activeTarget = null;
640
+ var toolbarLifetime = null;
641
+ var closeOverflowMenu = function() {
642
+ };
633
643
  var warnedHere = {};
634
644
  var sortables = [];
635
645
  var instanceId = ++editorCounter;
@@ -657,7 +667,7 @@
657
667
  removeConfirmModal();
658
668
  removeSettingsPanels();
659
669
  removeDialog();
660
- mainControls.remove();
670
+ removeMainControls();
661
671
  createMainControls();
662
672
  reset();
663
673
  }
@@ -1034,6 +1044,34 @@
1034
1044
  e.preventDefault();
1035
1045
  }
1036
1046
  }, signal);
1047
+ if (settings.active_target) {
1048
+ var pressed = null;
1049
+ canvas.addEventListener("pointerdown", function(e) {
1050
+ pressed = { x: e.clientX, y: e.clientY };
1051
+ }, signal);
1052
+ canvas.addEventListener("click", function(e) {
1053
+ var from = pressed;
1054
+ pressed = null;
1055
+ if (!hasClass(canvas, "ge-editing")) {
1056
+ return;
1057
+ }
1058
+ if (from && Math.abs(e.clientX - from.x) + Math.abs(e.clientY - from.y) > settings.drag.threshold) {
1059
+ return;
1060
+ }
1061
+ var region = closest(e.target, targetSelector());
1062
+ changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
1063
+ }, signal);
1064
+ document.addEventListener("keydown", function(e) {
1065
+ if (e.key !== "Escape" || !activeTarget || openSettingsState || dialogState) {
1066
+ return;
1067
+ }
1068
+ var focus = document.activeElement;
1069
+ if (focus && (is(focus, "input, textarea, select") || focus.isContentEditable)) {
1070
+ return;
1071
+ }
1072
+ changeTarget(null);
1073
+ }, signal);
1074
+ }
1037
1075
  }
1038
1076
  function textReady(block) {
1039
1077
  if (!is(block, ".ge-content") || !canvas.contains(block)) {
@@ -1046,7 +1084,13 @@
1046
1084
  mainControls = element("div", { "class": "ge-mainControls" });
1047
1085
  htmlTextArea.parentNode.insertBefore(mainControls, htmlTextArea);
1048
1086
  wrapper = mainControls.appendChild(element("div", { "class": "ge-wrapper ge-top" }));
1049
- addRowGroup = wrapper.appendChild(element("div", { "class": "ge-addRowGroup btn-group" }));
1087
+ var overflowMenu = settings.toolbar_overflow !== "wrap";
1088
+ var start = wrapper;
1089
+ if (overflowMenu) {
1090
+ addClass(wrapper, "ge-toolbar-menu");
1091
+ start = wrapper.appendChild(element("div", { "class": "ge-toolbar-start" }));
1092
+ }
1093
+ addRowGroup = start.appendChild(element("div", { "class": "ge-addRowGroup btn-group" }));
1050
1094
  addContainerGroup = element("div", { "class": "ge-addContainerGroup btn-group ms-1" });
1051
1095
  settings.new_row_layouts.forEach(function(layout) {
1052
1096
  var grouped = !Array.isArray(layout);
@@ -1059,6 +1103,10 @@
1059
1103
  "data-ge-layout": grouped ? JSON.stringify(layout) : layout.join(",")
1060
1104
  });
1061
1105
  btn.addEventListener("click", function() {
1106
+ if (activeTarget) {
1107
+ addToTarget(btn, "tool");
1108
+ return;
1109
+ }
1062
1110
  var row = rowFromLayoutValue(layout);
1063
1111
  var added = addNode("row", row, function() {
1064
1112
  canvas.appendChild(row);
@@ -1077,7 +1125,7 @@
1077
1125
  icon += "</div>";
1078
1126
  btn.appendChild(create(icon));
1079
1127
  });
1080
- wrapper.appendChild(addContainerGroup);
1128
+ start.appendChild(addContainerGroup);
1081
1129
  Object.keys(CONTAINERS).forEach(function(type) {
1082
1130
  var definition = CONTAINERS[type];
1083
1131
  var button = labelButton(
@@ -1087,6 +1135,10 @@
1087
1135
  );
1088
1136
  attr(button, { "data-ge-toolbar": "container", "data-ge-container-type": type });
1089
1137
  button.addEventListener("click", function() {
1138
+ if (activeTarget) {
1139
+ addToTarget(button, "tool");
1140
+ return;
1141
+ }
1090
1142
  var row = createRow();
1091
1143
  var column = row.appendChild(createColumn(MAX_COL_SIZE));
1092
1144
  var container = column.appendChild(definition.create({}));
@@ -1157,8 +1209,99 @@
1157
1209
  end.appendChild(button);
1158
1210
  });
1159
1211
  }
1212
+ if (overflowMenu) {
1213
+ createOverflowMenu(start);
1214
+ }
1160
1215
  makeToolbarDraggable();
1161
1216
  }
1217
+ function removeMainControls() {
1218
+ if (toolbarLifetime) {
1219
+ toolbarLifetime.abort();
1220
+ }
1221
+ toolbarLifetime = null;
1222
+ closeOverflowMenu = function() {
1223
+ };
1224
+ mainControls.remove();
1225
+ }
1226
+ function createOverflowMenu(start) {
1227
+ var more = create('<div class="ge-toolbar-more"><button type="button" class="btn btn-sm btn-primary"><i class="bi bi-three-dots"></i></button><div class="ge-toolbar-overflow"><div class="ge-addRowGroup btn-group"></div><div class="ge-addContainerGroup btn-group"></div></div></div>');
1228
+ start.parentNode.insertBefore(more, start.nextSibling);
1229
+ var toggle2 = one(more, "button");
1230
+ var panel = one(more, ".ge-toolbar-overflow");
1231
+ 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
+ });
1238
+ toggle2.setAttribute("title", t("tool.more"));
1239
+ toggle2.setAttribute("aria-haspopup", "true");
1240
+ toggle2.setAttribute("aria-expanded", "false");
1241
+ var menuLifetime = toolbarLifetime = new AbortController();
1242
+ var signal = { signal: menuLifetime.signal };
1243
+ toggle2.addEventListener("click", function() {
1244
+ openOverflow(!hasClass(more, "ge-open"));
1245
+ });
1246
+ panel.addEventListener("click", function(e) {
1247
+ if (closest(e.target, "[data-ge-toolbar]")) {
1248
+ openOverflow(false);
1249
+ }
1250
+ });
1251
+ document.addEventListener("pointerdown", function(e) {
1252
+ if (!more.contains(e.target)) {
1253
+ openOverflow(false);
1254
+ }
1255
+ }, signal);
1256
+ document.addEventListener("keydown", function(e) {
1257
+ if (e.key === "Escape") {
1258
+ openOverflow(false);
1259
+ }
1260
+ }, signal);
1261
+ closeOverflowMenu = function() {
1262
+ openOverflow(false);
1263
+ };
1264
+ fit();
1265
+ if (window.ResizeObserver) {
1266
+ var pending = false;
1267
+ var observer = new window.ResizeObserver(function() {
1268
+ if (pending) {
1269
+ return;
1270
+ }
1271
+ pending = true;
1272
+ window.requestAnimationFrame(function() {
1273
+ pending = false;
1274
+ if (!menuLifetime.signal.aborted) {
1275
+ fit();
1276
+ }
1277
+ });
1278
+ });
1279
+ observer.observe(wrapper);
1280
+ observer.observe(start);
1281
+ menuLifetime.signal.addEventListener("abort", function() {
1282
+ observer.disconnect();
1283
+ });
1284
+ }
1285
+ function openOverflow(open) {
1286
+ open = open && hasClass(more, "ge-needed");
1287
+ toggleClass(more, "ge-open", open);
1288
+ toggle2.setAttribute("aria-expanded", open ? "true" : "false");
1289
+ }
1290
+ function fit() {
1291
+ homes.forEach(function(entry) {
1292
+ entry.home.appendChild(entry.button);
1293
+ });
1294
+ removeClass(more, "ge-needed");
1295
+ if (start.scrollWidth <= start.clientWidth) {
1296
+ openOverflow(false);
1297
+ return;
1298
+ }
1299
+ addClass(more, "ge-needed");
1300
+ 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);
1302
+ }
1303
+ }
1304
+ }
1162
1305
  function labelButton(button, label, iconClass) {
1163
1306
  button.setAttribute("title", label);
1164
1307
  if (iconClass) {
@@ -1180,6 +1323,10 @@
1180
1323
  "data-ge-item": index
1181
1324
  });
1182
1325
  button.addEventListener("click", function() {
1326
+ if (activeTarget) {
1327
+ addToTarget(button, item.source || "tool");
1328
+ return;
1329
+ }
1183
1330
  var made = item.create();
1184
1331
  var placed = item.inColumn ? inRowOfItsOwn(made) : made;
1185
1332
  var added = addNode(item.kind, made, function() {
@@ -1229,6 +1376,7 @@
1229
1376
  }
1230
1377
  helper = addClass(button.cloneNode(true), "ge-toolbar-helper");
1231
1378
  document.body.appendChild(helper);
1379
+ closeOverflowMenu();
1232
1380
  addClass(canvas, "ge-dropping");
1233
1381
  }
1234
1382
  css(helper, { left: move.pageX - 14, top: move.pageY - 14 });
@@ -1285,7 +1433,7 @@
1285
1433
  });
1286
1434
  return { region, before };
1287
1435
  }
1288
- function insertFeatureFromToolbar(button, where) {
1436
+ function insertFeatureFromToolbar(button, where, source) {
1289
1437
  var item = FEATURES[button.getAttribute("data-ge-feature")].toolbar[parseInt(button.getAttribute("data-ge-item"), 10)];
1290
1438
  var made = item.create();
1291
1439
  var placed = made;
@@ -1304,7 +1452,7 @@
1304
1452
  } else {
1305
1453
  where.region.appendChild(placed);
1306
1454
  }
1307
- }, { parent: where.region, source: item.source || "dragdrop" });
1455
+ }, { parent: where.region, source: item.source || source || "dragdrop" });
1308
1456
  }
1309
1457
  function inRowOfItsOwn(node) {
1310
1458
  var row = createRow();
@@ -1331,9 +1479,9 @@
1331
1479
  dropMarker.remove();
1332
1480
  }
1333
1481
  }
1334
- function insertFromToolbar(button, where) {
1482
+ function insertFromToolbar(button, where, source) {
1335
1483
  if (button.getAttribute("data-ge-toolbar") === "feature") {
1336
- return insertFeatureFromToolbar(button, where);
1484
+ return insertFeatureFromToolbar(button, where, source);
1337
1485
  }
1338
1486
  var container = button.getAttribute("data-ge-toolbar") === "container";
1339
1487
  var type = button.getAttribute("data-ge-container-type");
@@ -1348,7 +1496,7 @@
1348
1496
  } else {
1349
1497
  where.region.appendChild(placed);
1350
1498
  }
1351
- }, { parent: where.region, source: "dragdrop" });
1499
+ }, { parent: where.region, source: source || "dragdrop" });
1352
1500
  }
1353
1501
  function widthFamily() {
1354
1502
  var values = [];
@@ -1588,6 +1736,7 @@
1588
1736
  }
1589
1737
  function openSource() {
1590
1738
  deinit();
1739
+ changeTarget(null);
1591
1740
  htmlTextArea.style.height = 0.8 * document.documentElement.clientHeight + "px";
1592
1741
  htmlTextArea.value = canvas.innerHTML;
1593
1742
  show(htmlTextArea);
@@ -1603,6 +1752,32 @@
1603
1752
  init();
1604
1753
  hide(htmlTextArea);
1605
1754
  }
1755
+ function targetSelector() {
1756
+ return [".column"].concat(pluginHooks("regions")).join(", ");
1757
+ }
1758
+ function isTarget(node) {
1759
+ return !!node && node !== canvas && canvas.contains(node) && is(node, targetSelector());
1760
+ }
1761
+ function changeTarget(node) {
1762
+ if (node === activeTarget) {
1763
+ return;
1764
+ }
1765
+ var from = activeTarget;
1766
+ if (from) {
1767
+ removeClass(from, "ge-active-target");
1768
+ }
1769
+ activeTarget = node;
1770
+ if (node && hasClass(canvas, "ge-editing")) {
1771
+ addClass(node, "ge-active-target");
1772
+ }
1773
+ emit("target-change", { canvas, target: node, from });
1774
+ }
1775
+ function addToTarget(button, source) {
1776
+ var made = insertFromToolbar(button, { region: activeTarget, before: null }, source);
1777
+ if (made && made.scrollIntoView) {
1778
+ made.scrollIntoView({ behavior: "smooth" });
1779
+ }
1780
+ }
1606
1781
  function init() {
1607
1782
  if (openSettingsState && !attached(openSettingsState.node)) {
1608
1783
  closeSettings();
@@ -1626,10 +1801,18 @@
1626
1801
  makeResizable();
1627
1802
  switchLayout(curView);
1628
1803
  refreshPreviews(canvas);
1804
+ if (activeTarget && !canvas.contains(activeTarget)) {
1805
+ changeTarget(null);
1806
+ } else if (activeTarget) {
1807
+ addClass(activeTarget, "ge-active-target");
1808
+ }
1629
1809
  }
1630
1810
  function deinit() {
1631
1811
  closeSettings();
1632
1812
  removeClass(canvas, "ge-editing ge-drag-drawer ge-dropping");
1813
+ if (activeTarget) {
1814
+ removeClass(activeTarget, "ge-active-target");
1815
+ }
1633
1816
  plugins("onBeforeDeinit");
1634
1817
  closeSizePicker();
1635
1818
  hideDropMarker();
@@ -1671,10 +1854,11 @@
1671
1854
  closeSource();
1672
1855
  }
1673
1856
  deinit();
1857
+ activeTarget = null;
1674
1858
  removeConfirmModal();
1675
1859
  removeSettingsPanels();
1676
1860
  removeDialog();
1677
- mainControls.remove();
1861
+ removeMainControls();
1678
1862
  htmlTextArea.remove();
1679
1863
  lifetime.abort();
1680
1864
  instances.delete(canvas);
@@ -4047,6 +4231,23 @@
4047
4231
  return featureMethods[name].apply(null, arguments);
4048
4232
  };
4049
4233
  }
4234
+ function apiSetActiveTarget(value) {
4235
+ if (!settings.active_target) {
4236
+ warnOnceHere("active_target", "setActiveTarget needs the active_target setting: without it, it does nothing");
4237
+ return;
4238
+ }
4239
+ if (value === null || value === void 0) {
4240
+ changeTarget(null);
4241
+ return;
4242
+ }
4243
+ var node = nodeFrom(value);
4244
+ if (!isTarget(node)) {
4245
+ var named = typeof value === "string" ? value : node ? "<" + node.tagName.toLowerCase() + ">" : String(value);
4246
+ warn("setActiveTarget: " + named + " is not a column or a region of the canvas");
4247
+ return;
4248
+ }
4249
+ changeTarget(node);
4250
+ }
4050
4251
  var own = {
4051
4252
  getHtml,
4052
4253
  getPlainHtml,
@@ -4080,7 +4281,11 @@
4080
4281
  },
4081
4282
  setLocale,
4082
4283
  getUtility,
4083
- setUtility
4284
+ setUtility,
4285
+ getActiveTarget: function() {
4286
+ return settings.active_target ? activeTarget : null;
4287
+ },
4288
+ setActiveTarget: apiSetActiveTarget
4084
4289
  };
4085
4290
  Object.keys(own).forEach(function(name) {
4086
4291
  var value = !!(METHODS[name] && METHODS[name].value);
@@ -4119,7 +4324,7 @@
4119
4324
  GridEditor._plainHtml = plainHtml;
4120
4325
  GridEditor.Sortable = null;
4121
4326
  GridEditor.bootstrap = null;
4122
- GridEditor.version = false ? "dev" : "8.1.0";
4327
+ GridEditor.version = false ? "dev" : "8.3.0";
4123
4328
  GridEditor.locales = {
4124
4329
  en: {
4125
4330
  "tool.move": "Move",
@@ -4144,6 +4349,7 @@
4144
4349
  "tool.indent_increase": "Increase indent\n(hold shift for max)",
4145
4350
  "tool.edit_source": "Edit Source Code",
4146
4351
  "tool.preview": "Preview",
4352
+ "tool.more": "More",
4147
4353
  "panel.title": "{kind} settings",
4148
4354
  "panel.close": "Close",
4149
4355
  "panel.done": "Done",