@themarioga/grid-editor 6.0.0-beta.3 → 6.0.0-beta.4

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 (41) hide show
  1. package/BUILDING.md +3 -1
  2. package/CHANGELOG.md +50 -1
  3. package/README.md +16 -5
  4. package/UPGRADING.md +36 -7
  5. package/dist/grideditor.css +14 -0
  6. package/dist/grideditor.min.css +1 -1
  7. package/dist/grideditor.min.css.map +1 -1
  8. package/dist/jquery.grideditor.bundle.min.js +2 -2
  9. package/dist/jquery.grideditor.js +303 -385
  10. package/dist/jquery.grideditor.min.js +1 -1
  11. package/dist/jquery.grideditor.min.js.map +1 -1
  12. package/dist/locales/grideditor.es.js +3 -0
  13. package/dist/locales/grideditor.es.min.js +1 -1
  14. package/dist/locales/grideditor.es.min.js.map +1 -1
  15. package/dist/plugins/grideditor.ckeditor.js +397 -3
  16. package/dist/plugins/grideditor.ckeditor.min.js +1 -1
  17. package/dist/plugins/grideditor.ckeditor.min.js.map +1 -1
  18. package/dist/plugins/grideditor.summernote.js +397 -3
  19. package/dist/plugins/grideditor.summernote.min.js +1 -1
  20. package/dist/plugins/grideditor.summernote.min.js.map +1 -1
  21. package/dist/plugins/grideditor.tinymce.js +397 -3
  22. package/dist/plugins/grideditor.tinymce.min.js +1 -1
  23. package/dist/plugins/grideditor.tinymce.min.js.map +1 -1
  24. package/dist/plugins/grideditor.visibility.js +1 -1
  25. package/dist/plugins/grideditor.visibility.min.js +1 -1
  26. package/dist/plugins/grideditor.visibility.min.js.map +1 -1
  27. package/docs/events.md +11 -2
  28. package/docs/locale-keys.md +12 -3
  29. package/docs/plugins.md +109 -46
  30. package/example/custom_editor.html +193 -0
  31. package/example/index.html +8 -0
  32. package/example/wrap_content.html +5 -3
  33. package/package.json +1 -1
  34. package/src/js/jquery.grideditor.js +303 -385
  35. package/src/js/locales/grideditor.es.js +3 -0
  36. package/src/js/plugins/grideditor.ckeditor.js +7 -3
  37. package/src/js/plugins/grideditor.summernote.js +7 -3
  38. package/src/js/plugins/grideditor.tinymce.js +7 -3
  39. package/src/js/plugins/grideditor.visibility.js +1 -1
  40. package/src/js/text/grideditor.text.js +389 -0
  41. package/src/less/grideditor.less +17 -0
package/docs/plugins.md CHANGED
@@ -14,15 +14,18 @@ the one to read first if you are about to write your own.
14
14
  <script src="dist/plugins/grideditor.elements.min.js"></script>
15
15
  ```
16
16
 
17
- There are four kinds. A **container plugin** builds a type of container — it
17
+ There are three kinds. A **container plugin** builds a type of container — it
18
18
  registers under `$.fn.gridEditor.containers`, and the toolbar offers a button
19
19
  for it. A **utility plugin** declares families of Bootstrap's responsive
20
20
  utility classes — `$.fn.gridEditor.utilities` — and the editor edits them per
21
- breakpoint. A **text editor plugin** edits content areas with a rich text
22
- editor — `$.fn.gridEditor.texts`, one per editor: tinyMCE, CKEditor,
23
- summernote. A **feature plugin** is anything else the editor can do —
21
+ breakpoint. A **feature plugin** is anything else the editor can do —
24
22
  `$.fn.gridEditor.features`, hooks into the canvas, and may contribute methods.
25
- All four are factories called once per editor with the same handle.
23
+ All three are factories called once per editor with the same handle.
24
+
25
+ Text is a feature plugin too. The core knows the grid and the host's *plain
26
+ content* - the markup it found that is not the grid's - and nothing of text:
27
+ the text editors, tinyMCE, CKEditor and summernote, are plugins, and so is an
28
+ editor a host writes itself. See [Text](#text).
26
29
 
27
30
  The `plugins` setting names which of the loaded ones to use:
28
31
 
@@ -60,6 +63,7 @@ $.fn.gridEditor.containers.carousel = function(ge) {
60
63
 
61
64
  return {
62
65
  labelKey: 'container.add_carousel', // the toolbar button's label
66
+ iconClass: 'bi bi-images', // optional: the button shows it in place of the label
63
67
  addPaneKey: 'container.add_slide', // the drawer's add pane tool
64
68
  paneKind: 'slide', // the kind its panes report
65
69
 
@@ -77,6 +81,9 @@ $.fn.gridEditor.containers.carousel = function(ge) {
77
81
  })(jQuery);
78
82
  ```
79
83
 
84
+ - **`iconClass`**, when given, is the toolbar button's face: the icon alone,
85
+ with the label as its title. Without one the button shows a plus and the
86
+ label.
80
87
  - **`create(options)`** returns a detached container. It must carry
81
88
  `data-ge-container="<type>"`: that attribute, and never a class, is how the
82
89
  editor recognises one.
@@ -129,6 +136,9 @@ not change without a major version.
129
136
  | `ge.rowFromLayout(layout)` | A detached row from a layout: `[8, 4]`, `['auto', 'equal']` or `{ row_cols, columns }` |
130
137
  | `ge.drawerOf(node)` | A node's drawer: its first child, or for a content area the one beside it in its text block |
131
138
  | `ge.textReady(block)` | A text editor has rewritten a content area: whatever the editor and its plugins put in there goes back in |
139
+ | `ge.attachPicker(tool, open)` | Hold a tool, or rest the pointer on it, and `open` is called: how a tool offers a choice |
140
+ | `ge.openPicker(anchor, choices, className?)` | The choice itself, as a strip under `anchor`: one button per `{ label, title, attributes, choose }` |
141
+ | `ge.closePicker()` | Close it; true when one was open, which is also a click's answer |
132
142
  | `ge.nodeHtml(node)` | One node's markup as `getHtml` would give it. The canvas leaves editing to read it and comes back, as it does for `getHtml` |
133
143
  | `ge.toolbarItems(name)` | The toolbar buttons the feature plugin `name` declared, for showing and hiding them |
134
144
  | `ge.bareStyle(node, family, property)` | A css property's value on the node with none of the family's classes: what a preview shows when no class applies and that is not a constant |
@@ -150,7 +160,10 @@ $.fn.gridEditor.features.elements = function(ge) {
150
160
  kindOf: function(node) { … }, // what an event calls this node
151
161
  onInit: function() { … }, // every init: put the furniture in
152
162
  onDeinit: function() { … }, // every deinit: take it out again
163
+ onBeforeDeinit: function() { … }, // every deinit, before the drawers come off: close what you opened
153
164
  onContentReady: function(area) { … }, // a rich text editor just took over, or rewrote a text
165
+ textTypes: function() { … }, // the text types this plugin edits, see "Text"
166
+
154
167
  cuts: '[data-my-block]', // what cuts a text: a block of the column, never part of a text
155
168
  onSortable: function(sortable) { … }, // declare your own sortable lists
156
169
  blocks: '.ge-section', // more blocks the canvas and the columns move
@@ -211,10 +224,17 @@ animation for rows, columns, containers and elements, kept in a
211
224
 
212
225
  A node's drawer is built again on every `init`, so a tool reads the node
213
226
  rather than remembering anything about it.
214
- - A **`toolbar`** item can also have an `iconClass`, `bi bi-plus` otherwise,
227
+ - A **`toolbar`** item can also have an `iconClass`, which it shows alone,
228
+ with the label as its title, where one without shows a plus and the label;
215
229
  and a `source` for the add events, `tool` or `dragdrop` otherwise. With
216
230
  `align: 'end'` it goes on the right of the toolbar, beside the source and
217
- preview buttons, as its icon alone, with the label as its title.
231
+ preview buttons, always as an icon - `bi bi-plus` when it has none.
232
+ `label`, a string or a function called whenever the toolbar is built, stands
233
+ in for `labelKey` when the label takes parameters; `className` goes on the
234
+ button. With `inColumn: true` what it makes belongs in a column, as a
235
+ container or a text does: a click puts it in a row and a column of its own
236
+ at the end of the canvas, and a drop anywhere but in a column does the
237
+ same where it was dropped.
218
238
 
219
239
  - **`onSortable(sortable)`** is handed the function the editor makes all of its
220
240
  own lists with. A plugin describes a list; it never touches the drag toolkit
@@ -257,53 +277,96 @@ plugin knows which of its parts move: the tabs plugin makes its strip sortable
257
277
  and puts the panes back in strip order in `afterPaneMove`.
258
278
 
259
279
 
260
- Text editor plugins
261
- -------------------
280
+ Text
281
+ ----
282
+
283
+ ### Plain content
284
+
285
+ What the editor finds in a column that is not the grid's - loose markup, the
286
+ page it was started on before it had a row - it wraps in a content area with
287
+ no type: the host's **plain content**, `<div class="ge-content">`. While
288
+ editing it is a block with a drawer of two tools, move and delete, and no
289
+ gear; it is edited in the source, with the toolbar's code button, and nothing
290
+ in the editor makes a new one. `getHtml` saves it as it is, and it is plain
291
+ content again when the page comes back. Events call it `kind: 'plain'`.
262
292
 
263
- A text editor plugin edits content areas with a rich text editor. It is
264
- registered under the content type it edits - the name `content_types` uses -
265
- and the three that ship, `grideditor.tinymce.js`, `grideditor.ckeditor.js` and
266
- `grideditor.summernote.js`, are the ones to read:
293
+ A text is a content area with a type on it - `data-ge-content-type` and the
294
+ class `ge-content-type-<type>` - and belongs to the plugin that declares the
295
+ type. A text whose type no plugin declares is a block to move and delete, and
296
+ its drawer says no editor for it is loaded.
297
+
298
+ ### textTypes
299
+
300
+ A feature plugin that edits text declares its types, and that is all the
301
+ core asks of it:
267
302
 
268
303
  ```javascript
269
- $.fn.gridEditor.texts.mytext = function(ge) {
304
+ $.fn.gridEditor.features.mytext = function(ge) {
270
305
  return {
271
- labelKey: 'text.mytext', // its name, in the toolbar and the drawer, optional
272
- initialContent: '<p>Write here</p>', // what a new text holds
273
- missingKey: 'error.mytext_missing', // the error when the library is not loaded, optional
274
- available: function() { return !!window.MyText; }, // optional, true otherwise
275
-
276
- start: function(block) { … }, // open the editor on this content area
277
- stop: function(block) { … }, // close it, and leave the content area as it was
306
+ textTypes: function() {
307
+ return [{
308
+ type: 'mytext', // what data-ge-content-type says
309
+ label: 'My text', // what the choice of editor shows
310
+ available: function() { … }, // optional: false, and missingKey is logged instead
311
+ missingKey: 'error.mytext_missing', // optional
312
+ offered: true, // optional: false owns the type without offering it
313
+ edit: function(block) { … }, // the type is on it: take it over, open the editor
314
+ }];
315
+ },
278
316
  };
279
317
  };
280
318
  ```
281
319
 
282
- - **`start(block)`** is called when the user clicks a content area of this
283
- type. The editor marks it `ge-rte-active` first, and does not call `start`
284
- again until it has been stopped. Once the library has taken the content
285
- area over, call **`ge.textReady(block)`**: it rewrote what was inside, and
286
- the editor and its plugins put their own furniture back - an element's
287
- drawer, for one. Call it again whenever the library rewrites the content
288
- area again, as tinyMCE's undo does.
289
- - **`stop(block)`** is called for every content area of this type on each
290
- `deinit`, which `getHtml` runs: a content area whose editor never started is
291
- the plugin's to ignore. Whatever the library and `start` added - classes,
292
- `contenteditable`, inline styles, ids - comes off here.
293
- - **`available()`** false and the editor logs `missingKey`'s message and
294
- starts nothing, without marking the content area, so a later click tries
295
- again once the library is there.
296
-
297
- A text editor is chosen by `content_types`, never by the `plugins` setting: a
298
- page that names its containers there has named no editor.
299
-
300
- Up to 5.x the main bundle carried a copy of the three shipped ones; since 6.0
301
- a page loads the plugin of the editor it uses, as it loads any other.
302
-
303
- 5.x's `$.fn.gridEditor.RTEs.mytext = { init, deinit, initialContent }` still
304
- works: `init(settings, contentAreas)` and `deinit(settings, contentAreas)` are
305
- wrapped as `start` and `stop`, with a warning that `RTEs` is deprecated. It goes
306
- in 7.0.
320
+ The core uses them three ways:
321
+
322
+ - **Whose a text is.** A content area of a type declared here is the plugin's:
323
+ the core wraps it in a `.ge-text-block` while editing, as it does plain
324
+ content, and leaves the drawer to the plugin - put one in on `onInit`. Two
325
+ plugins declaring one type: the first one registered has it, and the second
326
+ is warned about once.
327
+ - **What plain content can become.** A click on plain content, with one type
328
+ offered, makes it a text of that type; with several, it offers them, in the
329
+ order the plugins were registered. The core fires `before-convert`, which
330
+ can cancel it, puts the type on the content area - nothing else about it
331
+ changes - takes its plain drawer off, fires `after-convert` and calls
332
+ `edit(block)`. See [events.md](events.md).
333
+ - **What `createColumn(size, { content })` holds.** A text of the first type
334
+ offered, or plain content when there is none.
335
+
336
+ A plugin opens its editor on a click on its own texts - the core only handles
337
+ clicks on plain content - and closes it in `onBeforeDeinit`, which every
338
+ `deinit` runs while the drawers and the text blocks are still there, before
339
+ `getHtml` reads the markup. Whatever the editor put on the content area comes
340
+ off there.
341
+
342
+ ### The shipped text editors
343
+
344
+ `grideditor.tinymce.js`, `grideditor.ckeditor.js` and
345
+ `grideditor.summernote.js` each carry what text is to the editor - the text
346
+ block's drawer, the *Text* buttons in the toolbar and the *Add text* tool in
347
+ each column, `createText`, opening an editor on a click and closing it with
348
+ the host's attributes put back, and `textTypes` - from
349
+ `src/js/text/grideditor.text.js`, which the build puts at the top of each.
350
+ However many a page loads, that is installed once.
351
+
352
+ The editors offered are `content_types`, every one loaded by default, in the
353
+ order the page loaded them; the `plugins` setting does not choose them. A
354
+ text of an editor that is loaded but not offered is still edited.
355
+
356
+ ### A text editor of your own
357
+
358
+ A feature plugin with `textTypes`, a drawer for its texts, a toolbar item
359
+ with `inColumn: true` if it makes new ones, a click handler that opens its
360
+ editor, and `onBeforeDeinit` to close it.
361
+ [example/custom_editor.html](../example/custom_editor.html) is one, in full,
362
+ on the browser's `contenteditable`, on a page that loads none of the shipped
363
+ editors.
364
+
365
+ Up to 5.x an editor of a host's own registered under
366
+ `$.fn.gridEditor.RTEs`, and in 5.x and the 6.0 betas under
367
+ `$.fn.gridEditor.texts`. 6.0 removes the first - what is registered there is
368
+ ignored, with a warning - and `texts` is the shipped editors' own registry,
369
+ not a contract.
307
370
 
308
371
 
309
372
  Utility plugins
@@ -0,0 +1,193 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5
+
6
+ <!-- CSS dependencies -->
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.css">
9
+
10
+ <!-- Javascript dependencies -->
11
+ <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
13
+
14
+ <!-- Grid editor CSS -->
15
+ <link rel="stylesheet" type="text/css" href="../dist/grideditor.css" />
16
+
17
+ <!-- The editor, and no text editor of the shipped ones: the one this page
18
+ edits text with is written below -->
19
+ <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.6/Sortable.min.js"></script>
20
+ <script src="../dist/jquery.grideditor.min.js"></script>
21
+
22
+ <!-- A text editor of the page's own. It is a feature plugin like any
23
+ other: the core knows nothing of text, and asks the plugins through
24
+ textTypes which types there are. This one edits with the browser's
25
+ own contenteditable. -->
26
+ <script id="simpletext-plugin">
27
+ (function($) {
28
+
29
+ $.extend($.fn.gridEditor.locales.en, {
30
+ 'simpletext.label': 'Simple text',
31
+ 'simpletext.add': 'Simple text',
32
+ });
33
+
34
+ var TYPE = 'simpletext';
35
+
36
+ $.fn.gridEditor.features.simpletext = function(ge) {
37
+
38
+ /** A content area of this plugin's: its type is on it. */
39
+ function isOurs(area) {
40
+ return area.attr('data-ge-content-type') === TYPE;
41
+ }
42
+
43
+ function start(area) {
44
+ if (area.hasClass('ge-rte-active')) { return; }
45
+
46
+ area.addClass('ge-rte-active').attr('contenteditable', 'true').trigger('focus');
47
+ }
48
+
49
+ // Whatever start put on the content area comes off: what is
50
+ // left is what getHtml saves
51
+ function stop(area) {
52
+ area.removeClass('ge-rte-active').removeAttr('contenteditable');
53
+ }
54
+
55
+ /**
56
+ * A text's drawer. The editor wraps each content area of a
57
+ * column in a .ge-text-block while editing, and leaves the
58
+ * drawer of a type a plugin declares to that plugin.
59
+ */
60
+ function createDrawer(textBlock) {
61
+ var area = textBlock.children('.ge-content');
62
+ var drawer = $('<div class="ge-tools-drawer ge-text-drawer" />').prependTo(textBlock);
63
+
64
+ ge.createMoveTool(drawer);
65
+ ge.createTool(drawer, ge.t('tool.delete_text'), 'ge-delete-text', 'bi bi-trash', function() {
66
+ ge.deleteNode('text', area, ge.t('confirm.delete_text'), function(removed) {
67
+ stop(area);
68
+ textBlock.slideUp(function() {
69
+ textBlock.remove();
70
+ removed();
71
+ });
72
+ });
73
+ });
74
+ }
75
+
76
+ function onClick() {
77
+ if (isOurs($(this))) { start($(this)); }
78
+ }
79
+
80
+ return {
81
+ // The types this plugin edits. The core uses them to know
82
+ // whose a content area is, and to offer them when the
83
+ // host's plain content is clicked: edit() is handed the
84
+ // content area once the core has written the type on it
85
+ textTypes: function() {
86
+ return [{
87
+ type: TYPE,
88
+ label: ge.t('simpletext.label'),
89
+ edit: function(area) {
90
+ var textBlock = area.parent('.ge-text-block');
91
+ if (textBlock.length && !textBlock.children('.ge-tools-drawer').length) {
92
+ createDrawer(textBlock);
93
+ }
94
+
95
+ start(area);
96
+ },
97
+ }];
98
+ },
99
+
100
+ // A button to make a new text, in a row of its own or
101
+ // where it is dropped in a column
102
+ toolbar: [{
103
+ labelKey: 'simpletext.add',
104
+ iconClass: 'bi bi-fonts',
105
+ kind: 'text',
106
+ inColumn: true,
107
+ create: function() {
108
+ return $('<div class="ge-content" />')
109
+ .addClass('ge-content-type-' + TYPE)
110
+ .attr('data-ge-content-type', TYPE)
111
+ .html('<p>Write here</p>');
112
+ },
113
+ }],
114
+
115
+ onInit: function() {
116
+ ge.canvas.find('.ge-text-block').each(function() {
117
+ var textBlock = $(this);
118
+ if (textBlock.children('.ge-tools-drawer').length) { return; }
119
+ if (isOurs(textBlock.children('.ge-content'))) { createDrawer(textBlock); }
120
+ });
121
+
122
+ ge.canvas.off('click.simpletext').on('click.simpletext', '.ge-content', onClick);
123
+ },
124
+
125
+ // Before the drawers and the text blocks come off
126
+ onBeforeDeinit: function() {
127
+ ge.canvas.find('.ge-content').each(function() {
128
+ if (isOurs($(this))) { stop($(this)); }
129
+ });
130
+ },
131
+
132
+ onDeinit: function() {
133
+ ge.canvas.off('click.simpletext');
134
+ },
135
+ };
136
+ };
137
+
138
+ })(jQuery);
139
+ </script>
140
+
141
+ <script>
142
+ $(function() {
143
+ $('#myGrid').gridEditor({
144
+ new_row_layouts: [[12], [6, 6], [4, 4, 4]],
145
+ });
146
+
147
+ $('#output').on('click', function() {
148
+ $('#html').text($('#myGrid').gridEditor('getHtml'));
149
+ });
150
+ });
151
+ </script>
152
+
153
+ <title>Grid Editor example - a text editor of your own</title>
154
+ </head>
155
+ <body>
156
+ <!-- Back to the demo index -->
157
+ <div class="container pt-3">
158
+ <a class="link-secondary" href="index.html"><i class="bi bi-arrow-left"></i> All demos</a>
159
+ </div>
160
+
161
+ <div class="container py-3">
162
+ <h2>A text editor of your own</h2>
163
+ <p class="text-body-secondary">
164
+ No tinyMCE, CKEditor or summernote on this page: its text editor is
165
+ the plugin in the page's source, a few dozen lines on the browser's
166
+ <code>contenteditable</code>. The markup below had no text editor's
167
+ type on it, so the editor took it for the host's <em>plain
168
+ content</em>: it can be moved and deleted, and a click makes it a
169
+ text of this editor. The second column was saved as one already.
170
+ See <a href="../docs/plugins.md">docs/plugins.md</a>.
171
+ </p>
172
+
173
+ <div id="myGrid">
174
+ <div class="row">
175
+ <div class="col-lg-6">
176
+ <h3>Plain content</h3>
177
+ <p>Loose markup of the page's own. Click it and it is a simple text.</p>
178
+ </div>
179
+ <div class="col-lg-6">
180
+ <div class="ge-content ge-content-type-simpletext" data-ge-content-type="simpletext">
181
+ <p>A simple text, saved as one: a click edits it.</p>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+
187
+ <p class="mt-4">
188
+ <button type="button" class="btn btn-outline-primary btn-sm" id="output">Show getHtml</button>
189
+ </p>
190
+ <pre class="bg-body-tertiary border rounded p-3 small"><code id="html"></code></pre>
191
+ </div>
192
+ </body>
193
+ </html>
@@ -61,6 +61,14 @@
61
61
  <span class="text-body-secondary">The plugin model, with a container plugin written in the page itself</span>
62
62
  </a>
63
63
 
64
+ <a class="list-group-item list-group-item-action" href="custom_editor.html">
65
+ <div class="d-flex justify-content-between">
66
+ <strong>A text editor of your own</strong>
67
+ <code class="text-body-secondary">custom_editor.html</code>
68
+ </div>
69
+ <span class="text-body-secondary">No shipped text editor: one written in the page as a plugin, on the textTypes hook</span>
70
+ </a>
71
+
64
72
  <a class="list-group-item list-group-item-action" href="attributes.html">
65
73
  <div class="d-flex justify-content-between">
66
74
  <strong>A plugin with a modal</strong>
@@ -63,9 +63,11 @@
63
63
  <code>.col-*</code> anywhere. Grid editor does not refuse it: it
64
64
  wraps all of it into one row with a single
65
65
  <code>col-lg-12</code> column, and from there it is an ordinary
66
- grid. Add rows, split the column, edit the text, then press
67
- <em>Refresh</em> to see the html that comes out: as
68
- <code>getHtml</code> returns it, to save and edit again, and as
66
+ grid. What was in there is the page's <em>plain content</em>: a
67
+ block to move and delete, edited in the source, until a click
68
+ makes it a text of tinyMCE's. Add rows, split the column, edit the
69
+ text, then press <em>Refresh</em> to see the html that comes out:
70
+ as <code>getHtml</code> returns it, to save and edit again, and as
69
71
  <code>getPlainHtml</code> returns it, to publish.
70
72
  </p>
71
73
 
package/package.json CHANGED
@@ -34,7 +34,7 @@
34
34
  "comment": "A scoped package publishes restricted unless it is told otherwise.",
35
35
  "access": "public"
36
36
  },
37
- "version": "6.0.0-beta.3",
37
+ "version": "6.0.0-beta.4",
38
38
  "main": "dist/jquery.grideditor.js",
39
39
  "files": [
40
40
  "dist",