ckeditor5 1.35.1 → 1.82.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.

Potentially problematic release.


This version of ckeditor5 might be problematic. Click here for more details.

Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -158
  3. data/lib/ckeditor5/rails/assets/assets_bundle_html_serializer.rb +2 -2
  4. data/lib/ckeditor5/rails/assets/webcomponent_bundle.rb +21 -2
  5. data/lib/ckeditor5/rails/assets/webcomponents/components/context.mjs +123 -0
  6. data/lib/ckeditor5/rails/assets/webcomponents/components/editable.mjs +113 -0
  7. data/lib/ckeditor5/rails/assets/webcomponents/components/editor.mjs +778 -0
  8. data/lib/ckeditor5/rails/assets/webcomponents/components/ui-part.mjs +26 -0
  9. data/lib/ckeditor5/rails/assets/webcomponents/utils.mjs +235 -0
  10. data/lib/ckeditor5/rails/cdn/ckeditor_bundle.rb +2 -2
  11. data/lib/ckeditor5/rails/cdn/concerns/bundle_builder.rb +7 -5
  12. data/lib/ckeditor5/rails/cdn/helpers.rb +2 -2
  13. data/lib/ckeditor5/rails/context/helpers.rb +1 -6
  14. data/lib/ckeditor5/rails/context/preset_builder.rb +2 -2
  15. data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +1 -1
  16. data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +4 -14
  17. data/lib/ckeditor5/rails/editor/props.rb +12 -7
  18. data/lib/ckeditor5/rails/editor/props_inline_plugin.rb +3 -6
  19. data/lib/ckeditor5/rails/editor/props_patch_plugin.rb +4 -2
  20. data/lib/ckeditor5/rails/engine.rb +6 -7
  21. data/lib/ckeditor5/rails/plugins/custom_translations_loader.rb +4 -3
  22. data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +3 -2
  23. data/lib/ckeditor5/rails/plugins/special_characters_bootstrap.rb +3 -2
  24. data/lib/ckeditor5/rails/plugins/wproofreader.rb +3 -2
  25. data/lib/ckeditor5/rails/presets/concerns/plugin_methods.rb +3 -39
  26. data/lib/ckeditor5/rails/presets/manager.rb +3 -8
  27. data/lib/ckeditor5/rails/presets/preset_builder.rb +18 -28
  28. data/lib/ckeditor5/rails/presets/special_characters_builder.rb +2 -1
  29. data/lib/ckeditor5/rails/semver.rb +1 -1
  30. data/lib/ckeditor5/rails/version.rb +2 -2
  31. data/spec/e2e/features/context_spec.rb +1 -1
  32. data/spec/e2e/spec_helper.rb +1 -1
  33. data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +12 -15
  34. data/spec/lib/ckeditor5/rails/context/preset_builder_spec.rb +0 -18
  35. data/spec/lib/ckeditor5/rails/editor/helpers/editor_helpers_spec.rb +0 -27
  36. data/spec/lib/ckeditor5/rails/editor/props_inline_plugin_spec.rb +0 -28
  37. data/spec/lib/ckeditor5/rails/editor/props_spec.rb +3 -13
  38. data/spec/lib/ckeditor5/rails/presets/manager_spec.rb +2 -58
  39. data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +2 -26
  40. data/spec/spec_helper.rb +1 -1
  41. metadata +10 -47
  42. data/lib/ckeditor5/rails/plugins/patches/fix_color_picker_race_condition.rb +0 -50
  43. data/lib/ckeditor5/rails/plugins.rb +0 -15
  44. data/npm_package/dist/index.cjs +0 -2
  45. data/npm_package/dist/index.cjs.map +0 -1
  46. data/npm_package/dist/index.d.ts +0 -1
  47. data/npm_package/dist/index.mjs +0 -723
  48. data/npm_package/dist/index.mjs.map +0 -1
  49. data/npm_package/dist/src/components/context.d.ts +0 -24
  50. data/npm_package/dist/src/components/context.d.ts.map +0 -1
  51. data/npm_package/dist/src/components/editable.d.ts +0 -34
  52. data/npm_package/dist/src/components/editable.d.ts.map +0 -1
  53. data/npm_package/dist/src/components/editor/editor.d.ts +0 -79
  54. data/npm_package/dist/src/components/editor/editor.d.ts.map +0 -1
  55. data/npm_package/dist/src/components/editor/index.d.ts +0 -3
  56. data/npm_package/dist/src/components/editor/index.d.ts.map +0 -1
  57. data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts +0 -36
  58. data/npm_package/dist/src/components/editor/multiroot-editables-tracker.d.ts.map +0 -1
  59. data/npm_package/dist/src/components/index.d.ts +0 -5
  60. data/npm_package/dist/src/components/index.d.ts.map +0 -1
  61. data/npm_package/dist/src/components/ui-part.d.ts +0 -2
  62. data/npm_package/dist/src/components/ui-part.d.ts.map +0 -1
  63. data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts +0 -7
  64. data/npm_package/dist/src/helpers/exec-if-dom-ready.d.ts.map +0 -1
  65. data/npm_package/dist/src/helpers/index.d.ts +0 -8
  66. data/npm_package/dist/src/helpers/index.d.ts.map +0 -1
  67. data/npm_package/dist/src/helpers/inject-script.d.ts +0 -8
  68. data/npm_package/dist/src/helpers/inject-script.d.ts.map +0 -1
  69. data/npm_package/dist/src/helpers/is-safe-key.d.ts +0 -8
  70. data/npm_package/dist/src/helpers/is-safe-key.d.ts.map +0 -1
  71. data/npm_package/dist/src/helpers/load-async-css.d.ts +0 -9
  72. data/npm_package/dist/src/helpers/load-async-css.d.ts.map +0 -1
  73. data/npm_package/dist/src/helpers/load-async-imports.d.ts +0 -25
  74. data/npm_package/dist/src/helpers/load-async-imports.d.ts.map +0 -1
  75. data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts +0 -9
  76. data/npm_package/dist/src/helpers/resolve-config-element-references.d.ts.map +0 -1
  77. data/npm_package/dist/src/helpers/uid.d.ts +0 -7
  78. data/npm_package/dist/src/helpers/uid.d.ts.map +0 -1
  79. data/npm_package/dist/src/index.d.ts +0 -1
  80. data/npm_package/dist/src/index.d.ts.map +0 -1
  81. data/npm_package/dist/vite.config.d.ts +0 -3
  82. data/npm_package/dist/vite.config.d.ts.map +0 -1
  83. data/npm_package/package.json +0 -41
@@ -0,0 +1,26 @@
1
+ class CKEditorUIPartComponent extends HTMLElement {
2
+ /**
3
+ * Lifecycle callback when element is added to DOM
4
+ * Adds the toolbar to the editor UI
5
+ */
6
+ connectedCallback() {
7
+ execIfDOMReady(async () => {
8
+ const uiPart = this.getAttribute('name');
9
+ const editor = await this.#queryEditorElement().instancePromise.promise;
10
+
11
+ this.appendChild(editor.ui.view[uiPart].element);
12
+ });
13
+ }
14
+
15
+ /**
16
+ * Finds the parent editor component
17
+ *
18
+ * @private
19
+ * @returns {CKEditorComponent|null} Parent editor component or null if not found
20
+ */
21
+ #queryEditorElement() {
22
+ return this.closest('ckeditor-component') || document.body.querySelector('ckeditor-component');
23
+ }
24
+ }
25
+
26
+ customElements.define('ckeditor-ui-part-component', CKEditorUIPartComponent);
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Executes callback when DOM is ready
3
+ *
4
+ * @param {() => void} callback - Function to execute when DOM is ready
5
+ */
6
+ function execIfDOMReady(callback) {
7
+ switch (document.readyState) {
8
+ case 'loading':
9
+ document.addEventListener('DOMContentLoaded', callback, { once: true });
10
+ break;
11
+
12
+ case 'interactive':
13
+ case 'complete':
14
+ setTimeout(callback, 0);
15
+ break;
16
+
17
+ default:
18
+ console.warn('Unexpected document.readyState:', document.readyState);
19
+ setTimeout(callback, 0);
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Dynamically imports modules based on configuration
25
+ *
26
+ * @param {Array<Object>} imports - Array of import configurations
27
+ * @param {Object} imports[].name - Name of inline plugin (for inline type)
28
+ * @param {Object} imports[].code - Source code of inline plugin (for inline type)
29
+ * @param {Object} imports[].import_name - Module path to import (for external type)
30
+ * @param {Object} imports[].import_as - Name to import as (for external type)
31
+ * @param {Object} imports[].window_name - Global window object name (for external type)
32
+ * @param {('inline'|'external')} imports[].type - Type of import
33
+ * @returns {Promise<Array<any>>} Array of loaded modules
34
+ * @throws {Error} When plugin loading fails
35
+ */
36
+ function loadAsyncImports(imports = []) {
37
+ const loadExternalPlugin = async ({ url, import_name, import_as, window_name, stylesheets }) => {
38
+ if (stylesheets?.length) {
39
+ await loadAsyncCSS(stylesheets);
40
+ }
41
+
42
+ if (window_name) {
43
+ function isScriptPresent() {
44
+ return Object.prototype.hasOwnProperty.call(window, window_name);
45
+ }
46
+
47
+ if (url && !isScriptPresent()) {
48
+ await injectScript(url);
49
+ }
50
+
51
+ if (!isScriptPresent()) {
52
+ window.dispatchEvent(
53
+ new CustomEvent(`ckeditor:request-cjs-plugin:${window_name}`)
54
+ );
55
+ }
56
+
57
+ if (!isScriptPresent()) {
58
+ throw new Error(
59
+ `Plugin window['${window_name}'] not found in global scope. ` +
60
+ 'Please ensure the plugin is loaded before CKEditor initialization.'
61
+ );
62
+ }
63
+
64
+ return window[window_name];
65
+ }
66
+
67
+ const module = await import(import_name);
68
+ const imported = module[import_as || 'default'];
69
+
70
+ if (!imported) {
71
+ throw new Error(
72
+ `Plugin "${import_as || 'default'}" not found in the ESM module ` +
73
+ `"${import_name}"! Available imports: ${Object.keys(module).join(', ')}! ` +
74
+ 'Consider changing "import_as" value.'
75
+ );
76
+ }
77
+
78
+ return imported;
79
+ };
80
+
81
+ function uncompressImport(pkg) {
82
+ if (typeof pkg === 'string') {
83
+ return loadExternalPlugin({ import_name: 'ckeditor5', import_as: pkg });
84
+ }
85
+
86
+ return loadExternalPlugin(pkg);
87
+ }
88
+
89
+ return Promise.all(imports.map(uncompressImport));
90
+ }
91
+
92
+ /**
93
+ * Checks if stylesheet with given href already exists in document
94
+ *
95
+ * @param {string} href - Stylesheet URL to check
96
+ * @returns {boolean} True if stylesheet already exists
97
+ */
98
+ function stylesheetExists(href) {
99
+ return Array
100
+ .from(document.styleSheets)
101
+ .some(sheet =>
102
+ sheet.href === href || sheet.href === new URL(href, window.location.href).href
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Dynamically loads CSS files based on configuration
108
+ *
109
+ * @param {Array<string>} imports - Array of CSS file URLs to load
110
+ * @returns {Promise<Array<void>>} Array of promises for each CSS file load
111
+ * @throws {Error} When CSS file loading fails
112
+ */
113
+ function loadAsyncCSS(stylesheets = []) {
114
+ const promises = stylesheets.map(href =>
115
+ new Promise((resolve, reject) => {
116
+ if (stylesheetExists(href)) {
117
+ resolve();
118
+ return;
119
+ }
120
+
121
+ const link = document.createElement('link');
122
+ link.rel = 'stylesheet';
123
+ link.href = href;
124
+
125
+ link.onerror = reject;
126
+ link.onload = () => resolve();
127
+
128
+ document.head.appendChild(link);
129
+ })
130
+ );
131
+
132
+ return Promise.all(promises);
133
+ }
134
+
135
+ const SCRIPT_LOAD_PROMISES = new Map();
136
+
137
+ /**
138
+ * Dynamically loads script files based on configuration.
139
+ * Uses caching to avoid loading the same script multiple times.
140
+ *
141
+ * @param {string} url - URL of the script to load
142
+ */
143
+ function injectScript(url) {
144
+ if (SCRIPT_LOAD_PROMISES.has(url)) {
145
+ return SCRIPT_LOAD_PROMISES.get(url);
146
+ }
147
+
148
+ const promise = new Promise((resolve, reject) => {
149
+ const script = document.createElement('script');
150
+ script.src = url;
151
+ script.onload = resolve;
152
+ script.onerror = reject;
153
+
154
+ document.head.appendChild(script);
155
+ });
156
+
157
+ SCRIPT_LOAD_PROMISES.set(url, promise);
158
+ return promise;
159
+ }
160
+
161
+ /**
162
+ * Checks if a key is safe to use in configuration objects to prevent prototype pollution
163
+ *
164
+ * @param {string} key - Key name to check
165
+ * @returns {boolean} True if key is safe to use
166
+ */
167
+ function isSafeKey(key) {
168
+ return typeof key === 'string' &&
169
+ key !== '__proto__' &&
170
+ key !== 'constructor' &&
171
+ key !== 'prototype';
172
+ }
173
+
174
+ /**
175
+ * Resolves element references in configuration object.
176
+ * Looks for objects with { $element: "selector" } format and replaces them with actual DOM elements.
177
+ *
178
+ * @param {Object} obj - Configuration object to process
179
+ * @returns {Object} Processed configuration object with resolved element references
180
+ * @throws {Error} When element reference is invalid
181
+ */
182
+ function resolveElementReferences(obj) {
183
+ if (!obj || typeof obj !== 'object') {
184
+ return obj;
185
+ }
186
+
187
+ if (Array.isArray(obj)) {
188
+ return obj.map(item => resolveElementReferences(item));
189
+ }
190
+
191
+ const result = Object.create(null);
192
+
193
+ for (const key of Object.getOwnPropertyNames(obj)) {
194
+ if (!isSafeKey(key)) {
195
+ console.warn(`Suspicious key "${key}" detected in config, skipping`);
196
+ continue;
197
+ }
198
+
199
+ const value = obj[key];
200
+
201
+ if (value && typeof value === 'object') {
202
+ if (value.$element) {
203
+ const selector = value.$element;
204
+
205
+ if (typeof selector !== 'string') {
206
+ console.warn(`Invalid selector type for "${key}", expected string`);
207
+ continue;
208
+ }
209
+
210
+ const element = document.querySelector(selector);
211
+
212
+ if (!element) {
213
+ console.warn(`Element not found for selector: ${selector}`);
214
+ }
215
+
216
+ result[key] = element || null;
217
+ } else {
218
+ result[key] = resolveElementReferences(value);
219
+ }
220
+ } else {
221
+ result[key] = value;
222
+ }
223
+ }
224
+
225
+ return result;
226
+ }
227
+
228
+ /**
229
+ * Generates a unique identifier string
230
+ *
231
+ * @returns {string} Random string that can be used as unique identifier
232
+ */
233
+ function uid() {
234
+ return Math.random().toString(36).substring(2);
235
+ }
@@ -43,7 +43,7 @@ module CKEditor5::Rails
43
43
  end
44
44
 
45
45
  def translations_js_url_imports
46
- translations.map do |lang|
46
+ translations.filter_map do |lang|
47
47
  next if lang == :en
48
48
 
49
49
  url = create_cdn_url(import_name, version, "translations/#{lang}.js")
@@ -53,7 +53,7 @@ module CKEditor5::Rails
53
53
  import_name: "#{import_name}/translations/#{lang}.js",
54
54
  translation: true
55
55
  )
56
- end.compact
56
+ end
57
57
  end
58
58
  end
59
59
  end
@@ -4,11 +4,13 @@ module CKEditor5::Rails
4
4
  module Cdn::Concerns
5
5
  module BundleBuilder
6
6
  def create_preset_bundle(preset)
7
- cdn = preset.cdn
8
- version = preset.version
9
- translations = preset.translations
10
- ckbox = preset.ckbox
11
- premium = preset.premium
7
+ preset => {
8
+ cdn:,
9
+ version:,
10
+ translations:,
11
+ ckbox:,
12
+ premium:
13
+ }
12
14
 
13
15
  bundle = build_base_cdn_bundle(cdn, version, translations)
14
16
  bundle << build_premium_cdn_bundle(cdn, version, translations) if premium
@@ -55,7 +55,7 @@ module CKEditor5::Rails
55
55
  #
56
56
  # @example Using preset builder object
57
57
  # <% @preset = ckeditor5_preset do
58
- # version '43.3.1'
58
+ # version '44.3.0'
59
59
  # toolbar :bold, :italic
60
60
  # plugins :Bold, :Italic
61
61
  # end %>
@@ -169,7 +169,7 @@ module CKEditor5::Rails
169
169
  if language.present?
170
170
  new_preset.language(language)
171
171
  elsif !new_preset.language?
172
- new_preset.language(I18n.locale.downcase)
172
+ new_preset.language(I18n.locale)
173
173
  end
174
174
 
175
175
  validate_required_preset_params!(new_preset, preset)
@@ -31,12 +31,7 @@ module CKEditor5::Rails::Context
31
31
 
32
32
  tags = []
33
33
  tags << ckeditor5_inline_plugins_tags(preset)
34
- tags << tag.public_send(
35
- :'ckeditor-context-component',
36
- 'data-turbo-temporary': true,
37
- **context_props.to_attributes,
38
- &block
39
- )
34
+ tags << tag.public_send(:'ckeditor-context-component', **context_props.to_attributes, &block)
40
35
 
41
36
  safe_join(tags)
42
37
  end
@@ -12,7 +12,7 @@ module CKEditor5::Rails
12
12
  #
13
13
  # @example Basic preset definition
14
14
  # preset = PresetBuilder.new do
15
- # version '43.3.1'
15
+ # version '44.3.0'
16
16
  # gpl
17
17
  # type :classic
18
18
  # toolbar :bold, :italic
@@ -35,7 +35,7 @@ module CKEditor5::Rails
35
35
  # @param block [Proc] Optional configuration block
36
36
  # @example Initialize with block
37
37
  # PresetBuilder.new do
38
- # version '43.3.1'
38
+ # version '44.3.0'
39
39
  # toolbar :bold, :italic
40
40
  # end
41
41
  def initialize(&block)
@@ -44,7 +44,7 @@ module CKEditor5::Rails::Editor::Helpers
44
44
  #
45
45
  # @example Creating a custom preset in controller
46
46
  # @preset = ckeditor5_preset do
47
- # version '43.3.1'
47
+ # version '44.3.0'
48
48
  # toolbar :sourceEditing, :|, :bold, :italic
49
49
  # plugins :Essentials, :Paragraph, :Bold, :Italic
50
50
  # end
@@ -74,7 +74,7 @@ module CKEditor5::Rails
74
74
 
75
75
  # Add some fallbacks
76
76
  config[:licenseKey] ||= context[:license_key] || preset.license_key
77
- config[:language] = { ui: language.downcase } if language
77
+ config[:language] = { ui: language } if language
78
78
 
79
79
  editor_props = Editor::Props.new(
80
80
  type, config,
@@ -85,7 +85,7 @@ module CKEditor5::Rails
85
85
 
86
86
  tag_attributes = html_attributes.merge(editor_props.to_attributes)
87
87
 
88
- tag.public_send(:'ckeditor-component', 'data-turbo-temporary': true, **tag_attributes, &block)
88
+ tag.public_send(:'ckeditor-component', **tag_attributes, &block)
89
89
  end
90
90
 
91
91
  # Creates an editable area for multiroot or decoupled editors.
@@ -96,12 +96,7 @@ module CKEditor5::Rails
96
96
  # @example Creating a named editable area in multiroot editor
97
97
  # <%= ckeditor5_editable 'content', style: 'border: 1px solid gray' %>
98
98
  def ckeditor5_editable(name = nil, **kwargs, &block)
99
- tag.public_send(
100
- :'ckeditor-editable-component',
101
- 'data-turbo-temporary': true,
102
- name: name,
103
- **kwargs, &block
104
- )
99
+ tag.public_send(:'ckeditor-editable-component', name: name, **kwargs, &block)
105
100
  end
106
101
 
107
102
  # Creates a UI part component for the editor (toolbar, menubar).
@@ -112,12 +107,7 @@ module CKEditor5::Rails
112
107
  # @example Creating a toolbar component
113
108
  # <%= ckeditor5_ui_part 'toolbar' %>
114
109
  def ckeditor5_ui_part(name, **kwargs, &block)
115
- tag.public_send(
116
- :'ckeditor-ui-part-component',
117
- 'data-turbo-temporary': true,
118
- name: name,
119
- **kwargs, &block
120
- )
110
+ tag.public_send(:'ckeditor-ui-part-component', name: name, **kwargs, &block)
121
111
  end
122
112
 
123
113
  # Creates a toolbar component for decoupled editor.
@@ -30,14 +30,9 @@ module CKEditor5::Rails::Editor
30
30
 
31
31
  def to_attributes
32
32
  {
33
- bundle: bundle&.to_json,
34
- plugins: serialize_plugins,
35
- config: serialize_config,
36
- watchdog: watchdog,
37
- type: EDITOR_TYPES[@type]
33
+ type: EDITOR_TYPES[@type],
34
+ **serialized_attributes
38
35
  }
39
- .merge(editable_height ? { 'editable-height': editable_height } : {})
40
- .transform_keys(&:to_sym)
41
36
  end
42
37
 
43
38
  def self.valid_editor_type?(type)
@@ -48,6 +43,16 @@ module CKEditor5::Rails::Editor
48
43
 
49
44
  attr_reader :bundle, :watchdog, :type, :config, :editable_height
50
45
 
46
+ def serialized_attributes
47
+ {
48
+ bundle: bundle.to_json,
49
+ plugins: serialize_plugins,
50
+ config: serialize_config,
51
+ watchdog: watchdog
52
+ }
53
+ .merge(editable_height ? { 'editable-height' => editable_height } : {})
54
+ end
55
+
51
56
  def serialize_plugins
52
57
  (config[:plugins] || []).map { |plugin| PropsBasePlugin.normalize(plugin).to_h }.to_json
53
58
  end
@@ -4,20 +4,17 @@ require_relative 'props_base_plugin'
4
4
 
5
5
  module CKEditor5::Rails::Editor
6
6
  class PropsInlinePlugin < PropsBasePlugin
7
- attr_reader :code, :compress
7
+ attr_reader :code
8
8
 
9
- def initialize(name, code, compress: true)
9
+ def initialize(name, code)
10
10
  super(name)
11
11
 
12
12
  raise ArgumentError, 'Code must be a String' unless code.is_a?(String)
13
13
 
14
14
  @code = "(async () => { #{code} })()"
15
- @compress = compress
16
15
  end
17
16
 
18
- def try_compress!
19
- return unless @compress
20
-
17
+ def compress!
21
18
  @code = Terser.new(compress: false, mangle: true).compile(@code)
22
19
  end
23
20
 
@@ -7,11 +7,13 @@ module CKEditor5::Rails::Editor
7
7
  class PropsPatchPlugin < PropsInlinePlugin
8
8
  attr_reader :min_version, :max_version
9
9
 
10
- def initialize(name, code, min_version: nil, max_version: nil, compress: true)
11
- super(name, code, compress: compress)
10
+ def initialize(name, code, min_version: nil, max_version: nil)
11
+ super(name, code)
12
12
 
13
13
  @min_version = min_version && CKEditor5::Rails::Semver.new(min_version)
14
14
  @max_version = max_version && CKEditor5::Rails::Semver.new(max_version)
15
+
16
+ compress!
15
17
  end
16
18
 
17
19
  def self.applicable_for_version?(editor_version, min_version: nil, max_version: nil)
@@ -3,7 +3,10 @@
3
3
  require 'rails/engine'
4
4
 
5
5
  require_relative 'presets/manager'
6
- require_relative 'plugins'
6
+ require_relative 'plugins/simple_upload_adapter'
7
+ require_relative 'plugins/wproofreader'
8
+ require_relative 'plugins/special_characters_bootstrap'
9
+ require_relative 'plugins/custom_translations_loader'
7
10
 
8
11
  module CKEditor5::Rails
9
12
  class PresetNotFoundError < ArgumentError; end
@@ -54,10 +57,7 @@ module CKEditor5::Rails
54
57
 
55
58
  def configure(&block)
56
59
  proxy = ConfigurationProxy.new(config.ckeditor5)
57
-
58
- config.after_initialize do
59
- proxy.instance_eval(&block)
60
- end
60
+ proxy.instance_eval(&block)
61
61
  end
62
62
 
63
63
  def find_preset(preset)
@@ -81,8 +81,7 @@ module CKEditor5::Rails
81
81
  :type, :menubar, :plugins, :plugin, :inline_plugin,
82
82
  :toolbar, :block_toolbar, :balloon_toolbar,
83
83
  :language, :ckbox, :configure, :automatic_upgrades, :simple_upload_adapter,
84
- :editable_height, :wproofreader, :custom_translations, :apply_integration_patches,
85
- :compression, :compression?, to: :default_preset
84
+ :editable_height, :wproofreader, :custom_translations, to: :default_preset
86
85
 
87
86
  def initialize(configuration)
88
87
  @configuration = configuration
@@ -4,8 +4,8 @@ require_relative '../editor/props_inline_plugin'
4
4
 
5
5
  module CKEditor5::Rails::Plugins
6
6
  class CustomTranslationsLoader < CKEditor5::Rails::Editor::PropsInlinePlugin
7
- def initialize(translations, **kwargs) # rubocop:disable Metrics/MethodLength
8
- code = <<~JS
7
+ def initialize(translations) # rubocop:disable Metrics/MethodLength
8
+ code = <<~JS.freeze
9
9
  const { Plugin } = await import('ckeditor5');
10
10
 
11
11
  function resolveTranslationReferences(uiLanguage, config, visited = new WeakSet()) {
@@ -90,7 +90,8 @@ module CKEditor5::Rails::Plugins
90
90
  }
91
91
  JS
92
92
 
93
- super(:CustomTranslationsLoader, code, **kwargs)
93
+ super(:CustomTranslationsLoader, code)
94
+ compress!
94
95
  end
95
96
  end
96
97
  end
@@ -82,8 +82,9 @@ module CKEditor5::Rails::Plugins
82
82
  }
83
83
  JS
84
84
 
85
- def initialize(**kwargs)
86
- super(:SimpleUploadAdapter, PLUGIN_CODE, **kwargs)
85
+ def initialize
86
+ super(:SimpleUploadAdapter, PLUGIN_CODE)
87
+ compress!
87
88
  end
88
89
  end
89
90
  end
@@ -50,8 +50,9 @@ module CKEditor5::Rails::Plugins
50
50
  }
51
51
  JS
52
52
 
53
- def initialize(**kwargs)
54
- super(:SpecialCharactersBootstrap, PLUGIN_CODE, **kwargs)
53
+ def initialize
54
+ super(:SpecialCharactersBootstrap, PLUGIN_CODE)
55
+ compress!
55
56
  end
56
57
  end
57
58
  end
@@ -67,8 +67,9 @@ module CKEditor5::Rails::Plugins
67
67
  }
68
68
  JS
69
69
 
70
- def initialize(**kwargs)
71
- super(:WProofreaderSync, PLUGIN_CODE, **kwargs)
70
+ def initialize
71
+ super(:WProofreaderSync, PLUGIN_CODE)
72
+ compress!
72
73
  end
73
74
  end
74
75
  end
@@ -12,30 +12,11 @@ module CKEditor5::Rails
12
12
  class MissingInlinePluginError < StandardError; end
13
13
  class UnsupportedESModuleError < StandardError; end
14
14
  class InvalidPatchPluginError < ArgumentError; end
15
- class CompressionDisabledError < StandardError; end
16
15
 
17
16
  included do
18
17
  attr_reader :disallow_inline_plugin_compression
19
18
  end
20
19
 
21
- # Sets compression of inline plugin code. Make sure that it is called before setting the version
22
- # or adding plugins.
23
- # @example Disable compression
24
- # compression(enabled: false)
25
- # @return [void]
26
- # @note This method is useful for debugging purposes, as it allows you to see the uncompressed code.
27
- def compression(enabled: false)
28
- @disallow_inline_plugin_compression = !enabled
29
- end
30
-
31
- # Check if compression is enabled
32
- # @return [Boolean] True if compression is enabled, false otherwise
33
- # @example Check if compression is enabled
34
- # compression? # => true
35
- def compression?
36
- !@disallow_inline_plugin_compression
37
- end
38
-
39
20
  # Registers an external plugin loaded from a URL
40
21
  #
41
22
  # @param name [Symbol] Plugin name
@@ -54,7 +35,6 @@ module CKEditor5::Rails
54
35
  #
55
36
  # @param name [Symbol] Plugin name
56
37
  # @param code [String] JavaScript code defining the plugin
57
- # @param compress [Boolean] Whether to compress the code (default: true)
58
38
  # @example Define custom highlight plugin
59
39
  # inline_plugin :MyCustomPlugin, <<~JS
60
40
  # const { Plugin } = await import( 'ckeditor5' );
@@ -69,7 +49,7 @@ module CKEditor5::Rails
69
49
  # }
70
50
  # }
71
51
  # JS
72
- def inline_plugin(name, code, compress: !@disallow_inline_plugin_compression)
52
+ def inline_plugin(name, code)
73
53
  if code.match?(/export default/)
74
54
  raise UnsupportedESModuleError,
75
55
  'Inline plugins must not use ES module syntax!' \
@@ -81,7 +61,8 @@ module CKEditor5::Rails
81
61
  'Plugin code must return a class that extends Plugin!'
82
62
  end
83
63
 
84
- plugin = Editor::PropsInlinePlugin.new(name, code, compress: compress)
64
+ plugin = Editor::PropsInlinePlugin.new(name, code)
65
+ plugin.compress! unless disallow_inline_plugin_compression
85
66
 
86
67
  register_plugin(plugin)
87
68
  end
@@ -140,23 +121,6 @@ module CKEditor5::Rails
140
121
  builder
141
122
  end
142
123
 
143
- # Compresses inline plugins to reduce bundle size
144
- #
145
- # @raise [CompressionDisabledError] If inline plugin compression is disabled
146
- # @example Compress inline plugins
147
- # try_compress_inline_plugins!
148
- # @return [void]
149
- # @note This method is called automatically when defining a preset
150
- def try_compress_inline_plugins!
151
- raise CompressionDisabledError if @disallow_inline_plugin_compression
152
-
153
- config[:plugins].each do |plugin|
154
- next unless plugin.is_a?(Editor::PropsInlinePlugin)
155
-
156
- plugin.try_compress!
157
- end
158
- end
159
-
160
124
  private
161
125
 
162
126
  # Register a plugin in the editor configuration.