@themarioga/grid-editor 8.8.2 → 8.10.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.
@@ -328,9 +328,23 @@ var METHODS = {
328
328
  getUtility: { value: true },
329
329
  setUtility: { value: true },
330
330
  getActiveTarget: { value: true },
331
- setActiveTarget: {}
331
+ setActiveTarget: {},
332
+ getSelected: { value: true },
333
+ setSelected: {}
332
334
  };
333
335
  var PLACEMENTS = ["appendTo", "prependTo", "insertAfter", "insertBefore"];
336
+ var REFERENCES = [
337
+ "data-bs-target",
338
+ "data-bs-parent",
339
+ "href",
340
+ "aria-controls",
341
+ "aria-labelledby",
342
+ "aria-describedby",
343
+ "for",
344
+ "data-ge-popup-id",
345
+ "data-ge-popup-target"
346
+ ];
347
+ var GENERATED_ID = /^ge-([a-z][a-z-]*?)-\d+-[a-z0-9]+$/;
334
348
  var BREAKPOINTS = [
335
349
  { key: "xs", infix: "", colPrefix: "col-", offsetPrefix: "offset-", min: 0, preview: 400, labelKey: "view.xs" },
336
350
  { key: "sm", infix: "sm", colPrefix: "col-sm-", offsetPrefix: "offset-sm-", min: 576, preview: 576, labelKey: "view.sm" },
@@ -412,6 +426,10 @@ var NESTED_SETTINGS = {
412
426
  tools: true
413
427
  // The indent tools in the column's drawer
414
428
  },
429
+ sidebar: {
430
+ empty: null
431
+ // function(ge) -> { title, body } shown while nothing is selected, or null for the message
432
+ },
415
433
  drag: {
416
434
  delay: 0,
417
435
  // Milliseconds to hold before a drag starts
@@ -428,6 +446,8 @@ var NESTED_SETTINGS = {
428
446
  var warned = {};
429
447
  var editorCounter = 0;
430
448
  var instances = /* @__PURE__ */ new WeakMap();
449
+ var sidebarHolder = null;
450
+ var EDITOR_CONTROLS = ".ge-mainControls, .ge-settings-panel, .ge-sidebar-toggle, .ge-dialog, .ge-confirm, .ge-size-picker, .modal, .modal-backdrop";
431
451
  function translate(settings, key, params) {
432
452
  var locales = GridEditor.locales;
433
453
  var locale = locales[settings.locale] || {};
@@ -633,7 +653,9 @@ function build(instance, baseElem, optionsOrMethod) {
633
653
  "confirm_delete": true,
634
654
  // Ask before deleting a row or a column
635
655
  "settings_panel": "offcanvas",
636
- // Where a node's settings open: 'offcanvas', 'popover', 'modal' or 'inline'
656
+ // Where a node's settings open: 'offcanvas', 'popover', 'modal', 'inline' or 'sidebar'
657
+ "sidebar": NESTED_SETTINGS.sidebar,
658
+ // The 'sidebar' panel: what it shows while nothing is selected
637
659
  "drag": NESTED_SETTINGS.drag
638
660
  // How a drag behaves, whatever drives it
639
661
  }, optionsOrMethod);
@@ -659,6 +681,17 @@ function build(instance, baseElem, optionsOrMethod) {
659
681
  var sortables = [];
660
682
  var instanceId = ++editorCounter;
661
683
  var destroyed = false;
684
+ var selected = null;
685
+ var sidebarCollapsed = null;
686
+ var pluginHandle = null;
687
+ if (settings.settings_panel === "sidebar") {
688
+ if (sidebarHolder) {
689
+ warnOnceHere("sidebar", 'settings_panel "sidebar" is in use by another editor on the page, which has one sidebar: using offcanvas');
690
+ settings.settings_panel = "offcanvas";
691
+ } else {
692
+ sidebarHolder = instance;
693
+ }
694
+ }
662
695
  var detailsFor = /* @__PURE__ */ new WeakMap();
663
696
  var moves = /* @__PURE__ */ new WeakMap();
664
697
  var resizes = /* @__PURE__ */ new WeakMap();
@@ -1096,7 +1129,8 @@ function build(instance, baseElem, optionsOrMethod) {
1096
1129
  e.preventDefault();
1097
1130
  }
1098
1131
  }, signal);
1099
- if (settings.active_target) {
1132
+ var sidebarMode = panelMode() === "sidebar";
1133
+ if (settings.active_target || sidebarMode) {
1100
1134
  var pressed = null;
1101
1135
  canvas.addEventListener("pointerdown", function(e) {
1102
1136
  pressed = { x: e.clientX, y: e.clientY };
@@ -1110,23 +1144,60 @@ function build(instance, baseElem, optionsOrMethod) {
1110
1144
  if (from && Math.abs(e.clientX - from.x) + Math.abs(e.clientY - from.y) > settings.drag.threshold) {
1111
1145
  return;
1112
1146
  }
1113
- var region = closest(e.target, targetSelector());
1114
- if (region && region === activeTarget && (e.target === region || e.target === child(region, ".ge-tools-drawer"))) {
1115
- changeTarget(null);
1116
- return;
1147
+ if (settings.active_target) {
1148
+ clickTarget(e);
1149
+ }
1150
+ if (sidebarMode && canvas.contains(e.target)) {
1151
+ changeSelection(settingsNodeAt(e.target));
1117
1152
  }
1118
- changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
1119
1153
  }, signal);
1120
1154
  document.addEventListener("keydown", function(e) {
1121
- if (e.key !== "Escape" || !activeTarget || openSettingsState || dialogState) {
1155
+ if (e.key !== "Escape" || openSettingsState || dialogState) {
1156
+ return;
1157
+ }
1158
+ if (confirmDialog && hasClass(confirmDialog, "show")) {
1122
1159
  return;
1123
1160
  }
1124
1161
  var focus = document.activeElement;
1125
1162
  if (focus && (is(focus, "input, textarea, select") || focus.isContentEditable)) {
1126
1163
  return;
1127
1164
  }
1128
- changeTarget(null);
1165
+ if (selected && isEditing()) {
1166
+ changeSelection(null);
1167
+ } else if (activeTarget) {
1168
+ changeTarget(null);
1169
+ }
1170
+ }, signal);
1171
+ }
1172
+ if (sidebarMode) {
1173
+ canvas.addEventListener("focusin", function(e) {
1174
+ var node = isEditing() ? settingsNodeAt(e.target) : null;
1175
+ if (node) {
1176
+ changeSelection(node);
1177
+ }
1178
+ }, signal);
1179
+ document.addEventListener("click", function(e) {
1180
+ var target = e.target;
1181
+ if (!selected || !isEditing() || !target || target.nodeType !== 1) {
1182
+ return;
1183
+ }
1184
+ if (!attached(target) || canvas.contains(target)) {
1185
+ return;
1186
+ }
1187
+ if (closest(target, EDITOR_CONTROLS) || canvas.querySelector(".ge-rte-active")) {
1188
+ return;
1189
+ }
1190
+ changeSelection(null);
1129
1191
  }, signal);
1192
+ window.addEventListener("resize", reserveSidebarRoom, signal);
1193
+ }
1194
+ function clickTarget(e) {
1195
+ var region = closest(e.target, targetSelector());
1196
+ if (region && region === activeTarget && (e.target === region || e.target === child(region, ".ge-tools-drawer"))) {
1197
+ changeTarget(null);
1198
+ return;
1199
+ }
1200
+ changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
1130
1201
  }
1131
1202
  }
1132
1203
  function textReady(block) {
@@ -1898,6 +1969,7 @@ function build(instance, baseElem, optionsOrMethod) {
1898
1969
  function openSource() {
1899
1970
  deinit();
1900
1971
  changeTarget(null);
1972
+ changeSelection(null);
1901
1973
  htmlTextArea.style.height = 0.8 * document.documentElement.clientHeight + "px";
1902
1974
  htmlTextArea.value = canvas.innerHTML;
1903
1975
  show(htmlTextArea);
@@ -1943,6 +2015,9 @@ function build(instance, baseElem, optionsOrMethod) {
1943
2015
  if (openSettingsState && !attached(openSettingsState.node)) {
1944
2016
  closeSettings();
1945
2017
  }
2018
+ if (selected && !canvas.contains(selected)) {
2019
+ changeSelection(null);
2020
+ }
1946
2021
  if (dialogState && dialogState.home && !attached(dialogState.home)) {
1947
2022
  closeDialog();
1948
2023
  }
@@ -1967,9 +2042,11 @@ function build(instance, baseElem, optionsOrMethod) {
1967
2042
  } else if (activeTarget) {
1968
2043
  addClass(activeTarget, "ge-active-target");
1969
2044
  }
2045
+ showSidebar();
1970
2046
  }
1971
2047
  function deinit() {
1972
2048
  closeSettings();
2049
+ hideSidebar();
1973
2050
  removeClass(canvas, "ge-editing ge-drag-drawer ge-dropping");
1974
2051
  if (activeTarget) {
1975
2052
  removeClass(activeTarget, "ge-active-target");
@@ -2130,6 +2207,10 @@ function build(instance, baseElem, optionsOrMethod) {
2130
2207
  }
2131
2208
  deinit();
2132
2209
  activeTarget = null;
2210
+ selected = null;
2211
+ if (sidebarHolder === instance) {
2212
+ sidebarHolder = null;
2213
+ }
2133
2214
  removeConfirmModal();
2134
2215
  removeSettingsPanels();
2135
2216
  removeDialog();
@@ -2140,7 +2221,7 @@ function build(instance, baseElem, optionsOrMethod) {
2140
2221
  destroyed = true;
2141
2222
  }
2142
2223
  function loadPlugins() {
2143
- var api = pluginApi();
2224
+ var api = pluginHandle = pluginApi();
2144
2225
  registerFamily("grid", {}, widthFamily());
2145
2226
  if (settings.row_cols !== false) {
2146
2227
  registerFamily("grid", {}, rowColsFamily());
@@ -2200,6 +2281,7 @@ function build(instance, baseElem, optionsOrMethod) {
2200
2281
  t,
2201
2282
  warn,
2202
2283
  containerId,
2284
+ freshNode,
2203
2285
  defaultRegion,
2204
2286
  createTool,
2205
2287
  createMoveTool,
@@ -2737,6 +2819,63 @@ function build(instance, baseElem, optionsOrMethod) {
2737
2819
  containerCounter++;
2738
2820
  return "ge-" + type + "-" + containerCounter + "-" + Math.random().toString(36).slice(2, 6);
2739
2821
  }
2822
+ function freshNode(html) {
2823
+ var node = create(html);
2824
+ var renamed = {};
2825
+ var taken = function(id) {
2826
+ return !!document.getElementById(id) || Object.keys(renamed).some(function(old) {
2827
+ return renamed[old] === id;
2828
+ });
2829
+ };
2830
+ selfAndAll(node, "[id]").forEach(function(element2) {
2831
+ var id = element2.id;
2832
+ if (!document.getElementById(id)) {
2833
+ return;
2834
+ }
2835
+ var generated = GENERATED_ID.exec(id);
2836
+ var next;
2837
+ if (generated) {
2838
+ do {
2839
+ next = containerId(generated[1]);
2840
+ } while (taken(next));
2841
+ } else {
2842
+ var n = 2;
2843
+ while (taken(id + "-" + n)) {
2844
+ n++;
2845
+ }
2846
+ next = id + "-" + n;
2847
+ }
2848
+ renamed[id] = next;
2849
+ element2.id = next;
2850
+ });
2851
+ if (!Object.keys(renamed).length) {
2852
+ return node;
2853
+ }
2854
+ selfAndAll(node, "*").forEach(function(element2) {
2855
+ REFERENCES.forEach(function(name) {
2856
+ var value = element2.getAttribute(name);
2857
+ if (value === null) {
2858
+ return;
2859
+ }
2860
+ if (name === "href" && value.charAt(0) !== "#") {
2861
+ return;
2862
+ }
2863
+ var rewritten = value.split(/(\s+)/).map(function(token) {
2864
+ if (renamed[token]) {
2865
+ return renamed[token];
2866
+ }
2867
+ if (token.charAt(0) === "#" && renamed[token.slice(1)]) {
2868
+ return "#" + renamed[token.slice(1)];
2869
+ }
2870
+ return token;
2871
+ }).join("");
2872
+ if (rewritten !== value) {
2873
+ element2.setAttribute(name, rewritten);
2874
+ }
2875
+ });
2876
+ });
2877
+ return node;
2878
+ }
2740
2879
  function defaultRegion() {
2741
2880
  var row = createRow();
2742
2881
  row.appendChild(createColumn(MAX_COL_SIZE));
@@ -3261,9 +3400,11 @@ function build(instance, baseElem, optionsOrMethod) {
3261
3400
  function addSettingsTool(drawer, node, presets) {
3262
3401
  var details = createDetails(node, presets || []);
3263
3402
  detailsFor.set(node, details);
3264
- createTool(drawer, t("tool.settings"), "ge-settings", "bi bi-gear-fill", function() {
3265
- toggleSettings(node, details, this);
3266
- });
3403
+ if (panelMode() !== "sidebar") {
3404
+ createTool(drawer, t("tool.settings"), "ge-settings", "bi bi-gear-fill", function() {
3405
+ toggleSettings(node, details, this);
3406
+ });
3407
+ }
3267
3408
  var kind = kindOf(node);
3268
3409
  Object.keys(UTILITIES).forEach(function(name) {
3269
3410
  if (UTILITIES[name].drawerTools) {
@@ -3354,7 +3495,7 @@ function build(instance, baseElem, optionsOrMethod) {
3354
3495
  return;
3355
3496
  }
3356
3497
  var holder = element("div", { "class": "ge-panel-section", "data-ge-plugin": name });
3357
- if (mode === "offcanvas" || mode === "modal") {
3498
+ if (mode === "offcanvas" || mode === "modal" || mode === "sidebar") {
3358
3499
  holder.appendChild(sectionTitle(t(section.labelKey)));
3359
3500
  holder.appendChild(section.body);
3360
3501
  } else {
@@ -3378,7 +3519,7 @@ function build(instance, baseElem, optionsOrMethod) {
3378
3519
  });
3379
3520
  return sections;
3380
3521
  }
3381
- var PANEL_MODES = ["offcanvas", "popover", "modal", "inline"];
3522
+ var PANEL_MODES = ["offcanvas", "popover", "modal", "inline", "sidebar"];
3382
3523
  var settingsPanels = {};
3383
3524
  var openSettingsState = null;
3384
3525
  var modalState = /* @__PURE__ */ new WeakMap();
@@ -3393,7 +3534,14 @@ function build(instance, baseElem, optionsOrMethod) {
3393
3534
  return node && detailsFor.get(node) || null;
3394
3535
  }
3395
3536
  function settingsScope() {
3396
- return openSettingsState && openSettingsState.mode !== "inline" ? [canvas, openSettingsState.details] : [canvas];
3537
+ var scope = [canvas];
3538
+ if (openSettingsState && openSettingsState.mode !== "inline") {
3539
+ scope.push(openSettingsState.details);
3540
+ }
3541
+ if (sidebarShown) {
3542
+ scope.push(sidebarShown.details);
3543
+ }
3544
+ return scope;
3397
3545
  }
3398
3546
  function toggleSettings(node, details, gear) {
3399
3547
  var mode = panelMode();
@@ -3483,6 +3631,9 @@ function build(instance, baseElem, optionsOrMethod) {
3483
3631
  } else {
3484
3632
  hideModal(panel);
3485
3633
  }
3634
+ returnPanel(open);
3635
+ }
3636
+ function returnPanel(open) {
3486
3637
  removeClass(open.node, "ge-settings-target");
3487
3638
  open.details.style.removeProperty("display");
3488
3639
  dropEmptyStyle(open.details);
@@ -3515,6 +3666,11 @@ function build(instance, baseElem, optionsOrMethod) {
3515
3666
  panel = create('<div class="popover bs-popover-bottom ge-settings-panel ge-settings-popover" role="dialog"><div class="popover-arrow"></div><div class="popover-header"><span class="ge-settings-title"></span></div><div class="popover-body ge-settings-body"></div></div>');
3516
3667
  one(panel, ".popover-header").appendChild(closeButton());
3517
3668
  hide(panel);
3669
+ } else if (mode === "sidebar") {
3670
+ panel = create('<div class="offcanvas offcanvas-end ge-settings-panel ge-settings-sidebar" tabindex="-1" role="complementary"><div class="offcanvas-header"><h5 class="offcanvas-title ge-settings-title"></h5></div><div class="offcanvas-body ge-settings-body"></div></div>');
3671
+ panel.id = "ge-settings-sidebar-" + instanceId;
3672
+ one(panel, ".offcanvas-header").appendChild(closeButton());
3673
+ settingsPanels["sidebar-toggle"] = document.body.appendChild(sidebarToggle(panel));
3518
3674
  } else {
3519
3675
  panel = create('<div class="modal fade ge-settings-panel ge-settings-modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"><div class="modal-content"><div class="modal-header"><h5 class="modal-title ge-settings-title"></h5></div><div class="modal-body ge-settings-body"></div><div class="modal-footer"></div></div></div></div>');
3520
3676
  one(panel, ".modal-header").appendChild(closeButton());
@@ -3525,13 +3681,19 @@ function build(instance, baseElem, optionsOrMethod) {
3525
3681
  }
3526
3682
  delegate(panel, "click", ".ge-settings-close", function(e) {
3527
3683
  e.preventDefault();
3528
- closeSettings();
3684
+ if (mode === "sidebar") {
3685
+ changeSelection(null);
3686
+ } else {
3687
+ closeSettings();
3688
+ }
3529
3689
  });
3530
3690
  settingsPanels[mode] = document.body.appendChild(panel);
3531
3691
  return panel;
3532
3692
  }
3533
3693
  function removeSettingsPanels() {
3534
3694
  closeSettings();
3695
+ unshowSidebar();
3696
+ removeClass(document.documentElement, "ge-sidebar-open");
3535
3697
  Object.keys(settingsPanels).forEach(function(mode) {
3536
3698
  if (mode === "modal") {
3537
3699
  retireModal(settingsPanels[mode]);
@@ -3544,6 +3706,180 @@ function build(instance, baseElem, optionsOrMethod) {
3544
3706
  });
3545
3707
  settingsPanels = {};
3546
3708
  }
3709
+ var SIDEBAR_MIN_WIDTH = 576;
3710
+ var sidebarShown = null;
3711
+ var sidebarEmpty = null;
3712
+ function isEditing() {
3713
+ return hasClass(canvas, "ge-editing");
3714
+ }
3715
+ function sidebarToggle(panel) {
3716
+ var button = element("button", { type: "button", "class": "ge-sidebar-toggle", "aria-controls": panel.id });
3717
+ button.appendChild(element("i"));
3718
+ button.addEventListener("click", function() {
3719
+ foldSidebar(!sidebarCollapsed);
3720
+ });
3721
+ return button;
3722
+ }
3723
+ function foldSidebar(collapsed) {
3724
+ sidebarCollapsed = collapsed;
3725
+ applySidebar();
3726
+ }
3727
+ function applySidebar() {
3728
+ var panel = settingsPanels.sidebar;
3729
+ var toggle2 = settingsPanels["sidebar-toggle"];
3730
+ if (!panel) {
3731
+ return;
3732
+ }
3733
+ var open = !sidebarCollapsed;
3734
+ if (open && !hasClass(panel, "show")) {
3735
+ removeClass(panel, "hiding");
3736
+ panel.getBoundingClientRect();
3737
+ addClass(panel, "show");
3738
+ } else if (!open && hasClass(panel, "show")) {
3739
+ removeClass(panel, "show");
3740
+ addClass(panel, "hiding");
3741
+ window.setTimeout(function() {
3742
+ removeClass(panel, "hiding");
3743
+ }, 300);
3744
+ }
3745
+ var label = open ? t("panel.collapse") : t("panel.expand");
3746
+ toggle2.setAttribute("aria-expanded", open ? "true" : "false");
3747
+ toggle2.setAttribute("aria-label", label);
3748
+ toggle2.setAttribute("title", label);
3749
+ one(toggle2, "i").className = "bi " + (open ? "bi-chevron-right" : "bi-chevron-left");
3750
+ reserveSidebarRoom();
3751
+ }
3752
+ function reserveSidebarRoom() {
3753
+ toggleClass(
3754
+ document.documentElement,
3755
+ "ge-sidebar-open",
3756
+ !!settingsPanels.sidebar && isEditing() && !sidebarCollapsed && window.innerWidth >= SIDEBAR_MIN_WIDTH
3757
+ );
3758
+ }
3759
+ function showSidebar() {
3760
+ if (panelMode() !== "sidebar") {
3761
+ return;
3762
+ }
3763
+ var panel = settingsPanel("sidebar");
3764
+ if (sidebarCollapsed === null) {
3765
+ sidebarCollapsed = window.innerWidth < SIDEBAR_MIN_WIDTH;
3766
+ }
3767
+ panel.style.removeProperty("display");
3768
+ settingsPanels["sidebar-toggle"].style.removeProperty("display");
3769
+ renderSidebar();
3770
+ applySidebar();
3771
+ }
3772
+ function hideSidebar() {
3773
+ unshowDetails();
3774
+ var panel = settingsPanels.sidebar;
3775
+ if (!panel) {
3776
+ return;
3777
+ }
3778
+ panel.style.display = "none";
3779
+ settingsPanels["sidebar-toggle"].style.display = "none";
3780
+ removeClass(document.documentElement, "ge-sidebar-open");
3781
+ }
3782
+ function setSidebarTitle(text) {
3783
+ var panel = settingsPanels.sidebar;
3784
+ one(panel, ".ge-settings-title").textContent = text;
3785
+ panel.setAttribute("aria-label", text);
3786
+ }
3787
+ function unshowDetails() {
3788
+ var shown = sidebarShown;
3789
+ sidebarShown = null;
3790
+ if (shown) {
3791
+ returnPanel(shown);
3792
+ }
3793
+ }
3794
+ function unshowSidebar() {
3795
+ unshowDetails();
3796
+ if (sidebarEmpty) {
3797
+ sidebarEmpty.body.remove();
3798
+ sidebarEmpty = null;
3799
+ }
3800
+ }
3801
+ function renderSidebar() {
3802
+ var panel = settingsPanels.sidebar;
3803
+ if (!panel || !isEditing()) {
3804
+ return;
3805
+ }
3806
+ var details = selected ? detailsOf(selected) : null;
3807
+ if (details ? sidebarShown && sidebarShown.details === details : !sidebarShown && sidebarEmpty) {
3808
+ return;
3809
+ }
3810
+ unshowSidebar();
3811
+ var holder = one(panel, ".ge-settings-body");
3812
+ if (!details) {
3813
+ var content = emptyContent();
3814
+ var body = content ? content.body : element("p", { "class": "ge-sidebar-empty" }, t("panel.sidebar_empty"));
3815
+ setSidebarTitle(content ? content.title : t("panel.sidebar_title"));
3816
+ holder.appendChild(body);
3817
+ sidebarEmpty = { body };
3818
+ return;
3819
+ }
3820
+ sidebarShown = { node: selected, details, home: details.parentElement, next: details.nextElementSibling };
3821
+ setSidebarTitle(t("panel.title", { kind: kindLabel(selected) }));
3822
+ holder.appendChild(details);
3823
+ show(details);
3824
+ addClass(selected, "ge-settings-target");
3825
+ }
3826
+ function emptyContent() {
3827
+ var fromHost = settings.sidebar.empty;
3828
+ var found = null;
3829
+ if (typeof fromHost === "function") {
3830
+ found = emptyContentOf(fromHost(instance), function(result) {
3831
+ return result.title;
3832
+ });
3833
+ } else if (fromHost !== null && fromHost !== void 0) {
3834
+ warnOnceHere("sidebar.empty", "sidebar.empty is a function(ge) returning { title, body }, not " + typeof fromHost + ": ignored");
3835
+ }
3836
+ [CONTAINERS, FEATURES, UTILITIES].forEach(function(registry) {
3837
+ Object.keys(registry).forEach(function(name) {
3838
+ var plugin = registry[name];
3839
+ if (found || !plugin.sidebarEmpty) {
3840
+ return;
3841
+ }
3842
+ found = emptyContentOf(plugin.sidebarEmpty(pluginHandle), function(result) {
3843
+ return typeof result.titleKey === "string" && result.titleKey !== "" ? t(result.titleKey) : "";
3844
+ });
3845
+ });
3846
+ });
3847
+ return found;
3848
+ }
3849
+ function emptyContentOf(result, titleOf) {
3850
+ if (!result || !result.body || result.body.nodeType !== 1) {
3851
+ return null;
3852
+ }
3853
+ var title = titleOf(result);
3854
+ return { title: typeof title === "string" && title !== "" ? title : t("panel.sidebar_title"), body: result.body };
3855
+ }
3856
+ function settingsNodeAt(target) {
3857
+ var drawer = closest(target, ".ge-tools-drawer", canvas);
3858
+ if (drawer) {
3859
+ var home = drawer.parentElement;
3860
+ var owner = detailsFor.has(home) ? home : children(home).filter(function(each) {
3861
+ return detailsFor.has(each);
3862
+ })[0];
3863
+ if (owner) {
3864
+ return owner;
3865
+ }
3866
+ }
3867
+ for (var node = target; node && node !== canvas; node = node.parentElement) {
3868
+ if (detailsFor.has(node)) {
3869
+ return node;
3870
+ }
3871
+ }
3872
+ return null;
3873
+ }
3874
+ function changeSelection(node) {
3875
+ if (node === selected) {
3876
+ return;
3877
+ }
3878
+ var from = selected;
3879
+ selected = node;
3880
+ renderSidebar();
3881
+ emit("selection-change", { canvas, node, from });
3882
+ }
3547
3883
  function placePopover(panel, gear) {
3548
3884
  if (!attached(gear)) {
3549
3885
  return;
@@ -4658,6 +4994,23 @@ function build(instance, baseElem, optionsOrMethod) {
4658
4994
  }
4659
4995
  changeTarget(node);
4660
4996
  }
4997
+ function apiSetSelected(value) {
4998
+ if (panelMode() !== "sidebar") {
4999
+ warnOnceHere("sidebar-api", 'setSelected needs settings_panel "sidebar": without it, it does nothing');
5000
+ return;
5001
+ }
5002
+ if (value === null || value === void 0) {
5003
+ changeSelection(null);
5004
+ return;
5005
+ }
5006
+ var node = nodeFrom(value);
5007
+ if (!node || node === canvas || !canvas.contains(node) || !detailsFor.has(node)) {
5008
+ var named = typeof value === "string" ? value : node ? "<" + node.tagName.toLowerCase() + ">" : String(value);
5009
+ warn("setSelected: " + named + " is not a node of the canvas with settings");
5010
+ return;
5011
+ }
5012
+ changeSelection(node);
5013
+ }
4661
5014
  var own = {
4662
5015
  getHtml,
4663
5016
  getPlainHtml,
@@ -4696,7 +5049,11 @@ function build(instance, baseElem, optionsOrMethod) {
4696
5049
  getActiveTarget: function() {
4697
5050
  return settings.active_target ? activeTarget : null;
4698
5051
  },
4699
- setActiveTarget: apiSetActiveTarget
5052
+ setActiveTarget: apiSetActiveTarget,
5053
+ getSelected: function() {
5054
+ return panelMode() === "sidebar" ? selected : null;
5055
+ },
5056
+ setSelected: apiSetSelected
4700
5057
  };
4701
5058
  Object.keys(own).forEach(function(name) {
4702
5059
  var value = !!(METHODS[name] && METHODS[name].value);
@@ -4747,7 +5104,7 @@ GridEditor.t = translate;
4747
5104
  GridEditor._plainHtml = plainHtml;
4748
5105
  GridEditor.Sortable = null;
4749
5106
  GridEditor.bootstrap = null;
4750
- GridEditor.version = false ? "dev" : "8.8.2";
5107
+ GridEditor.version = false ? "dev" : "8.10.0";
4751
5108
  GridEditor.locales = {
4752
5109
  en: {
4753
5110
  "tool.move": "Move",
@@ -4780,6 +5137,10 @@ GridEditor.locales = {
4780
5137
  "panel.title": "{kind} settings",
4781
5138
  "panel.close": "Close",
4782
5139
  "panel.done": "Done",
5140
+ "panel.sidebar_title": "Settings",
5141
+ "panel.sidebar_empty": "Click an element to see its settings",
5142
+ "panel.collapse": "Hide settings",
5143
+ "panel.expand": "Show settings",
4783
5144
  "panel.id": "Id",
4784
5145
  "panel.classes": "Classes",
4785
5146
  "panel.section_general": "Id and classes",
@@ -47,7 +47,9 @@
47
47
  getUtility: { value: true },
48
48
  setUtility: { value: true },
49
49
  getActiveTarget: { value: true },
50
- setActiveTarget: {}
50
+ setActiveTarget: {},
51
+ getSelected: { value: true },
52
+ setSelected: {}
51
53
  };
52
54
  var TOOL_SETTINGS = [
53
55
  "row_tools",
@@ -1 +1 @@
1
- (()=>{var u=window.GridEditor;if(!u||typeof u.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");var i=window.jQuery,T=function(a,o){return u.t({locale:"en"},a,o)},m={};function b(a,o){m[a]||(m[a]=!0,window.console&&window.console.warn&&window.console.warn("grid-editor: "+o))}!i||!i.fn?b("no-jquery",T("warning.adapter_no_jquery")):x();function x(){var a={getHtml:{value:!0},getPlainHtml:{value:!0},init:{},deinit:{},reset:{},destroy:{},changeView:{},getView:{value:!0},createRow:{value:!0},createColumn:{value:!0},createElement:{value:!0},createText:{value:!0},createSection:{value:!0},createContainer:{value:!0},addTab:{value:!0},addAccordionItem:{value:!0},setLocale:{},getUtility:{value:!0},setUtility:{value:!0},getActiveTarget:{value:!0},setActiveTarget:{}},o=["row_tools","col_tools","element_tools","container_tools","tab_tools","accordion_tools","text_tools"];function g(r){return!!r&&r.nodeType===1}function l(r){return r instanceof i?r[0]||null:r}function h(r){if(r instanceof i)return l(r);if(r&&typeof r=="object"&&!Array.isArray(r)&&!g(r)){var t={};return Object.keys(r).forEach(function(e){t[e]=l(r[e])}),t}return r}function w(r){return g(r)?i(r):r}var s=new WeakMap;function p(r){if(!r||typeof r!="object")return r;if(s.has(r))return s.get(r);var t=Object.assign({},r);return["node","parent","canvas"].forEach(function(e){e in r&&(t[e]=i(r[e]||[]))}),r.container&&(t.container=i(r.container)),Array.isArray(r.nodes)&&(t.node=i(r.nodes)),["from","to"].forEach(function(e){var n=r[e];n&&typeof n=="object"&&"parent"in n&&(t[e]=Object.assign({},n,{parent:i(n.parent||[])}))}),s.set(r,t),t}var v=i.event.dispatch;i.event.dispatch=function(r){return arguments.length===1&&r instanceof window.CustomEvent&&typeof r.type=="string"&&r.type.indexOf("grideditor:")===0?v.call(this,r,p(r.detail)):v.apply(this,arguments)};function y(r){return function(t){return r.call(this,i.event.fix(t))}}function _(r){if(!r||!r.on)return r;var t;return typeof r.on=="function"?t=y(r.on):(t={},Object.keys(r.on).forEach(function(e){t[e]=y(r.on[e])})),Object.assign({},r,{on:t})}function j(r){return function(t,e){var n=typeof r=="string"?window[r]:r;return n(i(t),e)}}function E(r){if(r=Object.assign({},r||{}),r.callbacks){var t={};Object.keys(r.callbacks).forEach(function(n){var c=r.callbacks[n];t[n]=typeof c=="function"?function(f){return c(p(f))}:c}),r.callbacks=t}if(r.custom_filter&&r.custom_filter.length){var e=typeof r.custom_filter=="string"||typeof r.custom_filter=="function"?[r.custom_filter]:Array.prototype.slice.call(r.custom_filter);r.custom_filter=e.map(j)}return o.forEach(function(n){Array.isArray(r[n])&&(r[n]=r[n].map(_))}),r.source_textarea=l(r.source_textarea),r}function A(r){var t={canvas:i(r.canvas)};return Object.keys(a).forEach(function(e){t[e]=function(){var n=r[e].apply(r,Array.prototype.map.call(arguments,h));return n===r?void 0:w(n)}}),Object.defineProperty(t,"settings",{enumerable:!0,get:function(){return r.settings}}),t}u._created.push(function(r){i.data(r.canvas,"grideditor",A(r));var t=r.destroy;r.destroy=function(){var e=t.apply(this,arguments);return i.removeData(r.canvas,"grideditor"),e}});function O(r,t,e){var n=a[t];if(!n)return b("method:"+t,'unknown method "'+t+'"'),r;if(e=e.map(h),n.value){var c=r.first();if(!c.length)return null;var f=u.get(c[0]);return f?w(f[t].apply(f,e)):t==="getHtml"?c.html():t==="getPlainHtml"?u._plainHtml(c.html()):null}return r.each(function(){var d=u.get(this);d&&d[t].apply(d,e)}),r}i.fn.gridEditor=function(r){if(typeof r=="string")return O(this,r,Array.prototype.slice.call(arguments,1));var t=E(r);return this.each(function(){u.create(this,t)}),this},i.fn.gridEditor.locales=u.locales,i.fn.gridEditor.t=u.t}})();
1
+ (()=>{var u=window.GridEditor;if(!u||typeof u.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");var i=window.jQuery,T=function(a,o){return u.t({locale:"en"},a,o)},m={};function b(a,o){m[a]||(m[a]=!0,window.console&&window.console.warn&&window.console.warn("grid-editor: "+o))}!i||!i.fn?b("no-jquery",T("warning.adapter_no_jquery")):x();function x(){var a={getHtml:{value:!0},getPlainHtml:{value:!0},init:{},deinit:{},reset:{},destroy:{},changeView:{},getView:{value:!0},createRow:{value:!0},createColumn:{value:!0},createElement:{value:!0},createText:{value:!0},createSection:{value:!0},createContainer:{value:!0},addTab:{value:!0},addAccordionItem:{value:!0},setLocale:{},getUtility:{value:!0},setUtility:{value:!0},getActiveTarget:{value:!0},setActiveTarget:{},getSelected:{value:!0},setSelected:{}},o=["row_tools","col_tools","element_tools","container_tools","tab_tools","accordion_tools","text_tools"];function g(r){return!!r&&r.nodeType===1}function l(r){return r instanceof i?r[0]||null:r}function h(r){if(r instanceof i)return l(r);if(r&&typeof r=="object"&&!Array.isArray(r)&&!g(r)){var t={};return Object.keys(r).forEach(function(e){t[e]=l(r[e])}),t}return r}function v(r){return g(r)?i(r):r}var s=new WeakMap;function w(r){if(!r||typeof r!="object")return r;if(s.has(r))return s.get(r);var t=Object.assign({},r);return["node","parent","canvas"].forEach(function(e){e in r&&(t[e]=i(r[e]||[]))}),r.container&&(t.container=i(r.container)),Array.isArray(r.nodes)&&(t.node=i(r.nodes)),["from","to"].forEach(function(e){var n=r[e];n&&typeof n=="object"&&"parent"in n&&(t[e]=Object.assign({},n,{parent:i(n.parent||[])}))}),s.set(r,t),t}var p=i.event.dispatch;i.event.dispatch=function(r){return arguments.length===1&&r instanceof window.CustomEvent&&typeof r.type=="string"&&r.type.indexOf("grideditor:")===0?p.call(this,r,w(r.detail)):p.apply(this,arguments)};function y(r){return function(t){return r.call(this,i.event.fix(t))}}function _(r){if(!r||!r.on)return r;var t;return typeof r.on=="function"?t=y(r.on):(t={},Object.keys(r.on).forEach(function(e){t[e]=y(r.on[e])})),Object.assign({},r,{on:t})}function j(r){return function(t,e){var n=typeof r=="string"?window[r]:r;return n(i(t),e)}}function E(r){if(r=Object.assign({},r||{}),r.callbacks){var t={};Object.keys(r.callbacks).forEach(function(n){var c=r.callbacks[n];t[n]=typeof c=="function"?function(f){return c(w(f))}:c}),r.callbacks=t}if(r.custom_filter&&r.custom_filter.length){var e=typeof r.custom_filter=="string"||typeof r.custom_filter=="function"?[r.custom_filter]:Array.prototype.slice.call(r.custom_filter);r.custom_filter=e.map(j)}return o.forEach(function(n){Array.isArray(r[n])&&(r[n]=r[n].map(_))}),r.source_textarea=l(r.source_textarea),r}function A(r){var t={canvas:i(r.canvas)};return Object.keys(a).forEach(function(e){t[e]=function(){var n=r[e].apply(r,Array.prototype.map.call(arguments,h));return n===r?void 0:v(n)}}),Object.defineProperty(t,"settings",{enumerable:!0,get:function(){return r.settings}}),t}u._created.push(function(r){i.data(r.canvas,"grideditor",A(r));var t=r.destroy;r.destroy=function(){var e=t.apply(this,arguments);return i.removeData(r.canvas,"grideditor"),e}});function O(r,t,e){var n=a[t];if(!n)return b("method:"+t,'unknown method "'+t+'"'),r;if(e=e.map(h),n.value){var c=r.first();if(!c.length)return null;var f=u.get(c[0]);return f?v(f[t].apply(f,e)):t==="getHtml"?c.html():t==="getPlainHtml"?u._plainHtml(c.html()):null}return r.each(function(){var d=u.get(this);d&&d[t].apply(d,e)}),r}i.fn.gridEditor=function(r){if(typeof r=="string")return O(this,r,Array.prototype.slice.call(arguments,1));var t=E(r);return this.each(function(){u.create(this,t)}),this},i.fn.gridEditor.locales=u.locales,i.fn.gridEditor.t=u.t}})();