@themarioga/grid-editor 9.0.0-beta.1 → 9.0.0-beta.3
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 +28 -0
- package/README.md +70 -0
- package/UPGRADING.md +5 -0
- package/dist/grideditor.bundle.min.js +2 -2
- package/dist/grideditor.d.ts +41 -1
- package/dist/grideditor.esm.js +68 -2
- package/dist/grideditor.js +68 -2
- package/dist/grideditor.min.js +1 -1
- package/dist/grideditor.min.js.map +3 -3
- package/dist/locales/grideditor.es.esm.js +2 -0
- package/dist/locales/grideditor.es.js +2 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +2 -2
- package/dist/plugins/grideditor.clipboard.esm.js +116 -2
- package/dist/plugins/grideditor.clipboard.js +116 -2
- package/dist/plugins/grideditor.clipboard.min.js +1 -1
- package/dist/plugins/grideditor.clipboard.min.js.map +3 -3
- package/dist/plugins/grideditor.history.esm.js +360 -0
- package/dist/plugins/grideditor.history.js +365 -0
- package/dist/plugins/grideditor.history.min.js +1 -0
- package/dist/plugins/grideditor.history.min.js.map +7 -0
- package/docs/events.md +4 -1
- package/docs/locale-keys.md +11 -0
- package/docs/plugins.md +12 -1
- package/example/clipboard.html +22 -0
- package/example/history.html +94 -0
- package/example/index.html +8 -0
- package/package.json +1 -1
- package/src/js/grideditor.js +51 -1
- package/src/js/locales/grideditor.es.js +2 -0
- package/src/js/plugins/grideditor.clipboard.js +125 -2
- package/src/js/plugins/grideditor.history.js +367 -0
- package/types/grideditor.d.ts +41 -1
package/dist/grideditor.d.ts
CHANGED
|
@@ -178,6 +178,10 @@ export interface GridEditorOptions {
|
|
|
178
178
|
elements?: { enabled?: boolean | 'auto'; selector?: string; auto?: boolean; types?: ElementType[] };
|
|
179
179
|
/** The autosave plugin: what is edited, kept in the browser's storage as it changes. */
|
|
180
180
|
autosave?: AutosaveOptions;
|
|
181
|
+
/** The clipboard plugin. `shortcuts`: Ctrl+C and Ctrl+V on the node selected or the target; default active_target. */
|
|
182
|
+
clipboard?: { shortcuts?: boolean };
|
|
183
|
+
/** The history plugin: undo and redo. */
|
|
184
|
+
history?: HistoryOptions;
|
|
181
185
|
custom_filter?: CustomFilter | CustomFilter[] | '';
|
|
182
186
|
valid_col_sizes?: ColumnSize[];
|
|
183
187
|
valid_col_offsets?: number[];
|
|
@@ -220,6 +224,18 @@ export interface AutosaveOptions {
|
|
|
220
224
|
maxAge?: number | null;
|
|
221
225
|
}
|
|
222
226
|
|
|
227
|
+
/** The history plugin's options. */
|
|
228
|
+
export interface HistoryOptions {
|
|
229
|
+
/** Ctrl+Z, and Ctrl+Y or Ctrl+Shift+Z (⌘ on a Mac). Default true. */
|
|
230
|
+
shortcuts?: boolean;
|
|
231
|
+
/** The undo and redo buttons on the right of the toolbar. Default true. */
|
|
232
|
+
buttons?: boolean;
|
|
233
|
+
/** The steps that can be undone. Default 50. */
|
|
234
|
+
max?: number;
|
|
235
|
+
/** Milliseconds after the last change that make a step. Default 500. */
|
|
236
|
+
delay?: number;
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
/** A draft the autosave plugin kept. */
|
|
224
240
|
export interface AutosaveDraft {
|
|
225
241
|
html: string;
|
|
@@ -250,6 +266,19 @@ export interface AutosaveErrorPayload {
|
|
|
250
266
|
error: unknown;
|
|
251
267
|
}
|
|
252
268
|
|
|
269
|
+
export interface HistoryPayload {
|
|
270
|
+
canvas: HTMLElement;
|
|
271
|
+
/** The markup the canvas went to. */
|
|
272
|
+
html: string;
|
|
273
|
+
source: 'shortcut' | 'tool' | 'api';
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface HistoryChangePayload {
|
|
277
|
+
canvas: HTMLElement;
|
|
278
|
+
canUndo: boolean;
|
|
279
|
+
canRedo: boolean;
|
|
280
|
+
}
|
|
281
|
+
|
|
253
282
|
/** Where a node was, or went: its parent and its index among the blocks there. */
|
|
254
283
|
export interface Position {
|
|
255
284
|
parent: HTMLElement;
|
|
@@ -271,7 +300,7 @@ export interface Payload {
|
|
|
271
300
|
parent: HTMLElement | null;
|
|
272
301
|
canvas: HTMLElement;
|
|
273
302
|
breakpoint: View;
|
|
274
|
-
source: 'api' | 'tool' | 'dragdrop' | 'paste' | 'panel' | string;
|
|
303
|
+
source: 'api' | 'tool' | 'dragdrop' | 'paste' | 'panel' | 'shortcut' | string;
|
|
275
304
|
/** A pane inside a container. */
|
|
276
305
|
container?: HTMLElement;
|
|
277
306
|
}
|
|
@@ -383,6 +412,9 @@ export interface GridEditorEventMap {
|
|
|
383
412
|
'grideditor:after-autosave': AutosavePayload;
|
|
384
413
|
'grideditor:after-restore-draft': RestoreDraftPayload;
|
|
385
414
|
'grideditor:autosave-error': AutosaveErrorPayload;
|
|
415
|
+
'grideditor:after-undo': HistoryPayload;
|
|
416
|
+
'grideditor:after-redo': HistoryPayload;
|
|
417
|
+
'grideditor:history-change': HistoryChangePayload;
|
|
386
418
|
}
|
|
387
419
|
|
|
388
420
|
/** An event the editor dispatches on its canvas: a CustomEvent whose detail is the payload. */
|
|
@@ -521,6 +553,14 @@ export declare class GridEditor {
|
|
|
521
553
|
saveDraft?(): boolean;
|
|
522
554
|
getDraft?(): AutosaveDraft | null;
|
|
523
555
|
clearDraft?(): boolean;
|
|
556
|
+
/** The history plugin's, when it is loaded: true when it went to another step. */
|
|
557
|
+
undo?(): boolean;
|
|
558
|
+
redo?(): boolean;
|
|
559
|
+
/** Whether there is a step to go back to, a change not yet a step counting. */
|
|
560
|
+
canUndo?(): boolean;
|
|
561
|
+
canRedo?(): boolean;
|
|
562
|
+
/** What there is now becomes the first step, with nothing before or after it. */
|
|
563
|
+
clearHistory?(): boolean;
|
|
524
564
|
}
|
|
525
565
|
|
|
526
566
|
export default GridEditor;
|
package/dist/grideditor.esm.js
CHANGED
|
@@ -1545,6 +1545,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1545
1545
|
var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
|
|
1546
1546
|
var colour = item.align === "end" ? "btn-primary" : "btn-light";
|
|
1547
1547
|
var button = labelButton(element("a", { "class": "btn btn-sm " + colour + " ge-add-container ge-add-feature" }), label, iconClass);
|
|
1548
|
+
var acting = typeof item.action === "function";
|
|
1548
1549
|
addClass(button, item.className || "");
|
|
1549
1550
|
if (typeof item.hidden === "function" ? item.hidden() : item.hidden) {
|
|
1550
1551
|
hide(button);
|
|
@@ -1554,7 +1555,20 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1554
1555
|
"data-ge-feature": name,
|
|
1555
1556
|
"data-ge-item": index
|
|
1556
1557
|
});
|
|
1558
|
+
if (acting) {
|
|
1559
|
+
button.setAttribute("data-ge-action", "");
|
|
1560
|
+
if (typeof item.disabled === "function" ? item.disabled() : item.disabled) {
|
|
1561
|
+
addClass(button, "disabled");
|
|
1562
|
+
button.setAttribute("aria-disabled", "true");
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1557
1565
|
button.addEventListener("click", function() {
|
|
1566
|
+
if (acting) {
|
|
1567
|
+
if (!hasClass(button, "disabled")) {
|
|
1568
|
+
item.action(button);
|
|
1569
|
+
}
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1558
1572
|
if (activeTarget) {
|
|
1559
1573
|
addToTarget(button, item.source || "tool");
|
|
1560
1574
|
return;
|
|
@@ -1580,7 +1594,7 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
1580
1594
|
return !!settings.toolbar_drag;
|
|
1581
1595
|
}
|
|
1582
1596
|
function makeToolbarDraggable() {
|
|
1583
|
-
var buttons = all(mainControls, "[data-ge-toolbar]");
|
|
1597
|
+
var buttons = all(mainControls, "[data-ge-toolbar]:not([data-ge-action])");
|
|
1584
1598
|
buttons.forEach(function(button) {
|
|
1585
1599
|
removeClass(button, "ge-palette-button");
|
|
1586
1600
|
button.removeEventListener("pointerdown", startToolbarDrag);
|
|
@@ -2349,6 +2363,58 @@ function build(instance, baseElem, optionsOrMethod) {
|
|
|
2349
2363
|
refreshToolbar,
|
|
2350
2364
|
toolbarItems: function(name) {
|
|
2351
2365
|
return mainControls ? all(mainControls, '[data-ge-toolbar="feature"][data-ge-feature="' + name + '"]') : [];
|
|
2366
|
+
},
|
|
2367
|
+
getSelected: function() {
|
|
2368
|
+
return panelMode() === "sidebar" ? selected : null;
|
|
2369
|
+
},
|
|
2370
|
+
getActiveTarget: function() {
|
|
2371
|
+
return settings.active_target ? activeTarget : null;
|
|
2372
|
+
},
|
|
2373
|
+
// True when it took: a node that cannot be, or no setting
|
|
2374
|
+
// for it, says nothing, since a plugin putting back what it
|
|
2375
|
+
// remembers cannot know the node is still one
|
|
2376
|
+
setSelected: function(node) {
|
|
2377
|
+
var chosen = panelMode() === "sidebar" && !!node && node !== canvas && canvas.contains(node) && detailsFor.has(node);
|
|
2378
|
+
if (chosen) {
|
|
2379
|
+
changeSelection(node);
|
|
2380
|
+
}
|
|
2381
|
+
return chosen;
|
|
2382
|
+
},
|
|
2383
|
+
setActiveTarget: function(node) {
|
|
2384
|
+
var chosen = !!settings.active_target && isTarget(node);
|
|
2385
|
+
if (chosen) {
|
|
2386
|
+
changeTarget(node);
|
|
2387
|
+
}
|
|
2388
|
+
return chosen;
|
|
2389
|
+
},
|
|
2390
|
+
// What keeps Escape from the selection and the target, and an
|
|
2391
|
+
// inline panel unfolded in a drawer, which Escape leaves alone
|
|
2392
|
+
panelOpen: function() {
|
|
2393
|
+
if (openSettingsState || dialogState) {
|
|
2394
|
+
return true;
|
|
2395
|
+
}
|
|
2396
|
+
if (confirmDialog && hasClass(confirmDialog, "show")) {
|
|
2397
|
+
return true;
|
|
2398
|
+
}
|
|
2399
|
+
return panelMode() === "inline" && all(canvas, ".ge-tools-drawer > .ge-details").some(visible);
|
|
2400
|
+
},
|
|
2401
|
+
// The toolbar and the settings panels are outside the canvas
|
|
2402
|
+
contains: function(node) {
|
|
2403
|
+
if (!node || node.nodeType !== 1) {
|
|
2404
|
+
return false;
|
|
2405
|
+
}
|
|
2406
|
+
if (canvas.contains(node) || mainControls && mainControls.contains(node)) {
|
|
2407
|
+
return true;
|
|
2408
|
+
}
|
|
2409
|
+
if (dialogPanel && dialogPanel.contains(node)) {
|
|
2410
|
+
return true;
|
|
2411
|
+
}
|
|
2412
|
+
if (confirmDialog && confirmDialog.contains(node)) {
|
|
2413
|
+
return true;
|
|
2414
|
+
}
|
|
2415
|
+
return Object.keys(settingsPanels).some(function(mode) {
|
|
2416
|
+
return settingsPanels[mode].contains(node);
|
|
2417
|
+
});
|
|
2352
2418
|
}
|
|
2353
2419
|
};
|
|
2354
2420
|
}
|
|
@@ -5113,7 +5179,7 @@ GridEditor.t = translate;
|
|
|
5113
5179
|
GridEditor._plainHtml = plainHtml;
|
|
5114
5180
|
GridEditor.Sortable = null;
|
|
5115
5181
|
GridEditor.bootstrap = null;
|
|
5116
|
-
GridEditor.version = false ? "dev" : "9.0.0-beta.
|
|
5182
|
+
GridEditor.version = false ? "dev" : "9.0.0-beta.3";
|
|
5117
5183
|
GridEditor.locales = {
|
|
5118
5184
|
en: {
|
|
5119
5185
|
"tool.move": "Move",
|
package/dist/grideditor.js
CHANGED
|
@@ -1546,6 +1546,7 @@
|
|
|
1546
1546
|
var label = typeof item.label === "function" ? item.label() : item.label || t(item.labelKey);
|
|
1547
1547
|
var colour = item.align === "end" ? "btn-primary" : "btn-light";
|
|
1548
1548
|
var button = labelButton(element("a", { "class": "btn btn-sm " + colour + " ge-add-container ge-add-feature" }), label, iconClass);
|
|
1549
|
+
var acting = typeof item.action === "function";
|
|
1549
1550
|
addClass(button, item.className || "");
|
|
1550
1551
|
if (typeof item.hidden === "function" ? item.hidden() : item.hidden) {
|
|
1551
1552
|
hide(button);
|
|
@@ -1555,7 +1556,20 @@
|
|
|
1555
1556
|
"data-ge-feature": name,
|
|
1556
1557
|
"data-ge-item": index
|
|
1557
1558
|
});
|
|
1559
|
+
if (acting) {
|
|
1560
|
+
button.setAttribute("data-ge-action", "");
|
|
1561
|
+
if (typeof item.disabled === "function" ? item.disabled() : item.disabled) {
|
|
1562
|
+
addClass(button, "disabled");
|
|
1563
|
+
button.setAttribute("aria-disabled", "true");
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1558
1566
|
button.addEventListener("click", function() {
|
|
1567
|
+
if (acting) {
|
|
1568
|
+
if (!hasClass(button, "disabled")) {
|
|
1569
|
+
item.action(button);
|
|
1570
|
+
}
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1559
1573
|
if (activeTarget) {
|
|
1560
1574
|
addToTarget(button, item.source || "tool");
|
|
1561
1575
|
return;
|
|
@@ -1581,7 +1595,7 @@
|
|
|
1581
1595
|
return !!settings.toolbar_drag;
|
|
1582
1596
|
}
|
|
1583
1597
|
function makeToolbarDraggable() {
|
|
1584
|
-
var buttons = all(mainControls, "[data-ge-toolbar]");
|
|
1598
|
+
var buttons = all(mainControls, "[data-ge-toolbar]:not([data-ge-action])");
|
|
1585
1599
|
buttons.forEach(function(button) {
|
|
1586
1600
|
removeClass(button, "ge-palette-button");
|
|
1587
1601
|
button.removeEventListener("pointerdown", startToolbarDrag);
|
|
@@ -2350,6 +2364,58 @@
|
|
|
2350
2364
|
refreshToolbar,
|
|
2351
2365
|
toolbarItems: function(name) {
|
|
2352
2366
|
return mainControls ? all(mainControls, '[data-ge-toolbar="feature"][data-ge-feature="' + name + '"]') : [];
|
|
2367
|
+
},
|
|
2368
|
+
getSelected: function() {
|
|
2369
|
+
return panelMode() === "sidebar" ? selected : null;
|
|
2370
|
+
},
|
|
2371
|
+
getActiveTarget: function() {
|
|
2372
|
+
return settings.active_target ? activeTarget : null;
|
|
2373
|
+
},
|
|
2374
|
+
// True when it took: a node that cannot be, or no setting
|
|
2375
|
+
// for it, says nothing, since a plugin putting back what it
|
|
2376
|
+
// remembers cannot know the node is still one
|
|
2377
|
+
setSelected: function(node) {
|
|
2378
|
+
var chosen = panelMode() === "sidebar" && !!node && node !== canvas && canvas.contains(node) && detailsFor.has(node);
|
|
2379
|
+
if (chosen) {
|
|
2380
|
+
changeSelection(node);
|
|
2381
|
+
}
|
|
2382
|
+
return chosen;
|
|
2383
|
+
},
|
|
2384
|
+
setActiveTarget: function(node) {
|
|
2385
|
+
var chosen = !!settings.active_target && isTarget(node);
|
|
2386
|
+
if (chosen) {
|
|
2387
|
+
changeTarget(node);
|
|
2388
|
+
}
|
|
2389
|
+
return chosen;
|
|
2390
|
+
},
|
|
2391
|
+
// What keeps Escape from the selection and the target, and an
|
|
2392
|
+
// inline panel unfolded in a drawer, which Escape leaves alone
|
|
2393
|
+
panelOpen: function() {
|
|
2394
|
+
if (openSettingsState || dialogState) {
|
|
2395
|
+
return true;
|
|
2396
|
+
}
|
|
2397
|
+
if (confirmDialog && hasClass(confirmDialog, "show")) {
|
|
2398
|
+
return true;
|
|
2399
|
+
}
|
|
2400
|
+
return panelMode() === "inline" && all(canvas, ".ge-tools-drawer > .ge-details").some(visible);
|
|
2401
|
+
},
|
|
2402
|
+
// The toolbar and the settings panels are outside the canvas
|
|
2403
|
+
contains: function(node) {
|
|
2404
|
+
if (!node || node.nodeType !== 1) {
|
|
2405
|
+
return false;
|
|
2406
|
+
}
|
|
2407
|
+
if (canvas.contains(node) || mainControls && mainControls.contains(node)) {
|
|
2408
|
+
return true;
|
|
2409
|
+
}
|
|
2410
|
+
if (dialogPanel && dialogPanel.contains(node)) {
|
|
2411
|
+
return true;
|
|
2412
|
+
}
|
|
2413
|
+
if (confirmDialog && confirmDialog.contains(node)) {
|
|
2414
|
+
return true;
|
|
2415
|
+
}
|
|
2416
|
+
return Object.keys(settingsPanels).some(function(mode) {
|
|
2417
|
+
return settingsPanels[mode].contains(node);
|
|
2418
|
+
});
|
|
2353
2419
|
}
|
|
2354
2420
|
};
|
|
2355
2421
|
}
|
|
@@ -5114,7 +5180,7 @@
|
|
|
5114
5180
|
GridEditor._plainHtml = plainHtml;
|
|
5115
5181
|
GridEditor.Sortable = null;
|
|
5116
5182
|
GridEditor.bootstrap = null;
|
|
5117
|
-
GridEditor.version = false ? "dev" : "9.0.0-beta.
|
|
5183
|
+
GridEditor.version = false ? "dev" : "9.0.0-beta.3";
|
|
5118
5184
|
GridEditor.locales = {
|
|
5119
5185
|
en: {
|
|
5120
5186
|
"tool.move": "Move",
|