ckeditor5 1.1.7 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a512b289e611ca5d7480b5088b14f83ed459481b6f99f0c15b4467e627c464e7
4
- data.tar.gz: dc3969b71fd184b7e9bc39a95fc7d0702280203c940197925d8e8f8d17d22a50
3
+ metadata.gz: '028a09c0049e3eb489434b0447796369924801d0f5273a400e9783dbd3a8a70c'
4
+ data.tar.gz: e9a3c65f03a85b1361b612c85b00c5cb9d1d8385eeca716c5cea4f0e5817474b
5
5
  SHA512:
6
- metadata.gz: d3491c052e7e736f1ed484a67eaf7fae034fd73874977c4bcfd671295e5fe5d9673d7c27845df6877fb527a4a29763ad3529c58e30fcee893f8a174fe066ac84
7
- data.tar.gz: e579d1032b12e79d265da252ad74af5b090922aeb0eb4d68ab12c252d9ed173ec9b1f5e4cc904f4fcc62c4dbc0cb20b4b79ae87ee9cfff40afc33b1497caf464
6
+ metadata.gz: 5bf454b35f45aca3a44a2463d007cea579714c835d82edf7e6ed351db3c93a94aff59489bab7cea69cd78853acf50473ad9f7cf64819ee5c3c5bc5c0ef2d20a8
7
+ data.tar.gz: e394db6e299f6a48c88f50a306500bcae7c87c0eae6092bdf44c7f62e4a179da542f7299448db18045c086047da16a5818f3915416d9b10bb00747bda9e431ce
data/README.md CHANGED
@@ -75,6 +75,7 @@ Voilà! You have CKEditor 5 integrated with your Rails application. 🎉
75
75
  - [Commercial usage 💰](#commercial-usage-)
76
76
  - [Editor placement 🏗️](#editor-placement-️)
77
77
  - [Setting Initial Content 📝](#setting-initial-content-)
78
+ - [Watchdog 🐕](#watchdog-)
78
79
  - [Classic editor 📝](#classic-editor-)
79
80
  - [Multiroot editor 🌳](#multiroot-editor-)
80
81
  - [Inline editor 📝](#inline-editor-)
@@ -490,7 +491,7 @@ If you want to use CKEditor 5 under the GPL license, you can include the assets
490
491
  <!-- app/views/demos/index.html.erb -->
491
492
 
492
493
  <% content_for :head do %>
493
- <%= ckeditor5_assets %>
494
+ <%= ckeditor5_assets version: '43.3.0' %>
494
495
  <% end %>
495
496
  ```
496
497
 
@@ -562,9 +563,6 @@ end
562
563
 
563
564
  ### Commercial usage 💰
564
565
 
565
- <details>
566
- <summary>Expand to show more</summary>
567
-
568
566
  If you want to use CKEditor 5 under a commercial license, you can include the assets using the `ckeditor5_assets` helper method with the `license_key` keyword argument. The example below shows how to include the assets for the commercial license:
569
567
 
570
568
  ```erb
@@ -577,8 +575,6 @@ If you want to use CKEditor 5 under a commercial license, you can include the as
577
575
 
578
576
  In this scenario, the assets are included from the official CKEditor 5 CDN which is more reliable and provides better performance, especially for commercial usage.
579
577
 
580
- </details>
581
-
582
578
  ## Editor placement 🏗️
583
579
 
584
580
  The `ckeditor5_editor` helper renders CKEditor 5 instances in your views. Before using it, ensure you've included the necessary assets in your page's head section otherwise the editor won't work as there are no CKEditor 5 JavaScript and CSS files loaded.
@@ -605,6 +601,18 @@ The example below shows how to set the initial content of the editor using the `
605
601
  <% end %>
606
602
  ```
607
603
 
604
+ ### Watchdog 🐕
605
+
606
+ CKEditor 5 uses a watchdog utility to protect you from data loss in case the editor crashes. It saves your content just before the crash and creates a new instance of the editor with your content intact. It's enabled by default in the gem.
607
+
608
+ If you want to disable the watchdog, you can pass the `watchdog` keyword argument with the value `false`:
609
+
610
+ ```erb
611
+ <!-- app/views/demos/index.html.erb -->
612
+
613
+ <%= ckeditor5_editor watchdog: false %>
614
+ ```
615
+
608
616
  ### Classic editor 📝
609
617
 
610
618
  The classic editor is the most common type of editor. It provides a toolbar with various formatting options like bold, italic, underline, and link.
@@ -741,6 +749,8 @@ Decoupled editor is a variant of classic editor that allows you to separate the
741
749
  If you want to use a decoupled editor, you can pass the `type` keyword argument with the value `:decoupled`:
742
750
 
743
751
  ```erb
752
+ <!-- app/views/demos/index.html.erb -->
753
+
744
754
  <% content_for :head do %>
745
755
  <%= ckeditor5_assets %>
746
756
  <% end %>
@@ -45,6 +45,9 @@ class CKEditorComponent extends HTMLElement {
45
45
  /** @type {Promise<import('ckeditor5').Editor>|null} Promise to initialize editor instance */
46
46
  instancePromise = Promise.withResolvers();
47
47
 
48
+ /** @type {import('ckeditor5').Watchdog|null} Editor watchdog */
49
+ watchdog = null;
50
+
48
51
  /** @type {import('ckeditor5').Editor|null} Current editor instance */
49
52
  instance = null;
50
53
 
@@ -93,6 +96,7 @@ class CKEditorComponent extends HTMLElement {
93
96
  async disconnectedCallback() {
94
97
  try {
95
98
  await this.instance?.destroy();
99
+ await this.watchdog?.destroy();
96
100
  } catch (error) {
97
101
  console.error('Failed to destroy editor:', error);
98
102
  }
@@ -129,10 +133,11 @@ class CKEditorComponent extends HTMLElement {
129
133
  }
130
134
 
131
135
  /**
132
- * Initializes a new CKEditor instance
136
+ * Creates a new CKEditor instance
137
+ *
133
138
  * @private
134
139
  * @param {Record<string, HTMLElement>|CKEditorMultiRootEditablesTracker} editablesOrContent - Editable or content
135
- * @returns {Promise<import('ckeditor5').Editor>} Initialized editor instance
140
+ * @returns {Promise<{ editor: import('ckeditor5').Editor, watchdog: editor: import('ckeditor5').EditorWatchdog }>} Initialized editor instance
136
141
  * @throws {Error} When initialization fails
137
142
  */
138
143
  async #initializeEditor(editablesOrContent) {
@@ -142,6 +147,9 @@ class CKEditorComponent extends HTMLElement {
142
147
  this.#getTranslations()
143
148
  ]);
144
149
 
150
+ // Depending on the type of the editor the content supplied on the first
151
+ // argument is different. For ClassicEditor it's a element or string, for MultiRootEditor
152
+ // it's an object with editables, for DecoupledEditor it's string.
145
153
  let content = editablesOrContent;
146
154
 
147
155
  if (editablesOrContent instanceof CKEditorMultiRootEditablesTracker) {
@@ -158,13 +166,29 @@ class CKEditorComponent extends HTMLElement {
158
166
  plugins,
159
167
  };
160
168
 
161
- console.warn('Initializing CKEditor with config:', config);
169
+ console.warn('Initializing CKEditor with:', { config, watchdog: this.hasWatchdog() });
170
+
171
+ // Initialize watchdog if needed
172
+ let watchdog = null;
173
+ let instance = null;
162
174
 
163
- const instance = await Editor.create(content, config);
175
+ if (this.hasWatchdog()) {
176
+ const { EditorWatchdog } = await import('ckeditor5');
177
+ const watchdog = new EditorWatchdog(Editor);
178
+
179
+ await watchdog.create(content, config);
180
+
181
+ instance = watchdog.editor;
182
+ } else {
183
+ instance = await Editor.create(content, config);
184
+ }
164
185
 
165
186
  this.dispatchEvent(new CustomEvent('editor-ready', { detail: instance }));
166
187
 
167
- return instance;
188
+ return {
189
+ instance,
190
+ watchdog,
191
+ };
168
192
  }
169
193
 
170
194
  /**
@@ -198,7 +222,11 @@ class CKEditorComponent extends HTMLElement {
198
222
  }
199
223
 
200
224
  try {
201
- this.instance = await this.#initializeEditor(this.editables || this.#getConfig().initialData || '');
225
+ const { watchdog, instance } = await this.#initializeEditor(this.editables || this.#getConfig().initialData || '');
226
+
227
+ this.watchdog = watchdog;
228
+ this.instance = instance;
229
+
202
230
  this.#setupContentSync();
203
231
 
204
232
  this.instancePromise.resolve(this.instance);
@@ -228,6 +256,16 @@ class CKEditorComponent extends HTMLElement {
228
256
  return this.getAttribute('type') === 'DecoupledEditor';
229
257
  }
230
258
 
259
+ /**
260
+ * Checks if current editor has watchdog enabled
261
+ *
262
+ * @private
263
+ * @returns {boolean}
264
+ */
265
+ hasWatchdog() {
266
+ return this.getAttribute('watchdog') === 'true';
267
+ }
268
+
231
269
  /**
232
270
  * Parses editor configuration from config attribute
233
271
  *
@@ -9,13 +9,13 @@ module CKEditor5::Rails
9
9
  class EditorContextError < StandardError; end
10
10
  class PresetNotFoundError < ArgumentError; end
11
11
 
12
- def ckeditor5_editor(
12
+ def ckeditor5_editor( # rubocop:disable Metrics/ParameterLists
13
13
  config: nil, extra_config: {},
14
14
  type: nil, preset: :default,
15
- initial_data: nil,
15
+ initial_data: nil, watchdog: true,
16
16
  **html_attributes, &block
17
17
  )
18
- context = validate_and_get_editor_context!
18
+ controller_context = validate_and_get_editor_context!
19
19
  preset = fetch_editor_preset(preset)
20
20
 
21
21
  config ||= preset.config
@@ -26,10 +26,9 @@ module CKEditor5::Rails
26
26
 
27
27
  raise ArgumentError, 'Cannot pass initial data and block at the same time.' if initial_data && block
28
28
 
29
- editor_props = build_editor_props(
30
- config: config,
31
- type: type,
32
- context: context
29
+ editor_props = Editor::Props.new(
30
+ controller_context, type, config,
31
+ watchdog: watchdog
33
32
  )
34
33
 
35
34
  render_editor_component(editor_props, html_attributes, &block)
@@ -68,10 +67,6 @@ module CKEditor5::Rails
68
67
  raise PresetNotFoundError, "Preset #{preset} is not defined."
69
68
  end
70
69
 
71
- def build_editor_props(config:, type:, context:)
72
- Editor::Props.new(context, type, config)
73
- end
74
-
75
70
  def render_editor_component(props, html_attributes, &block)
76
71
  tag.send(:'ckeditor-component', **props.to_attributes, **html_attributes, &block)
77
72
  end
@@ -12,10 +12,11 @@ module CKEditor5::Rails::Editor
12
12
  multiroot: 'MultiRootEditor'
13
13
  }.freeze
14
14
 
15
- def initialize(context, type, config)
15
+ def initialize(controller_context, type, config, watchdog: true)
16
16
  raise ArgumentError, "Invalid editor type: #{type}" unless Props.valid_editor_type?(type)
17
17
 
18
- @context = context
18
+ @controller_context = controller_context
19
+ @watchdog = watchdog
19
20
  @type = type
20
21
  @config = config
21
22
  end
@@ -33,18 +34,19 @@ module CKEditor5::Rails::Editor
33
34
 
34
35
  private
35
36
 
36
- attr_reader :context, :type, :config
37
+ attr_reader :controller_context, :watchdog, :type, :config
37
38
 
38
39
  def serialized_attributes
39
40
  {
40
41
  translations: serialize_translations,
41
42
  plugins: serialize_plugins,
42
- config: serialize_config
43
+ config: serialize_config,
44
+ watchdog: watchdog
43
45
  }
44
46
  end
45
47
 
46
48
  def serialize_translations
47
- context[:bundle].translations_scripts.map(&:to_h).to_json
49
+ controller_context[:bundle].translations_scripts.map(&:to_h).to_json
48
50
  end
49
51
 
50
52
  def serialize_plugins
@@ -54,7 +56,7 @@ module CKEditor5::Rails::Editor
54
56
  def serialize_config
55
57
  config
56
58
  .except(:plugins)
57
- .tap { |cfg| cfg[:licenseKey] = context[:license_key] if context[:license_key] }
59
+ .tap { |cfg| cfg[:licenseKey] = controller_context[:license_key] if controller_context[:license_key] }
58
60
  .to_json
59
61
  end
60
62
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CKEditor5::Rails
4
- VERSION = '1.1.7'
4
+ VERSION = '1.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ckeditor5
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Bagiński