@themarioga/grid-editor 8.8.2 → 8.9.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.
- package/CHANGELOG.md +16 -0
- package/README.md +18 -0
- package/dist/grideditor.bundle.min.js +3 -3
- package/dist/grideditor.css +51 -0
- package/dist/grideditor.d.ts +28 -1
- package/dist/grideditor.esm.js +311 -20
- package/dist/grideditor.jquery.js +3 -1
- package/dist/grideditor.jquery.min.js +1 -1
- package/dist/grideditor.jquery.min.js.map +2 -2
- package/dist/grideditor.js +311 -20
- package/dist/grideditor.min.css +1 -1
- package/dist/grideditor.min.css.map +1 -1
- package/dist/grideditor.min.js +2 -2
- package/dist/grideditor.min.js.map +3 -3
- package/dist/locales/grideditor.es.esm.js +4 -0
- package/dist/locales/grideditor.es.js +4 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +2 -2
- package/docs/events.md +6 -0
- package/docs/locale-keys.md +4 -0
- package/docs/plugins.md +15 -1
- package/example/utilities.html +3 -1
- package/package.json +1 -1
- package/src/js/grideditor.jquery.js +2 -0
- package/src/js/grideditor.js +361 -29
- package/src/js/locales/grideditor.es.js +4 -0
- package/src/less/grideditor.less +59 -0
- package/types/grideditor.d.ts +28 -1
package/dist/grideditor.css
CHANGED
|
@@ -504,6 +504,57 @@
|
|
|
504
504
|
--bs-offcanvas-width: 340px;
|
|
505
505
|
--bs-offcanvas-height: 60vh;
|
|
506
506
|
}
|
|
507
|
+
/* The sidebar: always there while editing, with the page making room for it
|
|
508
|
+
(html.ge-sidebar-open) where the window is wide enough. Narrower than
|
|
509
|
+
Bootstrap's sm it covers the page instead. */
|
|
510
|
+
.ge-settings-sidebar {
|
|
511
|
+
--bs-offcanvas-width: 340px;
|
|
512
|
+
}
|
|
513
|
+
.ge-settings-sidebar .ge-sidebar-empty {
|
|
514
|
+
margin: 0;
|
|
515
|
+
color: var(--bs-secondary-color, #6c757d);
|
|
516
|
+
}
|
|
517
|
+
html.ge-sidebar-open {
|
|
518
|
+
padding-right: 340px;
|
|
519
|
+
}
|
|
520
|
+
/* On the panel's left edge, centred; folded away, on the window's right edge.
|
|
521
|
+
Its own element, so the panel can slide out from under it. */
|
|
522
|
+
.ge-sidebar-toggle {
|
|
523
|
+
position: fixed;
|
|
524
|
+
top: 50%;
|
|
525
|
+
right: 340px;
|
|
526
|
+
z-index: 1045;
|
|
527
|
+
display: flex;
|
|
528
|
+
align-items: center;
|
|
529
|
+
justify-content: center;
|
|
530
|
+
width: 1.5rem;
|
|
531
|
+
height: 3rem;
|
|
532
|
+
padding: 0;
|
|
533
|
+
transform: translateY(-50%);
|
|
534
|
+
border: 1px solid var(--bs-border-color, #dee2e6);
|
|
535
|
+
border-right: 0;
|
|
536
|
+
border-radius: 0.375rem 0 0 0.375rem;
|
|
537
|
+
background: var(--bs-body-bg, #fff);
|
|
538
|
+
color: var(--bs-body-color, #212529);
|
|
539
|
+
transition: right 0.3s ease-in-out;
|
|
540
|
+
}
|
|
541
|
+
.ge-sidebar-toggle[aria-expanded="false"] {
|
|
542
|
+
right: 0;
|
|
543
|
+
}
|
|
544
|
+
.ge-sidebar-toggle.ge-under-dialog {
|
|
545
|
+
z-index: 1040;
|
|
546
|
+
}
|
|
547
|
+
@media (max-width: 575.98px) {
|
|
548
|
+
.ge-settings-sidebar {
|
|
549
|
+
--bs-offcanvas-width: 100vw;
|
|
550
|
+
}
|
|
551
|
+
.ge-sidebar-toggle[aria-expanded="true"] {
|
|
552
|
+
right: calc(100vw - 1.5rem);
|
|
553
|
+
border: 1px solid var(--bs-border-color, #dee2e6);
|
|
554
|
+
border-left: 0;
|
|
555
|
+
border-radius: 0 0.375rem 0.375rem 0;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
507
558
|
.ge-settings-popover {
|
|
508
559
|
/* Popper would position it; without Popper that is the editor's job */
|
|
509
560
|
position: absolute;
|
package/dist/grideditor.d.ts
CHANGED
|
@@ -121,6 +121,18 @@ export interface InlineStyleOptions {
|
|
|
121
121
|
visibility?: { drawer?: boolean };
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/** What the sidebar shows while nothing is selected, instead of its message. */
|
|
125
|
+
export interface SidebarContent {
|
|
126
|
+
/** Text, not html. Default the sidebar's own title. */
|
|
127
|
+
title?: string;
|
|
128
|
+
body: Element;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface SidebarSettings {
|
|
132
|
+
/** Called whenever the sidebar is left with nothing selected. Null gives the message. */
|
|
133
|
+
empty?: ((ge: GridEditor) => SidebarContent | null) | null;
|
|
134
|
+
}
|
|
135
|
+
|
|
124
136
|
export type CustomFilter = ((canvas: HTMLElement, isInit: boolean) => void) | string;
|
|
125
137
|
|
|
126
138
|
/** The settings. Every one is optional. */
|
|
@@ -183,7 +195,10 @@ export interface GridEditorOptions {
|
|
|
183
195
|
locale_strings?: Record<string, string>;
|
|
184
196
|
callbacks?: Partial<GridEditorCallbacks>;
|
|
185
197
|
confirm_delete?: boolean;
|
|
186
|
-
|
|
198
|
+
/** Where a node's settings open. 'sidebar' is a panel that stays on the right while editing, showing the selected node's; one editor per page has it. */
|
|
199
|
+
settings_panel?: 'offcanvas' | 'popover' | 'modal' | 'inline' | 'sidebar';
|
|
200
|
+
/** The 'sidebar' panel. */
|
|
201
|
+
sidebar?: SidebarSettings;
|
|
187
202
|
drag?: { delay?: number; touch_delay?: number; threshold?: number; animation?: number; scroll?: boolean };
|
|
188
203
|
tinymce?: { config?: Record<string, unknown> };
|
|
189
204
|
ckeditor?: { config?: Record<string, unknown> };
|
|
@@ -317,6 +332,13 @@ export interface TargetChangePayload {
|
|
|
317
332
|
from: HTMLElement | null;
|
|
318
333
|
}
|
|
319
334
|
|
|
335
|
+
/** The selection changed, with settings_panel 'sidebar': the node whose settings the sidebar shows, or null. */
|
|
336
|
+
export interface SelectionChangePayload {
|
|
337
|
+
canvas: HTMLElement;
|
|
338
|
+
node: HTMLElement | null;
|
|
339
|
+
from: HTMLElement | null;
|
|
340
|
+
}
|
|
341
|
+
|
|
320
342
|
/** The events, by name, with their payloads. Adding fires a specific name and the generic one. */
|
|
321
343
|
export interface GridEditorEventMap {
|
|
322
344
|
'grideditor:before-add': Payload;
|
|
@@ -357,6 +379,7 @@ export interface GridEditorEventMap {
|
|
|
357
379
|
'grideditor:popup-orphan': PopupOrphanPayload;
|
|
358
380
|
'grideditor:view-change': ViewChangePayload;
|
|
359
381
|
'grideditor:target-change': TargetChangePayload;
|
|
382
|
+
'grideditor:selection-change': SelectionChangePayload;
|
|
360
383
|
'grideditor:after-autosave': AutosavePayload;
|
|
361
384
|
'grideditor:after-restore-draft': RestoreDraftPayload;
|
|
362
385
|
'grideditor:autosave-error': AutosaveErrorPayload;
|
|
@@ -468,6 +491,10 @@ export declare class GridEditor {
|
|
|
468
491
|
getActiveTarget(): HTMLElement | null;
|
|
469
492
|
/** Make a column or region, or the first a selector matches, where the toolbar adds; null for none. */
|
|
470
493
|
setActiveTarget(target: HTMLElement | string | null): this;
|
|
494
|
+
/** The node whose settings the sidebar shows, or null. Null unless settings_panel is 'sidebar'. */
|
|
495
|
+
getSelected(): HTMLElement | null;
|
|
496
|
+
/** Select a node with settings, or the first a selector matches, or null for none. Does nothing unless settings_panel is 'sidebar'. */
|
|
497
|
+
setSelected(node: HTMLElement | string | null): this;
|
|
471
498
|
getView(): View;
|
|
472
499
|
setLocale(code: string): this;
|
|
473
500
|
createRow(layout?: RowLayout, options?: Placement): HTMLElement | null;
|
package/dist/grideditor.esm.js
CHANGED
|
@@ -328,7 +328,9 @@ 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"];
|
|
334
336
|
var BREAKPOINTS = [
|
|
@@ -412,6 +414,10 @@ var NESTED_SETTINGS = {
|
|
|
412
414
|
tools: true
|
|
413
415
|
// The indent tools in the column's drawer
|
|
414
416
|
},
|
|
417
|
+
sidebar: {
|
|
418
|
+
empty: null
|
|
419
|
+
// function(ge) -> { title, body } shown while nothing is selected, or null for the message
|
|
420
|
+
},
|
|
415
421
|
drag: {
|
|
416
422
|
delay: 0,
|
|
417
423
|
// Milliseconds to hold before a drag starts
|
|
@@ -428,6 +434,8 @@ var NESTED_SETTINGS = {
|
|
|
428
434
|
var warned = {};
|
|
429
435
|
var editorCounter = 0;
|
|
430
436
|
var instances = /* @__PURE__ */ new WeakMap();
|
|
437
|
+
var sidebarHolder = null;
|
|
438
|
+
var EDITOR_CONTROLS = ".ge-mainControls, .ge-settings-panel, .ge-sidebar-toggle, .ge-dialog, .ge-confirm, .ge-size-picker, .modal, .modal-backdrop";
|
|
431
439
|
function translate(settings, key, params) {
|
|
432
440
|
var locales = GridEditor.locales;
|
|
433
441
|
var locale = locales[settings.locale] || {};
|
|
@@ -633,7 +641,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
633
641
|
"confirm_delete": true,
|
|
634
642
|
// Ask before deleting a row or a column
|
|
635
643
|
"settings_panel": "offcanvas",
|
|
636
|
-
// Where a node's settings open: 'offcanvas', 'popover', 'modal' or '
|
|
644
|
+
// Where a node's settings open: 'offcanvas', 'popover', 'modal', 'inline' or 'sidebar'
|
|
645
|
+
"sidebar": NESTED_SETTINGS.sidebar,
|
|
646
|
+
// The 'sidebar' panel: what it shows while nothing is selected
|
|
637
647
|
"drag": NESTED_SETTINGS.drag
|
|
638
648
|
// How a drag behaves, whatever drives it
|
|
639
649
|
}, optionsOrMethod);
|
|
@@ -659,6 +669,17 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
659
669
|
var sortables = [];
|
|
660
670
|
var instanceId = ++editorCounter;
|
|
661
671
|
var destroyed = false;
|
|
672
|
+
var selected = null;
|
|
673
|
+
var sidebarCollapsed = null;
|
|
674
|
+
var pluginHandle = null;
|
|
675
|
+
if (settings.settings_panel === "sidebar") {
|
|
676
|
+
if (sidebarHolder) {
|
|
677
|
+
warnOnceHere("sidebar", 'settings_panel "sidebar" is in use by another editor on the page, which has one sidebar: using offcanvas');
|
|
678
|
+
settings.settings_panel = "offcanvas";
|
|
679
|
+
} else {
|
|
680
|
+
sidebarHolder = instance;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
662
683
|
var detailsFor = /* @__PURE__ */ new WeakMap();
|
|
663
684
|
var moves = /* @__PURE__ */ new WeakMap();
|
|
664
685
|
var resizes = /* @__PURE__ */ new WeakMap();
|
|
@@ -1096,7 +1117,8 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1096
1117
|
e.preventDefault();
|
|
1097
1118
|
}
|
|
1098
1119
|
}, signal);
|
|
1099
|
-
|
|
1120
|
+
var sidebarMode = panelMode() === "sidebar";
|
|
1121
|
+
if (settings.active_target || sidebarMode) {
|
|
1100
1122
|
var pressed = null;
|
|
1101
1123
|
canvas.addEventListener("pointerdown", function(e) {
|
|
1102
1124
|
pressed = { x: e.clientX, y: e.clientY };
|
|
@@ -1110,24 +1132,61 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1110
1132
|
if (from && Math.abs(e.clientX - from.x) + Math.abs(e.clientY - from.y) > settings.drag.threshold) {
|
|
1111
1133
|
return;
|
|
1112
1134
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1135
|
+
if (settings.active_target) {
|
|
1136
|
+
clickTarget(e);
|
|
1137
|
+
}
|
|
1138
|
+
if (sidebarMode && canvas.contains(e.target)) {
|
|
1139
|
+
changeSelection(settingsNodeAt(e.target));
|
|
1117
1140
|
}
|
|
1118
|
-
changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
|
|
1119
1141
|
}, signal);
|
|
1120
1142
|
document.addEventListener("keydown", function(e) {
|
|
1121
|
-
if (e.key !== "Escape" ||
|
|
1143
|
+
if (e.key !== "Escape" || openSettingsState || dialogState) {
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
if (confirmDialog && hasClass(confirmDialog, "show")) {
|
|
1122
1147
|
return;
|
|
1123
1148
|
}
|
|
1124
1149
|
var focus = document.activeElement;
|
|
1125
1150
|
if (focus && (is(focus, "input, textarea, select") || focus.isContentEditable)) {
|
|
1126
1151
|
return;
|
|
1127
1152
|
}
|
|
1128
|
-
|
|
1153
|
+
if (selected && isEditing()) {
|
|
1154
|
+
changeSelection(null);
|
|
1155
|
+
} else if (activeTarget) {
|
|
1156
|
+
changeTarget(null);
|
|
1157
|
+
}
|
|
1129
1158
|
}, signal);
|
|
1130
1159
|
}
|
|
1160
|
+
if (sidebarMode) {
|
|
1161
|
+
canvas.addEventListener("focusin", function(e) {
|
|
1162
|
+
var node = isEditing() ? settingsNodeAt(e.target) : null;
|
|
1163
|
+
if (node) {
|
|
1164
|
+
changeSelection(node);
|
|
1165
|
+
}
|
|
1166
|
+
}, signal);
|
|
1167
|
+
document.addEventListener("click", function(e) {
|
|
1168
|
+
var target = e.target;
|
|
1169
|
+
if (!selected || !isEditing() || !target || target.nodeType !== 1) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
if (!attached(target) || canvas.contains(target)) {
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
if (closest(target, EDITOR_CONTROLS) || canvas.querySelector(".ge-rte-active")) {
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1178
|
+
changeSelection(null);
|
|
1179
|
+
}, signal);
|
|
1180
|
+
window.addEventListener("resize", reserveSidebarRoom, signal);
|
|
1181
|
+
}
|
|
1182
|
+
function clickTarget(e) {
|
|
1183
|
+
var region = closest(e.target, targetSelector());
|
|
1184
|
+
if (region && region === activeTarget && (e.target === region || e.target === child(region, ".ge-tools-drawer"))) {
|
|
1185
|
+
changeTarget(null);
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
changeTarget(region && region !== canvas && canvas.contains(region) ? region : null);
|
|
1189
|
+
}
|
|
1131
1190
|
}
|
|
1132
1191
|
function textReady(block) {
|
|
1133
1192
|
if (!is(block, ".ge-content") || !canvas.contains(block)) {
|
|
@@ -1898,6 +1957,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1898
1957
|
function openSource() {
|
|
1899
1958
|
deinit();
|
|
1900
1959
|
changeTarget(null);
|
|
1960
|
+
changeSelection(null);
|
|
1901
1961
|
htmlTextArea.style.height = 0.8 * document.documentElement.clientHeight + "px";
|
|
1902
1962
|
htmlTextArea.value = canvas.innerHTML;
|
|
1903
1963
|
show(htmlTextArea);
|
|
@@ -1943,6 +2003,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1943
2003
|
if (openSettingsState && !attached(openSettingsState.node)) {
|
|
1944
2004
|
closeSettings();
|
|
1945
2005
|
}
|
|
2006
|
+
if (selected && !canvas.contains(selected)) {
|
|
2007
|
+
changeSelection(null);
|
|
2008
|
+
}
|
|
1946
2009
|
if (dialogState && dialogState.home && !attached(dialogState.home)) {
|
|
1947
2010
|
closeDialog();
|
|
1948
2011
|
}
|
|
@@ -1967,9 +2030,11 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1967
2030
|
} else if (activeTarget) {
|
|
1968
2031
|
addClass(activeTarget, "ge-active-target");
|
|
1969
2032
|
}
|
|
2033
|
+
showSidebar();
|
|
1970
2034
|
}
|
|
1971
2035
|
function deinit() {
|
|
1972
2036
|
closeSettings();
|
|
2037
|
+
hideSidebar();
|
|
1973
2038
|
removeClass(canvas, "ge-editing ge-drag-drawer ge-dropping");
|
|
1974
2039
|
if (activeTarget) {
|
|
1975
2040
|
removeClass(activeTarget, "ge-active-target");
|
|
@@ -2130,6 +2195,10 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
2130
2195
|
}
|
|
2131
2196
|
deinit();
|
|
2132
2197
|
activeTarget = null;
|
|
2198
|
+
selected = null;
|
|
2199
|
+
if (sidebarHolder === instance) {
|
|
2200
|
+
sidebarHolder = null;
|
|
2201
|
+
}
|
|
2133
2202
|
removeConfirmModal();
|
|
2134
2203
|
removeSettingsPanels();
|
|
2135
2204
|
removeDialog();
|
|
@@ -2140,7 +2209,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
2140
2209
|
destroyed = true;
|
|
2141
2210
|
}
|
|
2142
2211
|
function loadPlugins() {
|
|
2143
|
-
var api = pluginApi();
|
|
2212
|
+
var api = pluginHandle = pluginApi();
|
|
2144
2213
|
registerFamily("grid", {}, widthFamily());
|
|
2145
2214
|
if (settings.row_cols !== false) {
|
|
2146
2215
|
registerFamily("grid", {}, rowColsFamily());
|
|
@@ -3261,9 +3330,11 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3261
3330
|
function addSettingsTool(drawer, node, presets) {
|
|
3262
3331
|
var details = createDetails(node, presets || []);
|
|
3263
3332
|
detailsFor.set(node, details);
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3333
|
+
if (panelMode() !== "sidebar") {
|
|
3334
|
+
createTool(drawer, t("tool.settings"), "ge-settings", "bi bi-gear-fill", function() {
|
|
3335
|
+
toggleSettings(node, details, this);
|
|
3336
|
+
});
|
|
3337
|
+
}
|
|
3267
3338
|
var kind = kindOf(node);
|
|
3268
3339
|
Object.keys(UTILITIES).forEach(function(name) {
|
|
3269
3340
|
if (UTILITIES[name].drawerTools) {
|
|
@@ -3354,7 +3425,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3354
3425
|
return;
|
|
3355
3426
|
}
|
|
3356
3427
|
var holder = element("div", { "class": "ge-panel-section", "data-ge-plugin": name });
|
|
3357
|
-
if (mode === "offcanvas" || mode === "modal") {
|
|
3428
|
+
if (mode === "offcanvas" || mode === "modal" || mode === "sidebar") {
|
|
3358
3429
|
holder.appendChild(sectionTitle(t(section.labelKey)));
|
|
3359
3430
|
holder.appendChild(section.body);
|
|
3360
3431
|
} else {
|
|
@@ -3378,7 +3449,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3378
3449
|
});
|
|
3379
3450
|
return sections;
|
|
3380
3451
|
}
|
|
3381
|
-
var PANEL_MODES = ["offcanvas", "popover", "modal", "inline"];
|
|
3452
|
+
var PANEL_MODES = ["offcanvas", "popover", "modal", "inline", "sidebar"];
|
|
3382
3453
|
var settingsPanels = {};
|
|
3383
3454
|
var openSettingsState = null;
|
|
3384
3455
|
var modalState = /* @__PURE__ */ new WeakMap();
|
|
@@ -3393,7 +3464,14 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3393
3464
|
return node && detailsFor.get(node) || null;
|
|
3394
3465
|
}
|
|
3395
3466
|
function settingsScope() {
|
|
3396
|
-
|
|
3467
|
+
var scope = [canvas];
|
|
3468
|
+
if (openSettingsState && openSettingsState.mode !== "inline") {
|
|
3469
|
+
scope.push(openSettingsState.details);
|
|
3470
|
+
}
|
|
3471
|
+
if (sidebarShown) {
|
|
3472
|
+
scope.push(sidebarShown.details);
|
|
3473
|
+
}
|
|
3474
|
+
return scope;
|
|
3397
3475
|
}
|
|
3398
3476
|
function toggleSettings(node, details, gear) {
|
|
3399
3477
|
var mode = panelMode();
|
|
@@ -3483,6 +3561,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3483
3561
|
} else {
|
|
3484
3562
|
hideModal(panel);
|
|
3485
3563
|
}
|
|
3564
|
+
returnPanel(open);
|
|
3565
|
+
}
|
|
3566
|
+
function returnPanel(open) {
|
|
3486
3567
|
removeClass(open.node, "ge-settings-target");
|
|
3487
3568
|
open.details.style.removeProperty("display");
|
|
3488
3569
|
dropEmptyStyle(open.details);
|
|
@@ -3515,6 +3596,11 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3515
3596
|
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
3597
|
one(panel, ".popover-header").appendChild(closeButton());
|
|
3517
3598
|
hide(panel);
|
|
3599
|
+
} else if (mode === "sidebar") {
|
|
3600
|
+
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>');
|
|
3601
|
+
panel.id = "ge-settings-sidebar-" + instanceId;
|
|
3602
|
+
one(panel, ".offcanvas-header").appendChild(closeButton());
|
|
3603
|
+
settingsPanels["sidebar-toggle"] = document.body.appendChild(sidebarToggle(panel));
|
|
3518
3604
|
} else {
|
|
3519
3605
|
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
3606
|
one(panel, ".modal-header").appendChild(closeButton());
|
|
@@ -3525,13 +3611,19 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3525
3611
|
}
|
|
3526
3612
|
delegate(panel, "click", ".ge-settings-close", function(e) {
|
|
3527
3613
|
e.preventDefault();
|
|
3528
|
-
|
|
3614
|
+
if (mode === "sidebar") {
|
|
3615
|
+
changeSelection(null);
|
|
3616
|
+
} else {
|
|
3617
|
+
closeSettings();
|
|
3618
|
+
}
|
|
3529
3619
|
});
|
|
3530
3620
|
settingsPanels[mode] = document.body.appendChild(panel);
|
|
3531
3621
|
return panel;
|
|
3532
3622
|
}
|
|
3533
3623
|
function removeSettingsPanels() {
|
|
3534
3624
|
closeSettings();
|
|
3625
|
+
unshowSidebar();
|
|
3626
|
+
removeClass(document.documentElement, "ge-sidebar-open");
|
|
3535
3627
|
Object.keys(settingsPanels).forEach(function(mode) {
|
|
3536
3628
|
if (mode === "modal") {
|
|
3537
3629
|
retireModal(settingsPanels[mode]);
|
|
@@ -3544,6 +3636,180 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3544
3636
|
});
|
|
3545
3637
|
settingsPanels = {};
|
|
3546
3638
|
}
|
|
3639
|
+
var SIDEBAR_MIN_WIDTH = 576;
|
|
3640
|
+
var sidebarShown = null;
|
|
3641
|
+
var sidebarEmpty = null;
|
|
3642
|
+
function isEditing() {
|
|
3643
|
+
return hasClass(canvas, "ge-editing");
|
|
3644
|
+
}
|
|
3645
|
+
function sidebarToggle(panel) {
|
|
3646
|
+
var button = element("button", { type: "button", "class": "ge-sidebar-toggle", "aria-controls": panel.id });
|
|
3647
|
+
button.appendChild(element("i"));
|
|
3648
|
+
button.addEventListener("click", function() {
|
|
3649
|
+
foldSidebar(!sidebarCollapsed);
|
|
3650
|
+
});
|
|
3651
|
+
return button;
|
|
3652
|
+
}
|
|
3653
|
+
function foldSidebar(collapsed) {
|
|
3654
|
+
sidebarCollapsed = collapsed;
|
|
3655
|
+
applySidebar();
|
|
3656
|
+
}
|
|
3657
|
+
function applySidebar() {
|
|
3658
|
+
var panel = settingsPanels.sidebar;
|
|
3659
|
+
var toggle2 = settingsPanels["sidebar-toggle"];
|
|
3660
|
+
if (!panel) {
|
|
3661
|
+
return;
|
|
3662
|
+
}
|
|
3663
|
+
var open = !sidebarCollapsed;
|
|
3664
|
+
if (open && !hasClass(panel, "show")) {
|
|
3665
|
+
removeClass(panel, "hiding");
|
|
3666
|
+
panel.getBoundingClientRect();
|
|
3667
|
+
addClass(panel, "show");
|
|
3668
|
+
} else if (!open && hasClass(panel, "show")) {
|
|
3669
|
+
removeClass(panel, "show");
|
|
3670
|
+
addClass(panel, "hiding");
|
|
3671
|
+
window.setTimeout(function() {
|
|
3672
|
+
removeClass(panel, "hiding");
|
|
3673
|
+
}, 300);
|
|
3674
|
+
}
|
|
3675
|
+
var label = open ? t("panel.collapse") : t("panel.expand");
|
|
3676
|
+
toggle2.setAttribute("aria-expanded", open ? "true" : "false");
|
|
3677
|
+
toggle2.setAttribute("aria-label", label);
|
|
3678
|
+
toggle2.setAttribute("title", label);
|
|
3679
|
+
one(toggle2, "i").className = "bi " + (open ? "bi-chevron-right" : "bi-chevron-left");
|
|
3680
|
+
reserveSidebarRoom();
|
|
3681
|
+
}
|
|
3682
|
+
function reserveSidebarRoom() {
|
|
3683
|
+
toggleClass(
|
|
3684
|
+
document.documentElement,
|
|
3685
|
+
"ge-sidebar-open",
|
|
3686
|
+
!!settingsPanels.sidebar && isEditing() && !sidebarCollapsed && window.innerWidth >= SIDEBAR_MIN_WIDTH
|
|
3687
|
+
);
|
|
3688
|
+
}
|
|
3689
|
+
function showSidebar() {
|
|
3690
|
+
if (panelMode() !== "sidebar") {
|
|
3691
|
+
return;
|
|
3692
|
+
}
|
|
3693
|
+
var panel = settingsPanel("sidebar");
|
|
3694
|
+
if (sidebarCollapsed === null) {
|
|
3695
|
+
sidebarCollapsed = window.innerWidth < SIDEBAR_MIN_WIDTH;
|
|
3696
|
+
}
|
|
3697
|
+
panel.style.removeProperty("display");
|
|
3698
|
+
settingsPanels["sidebar-toggle"].style.removeProperty("display");
|
|
3699
|
+
renderSidebar();
|
|
3700
|
+
applySidebar();
|
|
3701
|
+
}
|
|
3702
|
+
function hideSidebar() {
|
|
3703
|
+
unshowDetails();
|
|
3704
|
+
var panel = settingsPanels.sidebar;
|
|
3705
|
+
if (!panel) {
|
|
3706
|
+
return;
|
|
3707
|
+
}
|
|
3708
|
+
panel.style.display = "none";
|
|
3709
|
+
settingsPanels["sidebar-toggle"].style.display = "none";
|
|
3710
|
+
removeClass(document.documentElement, "ge-sidebar-open");
|
|
3711
|
+
}
|
|
3712
|
+
function setSidebarTitle(text) {
|
|
3713
|
+
var panel = settingsPanels.sidebar;
|
|
3714
|
+
one(panel, ".ge-settings-title").textContent = text;
|
|
3715
|
+
panel.setAttribute("aria-label", text);
|
|
3716
|
+
}
|
|
3717
|
+
function unshowDetails() {
|
|
3718
|
+
var shown = sidebarShown;
|
|
3719
|
+
sidebarShown = null;
|
|
3720
|
+
if (shown) {
|
|
3721
|
+
returnPanel(shown);
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
function unshowSidebar() {
|
|
3725
|
+
unshowDetails();
|
|
3726
|
+
if (sidebarEmpty) {
|
|
3727
|
+
sidebarEmpty.body.remove();
|
|
3728
|
+
sidebarEmpty = null;
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
function renderSidebar() {
|
|
3732
|
+
var panel = settingsPanels.sidebar;
|
|
3733
|
+
if (!panel || !isEditing()) {
|
|
3734
|
+
return;
|
|
3735
|
+
}
|
|
3736
|
+
var details = selected ? detailsOf(selected) : null;
|
|
3737
|
+
if (details ? sidebarShown && sidebarShown.details === details : !sidebarShown && sidebarEmpty) {
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
unshowSidebar();
|
|
3741
|
+
var holder = one(panel, ".ge-settings-body");
|
|
3742
|
+
if (!details) {
|
|
3743
|
+
var content = emptyContent();
|
|
3744
|
+
var body = content ? content.body : element("p", { "class": "ge-sidebar-empty" }, t("panel.sidebar_empty"));
|
|
3745
|
+
setSidebarTitle(content ? content.title : t("panel.sidebar_title"));
|
|
3746
|
+
holder.appendChild(body);
|
|
3747
|
+
sidebarEmpty = { body };
|
|
3748
|
+
return;
|
|
3749
|
+
}
|
|
3750
|
+
sidebarShown = { node: selected, details, home: details.parentElement, next: details.nextElementSibling };
|
|
3751
|
+
setSidebarTitle(t("panel.title", { kind: kindLabel(selected) }));
|
|
3752
|
+
holder.appendChild(details);
|
|
3753
|
+
show(details);
|
|
3754
|
+
addClass(selected, "ge-settings-target");
|
|
3755
|
+
}
|
|
3756
|
+
function emptyContent() {
|
|
3757
|
+
var fromHost = settings.sidebar.empty;
|
|
3758
|
+
var found = null;
|
|
3759
|
+
if (typeof fromHost === "function") {
|
|
3760
|
+
found = emptyContentOf(fromHost(instance), function(result) {
|
|
3761
|
+
return result.title;
|
|
3762
|
+
});
|
|
3763
|
+
} else if (fromHost !== null && fromHost !== void 0) {
|
|
3764
|
+
warnOnceHere("sidebar.empty", "sidebar.empty is a function(ge) returning { title, body }, not " + typeof fromHost + ": ignored");
|
|
3765
|
+
}
|
|
3766
|
+
[CONTAINERS, FEATURES, UTILITIES].forEach(function(registry) {
|
|
3767
|
+
Object.keys(registry).forEach(function(name) {
|
|
3768
|
+
var plugin = registry[name];
|
|
3769
|
+
if (found || !plugin.sidebarEmpty) {
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3772
|
+
found = emptyContentOf(plugin.sidebarEmpty(pluginHandle), function(result) {
|
|
3773
|
+
return typeof result.titleKey === "string" && result.titleKey !== "" ? t(result.titleKey) : "";
|
|
3774
|
+
});
|
|
3775
|
+
});
|
|
3776
|
+
});
|
|
3777
|
+
return found;
|
|
3778
|
+
}
|
|
3779
|
+
function emptyContentOf(result, titleOf) {
|
|
3780
|
+
if (!result || !result.body || result.body.nodeType !== 1) {
|
|
3781
|
+
return null;
|
|
3782
|
+
}
|
|
3783
|
+
var title = titleOf(result);
|
|
3784
|
+
return { title: typeof title === "string" && title !== "" ? title : t("panel.sidebar_title"), body: result.body };
|
|
3785
|
+
}
|
|
3786
|
+
function settingsNodeAt(target) {
|
|
3787
|
+
var drawer = closest(target, ".ge-tools-drawer", canvas);
|
|
3788
|
+
if (drawer) {
|
|
3789
|
+
var home = drawer.parentElement;
|
|
3790
|
+
var owner = detailsFor.has(home) ? home : children(home).filter(function(each) {
|
|
3791
|
+
return detailsFor.has(each);
|
|
3792
|
+
})[0];
|
|
3793
|
+
if (owner) {
|
|
3794
|
+
return owner;
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
for (var node = target; node && node !== canvas; node = node.parentElement) {
|
|
3798
|
+
if (detailsFor.has(node)) {
|
|
3799
|
+
return node;
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
return null;
|
|
3803
|
+
}
|
|
3804
|
+
function changeSelection(node) {
|
|
3805
|
+
if (node === selected) {
|
|
3806
|
+
return;
|
|
3807
|
+
}
|
|
3808
|
+
var from = selected;
|
|
3809
|
+
selected = node;
|
|
3810
|
+
renderSidebar();
|
|
3811
|
+
emit("selection-change", { canvas, node, from });
|
|
3812
|
+
}
|
|
3547
3813
|
function placePopover(panel, gear) {
|
|
3548
3814
|
if (!attached(gear)) {
|
|
3549
3815
|
return;
|
|
@@ -4658,6 +4924,23 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4658
4924
|
}
|
|
4659
4925
|
changeTarget(node);
|
|
4660
4926
|
}
|
|
4927
|
+
function apiSetSelected(value) {
|
|
4928
|
+
if (panelMode() !== "sidebar") {
|
|
4929
|
+
warnOnceHere("sidebar-api", 'setSelected needs settings_panel "sidebar": without it, it does nothing');
|
|
4930
|
+
return;
|
|
4931
|
+
}
|
|
4932
|
+
if (value === null || value === void 0) {
|
|
4933
|
+
changeSelection(null);
|
|
4934
|
+
return;
|
|
4935
|
+
}
|
|
4936
|
+
var node = nodeFrom(value);
|
|
4937
|
+
if (!node || node === canvas || !canvas.contains(node) || !detailsFor.has(node)) {
|
|
4938
|
+
var named = typeof value === "string" ? value : node ? "<" + node.tagName.toLowerCase() + ">" : String(value);
|
|
4939
|
+
warn("setSelected: " + named + " is not a node of the canvas with settings");
|
|
4940
|
+
return;
|
|
4941
|
+
}
|
|
4942
|
+
changeSelection(node);
|
|
4943
|
+
}
|
|
4661
4944
|
var own = {
|
|
4662
4945
|
getHtml,
|
|
4663
4946
|
getPlainHtml,
|
|
@@ -4696,7 +4979,11 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4696
4979
|
getActiveTarget: function() {
|
|
4697
4980
|
return settings.active_target ? activeTarget : null;
|
|
4698
4981
|
},
|
|
4699
|
-
setActiveTarget: apiSetActiveTarget
|
|
4982
|
+
setActiveTarget: apiSetActiveTarget,
|
|
4983
|
+
getSelected: function() {
|
|
4984
|
+
return panelMode() === "sidebar" ? selected : null;
|
|
4985
|
+
},
|
|
4986
|
+
setSelected: apiSetSelected
|
|
4700
4987
|
};
|
|
4701
4988
|
Object.keys(own).forEach(function(name) {
|
|
4702
4989
|
var value = !!(METHODS[name] && METHODS[name].value);
|
|
@@ -4747,7 +5034,7 @@ GridEditor.t = translate;
|
|
|
4747
5034
|
GridEditor._plainHtml = plainHtml;
|
|
4748
5035
|
GridEditor.Sortable = null;
|
|
4749
5036
|
GridEditor.bootstrap = null;
|
|
4750
|
-
GridEditor.version = false ? "dev" : "8.
|
|
5037
|
+
GridEditor.version = false ? "dev" : "8.9.0";
|
|
4751
5038
|
GridEditor.locales = {
|
|
4752
5039
|
en: {
|
|
4753
5040
|
"tool.move": "Move",
|
|
@@ -4780,6 +5067,10 @@ GridEditor.locales = {
|
|
|
4780
5067
|
"panel.title": "{kind} settings",
|
|
4781
5068
|
"panel.close": "Close",
|
|
4782
5069
|
"panel.done": "Done",
|
|
5070
|
+
"panel.sidebar_title": "Settings",
|
|
5071
|
+
"panel.sidebar_empty": "Click an element to see its settings",
|
|
5072
|
+
"panel.collapse": "Hide settings",
|
|
5073
|
+
"panel.expand": "Show settings",
|
|
4783
5074
|
"panel.id": "Id",
|
|
4784
5075
|
"panel.classes": "Classes",
|
|
4785
5076
|
"panel.section_general": "Id and classes",
|
|
@@ -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
|
|
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}})();
|