@themarioga/grid-editor 3.1.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.
Files changed (52) hide show
  1. package/AUTO_SAVE.md +30 -0
  2. package/BUILDING.md +68 -0
  3. package/CHANGELOG.md +362 -0
  4. package/LICENSE +23 -0
  5. package/README.md +521 -0
  6. package/UPGRADING.md +88 -0
  7. package/dist/grideditor.css +3875 -0
  8. package/dist/grideditor.min.css +2 -0
  9. package/dist/grideditor.min.css.map +1 -0
  10. package/dist/jquery.grideditor.js +2996 -0
  11. package/dist/jquery.grideditor.min.js +2 -0
  12. package/dist/jquery.grideditor.min.js.map +1 -0
  13. package/dist/locales/grideditor.es.js +74 -0
  14. package/dist/locales/grideditor.es.min.js +2 -0
  15. package/dist/locales/grideditor.es.min.js.map +1 -0
  16. package/dist/plugins/grideditor.accordion.js +185 -0
  17. package/dist/plugins/grideditor.accordion.min.js +2 -0
  18. package/dist/plugins/grideditor.accordion.min.js.map +1 -0
  19. package/dist/plugins/grideditor.elements.js +141 -0
  20. package/dist/plugins/grideditor.elements.min.js +2 -0
  21. package/dist/plugins/grideditor.elements.min.js.map +1 -0
  22. package/dist/plugins/grideditor.popup.js +143 -0
  23. package/dist/plugins/grideditor.popup.min.js +2 -0
  24. package/dist/plugins/grideditor.popup.min.js.map +1 -0
  25. package/dist/plugins/grideditor.tabs.js +140 -0
  26. package/dist/plugins/grideditor.tabs.min.js +2 -0
  27. package/dist/plugins/grideditor.tabs.min.js.map +1 -0
  28. package/docs/events.md +158 -0
  29. package/docs/locale-keys.md +140 -0
  30. package/docs/plugins.md +163 -0
  31. package/example/autosave.html +89 -0
  32. package/example/basic.html +93 -0
  33. package/example/breakpoints.html +94 -0
  34. package/example/ckeditor.html +104 -0
  35. package/example/containers.html +214 -0
  36. package/example/elements.html +147 -0
  37. package/example/index.html +119 -0
  38. package/example/locale.html +84 -0
  39. package/example/plugins.html +217 -0
  40. package/example/summernote.html +106 -0
  41. package/example/wrap_content.html +44 -0
  42. package/package.json +66 -0
  43. package/src/js/jquery.grideditor.ckeditor.js +77 -0
  44. package/src/js/jquery.grideditor.js +2711 -0
  45. package/src/js/jquery.grideditor.summernote.js +72 -0
  46. package/src/js/jquery.grideditor.tinymce.js +135 -0
  47. package/src/js/locales/grideditor.es.js +74 -0
  48. package/src/js/plugins/grideditor.accordion.js +185 -0
  49. package/src/js/plugins/grideditor.elements.js +141 -0
  50. package/src/js/plugins/grideditor.popup.js +143 -0
  51. package/src/js/plugins/grideditor.tabs.js +140 -0
  52. package/src/less/grideditor.less +594 -0
package/AUTO_SAVE.md ADDED
@@ -0,0 +1,30 @@
1
+ ## Auto save and layout import/export
2
+
3
+ The `example/autosave.html` demo shows how to add **auto save** and
4
+ **import/export** on top of Grid Editor, using only the plugin's existing
5
+ public API (`gridEditor('getHtml')` and `gridEditor('remove')`).
6
+
7
+ ### Features
8
+
9
+ - **Auto save**
10
+ Saves the layout to `localStorage` every 5 seconds, so work is not lost on
11
+ an accidental refresh. The saved draft is restored on page load.
12
+
13
+ - **Import a saved layout**
14
+ Load a previously exported `.html` file back into the editor.
15
+
16
+ - **Export HTML**
17
+ Download the edited layout as an HTML file for saving or sharing.
18
+
19
+ - **Clear draft**
20
+ Remove the stored layout from `localStorage` and start over.
21
+
22
+ ### Demo
23
+
24
+ Build the `dist/` files first, then open the example:
25
+
26
+ ```bash
27
+ npm install
28
+ npm run build
29
+ open example/autosave.html
30
+ ```
package/BUILDING.md ADDED
@@ -0,0 +1,68 @@
1
+ How to build grid-editor
2
+ ========================
3
+
4
+ Do NOT make changes to the files in the `dist` directory.
5
+
6
+ Instead, update the files in the `src` directory. Then install the dependencies:
7
+
8
+ * `npm install`
9
+
10
+ From then on out, you can build the files in the `dist` directory by running:
11
+
12
+ * `npm run build`
13
+
14
+ During development, you can also run `npm run watch` to automatically rebuild on changes.
15
+
16
+ The build emits the plugin as `dist/jquery.grideditor.js`, the stylesheet as
17
+ `dist/grideditor.css`, each with a minified twin and a source map beside it,
18
+ and the files in `src/js/locales/` and `src/js/plugins/` one by one under
19
+ `dist/locales/` and `dist/plugins/`. Neither of those two directories is part
20
+ of the main bundle: the `src/js/*.js` glob does not descend, so a page loads
21
+ the languages and the container plugins it actually wants. See
22
+ [docs/plugins.md](docs/plugins.md) for what a container plugin is. Locale files are
23
+ deliberately not part of the main bundle: a page loads only the languages it
24
+ offers. English is the exception and lives in the bundle, because it is the
25
+ fallback every string lookup ends at. See `docs/locale-keys.md` for the keys,
26
+ and `src/js/locales/grideditor.es.js` for what a locale file looks like.
27
+
28
+ Running the tests
29
+ =================
30
+
31
+ The tests drive real pages in a real Chrome over the DevTools protocol, so they
32
+ need Chrome or Chromium installed. They test the files in the `dist` directory,
33
+ so build first:
34
+
35
+ * `npm run build`
36
+ * `npm test`
37
+
38
+ There is nothing extra to install: the tests use node and Chrome, and start
39
+ their own web server. `npm test` runs every suite in `test/` in one Chrome and
40
+ prints one summary, and exits non-zero if anything failed. To run a single
41
+ suite, pass part of its name:
42
+
43
+ * `npm test -- rte`
44
+
45
+ A suite can also be run on its own with `node test/rte.js`.
46
+
47
+ The fixture pages in `test/fixtures` load jQuery, jQuery UI and Bootstrap from
48
+ `test/vendor` rather than from a CDN, so most of the suite runs offline. The
49
+ rich text editor suite is the exception: it loads tinyMCE, CKEditor and
50
+ Summernote from their CDNs to test against the real editors, and the runner
51
+ skips it, with a reason, when there is no network. `OFFLINE=1 npm test` forces
52
+ that path.
53
+
54
+ Set `CHROME=/path/to/chrome` if your browser is not on the PATH under a name
55
+ the tests look for, `HEADFUL=1` to watch the run in a visible window, or
56
+ `CHROME_LOG=1` to see Chrome's own output. A run leaves a screenshot of the
57
+ editor in `test/screenshots`.
58
+
59
+ See `test/vendor/README.md` for what is vendored and how to refresh it, and the
60
+ comment at the top of `test/run.js` for what a suite looks like.
61
+
62
+ Linting
63
+ =======
64
+
65
+ * `npm run lint`
66
+
67
+ The configuration lives in `eslint.config.js`. Keep it clean: almost every rule
68
+ is a warning, so warnings are the output that matters.
package/CHANGELOG.md ADDED
@@ -0,0 +1,362 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+
8
+ ## [3.1.0] - 2026-09-22
9
+ ### Added
10
+ - A public API, dispatched from a table instead of a chain of string
11
+ comparisons: `init`, `deinit`, `reset`, `destroy`, `changeView`, `getView`,
12
+ `createRow`, `createColumn` and `createElement`, alongside the existing
13
+ `getHtml`. `create*` methods return the node they made, everything else
14
+ returns the jQuery set and chains.
15
+ - `create*` accepts `appendTo`, `prependTo`, `insertAfter` and `insertBefore`.
16
+ Given one, grid-editor places the node and resets the canvas; given none,
17
+ the node comes back detached for the host to place.
18
+ - `element.data('grideditor')` is documented API: the same methods, plus a
19
+ frozen copy of `settings` and the `canvas`.
20
+ - `createContainer`, `addTab`, `addAccordionItem` and `setLocale` are
21
+ registered but not implemented yet: calling one warns and returns `null`
22
+ rather than doing nothing silently.
23
+ - Host callbacks. Every operation is announced twice: as a jQuery event on the
24
+ canvas - the specific name, then the generic one - and as the matching
25
+ `settings.callbacks` entry. `grideditor:before-add-row`,
26
+ `-column`, `-element` and their `after-` counterparts, the generic
27
+ `grideditor:before-add`/`after-add`, plus `before-delete`/`after-delete`,
28
+ `before-move`/`after-move` and `before-resize`/`after-resize`. Every payload
29
+ carries `kind`, `node`, `parent`, `canvas`, `breakpoint` and `source`
30
+ (`tool`, `api` or `dragdrop`); a move adds `from`/`to` positions and a
31
+ resize the sizes it moved between.
32
+ - Canceling. `preventDefault()` on either event, or `false` from the callback,
33
+ cancels a `before-*`: nothing is inserted, deleted or resized, no `after-*`
34
+ fires, and a canceled `create*` returns `null`. A canceled move is put back
35
+ with jQuery UI's own `cancel`, since a drag cannot be refused once it has
36
+ started.
37
+ - A re-entrancy queue: `init`, `reset` and the `create*` methods called from
38
+ inside a handler run when the operation that called them has finished,
39
+ instead of rebuilding the canvas underneath it.
40
+ - `callbacks`, `confirm_delete` and `sortable_options` settings.
41
+ - Translatable UI strings. Every user-visible string - the tool tooltips, the
42
+ add-row buttons, the layout mode dropdown, the settings panel, the delete
43
+ confirms and the "editor not available" console errors - now comes from
44
+ `t(key)`, with `{name}` interpolation. Lookup order is `locale_strings`, the
45
+ selected locale, English, then the key itself, which is shown and logged
46
+ once rather than leaving an empty tooltip.
47
+ - `$.fn.gridEditor.locales`, with `locales.en` built into the main bundle as
48
+ the fallback, and `$.fn.gridEditor.t(settings, key)` for editor
49
+ integrations. `locale` and `locale_strings` settings, and a `setLocale`
50
+ method that re-renders the controls.
51
+ - A Spanish locale, `dist/locales/grideditor.es.js`, built from
52
+ `src/js/locales/grideditor.es.js`. It translates every key in `locales.en`,
53
+ which `test/locales.js` asserts, so a change that adds a string adds its
54
+ Spanish in the same commit.
55
+ - `docs/locale-keys.md`: the key catalogue, hand-written, with
56
+ `test/locales.js` holding it to the source in both directions.
57
+ - `example/locale.html`: an example page with a language dropdown calling
58
+ `setLocale`.
59
+ - The settings panel is on every drawer: a container, a tab, an accordion item
60
+ and an element have the same id and class fields as a row and a column, with
61
+ `container_classes`, `pane_classes` and `element_classes` for preset toggles.
62
+ - The settings panel on a row or a column has a css class field beside the id
63
+ one, so classes can be set at all rather than only toggled from a list the
64
+ host configured. It shows the host's own classes and leaves the grid's and
65
+ the editor's alone, and an emptied id field takes the id away rather than
66
+ leaving an empty one.
67
+ - The stylesheet is minified too: `dist/grideditor.min.css`, with a source map,
68
+ built and watched alongside the readable one. The task existed and was never
69
+ run.
70
+ - The build copies and minifies each `src/js/locales/*.js` into `dist/locales/`
71
+ individually, with a watch target of its own. The main bundle is unchanged:
72
+ the `src/js/*.js` glob does not descend.
73
+ - `ge-settings`, `ge-delete-row` and `ge-delete-column` classes on the tools
74
+ that had none, so hosts and tests can find them without matching a tooltip
75
+ that is now translated.
76
+ - All six Bootstrap 5 breakpoints, plus an `all` view that writes every one of
77
+ them at once and is the new default. `changeView` takes a key (`xs`…`xxl` or
78
+ `all`), `getView` returns it, `layout_modes` says which the dropdown offers
79
+ and `default_view` says where the editor starts. The canvas gets
80
+ `ge-layout-<key>`, which constrains it to that tier's width and makes that
81
+ tier's classes the effective ones whatever the window is doing.
82
+ - Column offsets: two indent tools per column, `valid_col_offsets`, and
83
+ `createColumn(size, { offset: n })`. Offsets are visualized in every layout
84
+ mode, and shift-click takes a column to the row's edge or back to none.
85
+ - A sizing core that owns every size and offset class the editor reads or
86
+ writes, with one 12 unit budget for all of them. Its getters answer for the
87
+ tier they were asked about, and follow Bootstrap's own cascade downward when
88
+ a tier says nothing, rather than returning the first value they happen to
89
+ find.
90
+ - `before-indent` and `after-indent`, so the indent tools are not a silent
91
+ operation. They carry the same payload as the resize pair, with `from` and
92
+ `to` as offsets.
93
+ - `example/breakpoints.html`, showing the six tiers and the all view.
94
+ - Element level controls, the level below a column. A node inside a content
95
+ area that the host marks with `data-ge-element` becomes an element: one
96
+ movable, deletable thing rather than rich text. Each gets a drawer with
97
+ move, an info tool named from `data-ge-element`/`data-ge-label`, the host's
98
+ own `element_tools`, and delete. Elements sort within a content area and
99
+ between content areas, and their events carry `kind: 'element'`.
100
+ - The `elements` setting: `selector` (default `[data-ge-element]`), `auto`
101
+ (default `false`, treats every child of a content area as an element, for a
102
+ page that configures no rich text editor) and `enabled` (default `'auto'`,
103
+ which turns the feature on when the page has any elements).
104
+ - Elements inside a content area get `contenteditable="false"` while editing,
105
+ so a rich text editor treats them as atomic rather than as text to rewrite.
106
+ Checked against a real tinyMCE, not assumed.
107
+ - `example/elements.html`, including the pattern for an element with no visual
108
+ output of its own: the host supplies a placeholder and its own tools, which
109
+ is all spec 4.4 asks for.
110
+ - The element level controls are a plugin too,
111
+ `dist/plugins/grideditor.elements.js`, registered under
112
+ `$.fn.gridEditor.features`: a feature plugin hooks into the canvas rather
113
+ than building a container type, and may contribute methods - `createElement`
114
+ says so and returns null when the plugin is not loaded.
115
+ - Container plugins. Tabs, accordions and popups are not in the main bundle:
116
+ each is a file under `dist/plugins/`, and loading it is what makes the type
117
+ available, the way loading a locale file adds a language. A page takes the
118
+ ones it offers, the toolbar shows a button per loaded plugin, and the
119
+ `plugins` setting narrows that when a page loads more than it wants to show.
120
+ A container in the markup whose plugin is not loaded is left alone and comes
121
+ back out of `getHtml` untouched. `$.fn.gridEditor.containers` is the
122
+ registry, and [docs/plugins.md](docs/plugins.md) is the contract: what a
123
+ plugin returns, and the handle it gets to work through.
124
+ - Containers: tabs, accordions and popups. A container is marked with
125
+ `data-ge-container` and holds panes, and every pane is an ordinary canvas
126
+ region, so rows, columns, content areas and elements nest inside one exactly
127
+ as they do at the top level. Containers nest too. Each gets a drawer with
128
+ move, add pane, delete and the host's `container_tools`; panes get their own
129
+ drawer, their own `tab_tools`/`accordion_tools`, and a label edited in place.
130
+ The toolbar offers one button per type, listed in the `containers` setting.
131
+ - `createContainer(type, options)`, `addTab(container, options)` and
132
+ `addAccordionItem(container, options)`, which complete the method table.
133
+ Every container and pane operation goes through the add, delete and move
134
+ events, with `kind` naming the type: `tabs`, `accordion`, `popup`, `tab`,
135
+ `accordion-item`.
136
+ - Tabs: a sortable strip whose panes follow their tabs, so the output reads in
137
+ tab order.
138
+ - Accordions: `stay_open`, items that open and close from their headers while
139
+ editing - with the state kept in `data-ge-open`, so what is left open on the
140
+ canvas is what the authored page opens with - and items that drag into any
141
+ other accordion on the canvas, taking that accordion's `data-bs-parent` and
142
+ its idea of whether several items may be open. The editor answers the click
143
+ itself; Bootstrap's collapse is never asked to run over the canvas.
144
+ - Popups: a Bootstrap modal plus its trigger, rendered unfolded and static
145
+ while editing so its body is an ordinary region - no backdrop, no focus trap,
146
+ no `bootstrap.Modal` instantiated. The drawer folds it away. Any node the
147
+ host marks with `data-ge-popup-target` is a trigger: grid-editor leaves the
148
+ markup alone and writes Bootstrap's attributes onto it at `getHtml` time. A
149
+ trigger whose popup is gone is re-pointed when exactly one popup is left in
150
+ its column, and otherwise marked `.ge-popup-orphan` and reported through
151
+ `grideditor:popup-orphan`. It is never deleted.
152
+ - `example/containers.html`, with all three types, a host trigger, two levels
153
+ of nesting, and a button that opens the exported html as a real page with
154
+ Bootstrap and no grid-editor.
155
+ - Resizing a column by dragging its edge. jQuery UI `resizable` on every
156
+ column, east handle by default, with `resize.enabled`, `resize.handles`,
157
+ `resize.balance` and `resizable_options` to steer it. The column follows the
158
+ pointer in pixels, its drawer shows the class it would land on, and on drop
159
+ the pixels are snapped to whole units with `round(width / rowWidth * 12)`,
160
+ clamped by the same budget the tools obey. `resize.balance: 'next'` takes
161
+ the units out of the following column so a full row stays full; `false`
162
+ leaves the row to wrap. The resize handle is on the column's edge and the
163
+ sort handle is the drawer, so the two gestures never share a pixel.
164
+ - A test runner, `test/run.js`, behind `npm test`. It shares one Chrome and one
165
+ web server across every suite in `test/`, prints one summary and exits
166
+ non-zero on any failure. `npm test -- rte` runs a single suite, and
167
+ `node test/rte.js` still works on its own.
168
+ - Vendored test dependencies under `test/vendor` (jQuery, jQuery UI, Bootstrap
169
+ and bootstrap-icons), and a base fixture page in `test/fixtures` that loads
170
+ them, so the suite runs with the network switched off. The rich text editor
171
+ suite keeps loading the editors from their CDNs and is skipped, with a
172
+ reason, when there is no network.
173
+ - `npm run lint`, on a flat `eslint.config.js` for eslint 9, with eslint pinned
174
+ in devDependencies. The old `.eslintrc` named `babel-eslint` and
175
+ pre-flat-config rule names, so it had stopped running on a current eslint.
176
+
177
+ ### Changed
178
+ - The example pages are named after what they show: the tinyMCE demo that was
179
+ `example/index.html` is `example/basic.html`, and `example/index-autosave.html`
180
+ is `example/autosave.html`. `example/index.html` is now an index of the demos,
181
+ so opening `example/` lands on a list rather than on one of them.
182
+ - `$(el).gridEditor('remove')` returns the jQuery object instead of
183
+ `undefined`, so it chains like the other methods.
184
+ - A method called on an element with no editor on it is a no-op that returns
185
+ the set, instead of doing nothing in some cases and throwing in others.
186
+ `getHtml` still reads the element's html.
187
+ - An unknown method name warns once and returns the set.
188
+ - The layout modes come from one table, which `changeView`, `getView`, the
189
+ column classes and the mode dropdown all read. Clicking the dropdown now
190
+ goes through `changeView`.
191
+
192
+ - Deleting asks in a Bootstrap modal rather than `window.confirm`: it is
193
+ styled like the rest of the page, it is translated with everything else, and
194
+ it does not block the page while it is up. The editor builds it outside the
195
+ canvas, so it is never part of `getHtml`, and a page that loaded Bootstrap's
196
+ css but not its javascript still gets asked by the browser.
197
+ - Deleting a row or a column goes through `before-delete`, then the question,
198
+ then `after-delete` once the animation has finished. The host's handler runs
199
+ first on purpose: a host that cancels to show its own dialog never wants the
200
+ built-in confirm to have appeared already. `confirm_delete: false` skips the
201
+ built-in one.
202
+ - `after-resize` fires once the column class has actually been written, rather
203
+ than while jQuery UI is still animating the class swap.
204
+ - A drag that ends where it started is not reported as a move, and dragging a
205
+ content area reports `kind: 'content'`.
206
+ - Adding a node brings the canvas up to date with `init()` rather than a full
207
+ `deinit`/`init`, so inserting a row somewhere else no longer closes the rich
208
+ text editor the user is typing in.
209
+
210
+ - The layout mode dropdown is built from the layout mode table rather than
211
+ from a markup string, which also restores the closing tag the Tablet item
212
+ had been missing.
213
+
214
+ - **BREAKING:** the layout mode classes on the canvas are `ge-layout-xs`
215
+ through `ge-layout-xxl` and `ge-layout-all`, replacing `ge-layout-desktop`,
216
+ `ge-layout-tablet` and `ge-layout-phone`.
217
+ - **BREAKING:** `addAllColClasses` is conservative now. A column that carries
218
+ any size class is left exactly as authored, instead of being seeded with one
219
+ class per tier; a column with no sizing at all gets a single `col-12`, which
220
+ applies at every tier. With six tiers the old behaviour would have put six
221
+ classes on every column.
222
+ - `toolbar_drag`, which makes the toolbar a palette: a button dragged onto the
223
+ canvas creates its row or container where it is dropped, with a line showing
224
+ where that will be and the canvas opening up so the gaps between rows are
225
+ something a pointer can hit. A container dropped straight onto the canvas
226
+ brings the row and column it needs; dropped into a column it goes straight
227
+ in. `'auto'`, the default, follows `drag_handle: 'drawer'`.
228
+ - `drag_handle`, which says what a drag starts from: the move tool as before,
229
+ or the whole tools drawer, in which case the move tool is not rendered at
230
+ all. The other tools in a draggable drawer keep answering to a click, and a
231
+ drag starting on one is not a move.
232
+ - Holding the add column tool offers the column widths instead of taking the
233
+ default one: the sizes in `valid_col_sizes`, with the ones that no longer fit
234
+ the row marked. It answers to a held finger as well as a hovering pointer,
235
+ and the tooltip says so, because a gesture nobody can see is a gesture nobody
236
+ finds. `add_column: { size, picker, delay }` configures it, and a click now
237
+ adds a full width column rather than a three unit one.
238
+ - The add row tool in a column's drawer adds an empty row. It used to add one
239
+ with two half width columns in it, which is a layout decision the tool has no
240
+ business making: the new row's own drawer is where columns are added.
241
+ - The size a tool starts from is the one that applies at the tier being
242
+ edited, following the cascade: in the all view that is the widest tier,
243
+ which is what the unconstrained canvas is showing.
244
+ - Growing a column is refused when its indent leaves no room, rather than
245
+ silently rewriting the indent. Growing an indent shrinks the column, because
246
+ the indent is the thing the user just asked for.
247
+ - Size changes are written directly and animated by the stylesheet, rather
248
+ than through jQuery UI's `switchClass`, so `after-resize` fires with the
249
+ class already on the column.
250
+ - `getHtml` strips inline pixel widths, so a drag-resized column exports as
251
+ its class and nothing else.
252
+ - The layout mode LESS is list-driven over the breakpoint table instead of
253
+ taking exactly four tier arguments, and covers offsets as well as columns.
254
+ A preview reproduces Bootstrap's cascade rather than showing one tier in
255
+ isolation: a column carrying only `col-4` is four units wide in the `sm`
256
+ preview too, and `col-sm-6` overrides it. The 2.x code switched every other
257
+ tier off, which only worked because every column was seeded with a class per
258
+ tier.
259
+
260
+ - A canceled `before-resize` on a drag is refused on every step of the drag
261
+ rather than before it starts: jQuery UI's `resizable` ignores `false` from
262
+ its start handler, unlike its `draggable`. Nothing is written either way.
263
+ - `getHtml` output no longer carries an empty `style` attribute where an
264
+ inline width was stripped.
265
+
266
+ - Settings that are objects of grid-editor's own keys - `elements` and
267
+ `resize` - are merged with their defaults rather than replaced, so naming
268
+ one key no longer silently drops the others.
269
+ - The tinyMCE integration passes `promotion: false`, so the editor's "Upgrade"
270
+ badge stays out of the menubar of an inline editor sitting in someone's
271
+ page. A host that wants it passes `promotion: true` in its own config.
272
+ - The rich text editor integrations fire `ge-rte-ready` on the content area
273
+ once their editor is up. An editor rewrites what is inside the content area
274
+ as it takes over, which costs the element drawers in it; this is how they
275
+ are put back.
276
+
277
+ - While editing, a Bootstrap toggle the editor needs to keep quiet is moved
278
+ aside - `data-bs-toggle` becomes `data-ge-bs-toggle` - rather than fought
279
+ with. Bootstrap binds its data-api handlers on the document in the capture
280
+ phase, so a listener on the node itself cannot stop one.
281
+ - `wrapContent` no longer wraps the editor's own furniture. jQuery UI's resize
282
+ handle was being treated as loose content and wrapped into a content area of
283
+ its own on the next `init`, so a canvas collected an empty content area per
284
+ column per reset. It also leaves containers alone, since a container sits in
285
+ the column beside the content areas rather than inside one.
286
+ - The instance handle is in place before the first `init` runs, so a host
287
+ handler that fires during initialization can already reach the editor.
288
+
289
+ - **BREAKING:** the `containers` setting is `plugins`, and it names the
290
+ container plugins to use rather than a fixed list of built in types. It
291
+ defaults to every plugin the page loaded.
292
+ - **BREAKING:** `row_classes` and `col_classes` default to `[]`. They used to
293
+ default to a single `Example class` toggle, which shipped a placeholder into
294
+ every host's interface.
295
+
296
+ ### Deprecated
297
+ - `remove`, in favour of `destroy`, which does the same thing. `remove` still
298
+ works and warns once per instance.
299
+
300
+ ### Fixed
301
+ - Calling `deinit` twice threw from jQuery UI, which `reset` could reach now
302
+ that both are public methods.
303
+
304
+ ## [2.0.0] - 2026-09-21
305
+ ### Changed
306
+ - **BREAKING:** Migrate from Bootstrap 4 to Bootstrap 5. The layout mode
307
+ dropdown now uses `data-bs-toggle`, so consumers must load Bootstrap 5.
308
+ - **BREAKING:** Replace Font Awesome with Bootstrap Icons. Consumers must load
309
+ bootstrap-icons instead of Font Awesome. The default `iconClass` for custom
310
+ `row_tools` and `col_tools` is now `bi bi-wrench`.
311
+ Based on work by [@vahidalvandi](https://github.com/vahidalvandi).
312
+ - **BREAKING:** The tinyMCE integration now targets tinyMCE 6 and no longer
313
+ uses the `jquery.tinymce.js` plugin, which tinyMCE dropped after 5.x. Pages
314
+ using `content_types: ['tinymce']` must load tinyMCE 6 and must stop loading
315
+ the jQuery integration plugin. A `tinymce.config.oninit` callback still
316
+ works, and `init_instance_callback` is now honoured too.
317
+
318
+ ### Added
319
+ - Browser tests for the rich text editor integrations, run with `npm test`.
320
+ They drive the example pages in a real Chrome over the DevTools protocol,
321
+ against the real editors, since what breaks in these integrations only
322
+ happens in a browser. They need node and Chrome, and nothing else: see
323
+ BUILDING.md.
324
+ - `example/index-autosave.html`, demonstrating auto save to localStorage plus
325
+ layout import/export, by [@Ka-Bar](https://github.com/Ka-Bar).
326
+ - Example dependencies updated to current releases: jQuery 4.0.0, jQuery UI
327
+ 1.14.2, Bootstrap 5.3.8, Bootstrap Icons 1.13.1, summernote 0.9.1,
328
+ CKEditor 4.22.1 and TinyMCE 6.8.6. CKEditor stops short of the latest
329
+ release on purpose: 4.22.1 is the last under the GPL/LGPL/MPL triple
330
+ licence, as 4.23.0 and above are CKEditor 4 LTS under the commercial
331
+ Extended Support Model. TinyMCE stops at 6.8.6 because it is the last MIT
332
+ licensed release; 7.x is GPL-2.0-or-later and 8.x is commercial.
333
+
334
+ ### Fixed
335
+ - Clear `ge-rte-active` after the rich text editor has been torn down rather
336
+ than before. An inline editor may restore the class attribute it snapshotted
337
+ when it was created, as tinyMCE does, which put the class straight back and
338
+ made `initRTE` ignore every later click: no content area could be edited
339
+ again after a single `getHtml()` or `remove()`. The tinyMCE integration now
340
+ also cleans up after the late removal it can perform from
341
+ `init_instance_callback`, which used to leave `active` behind and arm a
342
+ pending-remove flag that destroyed the next editor created on that content
343
+ area. This affected the pre-6 integration too.
344
+ - Guard the rich text editor lookup. A `content_types` entry with no matching
345
+ registered editor, or an empty `content_types`, made `getHtml`, `remove`,
346
+ add row and add column throw on an undefined editor. They now no-op for that
347
+ content area, matching how `initRTE` already behaved.
348
+
349
+ ## [1.0.8]
350
+ - Fix for moving rows in columns #117
351
+
352
+ ## [1.0.3] - 2019-05-18
353
+ ### Added
354
+ - Support for fontawesome 4 and 5
355
+
356
+ ## [1.0.2] - 2019-05-18
357
+ ### Added
358
+ - npm scripts for calling grunt
359
+
360
+ ### Changed
361
+ - Migrate from glyphicon to fontawesome #98 by [@Nuranto](https://github.com/Nuranto)
362
+ - Wrap source_html content if neccessary. #101 by [@Nuranto](https://github.com/Nuranto)
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Frontwise / Friendly-Pixel
4
+ Copyright (c) 2026 Mario Gonzalez
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+