@themarioga/grid-editor 8.4.0 → 8.6.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 +51 -0
- package/README.md +105 -5
- package/dist/grideditor.bundle.min.js +3 -3
- package/dist/grideditor.css +15 -4
- package/dist/grideditor.d.ts +76 -4
- package/dist/grideditor.esm.js +212 -38
- package/dist/grideditor.js +212 -38
- 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 +5 -0
- package/dist/locales/grideditor.es.js +5 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +2 -2
- package/dist/plugins/grideditor.accordion.esm.js +7 -0
- package/dist/plugins/grideditor.accordion.js +7 -0
- package/dist/plugins/grideditor.accordion.min.js +1 -1
- package/dist/plugins/grideditor.accordion.min.js.map +3 -3
- package/dist/plugins/grideditor.autosave.esm.js +309 -0
- package/dist/plugins/grideditor.autosave.js +316 -0
- package/dist/plugins/grideditor.autosave.min.js +1 -0
- package/dist/plugins/grideditor.autosave.min.js.map +7 -0
- package/dist/plugins/grideditor.card.esm.js +10 -0
- package/dist/plugins/grideditor.card.js +10 -0
- package/dist/plugins/grideditor.card.min.js +1 -1
- package/dist/plugins/grideditor.card.min.js.map +3 -3
- package/dist/plugins/grideditor.ckeditor.esm.js +30 -1
- package/dist/plugins/grideditor.ckeditor.js +30 -1
- package/dist/plugins/grideditor.ckeditor.min.js +1 -1
- package/dist/plugins/grideditor.ckeditor.min.js.map +3 -3
- package/dist/plugins/grideditor.clipboard.esm.js +3 -0
- package/dist/plugins/grideditor.clipboard.js +3 -0
- package/dist/plugins/grideditor.clipboard.min.js +1 -1
- package/dist/plugins/grideditor.clipboard.min.js.map +2 -2
- package/dist/plugins/grideditor.codemirror-inline.esm.js +11 -0
- package/dist/plugins/grideditor.codemirror-inline.js +11 -0
- package/dist/plugins/grideditor.codemirror-inline.min.js +1 -1
- package/dist/plugins/grideditor.codemirror-inline.min.js.map +3 -3
- package/dist/plugins/grideditor.elements.esm.js +78 -4
- package/dist/plugins/grideditor.elements.js +78 -4
- package/dist/plugins/grideditor.elements.min.js +1 -1
- package/dist/plugins/grideditor.elements.min.js.map +3 -3
- package/dist/plugins/grideditor.gutters.esm.js +5 -0
- package/dist/plugins/grideditor.gutters.js +5 -0
- package/dist/plugins/grideditor.gutters.min.js +1 -1
- package/dist/plugins/grideditor.gutters.min.js.map +3 -3
- package/dist/plugins/grideditor.inline-style.esm.js +18 -10
- package/dist/plugins/grideditor.inline-style.js +18 -10
- package/dist/plugins/grideditor.inline-style.min.js +3 -3
- package/dist/plugins/grideditor.inline-style.min.js.map +3 -3
- package/dist/plugins/grideditor.order.esm.js +5 -0
- package/dist/plugins/grideditor.order.js +5 -0
- package/dist/plugins/grideditor.order.min.js +1 -1
- package/dist/plugins/grideditor.order.min.js.map +3 -3
- package/dist/plugins/grideditor.popup.esm.js +17 -6
- package/dist/plugins/grideditor.popup.js +17 -6
- package/dist/plugins/grideditor.popup.min.js +1 -1
- package/dist/plugins/grideditor.popup.min.js.map +3 -3
- package/dist/plugins/grideditor.sections.esm.js +6 -3
- package/dist/plugins/grideditor.sections.js +6 -3
- package/dist/plugins/grideditor.sections.min.js +1 -1
- package/dist/plugins/grideditor.sections.min.js.map +3 -3
- package/dist/plugins/grideditor.summernote.esm.js +40 -1
- package/dist/plugins/grideditor.summernote.js +40 -1
- package/dist/plugins/grideditor.summernote.min.js +1 -1
- package/dist/plugins/grideditor.summernote.min.js.map +3 -3
- package/dist/plugins/grideditor.tabs.esm.js +7 -0
- package/dist/plugins/grideditor.tabs.js +7 -0
- package/dist/plugins/grideditor.tabs.min.js +1 -1
- package/dist/plugins/grideditor.tabs.min.js.map +3 -3
- package/dist/plugins/grideditor.tinymce.esm.js +32 -1
- package/dist/plugins/grideditor.tinymce.js +32 -1
- package/dist/plugins/grideditor.tinymce.min.js +1 -1
- package/dist/plugins/grideditor.tinymce.min.js.map +3 -3
- package/docs/events.md +8 -0
- package/docs/locale-keys.md +16 -1
- package/docs/plugins.md +60 -7
- package/example/autosave.html +39 -22
- package/example/index.html +1 -1
- package/example/plugins.html +10 -0
- package/package.json +1 -2
- package/src/js/grideditor.js +248 -28
- package/src/js/inline-style/display.js +4 -3
- package/src/js/inline-style/drawerflow.js +10 -5
- package/src/js/locales/grideditor.es.js +5 -0
- package/src/js/plugins/grideditor.accordion.js +6 -0
- package/src/js/plugins/grideditor.autosave.js +349 -0
- package/src/js/plugins/grideditor.card.js +6 -0
- package/src/js/plugins/grideditor.ckeditor.js +6 -0
- package/src/js/plugins/grideditor.clipboard.js +3 -0
- package/src/js/plugins/grideditor.codemirror-inline.js +7 -0
- package/src/js/plugins/grideditor.elements.js +98 -4
- package/src/js/plugins/grideditor.gutters.js +4 -0
- package/src/js/plugins/grideditor.inline-style.js +2 -0
- package/src/js/plugins/grideditor.order.js +4 -0
- package/src/js/plugins/grideditor.popup.js +15 -6
- package/src/js/plugins/grideditor.sections.js +4 -3
- package/src/js/plugins/grideditor.summernote.js +14 -0
- package/src/js/plugins/grideditor.tabs.js +6 -0
- package/src/js/plugins/grideditor.tinymce.js +8 -0
- package/src/js/text/grideditor.text.js +27 -1
- package/src/less/grideditor.less +16 -8
- package/types/grideditor.d.ts +76 -4
- package/AUTO_SAVE.md +0 -30
package/dist/grideditor.css
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
position: relative;
|
|
3
3
|
min-height: 22px;
|
|
4
4
|
margin-bottom: 10px;
|
|
5
|
+
/* The add buttons on the left are grey, so the blue is left to the
|
|
6
|
+
source, preview and layout buttons on the right */
|
|
5
7
|
/* toolbar_groups: the tabs choosing which category of add buttons
|
|
6
8
|
shows, at the start of the line. Never squeezed, and never behind the
|
|
7
9
|
more button */
|
|
@@ -23,16 +25,25 @@
|
|
|
23
25
|
z-index: 20;
|
|
24
26
|
top: 0;
|
|
25
27
|
}
|
|
26
|
-
.ge-mainControls .ge-addRowGroup .btn.btn-
|
|
28
|
+
.ge-mainControls .ge-addRowGroup .btn.btn-light,
|
|
29
|
+
.ge-mainControls .ge-addContainerGroup .btn.btn-light,
|
|
30
|
+
.ge-mainControls .ge-toolbar-more > .btn.btn-light {
|
|
27
31
|
background: #f4f4f4;
|
|
28
32
|
color: #666;
|
|
29
33
|
border-color: #999;
|
|
30
|
-
display: flex;
|
|
31
|
-
align-items: center;
|
|
32
34
|
}
|
|
33
|
-
.ge-mainControls .ge-addRowGroup .btn.btn-
|
|
35
|
+
.ge-mainControls .ge-addRowGroup .btn.btn-light:hover,
|
|
36
|
+
.ge-mainControls .ge-addContainerGroup .btn.btn-light:hover,
|
|
37
|
+
.ge-mainControls .ge-toolbar-more > .btn.btn-light:hover,
|
|
38
|
+
.ge-mainControls .ge-addRowGroup .btn.btn-light:active,
|
|
39
|
+
.ge-mainControls .ge-addContainerGroup .btn.btn-light:active,
|
|
40
|
+
.ge-mainControls .ge-toolbar-more > .btn.btn-light:active {
|
|
34
41
|
background: #E3E3E3;
|
|
35
42
|
}
|
|
43
|
+
.ge-mainControls .ge-addRowGroup .btn.btn-light {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
}
|
|
36
47
|
.ge-mainControls .ge-addRowGroup .ge-row-icon {
|
|
37
48
|
width: 48px;
|
|
38
49
|
/* A button shrinks to its content, and an equal column has none */
|
package/dist/grideditor.d.ts
CHANGED
|
@@ -125,7 +125,9 @@ export interface GridEditorOptions {
|
|
|
125
125
|
inline_style?: InlineStyleOptions;
|
|
126
126
|
/** The tabs plugin: the variant of the tabs containers made new. */
|
|
127
127
|
tabs?: TabsOptions;
|
|
128
|
-
elements?: { enabled?: boolean | 'auto'; selector?: string; auto?: boolean };
|
|
128
|
+
elements?: { enabled?: boolean | 'auto'; selector?: string; auto?: boolean; types?: ElementType[] };
|
|
129
|
+
/** The autosave plugin: what is edited, kept in the browser's storage as it changes. */
|
|
130
|
+
autosave?: AutosaveOptions;
|
|
129
131
|
custom_filter?: CustomFilter | CustomFilter[] | '';
|
|
130
132
|
valid_col_sizes?: ColumnSize[];
|
|
131
133
|
valid_col_offsets?: number[];
|
|
@@ -151,6 +153,50 @@ export interface GridEditorOptions {
|
|
|
151
153
|
[plugin: string]: unknown;
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
/** The autosave plugin's options. */
|
|
157
|
+
export interface AutosaveOptions {
|
|
158
|
+
/** Saving from the start; the methods turn it on and off. Default true. */
|
|
159
|
+
enabled?: boolean;
|
|
160
|
+
/** localStorage or sessionStorage. Default 'local'. */
|
|
161
|
+
storage?: 'local' | 'session';
|
|
162
|
+
/** Where the draft is kept. Default 'grideditor.autosave:' + the page's path + '#' + the canvas's id. One per document on a page that loads several. */
|
|
163
|
+
key?: string | null;
|
|
164
|
+
/** Milliseconds after the last change. Default 1000. */
|
|
165
|
+
delay?: number;
|
|
166
|
+
/** Milliseconds a draft is offered for; null, the default, for ever. */
|
|
167
|
+
maxAge?: number | null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** A draft the autosave plugin kept. */
|
|
171
|
+
export interface AutosaveDraft {
|
|
172
|
+
html: string;
|
|
173
|
+
/** When, as an ISO 8601 date. */
|
|
174
|
+
savedAt: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface GetHtmlOptions {
|
|
178
|
+
/** Read the canvas without it leaving editing: open texts and settings panels stay open. */
|
|
179
|
+
keepEditing?: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface AutosavePayload {
|
|
183
|
+
canvas: HTMLElement;
|
|
184
|
+
html: string;
|
|
185
|
+
savedAt: string;
|
|
186
|
+
source: 'change' | 'pagehide' | 'api' | 'destroy';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface RestoreDraftPayload {
|
|
190
|
+
canvas: HTMLElement;
|
|
191
|
+
html: string;
|
|
192
|
+
savedAt: string;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface AutosaveErrorPayload {
|
|
196
|
+
canvas: HTMLElement;
|
|
197
|
+
error: unknown;
|
|
198
|
+
}
|
|
199
|
+
|
|
154
200
|
/** Where a node was, or went: its parent and its index among the blocks there. */
|
|
155
201
|
export interface Position {
|
|
156
202
|
parent: HTMLElement;
|
|
@@ -271,6 +317,9 @@ export interface GridEditorEventMap {
|
|
|
271
317
|
'grideditor:popup-orphan': PopupOrphanPayload;
|
|
272
318
|
'grideditor:view-change': ViewChangePayload;
|
|
273
319
|
'grideditor:target-change': TargetChangePayload;
|
|
320
|
+
'grideditor:after-autosave': AutosavePayload;
|
|
321
|
+
'grideditor:after-restore-draft': RestoreDraftPayload;
|
|
322
|
+
'grideditor:autosave-error': AutosaveErrorPayload;
|
|
274
323
|
}
|
|
275
324
|
|
|
276
325
|
/** An event the editor dispatches on its canvas: a CustomEvent whose detail is the payload. */
|
|
@@ -286,6 +335,22 @@ export type GridEditorCallbacks = {
|
|
|
286
335
|
};
|
|
287
336
|
|
|
288
337
|
/** A plugin's factory: called once per editor with the handle in docs/plugins.md. */
|
|
338
|
+
/** An element the toolbar offers, from elements.types. */
|
|
339
|
+
export interface ElementType {
|
|
340
|
+
/** What it is: its data-ge-element. */
|
|
341
|
+
type: string;
|
|
342
|
+
/** Its markup: html, or a function called for each one made that returns html or a node. */
|
|
343
|
+
html: string | (() => string | Node);
|
|
344
|
+
/** Its button's label, as it is. */
|
|
345
|
+
label?: string;
|
|
346
|
+
/** Its button's label, a locale key: wins over label, and follows setLocale. */
|
|
347
|
+
labelKey?: string;
|
|
348
|
+
/** The button shows this icon alone, with the label as its title. */
|
|
349
|
+
iconClass?: string;
|
|
350
|
+
/** Its toolbar_groups category. Default 'elements'. */
|
|
351
|
+
group?: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
289
354
|
export type PluginFactory = ((ge: any) => Record<string, unknown>) & { always?: boolean };
|
|
290
355
|
|
|
291
356
|
export interface CreateColumnOptions extends Placement {
|
|
@@ -346,10 +411,10 @@ export declare class GridEditor {
|
|
|
346
411
|
/** A read-only copy of the settings the editor runs with. */
|
|
347
412
|
readonly settings: Readonly<GridEditorOptions>;
|
|
348
413
|
|
|
349
|
-
/** The html to save: no drawers, no editor classes, no inline styles. */
|
|
350
|
-
getHtml(): string;
|
|
414
|
+
/** The html to save: no drawers, no editor classes, no inline styles. keepEditing reads it without the canvas leaving editing. */
|
|
415
|
+
getHtml(options?: GetHtmlOptions): string;
|
|
351
416
|
/** getHtml without grid-editor's marking, for publishing. It cannot be edited again as it was. */
|
|
352
|
-
getPlainHtml(): string;
|
|
417
|
+
getPlainHtml(options?: GetHtmlOptions): string;
|
|
353
418
|
/** Run the editing pass over the canvas again, after markup was put in. */
|
|
354
419
|
init(): this;
|
|
355
420
|
/** Take the editing furniture off, leaving the markup. */
|
|
@@ -379,6 +444,13 @@ export declare class GridEditor {
|
|
|
379
444
|
getUtility(node: Target, family: string, view?: View): string | null;
|
|
380
445
|
/** Write one through the events; null is inherit. False when canceled or nothing changed. */
|
|
381
446
|
setUtility(node: Target, family: string, value: string | number | null, view?: View): boolean;
|
|
447
|
+
/** The autosave plugin's, when it is loaded: false when the browser gives it no storage. */
|
|
448
|
+
enableAutosave?(): boolean;
|
|
449
|
+
disableAutosave?(): boolean;
|
|
450
|
+
/** Save now, if it changed: true when it was written. */
|
|
451
|
+
saveDraft?(): boolean;
|
|
452
|
+
getDraft?(): AutosaveDraft | null;
|
|
453
|
+
clearDraft?(): boolean;
|
|
382
454
|
}
|
|
383
455
|
|
|
384
456
|
export default GridEditor;
|
package/dist/grideditor.esm.js
CHANGED
|
@@ -392,8 +392,10 @@ var NESTED_SETTINGS = {
|
|
|
392
392
|
// 'auto' turns them on when the page has any
|
|
393
393
|
selector: "[data-ge-element]",
|
|
394
394
|
// What the host marks an element with
|
|
395
|
-
auto: false
|
|
395
|
+
auto: false,
|
|
396
396
|
// Treat every child of a content area as an element
|
|
397
|
+
types: []
|
|
398
|
+
// The elements the toolbar offers: { type, html, label | labelKey, iconClass, group }
|
|
397
399
|
},
|
|
398
400
|
resize: {
|
|
399
401
|
enabled: true,
|
|
@@ -760,31 +762,53 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
760
762
|
whenConfirmed();
|
|
761
763
|
return;
|
|
762
764
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
if (window.confirm(message)) {
|
|
765
|
+
confirmWith(message, { danger: true }, function(confirmed) {
|
|
766
|
+
if (confirmed) {
|
|
766
767
|
whenConfirmed();
|
|
767
768
|
}
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
function confirmWith(message, options, answer) {
|
|
772
|
+
options = options || {};
|
|
773
|
+
var Modal = modalLibrary();
|
|
774
|
+
if (!Modal) {
|
|
775
|
+
answer(window.confirm(message));
|
|
768
776
|
return;
|
|
769
777
|
}
|
|
770
778
|
var modal = confirmModal();
|
|
771
779
|
var confirmed = false;
|
|
780
|
+
var ok = one(modal, ".ge-confirm-ok");
|
|
781
|
+
if (pendingAnswer) {
|
|
782
|
+
pendingAnswer(null);
|
|
783
|
+
}
|
|
784
|
+
var settle = function(value) {
|
|
785
|
+
if (pendingAnswer !== settle) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
pendingAnswer = null;
|
|
789
|
+
answer(value);
|
|
790
|
+
};
|
|
791
|
+
pendingAnswer = settle;
|
|
792
|
+
one(modal, ".modal-title").textContent = options.title || t("confirm.title");
|
|
793
|
+
one(modal, ".ge-confirm-cancel").textContent = options.cancel || t("confirm.cancel");
|
|
794
|
+
ok.textContent = options.ok || t("confirm.ok");
|
|
795
|
+
toggleClass(ok, "btn-danger", !!options.danger);
|
|
796
|
+
toggleClass(ok, "btn-primary", !options.danger);
|
|
772
797
|
one(modal, ".ge-confirm-message").textContent = message;
|
|
773
|
-
|
|
798
|
+
ok.onclick = function() {
|
|
774
799
|
confirmed = true;
|
|
775
800
|
Modal.getInstance(modal).hide();
|
|
776
801
|
};
|
|
777
802
|
confirmHandlers.hidden = function() {
|
|
778
|
-
|
|
779
|
-
whenConfirmed();
|
|
780
|
-
}
|
|
803
|
+
settle(confirmed);
|
|
781
804
|
};
|
|
782
805
|
confirmHandlers.shown = function() {
|
|
783
|
-
|
|
806
|
+
ok.focus();
|
|
784
807
|
};
|
|
785
808
|
Modal.getOrCreateInstance(modal).show();
|
|
786
809
|
}
|
|
787
810
|
var confirmHandlers = { hidden: null, shown: null };
|
|
811
|
+
var pendingAnswer = null;
|
|
788
812
|
function confirmModal() {
|
|
789
813
|
if (confirmDialog) {
|
|
790
814
|
return confirmDialog;
|
|
@@ -798,13 +822,14 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
798
822
|
one(confirmDialog, ".ge-confirm-cancel").textContent = t("confirm.cancel");
|
|
799
823
|
one(confirmDialog, ".ge-confirm-ok").textContent = t("confirm.ok");
|
|
800
824
|
trackModal(confirmDialog);
|
|
825
|
+
var asking = confirmDialog;
|
|
801
826
|
confirmDialog.addEventListener("hidden.bs.modal", function() {
|
|
802
|
-
if (confirmHandlers.hidden) {
|
|
827
|
+
if (asking === confirmDialog && confirmHandlers.hidden) {
|
|
803
828
|
confirmHandlers.hidden();
|
|
804
829
|
}
|
|
805
830
|
});
|
|
806
831
|
confirmDialog.addEventListener("shown.bs.modal", function() {
|
|
807
|
-
if (confirmHandlers.shown) {
|
|
832
|
+
if (asking === confirmDialog && confirmHandlers.shown) {
|
|
808
833
|
confirmHandlers.shown();
|
|
809
834
|
}
|
|
810
835
|
});
|
|
@@ -818,6 +843,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
818
843
|
confirmHandlers.shown = null;
|
|
819
844
|
retireModal(confirmDialog);
|
|
820
845
|
confirmDialog = null;
|
|
846
|
+
if (pendingAnswer) {
|
|
847
|
+
pendingAnswer(null);
|
|
848
|
+
}
|
|
821
849
|
}
|
|
822
850
|
function retireModal(panel) {
|
|
823
851
|
var Modal = modalLibrary();
|
|
@@ -1112,7 +1140,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1112
1140
|
settings.new_row_layouts.forEach(function(layout) {
|
|
1113
1141
|
var grouped = !Array.isArray(layout);
|
|
1114
1142
|
var btn = element("a", {
|
|
1115
|
-
"class": "btn btn-sm btn-
|
|
1143
|
+
"class": "btn btn-sm btn-light",
|
|
1116
1144
|
title: grouped ? t("row.add_row_cols", { columns: layout.columns, counts: rowColsText(layout.row_cols) }) : t("row.add", { layout: layout.join("-") }),
|
|
1117
1145
|
// What this button makes, in the markup rather than in
|
|
1118
1146
|
// memory: a drag works on a clone of it
|
|
@@ -1147,7 +1175,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1147
1175
|
Object.keys(CONTAINERS).forEach(function(type) {
|
|
1148
1176
|
var definition = CONTAINERS[type];
|
|
1149
1177
|
var button = labelButton(
|
|
1150
|
-
element("a", { "class": "btn btn-sm btn-
|
|
1178
|
+
element("a", { "class": "btn btn-sm btn-light ge-add-container" }),
|
|
1151
1179
|
t(definition.labelKey),
|
|
1152
1180
|
definition.iconClass
|
|
1153
1181
|
);
|
|
@@ -1239,7 +1267,8 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1239
1267
|
}
|
|
1240
1268
|
var CORE_GROUPS = [
|
|
1241
1269
|
{ name: "rows", labelKey: "group.rows" },
|
|
1242
|
-
{ name: "content", labelKey: "group.content" }
|
|
1270
|
+
{ name: "content", labelKey: "group.content" },
|
|
1271
|
+
{ name: "elements", labelKey: "group.elements" }
|
|
1243
1272
|
];
|
|
1244
1273
|
function toolbarGroupOf(value) {
|
|
1245
1274
|
return typeof value === "string" && value.trim() !== "" ? value : null;
|
|
@@ -1267,7 +1296,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1267
1296
|
names.forEach(function(name) {
|
|
1268
1297
|
var tab = tabs.appendChild(element("button", {
|
|
1269
1298
|
type: "button",
|
|
1270
|
-
"class": "btn btn-sm btn-outline-
|
|
1299
|
+
"class": "btn btn-sm btn-outline-secondary",
|
|
1271
1300
|
role: "tab",
|
|
1272
1301
|
"data-ge-group": name
|
|
1273
1302
|
}, groupLabel(name)));
|
|
@@ -1316,7 +1345,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1316
1345
|
mainControls.remove();
|
|
1317
1346
|
}
|
|
1318
1347
|
function createOverflowMenu(start) {
|
|
1319
|
-
var more = create('<div class="ge-toolbar-more"><button type="button" class="btn btn-sm btn-
|
|
1348
|
+
var more = create('<div class="ge-toolbar-more"><button type="button" class="btn btn-sm btn-light"><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>');
|
|
1320
1349
|
start.parentNode.insertBefore(more, start.nextSibling);
|
|
1321
1350
|
var toggle2 = one(more, "button");
|
|
1322
1351
|
var panel = one(more, ".ge-toolbar-overflow");
|
|
@@ -1407,7 +1436,8 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1407
1436
|
function featureButton(name, item, index) {
|
|
1408
1437
|
var iconClass = item.iconClass || (item.align === "end" ? "bi bi-plus" : null);
|
|
1409
1438
|
var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
|
|
1410
|
-
var
|
|
1439
|
+
var colour = item.align === "end" ? "btn-primary" : "btn-light";
|
|
1440
|
+
var button = labelButton(element("a", { "class": "btn btn-sm " + colour + " ge-add-container ge-add-feature" }), label, iconClass);
|
|
1411
1441
|
addClass(button, item.className || "");
|
|
1412
1442
|
attr(button, {
|
|
1413
1443
|
"data-ge-toolbar": "feature",
|
|
@@ -1420,6 +1450,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1420
1450
|
return;
|
|
1421
1451
|
}
|
|
1422
1452
|
var made = item.create();
|
|
1453
|
+
if (!made) {
|
|
1454
|
+
return;
|
|
1455
|
+
}
|
|
1423
1456
|
var placed = item.inColumn ? inRowOfItsOwn(made) : made;
|
|
1424
1457
|
var added = addNode(item.kind, made, function() {
|
|
1425
1458
|
canvas.appendChild(placed);
|
|
@@ -1528,6 +1561,9 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1528
1561
|
function insertFeatureFromToolbar(button, where, source) {
|
|
1529
1562
|
var item = FEATURES[button.getAttribute("data-ge-feature")].toolbar[parseInt(button.getAttribute("data-ge-item"), 10)];
|
|
1530
1563
|
var made = item.create();
|
|
1564
|
+
if (!made) {
|
|
1565
|
+
return null;
|
|
1566
|
+
}
|
|
1531
1567
|
var placed = made;
|
|
1532
1568
|
if (item.inColumn) {
|
|
1533
1569
|
if (!is(where.region, ".column")) {
|
|
@@ -1909,22 +1945,122 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1909
1945
|
closeSizePicker();
|
|
1910
1946
|
hideDropMarker();
|
|
1911
1947
|
closeDialog();
|
|
1912
|
-
|
|
1913
|
-
drawer.remove();
|
|
1914
|
-
});
|
|
1948
|
+
removeDrawers(canvas);
|
|
1915
1949
|
pluginFields.clear();
|
|
1916
|
-
unwrapTexts();
|
|
1950
|
+
unwrapTexts(canvas);
|
|
1917
1951
|
plugins("onDeinit");
|
|
1918
1952
|
clearPreviews(canvas);
|
|
1919
|
-
|
|
1920
|
-
row.removeAttribute("data-ge-row-cols");
|
|
1921
|
-
});
|
|
1953
|
+
clearRowCols(canvas);
|
|
1922
1954
|
unmarkContainers();
|
|
1923
1955
|
removeSortable();
|
|
1924
1956
|
removeResizable();
|
|
1925
|
-
runFilter(false);
|
|
1957
|
+
runFilter(false, canvas);
|
|
1958
|
+
}
|
|
1959
|
+
function removeDrawers(root) {
|
|
1960
|
+
all(root, ".ge-tools-drawer").forEach(function(drawer) {
|
|
1961
|
+
drawer.remove();
|
|
1962
|
+
});
|
|
1963
|
+
}
|
|
1964
|
+
function clearRowCols(root) {
|
|
1965
|
+
all(root, "[data-ge-row-cols]").forEach(function(row) {
|
|
1966
|
+
row.removeAttribute("data-ge-row-cols");
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
function pluginsWithoutCleanMarkup() {
|
|
1970
|
+
var names = [];
|
|
1971
|
+
[CONTAINERS, FEATURES, UTILITIES].forEach(function(registry) {
|
|
1972
|
+
Object.keys(registry).forEach(function(name) {
|
|
1973
|
+
var plugin = registry[name];
|
|
1974
|
+
var marks = plugin.unmark || plugin.onDeinit || plugin.onBeforeDeinit;
|
|
1975
|
+
if (marks && !plugin.cleanMarkup) {
|
|
1976
|
+
names.push(name);
|
|
1977
|
+
}
|
|
1978
|
+
});
|
|
1979
|
+
});
|
|
1980
|
+
return names;
|
|
1981
|
+
}
|
|
1982
|
+
function copyCanvas() {
|
|
1983
|
+
var copy = canvas.cloneNode(true);
|
|
1984
|
+
var toLive = /* @__PURE__ */ new Map();
|
|
1985
|
+
var toCopy = /* @__PURE__ */ new Map();
|
|
1986
|
+
var live = document.createTreeWalker(canvas, NodeFilter.SHOW_ELEMENT);
|
|
1987
|
+
var copied = document.createTreeWalker(copy, NodeFilter.SHOW_ELEMENT);
|
|
1988
|
+
var a = live.currentNode;
|
|
1989
|
+
var b = copied.currentNode;
|
|
1990
|
+
while (a && b) {
|
|
1991
|
+
toLive.set(b, a);
|
|
1992
|
+
toCopy.set(a, b);
|
|
1993
|
+
a = live.nextNode();
|
|
1994
|
+
b = copied.nextNode();
|
|
1995
|
+
}
|
|
1996
|
+
return {
|
|
1997
|
+
root: copy,
|
|
1998
|
+
liveOf: function(node) {
|
|
1999
|
+
return toLive.get(node) || null;
|
|
2000
|
+
},
|
|
2001
|
+
copyOf: function(node) {
|
|
2002
|
+
return toCopy.get(node) || null;
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
1926
2005
|
}
|
|
1927
|
-
function
|
|
2006
|
+
function snapshotHtml() {
|
|
2007
|
+
if (sourceOpen) {
|
|
2008
|
+
return getHtml();
|
|
2009
|
+
}
|
|
2010
|
+
var missing = pluginsWithoutCleanMarkup();
|
|
2011
|
+
if (missing.length) {
|
|
2012
|
+
missing.forEach(function(name) {
|
|
2013
|
+
warnOnceHere("snapshot:" + name, 'the "' + name + '" plugin has no cleanMarkup, so the canvas leaves editing to be read: open texts and settings panels close');
|
|
2014
|
+
});
|
|
2015
|
+
return getHtml();
|
|
2016
|
+
}
|
|
2017
|
+
var copy = copyCanvas();
|
|
2018
|
+
var root = copy.root;
|
|
2019
|
+
[root].concat(all(root, ".ge-active-target, .ge-settings-target")).forEach(function(node) {
|
|
2020
|
+
removeClass(node, "ge-active-target ge-settings-target");
|
|
2021
|
+
dropEmptyClass(node);
|
|
2022
|
+
});
|
|
2023
|
+
all(root, ".ge-drop-marker").forEach(function(marker) {
|
|
2024
|
+
marker.remove();
|
|
2025
|
+
});
|
|
2026
|
+
removeDrawers(root);
|
|
2027
|
+
unwrapTexts(root);
|
|
2028
|
+
var refused = null;
|
|
2029
|
+
[CONTAINERS, FEATURES, UTILITIES].forEach(function(registry) {
|
|
2030
|
+
Object.keys(registry).forEach(function(name) {
|
|
2031
|
+
var plugin = registry[name];
|
|
2032
|
+
if (refused || !plugin.cleanMarkup) {
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
if (plugin.cleanMarkup(root, copy.liveOf) === false) {
|
|
2036
|
+
refused = name;
|
|
2037
|
+
}
|
|
2038
|
+
});
|
|
2039
|
+
});
|
|
2040
|
+
if (refused) {
|
|
2041
|
+
warnOnceHere("snapshot-refused:" + refused, 'the "' + refused + '" plugin cannot take its marking off a copy right now, so the canvas leaves editing to be read');
|
|
2042
|
+
return getHtml();
|
|
2043
|
+
}
|
|
2044
|
+
clearPreviews(root);
|
|
2045
|
+
clearRowCols(root);
|
|
2046
|
+
all(root, "[data-ge-container]").forEach(unmarkContainerClasses);
|
|
2047
|
+
sortables.forEach(function(sortableInstance) {
|
|
2048
|
+
var list = copy.copyOf(sortableInstance.el);
|
|
2049
|
+
if (list) {
|
|
2050
|
+
all(list, "[draggable]").forEach(function(node) {
|
|
2051
|
+
node.removeAttribute("draggable");
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
});
|
|
2055
|
+
removeResizeFurniture(root);
|
|
2056
|
+
runFilter(false, root);
|
|
2057
|
+
stripPixelWidths(root);
|
|
2058
|
+
return root.innerHTML;
|
|
2059
|
+
}
|
|
2060
|
+
function getHtml(options) {
|
|
2061
|
+
if (options && options.keepEditing) {
|
|
2062
|
+
return snapshotHtml();
|
|
2063
|
+
}
|
|
1928
2064
|
deinit();
|
|
1929
2065
|
stripPixelWidths(canvas);
|
|
1930
2066
|
var html = canvas.innerHTML;
|
|
@@ -1938,10 +2074,24 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1938
2074
|
init();
|
|
1939
2075
|
return html;
|
|
1940
2076
|
}
|
|
1941
|
-
function getPlainHtml() {
|
|
1942
|
-
return plainHtml(getHtml());
|
|
2077
|
+
function getPlainHtml(options) {
|
|
2078
|
+
return plainHtml(getHtml(options));
|
|
2079
|
+
}
|
|
2080
|
+
function setHtml2(html) {
|
|
2081
|
+
if (sourceOpen) {
|
|
2082
|
+
closeSource();
|
|
2083
|
+
if (mainControls) {
|
|
2084
|
+
all(mainControls, ".gm-edit-mode").forEach(function(button) {
|
|
2085
|
+
removeClass(button, "active btn-danger");
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
deinit();
|
|
2090
|
+
setHtml(canvas, html);
|
|
2091
|
+
init();
|
|
1943
2092
|
}
|
|
1944
2093
|
function destroy() {
|
|
2094
|
+
plugins("onDestroy");
|
|
1945
2095
|
if (sourceOpen) {
|
|
1946
2096
|
closeSource();
|
|
1947
2097
|
}
|
|
@@ -2054,6 +2204,11 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
2054
2204
|
closeDialog,
|
|
2055
2205
|
rowFromLayout: rowFromLayoutValue,
|
|
2056
2206
|
nodeHtml,
|
|
2207
|
+
// The markup as getHtml gives it, with the canvas left editing
|
|
2208
|
+
snapshotHtml,
|
|
2209
|
+
setHtml: setHtml2,
|
|
2210
|
+
// A question in the editor's confirm modal
|
|
2211
|
+
confirm: confirmWith,
|
|
2057
2212
|
// A text editor has rewritten a content area, so whatever the
|
|
2058
2213
|
// editor and its plugins had put in there goes back in
|
|
2059
2214
|
textReady,
|
|
@@ -2576,10 +2731,13 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
2576
2731
|
if (definition) {
|
|
2577
2732
|
definition.unmark(container);
|
|
2578
2733
|
}
|
|
2579
|
-
|
|
2580
|
-
dropEmptyClass(container);
|
|
2734
|
+
unmarkContainerClasses(container);
|
|
2581
2735
|
});
|
|
2582
2736
|
}
|
|
2737
|
+
function unmarkContainerClasses(container) {
|
|
2738
|
+
removeClass(container, "ge-container ge-container-" + containerTypeOf(container));
|
|
2739
|
+
dropEmptyClass(container);
|
|
2740
|
+
}
|
|
2583
2741
|
function prependDrawer(node, className) {
|
|
2584
2742
|
var drawer = element("div", { "class": className });
|
|
2585
2743
|
node.insertBefore(drawer, node.firstChild);
|
|
@@ -3980,13 +4138,16 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
3980
4138
|
on(handle, "pointerup pointercancel", onUp);
|
|
3981
4139
|
}
|
|
3982
4140
|
function removeResizable() {
|
|
3983
|
-
|
|
4141
|
+
removeResizeFurniture(canvas);
|
|
4142
|
+
}
|
|
4143
|
+
function removeResizeFurniture(root) {
|
|
4144
|
+
all(root, ".ge-resize-handle").forEach(function(handle) {
|
|
3984
4145
|
handle.remove();
|
|
3985
4146
|
});
|
|
3986
|
-
all(
|
|
4147
|
+
all(root, ".ge-resize-size").forEach(function(readout) {
|
|
3987
4148
|
readout.remove();
|
|
3988
4149
|
});
|
|
3989
|
-
stripPixelWidths(
|
|
4150
|
+
stripPixelWidths(root);
|
|
3990
4151
|
}
|
|
3991
4152
|
function snapUnits(col, pixels) {
|
|
3992
4153
|
var units = Math.round(pixels / rowContentWidth(col.parentElement) * MAX_COL_SIZE);
|
|
@@ -4194,7 +4355,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4194
4355
|
setOffset(column, tier, wanted.offset);
|
|
4195
4356
|
return column;
|
|
4196
4357
|
}
|
|
4197
|
-
function runFilter(isInit) {
|
|
4358
|
+
function runFilter(isInit, root) {
|
|
4198
4359
|
if (!settings.custom_filter || !settings.custom_filter.length) {
|
|
4199
4360
|
return;
|
|
4200
4361
|
}
|
|
@@ -4203,7 +4364,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4203
4364
|
if (typeof func == "string") {
|
|
4204
4365
|
func = window[func];
|
|
4205
4366
|
}
|
|
4206
|
-
func(canvas, isInit);
|
|
4367
|
+
func(root || canvas, isInit);
|
|
4207
4368
|
});
|
|
4208
4369
|
}
|
|
4209
4370
|
function textCutter() {
|
|
@@ -4323,8 +4484,8 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4323
4484
|
}
|
|
4324
4485
|
});
|
|
4325
4486
|
}
|
|
4326
|
-
function unwrapTexts() {
|
|
4327
|
-
all(
|
|
4487
|
+
function unwrapTexts(root) {
|
|
4488
|
+
all(root, ".ge-text-block").forEach(function(textBlock) {
|
|
4328
4489
|
unwrap(textBlock);
|
|
4329
4490
|
});
|
|
4330
4491
|
}
|
|
@@ -4497,6 +4658,18 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
4497
4658
|
instances.set(canvas, instance);
|
|
4498
4659
|
loadPlugins();
|
|
4499
4660
|
instance.settings = settingsCopy();
|
|
4661
|
+
Object.keys(featureMethods).forEach(function(name) {
|
|
4662
|
+
if (Object.prototype.hasOwnProperty.call(own, name) || name in instance) {
|
|
4663
|
+
return;
|
|
4664
|
+
}
|
|
4665
|
+
instance[name] = function() {
|
|
4666
|
+
if (destroyed) {
|
|
4667
|
+
warnOnceHere("destroyed:" + name, t("warning.destroyed", { method: name }));
|
|
4668
|
+
return null;
|
|
4669
|
+
}
|
|
4670
|
+
return featureMethods[name].apply(null, arguments);
|
|
4671
|
+
};
|
|
4672
|
+
});
|
|
4500
4673
|
setup();
|
|
4501
4674
|
init();
|
|
4502
4675
|
GridEditor._created.forEach(function(hook) {
|
|
@@ -4512,7 +4685,7 @@ GridEditor.t = translate;
|
|
|
4512
4685
|
GridEditor._plainHtml = plainHtml;
|
|
4513
4686
|
GridEditor.Sortable = null;
|
|
4514
4687
|
GridEditor.bootstrap = null;
|
|
4515
|
-
GridEditor.version = false ? "dev" : "8.
|
|
4688
|
+
GridEditor.version = false ? "dev" : "8.6.0";
|
|
4516
4689
|
GridEditor.locales = {
|
|
4517
4690
|
en: {
|
|
4518
4691
|
"tool.move": "Move",
|
|
@@ -4540,6 +4713,7 @@ GridEditor.locales = {
|
|
|
4540
4713
|
"tool.more": "More",
|
|
4541
4714
|
"group.rows": "Rows",
|
|
4542
4715
|
"group.content": "Content",
|
|
4716
|
+
"group.elements": "Elements",
|
|
4543
4717
|
"group.select": "Add",
|
|
4544
4718
|
"panel.title": "{kind} settings",
|
|
4545
4719
|
"panel.close": "Close",
|