@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/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,57 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
## [8.6.0] - 2026-10-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- The autosave plugin, `grideditor.autosave.js`: what is edited is kept in
|
|
12
|
+
`localStorage` or `sessionStorage` a second after each change and when the
|
|
13
|
+
page is left, without closing the text being typed into. An editor that
|
|
14
|
+
starts from the html a draft was made from asks, in its confirm modal,
|
|
15
|
+
whether to restore it. Options `enabled`, `storage`, `key`, `delay` and
|
|
16
|
+
`maxAge`; methods `enableAutosave`, `disableAutosave`, `saveDraft`,
|
|
17
|
+
`getDraft` and `clearDraft`; events `after-autosave`, `after-restore-draft`
|
|
18
|
+
and `autosave-error`.
|
|
19
|
+
- `getHtml({ keepEditing: true })` and `getPlainHtml({ keepEditing: true })`:
|
|
20
|
+
the same markup, read on a copy of the canvas, so the canvas never leaves
|
|
21
|
+
editing - open texts, settings panels and the focus stay where they are.
|
|
22
|
+
`custom_filter` is run on the copy too.
|
|
23
|
+
- For plugins: `cleanMarkup(root, liveOf)`, what `unmark`, `onDeinit` and
|
|
24
|
+
`onBeforeDeinit` take off, taken off the copy - a plugin that has one of
|
|
25
|
+
those and no `cleanMarkup` makes `keepEditing` fall back on `getHtml`, with
|
|
26
|
+
a warning; `onDestroy`; and on the handle `ge.snapshotHtml()`,
|
|
27
|
+
`ge.setHtml(html)` and `ge.confirm(message, options, answer)`. A text editor
|
|
28
|
+
of `GridEditor.texts` has `read(contentArea)` and `cleanCopy(copy, area)`.
|
|
29
|
+
Every shipped plugin and text editor has them.
|
|
30
|
+
- A feature plugin's `methods` are the instance's, whatever their names: up
|
|
31
|
+
to now only the editor's own documented ones were.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- `example/autosave.html` is built on the plugin, with an on/off switch and
|
|
35
|
+
a key per imported file; `AUTO_SAVE.md` is gone, its content in the README.
|
|
36
|
+
- The toolbar's add buttons on the left - rows, containers, the feature
|
|
37
|
+
plugins' and the overflow menu's button - are grey (`btn-light`), and the
|
|
38
|
+
`toolbar_groups` tabs `btn-outline-secondary`. Blue is left to the buttons
|
|
39
|
+
on the right: source, preview, layout and the `align: 'end'` ones.
|
|
40
|
+
|
|
41
|
+
## [8.5.0] - 2026-10-01
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
- `elements.types`: the elements the toolbar offers, a button each. A type
|
|
45
|
+
has its `type`, its `html` - a string, or a function called for each one
|
|
46
|
+
made - a `label` or `labelKey`, an `iconClass` and a `group`. A button
|
|
47
|
+
makes the html's root, marked with `data-ge-element` and `data-ge-label`
|
|
48
|
+
the way a host marks its own elements, or a `div` around html with no
|
|
49
|
+
single root. Declaring a type turns `enabled: 'auto'` on.
|
|
50
|
+
- `toolbar_groups`: a third core category, *Elements*, after *Content*. The
|
|
51
|
+
element buttons go there unless they name another `group`.
|
|
52
|
+
- A feature plugin's `toolbar` item whose `create()` returns `null` adds
|
|
53
|
+
nothing, rather than failing.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- `toolbar_groups`: the *Text* buttons are in *Elements* now, not in
|
|
57
|
+
*Content*, which keeps the containers and the sections.
|
|
58
|
+
|
|
8
59
|
## [8.4.0] - 2026-10-01
|
|
9
60
|
|
|
10
61
|
### Added
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ from any web server, or from GitHub Pages, with no build step.
|
|
|
36
36
|
| [example/summernote.html](example/summernote.html) | Summernote instead of tinyMCE | [live](https://themarioga.github.io/grid-editor/example/summernote.html) |
|
|
37
37
|
| [example/clipboard.html](example/clipboard.html) | Copy and paste, within an editor, between two, and between tabs | [live](https://themarioga.github.io/grid-editor/example/clipboard.html) |
|
|
38
38
|
| [example/wrap_content.html](example/wrap_content.html) | Non-bootstrap markup wrapped into the grid | [live](https://themarioga.github.io/grid-editor/example/wrap_content.html) |
|
|
39
|
-
| [example/autosave.html](example/autosave.html) |
|
|
39
|
+
| [example/autosave.html](example/autosave.html) | The autosave plugin: drafts kept as the user edits, offered back after a reload; import and export | [live](https://themarioga.github.io/grid-editor/example/autosave.html) |
|
|
40
40
|
| [example/adapter.html](example/adapter.html) | A page written for 6.x, with jQuery, running unchanged through the adapter | [live](https://themarioga.github.io/grid-editor/example/adapter.html) |
|
|
41
41
|
|
|
42
42
|
[example/angular](example/angular) is the editor in an Angular app, from the npm
|
|
@@ -142,6 +142,14 @@ which parts are elements, tabs, accordions or popups. That marking is how the
|
|
|
142
142
|
editor reads its markup back, so **save `getHtml`** for anything that will be
|
|
143
143
|
edited again.
|
|
144
144
|
|
|
145
|
+
`getHtml` takes the canvas out of editing to read it and puts it back, which
|
|
146
|
+
closes a text being typed into and a settings panel that is open.
|
|
147
|
+
`getHtml({ keepEditing: true })` gives the same markup without the canvas
|
|
148
|
+
leaving editing - it is read on a copy - which is what something that reads
|
|
149
|
+
it as the user works, an autosave, wants. A plugin that cannot be read on a
|
|
150
|
+
copy (see [docs/plugins.md](docs/plugins.md#reading-on-a-copy)) makes it fall
|
|
151
|
+
back on `getHtml`, with a warning in the console.
|
|
152
|
+
|
|
145
153
|
`getPlainHtml` is the same markup with that marking taken off, and each
|
|
146
154
|
`div.ge-content` replaced by what it holds. Bootstrap's own classes and
|
|
147
155
|
attributes stay, so tabs, accordions and popups still work in a page that
|
|
@@ -166,8 +174,8 @@ has, with the options it was made with, and warns once.
|
|
|
166
174
|
|
|
167
175
|
| Method | Arguments | Returns | What it does |
|
|
168
176
|
| --- | --- | --- | --- |
|
|
169
|
-
| `getHtml` |
|
|
170
|
-
| `getPlainHtml` |
|
|
177
|
+
| `getHtml` | `options?` | `String` | The clean html: no drawers, no editor classes, no inline styles. `{ keepEditing: true }` reads it without the canvas leaving editing |
|
|
178
|
+
| `getPlainHtml` | `options?` | `String` | `getHtml` without grid-editor's marking (`ge-*`, `column`, `data-ge-*`), for publishing. It cannot be edited again as it was. Takes the same `options` |
|
|
171
179
|
| `init` | — | `this` | Run the editing pass over the canvas again. Safe to call after you inject markup |
|
|
172
180
|
| `deinit` | — | `this` | Strip the editing furniture, leave the markup |
|
|
173
181
|
| `reset` | — | `this` | `deinit()` then `init()` |
|
|
@@ -379,7 +387,7 @@ new GridEditor('#myGrid', {
|
|
|
379
387
|
});
|
|
380
388
|
```
|
|
381
389
|
|
|
382
|
-
__`toolbar_groups`:__ Whether the toolbar's add buttons are sorted into categories, with tabs at the start of the toolbar choosing which one shows. Default `false`. With `true` the core's categories are *Rows*, the add row buttons,
|
|
390
|
+
__`toolbar_groups`:__ Whether the toolbar's add buttons are sorted into categories, with tabs at the start of the toolbar choosing which one shows. Default `false`. With `true` the core's categories are *Rows*, the add row buttons, *Content*, the containers and the sections, and *Elements*, the texts and the elements of `elements.types`; a plugin's buttons go in the category they name with `group` (see [docs/plugins.md](docs/plugins.md)), or in one of their own. The tab chosen is kept while the editor lives, through `setLocale` too. With a single category there is nothing to choose and no tabs. The buttons on the right - the view, source and preview, paste - are never grouped. The more button of `toolbar_overflow` holds what doesn't fit of the category shown; the tabs themselves never go behind it, so with a great many categories they can run out of room.
|
|
383
391
|
|
|
384
392
|
```javascript
|
|
385
393
|
new GridEditor('#myGrid', {
|
|
@@ -397,7 +405,7 @@ ge.canvas.addEventListener('grideditor:target-change', function(e) {
|
|
|
397
405
|
```
|
|
398
406
|
|
|
399
407
|
__`custom_filter`:__ Allows the execution of a custom function before initialization and after de-initialization. Accepts a functions or a function name as string.
|
|
400
|
-
Gives the `canvas` element and `isInit` (true/false) as parameter.
|
|
408
|
+
Gives the `canvas` element and `isInit` (true/false) as parameter. `getHtml({ keepEditing: true })` runs it too, with `isInit` false, on a copy of the canvas rather than the canvas: work on the element it is given, not on one you kept.
|
|
401
409
|
|
|
402
410
|
```javascript
|
|
403
411
|
new GridEditor('#myGrid', {
|
|
@@ -592,6 +600,32 @@ new GridEditor('#myGrid', {
|
|
|
592
600
|
enabled: 'auto', // on when the page has any; true or false to decide yourself
|
|
593
601
|
selector: '[data-ge-element]', // what counts as an element
|
|
594
602
|
auto: false, // true treats every loose node of a column as one
|
|
603
|
+
types: [], // the elements the toolbar offers, see below
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
__`elements.types`:__ The elements the toolbar offers, a button each, in this order. A click makes one in a row and column of its own at the end of the canvas - or at the end of the active target, with `active_target` - and a drag drops it in the column it lands in, as a text or a container. Declaring a type turns `enabled: 'auto'` on, so the buttons are there on a page with no elements yet; `enabled: false` takes them away too.
|
|
609
|
+
|
|
610
|
+
| Field | | |
|
|
611
|
+
| --- | --- | --- |
|
|
612
|
+
| `type` | required | what it is: its `data-ge-element` |
|
|
613
|
+
| `html` | required | its markup: html, or a function called for each one made, which returns html or a node |
|
|
614
|
+
| `label` / `labelKey` | | the button's label, as it is or as a locale key, which wins and follows `setLocale`. Without either, the `type` |
|
|
615
|
+
| `iconClass` | | the button shows the icon alone, with the label as its title |
|
|
616
|
+
| `group` | | its `toolbar_groups` category. Default `elements` |
|
|
617
|
+
|
|
618
|
+
What a button makes is the html's root, marked the way you mark your own elements - `data-ge-element`, and `data-ge-label` with the label unless the html has one - so `getHtml` gives it back as you would have written it. Html with more than one root, or none, is wrapped in a `div`. A `<script>` in html given as a string does not run. A type with no `type` or no `html` is left off the toolbar, and one whose function throws or gives nothing adds nothing; both with a warning in the console, as is a type whose markup does not match your `elements.selector`.
|
|
619
|
+
|
|
620
|
+
```javascript
|
|
621
|
+
new GridEditor('#myGrid', {
|
|
622
|
+
elements: {
|
|
623
|
+
types: [
|
|
624
|
+
{ type: 'quote', label: 'Pull quote', iconClass: 'bi bi-quote',
|
|
625
|
+
html: '<blockquote class="my-quote"><p>Quote</p></blockquote>' },
|
|
626
|
+
{ type: 'figure', labelKey: 'element.figure', group: 'media',
|
|
627
|
+
html: function() { return '<figure id="fig-' + Date.now() + '"><img src="…"></figure>'; } },
|
|
628
|
+
],
|
|
595
629
|
},
|
|
596
630
|
});
|
|
597
631
|
```
|
|
@@ -791,6 +825,72 @@ A paste is an add like any other: `before-add-*` and `after-add-*` with
|
|
|
791
825
|
`source: 'paste'`, and canceling the first turns it away. A copy fires
|
|
792
826
|
`grideditor:after-copy`.
|
|
793
827
|
|
|
828
|
+
### Autosave
|
|
829
|
+
|
|
830
|
+
A plugin:
|
|
831
|
+
|
|
832
|
+
```html
|
|
833
|
+
<script src="grid-editor/dist/plugins/grideditor.autosave.min.js"></script>
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
What is being edited is kept in the browser's storage as it changes: a second
|
|
837
|
+
after the last change, and when the page is left or reloaded. It is read with
|
|
838
|
+
`getHtml({ keepEditing: true })`, so a text being typed into stays open, with
|
|
839
|
+
its cursor. When an editor starts and a draft of the same html is saved, the
|
|
840
|
+
editor's confirm modal asks whether to restore it; *Discard*, or closing the
|
|
841
|
+
modal, takes the draft away.
|
|
842
|
+
|
|
843
|
+
```javascript
|
|
844
|
+
new GridEditor('#myGrid', {
|
|
845
|
+
autosave: {
|
|
846
|
+
enabled: true, // saving from the start; the methods turn it on and off
|
|
847
|
+
storage: 'local', // or 'session'
|
|
848
|
+
key: null, // where the draft is kept: one per document, see below
|
|
849
|
+
delay: 1000, // milliseconds after the last change
|
|
850
|
+
maxAge: null, // milliseconds a draft is offered for; null for ever
|
|
851
|
+
},
|
|
852
|
+
});
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
A draft remembers the html its editor started from, and is only offered to an
|
|
856
|
+
editor that starts from the same html. A page that loads one document after
|
|
857
|
+
another into the editor is not offered one document's draft over another, but
|
|
858
|
+
with one key, editing the second overwrites the first's draft. Give each
|
|
859
|
+
document a key of its own - its file name, its id - and each keeps its draft:
|
|
860
|
+
|
|
861
|
+
```javascript
|
|
862
|
+
new GridEditor('#myGrid', { autosave: { key: 'page-' + pageId } });
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
The default key is `grideditor.autosave:` with the page's path and the canvas's
|
|
866
|
+
id. Two editors on a page with the same key would overwrite each other's
|
|
867
|
+
drafts, so the second saves nothing and says so in the console.
|
|
868
|
+
|
|
869
|
+
| Method | Returns | What it does |
|
|
870
|
+
| --- | --- | --- |
|
|
871
|
+
| `enableAutosave()` | `Boolean` | Starts saving, from what there is now |
|
|
872
|
+
| `disableAutosave()` | `Boolean` | Stops saving; the draft is kept |
|
|
873
|
+
| `saveDraft()` | `Boolean` | Saves now, if the html changed, even when disabled; `true` when it wrote |
|
|
874
|
+
| `getDraft()` | `Object` | `{ html, savedAt }`, or `null` |
|
|
875
|
+
| `clearDraft()` | `Boolean` | Takes the draft away, as a page does once it has saved to its server |
|
|
876
|
+
|
|
877
|
+
The methods are there only when the plugin is loaded, and answer `false` or
|
|
878
|
+
`null` when the browser gives the page no storage - a private window may not -
|
|
879
|
+
in which case nothing is saved and the console says so.
|
|
880
|
+
|
|
881
|
+
| Event | Payload | Fires |
|
|
882
|
+
| --- | --- | --- |
|
|
883
|
+
| `grideditor:after-autosave` | `canvas`, `html`, `savedAt`, `source` (`change`, `pagehide`, `api` or `destroy`) | after a draft is written |
|
|
884
|
+
| `grideditor:after-restore-draft` | `canvas`, `html`, `savedAt` | after the user chose to restore one |
|
|
885
|
+
| `grideditor:autosave-error` | `canvas`, `error` | when the storage refused a draft - it is full; the next change tries again |
|
|
886
|
+
|
|
887
|
+
A draft in `localStorage` outlives the browser being closed, on a computer
|
|
888
|
+
someone else may use next: `storage: 'session'` keeps it for the tab only. A
|
|
889
|
+
draft is offered only to an editor that starts from the same html *as this
|
|
890
|
+
version of grid-editor reads it*, so one saved before an upgrade that changes
|
|
891
|
+
what `getHtml` gives is not offered after it. Drafts are a safety net, not a
|
|
892
|
+
place to keep work.
|
|
893
|
+
|
|
794
894
|
### Containers
|
|
795
895
|
|
|
796
896
|
Tabs, accordions, popups and cards. A tabs, accordion or popup container holds
|