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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 384ec0fadd3143749a408679b80aea46b61c8a8740fb06f2e6b24344f8929626
4
- data.tar.gz: edc8fb8ddc4e675638edc023ed9a9327d2c931f5c92010b102c5264c2e11aa12
3
+ metadata.gz: 96d36dda0de7c2996cd72c8299310ec4c125b9dc116eaa0905b6315d7163ef5d
4
+ data.tar.gz: 662863639b11c95b324541e600762a6c020579d0cd5f1897bf490aa42af54bf8
5
5
  SHA512:
6
- metadata.gz: b5518fa67e4c9fc81d63f477a425b2e8d1479f35966bd053eac26f352f12323f730e40e7274b02f981f6161e80787befe5e6000c1473c4c02f203ffd9255c87b
7
- data.tar.gz: 70719e1470023116b6714b3c386de48463c8b776ced330599d13feb5e79365c89fdbe810f3dbdd756786f052c8ae1b65267e8959c0d3ffda25410916cdcb79ec
6
+ metadata.gz: 0a93e0c0f088e10b267d4eb5938a5a0d71589a00d2257f8d472f28ebe18f732c0eb926ee0b8331c8cdaff8f14411f46795697683394cbc180ee34367c21aa852
7
+ data.tar.gz: 67c6218db4f5642a2fa3be5101fe11b1f4a4f47d1dbed601e964231d7037f3cf60a6adb7d982d36e56dff2f76f0c50dd9b165efe5040cb9b7926f3a8e8bf9b37
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # CKEditor 5 Rails Integration ✨
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)
4
- ![NPM Version](https://img.shields.io/npm/v/ckeditor5-rails?style=flat-square)
5
4
  [![Gem Version](https://img.shields.io/gem/v/ckeditor5?style=flat-square)](https://rubygems.org/gems/ckeditor5)
6
5
  [![Gem Total Downloads](https://img.shields.io/gem/dt/ckeditor5?style=flat-square&color=orange)](https://rubygems.org/gems/ckeditor5)
7
6
  [![Coverage](https://img.shields.io/codecov/c/github/mati365/ckeditor5-rails?style=flat-square)](https://codecov.io/gh/mati365/ckeditor5-rails)
@@ -11,12 +10,8 @@
11
10
 
12
11
  CKEditor 5 Ruby on Rails integration gem. Provides seamless integration of CKEditor 5 with Rails applications through web components and helper methods. This gem supports various editor types, including classic, inline, balloon, and decoupled editors. It also includes support for custom plugins, translations, and configuration options.
13
12
 
14
- **Requirements:**
15
- * Ruby >= 2.5
16
- * Rails >= 5.0
17
-
18
13
  > [!IMPORTANT]
19
- > This gem is unofficial and not maintained by CKSource. For official CKEditor 5 documentation, visit [ckeditor.com](https://ckeditor.com/docs/ckeditor5/latest/). If you encounter any issues in editor, please report them on the [GitHub repository](https://github.com/ckeditor/ckeditor5/issues).
14
+ > This gem is unofficial and not maintained by CKSource. For official CKEditor 5 documentation, visit [ckeditor.com](https://ckeditor.com/docs/ckeditor5/latest/). If you encounter any issues in integration, please report them on the [GitHub repository](https://github.com/Mati365/ckeditor5-rails/issues).
20
15
 
21
16
  <p align="center">
22
17
  <img src="docs/intro-classic-editor.png" alt="CKEditor 5 Classic Editor in Ruby on Rails application">
@@ -46,12 +41,8 @@ In your layout:
46
41
  ⚠️ **Important**: When using `importmap-rails`, make sure the importmap
47
42
  tags are rendered after `ckeditor5_assets` helper. In this scenario,
48
43
  content is yielded before rendering `javascript_importmap_tags`.
49
-
50
- If you are not using `importmap-rails`, you can ignore this note and just
51
- include `ckeditor5_assets` helper in the head section of your layout (or using `content_for`).
52
44
  -->
53
45
  <!-- javascript_importmap_tags -->
54
-
55
46
  <%= yield :head %>
56
47
  </head>
57
48
  <body>
@@ -96,7 +87,7 @@ CKEditor5::Rails.configure do
96
87
 
97
88
  # Optionally, you can specify version of CKEditor 5 to use.
98
89
  # If it's not specified the default version specified in the gem will be used.
99
- # version '47.6.0'
90
+ # version '44.3.0'
100
91
 
101
92
  # Upload images to the server using the simple upload adapter, instead of Base64 encoding.
102
93
  # simple_upload_adapter
@@ -110,31 +101,6 @@ end
110
101
 
111
102
  Voilà! You have CKEditor 5 integrated with your Rails application. 🎉
112
103
 
113
- ### If you are not using importmap (custom bundler) 📦
114
-
115
- If your app uses a custom JS bundler (for example Vite, esbuild, or Webpack), install the npm packages and import the integration in your JavaScript bundle.
116
-
117
- ```bash
118
- npm install ckeditor5-rails ckeditor5
119
- ```
120
-
121
- ```js
122
- // app/javascript/application.js (or your main bundle entry)
123
-
124
- import 'ckeditor5-rails';
125
- import 'ckeditor5/ckeditor5.css';
126
- ```
127
-
128
- If you use premium features, also install `ckeditor5-premium-features` and import its CSS.
129
-
130
- ```bash
131
- npm install ckeditor5-premium-features
132
- ```
133
-
134
- ```js
135
- import 'ckeditor5-premium-features/ckeditor5-premium-features.css';
136
- ```
137
-
138
104
  ## Try Demos! 🎮 ✨
139
105
 
140
106
  Explore various editor configurations with the interactive [demo application](https://github.com/Mati365/ckeditor5-rails/tree/main/sandbox/app/views/demos). For additional inspiration, visit the official CKEditor 5 [examples](https://ckeditor.com/docs/ckeditor5/latest/examples/builds/classic-editor.html).
@@ -154,7 +120,6 @@ For extending CKEditor's functionality, refer to the [plugins directory](https:/
154
120
 
155
121
  - [CKEditor 5 Rails Integration ✨](#ckeditor-5-rails-integration-)
156
122
  - [Installation 🛠️](#installation-️)
157
- - [If you are not using importmap (custom bundler) 📦](#if-you-are-not-using-importmap-custom-bundler-)
158
123
  - [Try Demos! 🎮 ✨](#try-demos--)
159
124
  - [Table of Contents 📚](#table-of-contents-)
160
125
  - [Presets 🎨](#presets-)
@@ -181,12 +146,10 @@ For extending CKEditor's functionality, refer to the [plugins directory](https:/
181
146
  - [`inline_plugin(name, code)` method](#inline_pluginname-code-method)
182
147
  - [`external_plugin(name, script:, import_as: nil, window_name: nil, stylesheets: [])` method](#external_pluginname-script-import_as-nil-window_name-nil-stylesheets--method)
183
148
  - [`patch_plugin(plugin)`](#patch_pluginplugin)
184
- - [`apply_integration_patches(compress: false)` method](#apply_integration_patchescompress-false-method)
185
- - [`simple_upload_adapter(url, compress: true)` method](#simple_upload_adapterurl-compress-true-method)
186
- - [`special_characters(compress: true, &block)` method](#special_characterscompress-true-block-method)
187
- - [`wproofreader(version: nil, cdn: nil, compress: true, **config)` method](#wproofreaderversion-nil-cdn-nil-compress-true-config-method)
188
- - [`custom_translations(lang_code = nil, translations = {}, compress: true)` method](#custom_translationslang_code--nil-translations---compress-true-method)
189
- - [`compression(enabled: true)` method](#compressionenabled-true-method)
149
+ - [`simple_upload_adapter(url)` method](#simple_upload_adapterurl-method)
150
+ - [`special_characters(&block)` method](#special_charactersblock-method)
151
+ - [`wproofreader(version: nil, cdn: nil, **config)` method](#wproofreaderversion-nil-cdn-nil-config-method)
152
+ - [`custom_translations(lang_code = nil, translations = {})` method](#custom_translationslang_code--nil-translations---method)
190
153
  - [Controller / View helpers 📦](#controller--view-helpers-)
191
154
  - [`ckeditor5_translation_ref(key)` method](#ckeditor5_translation_refkey-method)
192
155
  - [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
@@ -232,9 +195,7 @@ For extending CKEditor's functionality, refer to the [plugins directory](https:/
232
195
  - [`editor-change` event](#editor-change-event)
233
196
  - [Inline event handling](#inline-event-handling)
234
197
  - [Gem Development 🛠](#gem-development-)
235
- - [Building NPM package 📦](#building-npm-package-)
236
198
  - [Running tests 🧪](#running-tests-)
237
- - [Psst... 👀](#psst-)
238
199
  - [Trademarks 📜](#trademarks-)
239
200
  - [License 📜](#license-)
240
201
 
@@ -249,7 +210,7 @@ You can create your own by defining it in the `config/initializers/ckeditor5.rb`
249
210
 
250
211
  CKEditor5::Rails.configure do
251
212
  # It's possible to override the default preset right in the initializer.
252
- version '47.6.0'
213
+ version '44.3.0'
253
214
 
254
215
  # New presets inherit properties from the default preset defined in the initializer.
255
216
  # In this example, the custom preset inherits everything from default but disables the menubar:
@@ -259,7 +220,7 @@ CKEditor5::Rails.configure do
259
220
 
260
221
  # In order to define preset from scratch, you can use the `inherit: false` option.
261
222
  presets.define :blank_preset, inherit: false do
262
- version '47.6.0'
223
+ version '44.3.0'
263
224
 
264
225
  # It tells the integration to fetch the newest security patches and bug fixes.
265
226
  # It may be disabled, but it's highly recommended to keep it enabled to avoid
@@ -381,24 +342,10 @@ Defines the version of CKEditor 5 to be used. The example below shows how to set
381
342
  CKEditor5::Rails.configure do
382
343
  # ... other configuration
383
344
 
384
- version '47.6.0'
345
+ version '44.3.0'
385
346
  end
386
347
  ```
387
348
 
388
- In order to disable default patches, you can pass the `apply_patches: false` keyword argument to the `version` method.
389
-
390
- ```rb
391
- # config/initializers/ckeditor5.rb
392
-
393
- CKEditor5::Rails.configure do
394
- # ... other configuration
395
-
396
- version '47.6.0', apply_patches: false
397
- end
398
- ```
399
-
400
- The patches are defined in the `lib/ckeditor5/rails/plugins/patches` directory. If you want to apply custom patches, you can use the `patch_plugin` method.
401
-
402
349
  </details>
403
350
 
404
351
  #### `automatic_upgrades(enabled: true)` method
@@ -765,9 +712,7 @@ It is useful when you want to use Balloon Editor or Balloon Toolbar features.
765
712
 
766
713
  <br />
767
714
 
768
- Defines the visibility of the menubar. By default, it's set to `true`. In order to hide the menubar, you can pass the `visible: false` keyword argument.
769
-
770
- The example below shows how to set the menubar visibility:
715
+ Defines the visibility of the menubar. By default, it's set to `true`.
771
716
 
772
717
  ```rb
773
718
  # config/initializers/ckeditor5.rb
@@ -775,7 +720,9 @@ The example below shows how to set the menubar visibility:
775
720
  CKEditor5::Rails.configure do
776
721
  # ... other configuration
777
722
 
778
- menubar visible: false
723
+ toolbar :undo, :redo, :|, :heading, :|, :bold, :italic, :underline, :|,
724
+ :link, :insertImage, :ckbox, :mediaEmbed, :insertTable, :blockQuote, :|,
725
+ :bulletedList, :numberedList, :todoList, :outdent, :indent
779
726
  end
780
727
  ```
781
728
  </details>
@@ -921,9 +868,7 @@ end
921
868
 
922
869
  <br />
923
870
 
924
- ⚠️ **Warning:** Use with caution as this is an inline definition of the plugin code, and it can potentially cause XSS vulnerabilities. Only use this method with static, trusted JavaScript code. In order to pass some dynamic data to such plugin, you can use the `configure` method and override the selected preset in your controller.
925
-
926
- The example below shows how to define a custom plugin that doesn't do anything:
871
+ ⚠️ **Warning:** Use with caution as this is an inline definition of the plugin code, and it can potentially cause XSS vulnerabilities. Only use this method with static, trusted JavaScript code. The example below shows how to define a custom plugin that highlights the text:
927
872
 
928
873
  ```rb
929
874
  # config/initializers/ckeditor5.rb
@@ -1086,35 +1031,13 @@ class YourPatch < CKEditor5::Rails::Editor::PropsPatchPlugin
1086
1031
 
1087
1032
  def initialize
1088
1033
  super(:YourPatch, PLUGIN_CODE, min_version: nil, max_version: '45.0.0')
1034
+ compress!
1089
1035
  end
1090
1036
  end
1091
1037
  ```
1092
1038
  </details>
1093
1039
 
1094
- #### `apply_integration_patches(compress: false)` method
1095
-
1096
- <details>
1097
- <summary>Apply patches to the specific versions of CKEditor 5</summary>
1098
-
1099
- <br />
1100
-
1101
- Defines a method that applies patches to the specific versions of CKEditor 5. The example below shows how to apply patches to the `44.1.0` version:
1102
-
1103
- ```rb
1104
- # config/initializers/ckeditor5.rb
1105
-
1106
- CKEditor5::Rails.configure do
1107
- # ... other configuration
1108
-
1109
- apply_integration_patches
1110
- end
1111
- ```
1112
-
1113
- It's useful when you want to apply patches to the specific versions of CKEditor 5. The patches are defined in the `lib/ckeditor5/rails/plugins/patches` directory.
1114
-
1115
- </details>
1116
-
1117
- #### `simple_upload_adapter(url, compress: true)` method
1040
+ #### `simple_upload_adapter(url)` method
1118
1041
 
1119
1042
  <details>
1120
1043
  <summary>Configure server-side image upload endpoint</summary>
@@ -1137,7 +1060,7 @@ end
1137
1060
  ```
1138
1061
  </details>
1139
1062
 
1140
- #### `special_characters(compress: true, &block)` method
1063
+ #### `special_characters(&block)` method
1141
1064
 
1142
1065
  <details>
1143
1066
  <summary>Configure special characters plugin</summary>
@@ -1183,7 +1106,7 @@ For more info about the special characters plugin, check the [official documenta
1183
1106
 
1184
1107
  </details>
1185
1108
 
1186
- #### `wproofreader(version: nil, cdn: nil, compress: true, **config)` method
1109
+ #### `wproofreader(version: nil, cdn: nil, **config)` method
1187
1110
 
1188
1111
  <details>
1189
1112
  <summary>Configure WProofreader plugin</summary>
@@ -1237,7 +1160,7 @@ For more info about the WProofreader plugin, check the [official documentation](
1237
1160
 
1238
1161
  </details>
1239
1162
 
1240
- #### `custom_translations(lang_code = nil, translations = {}, compress: true)` method
1163
+ #### `custom_translations(lang_code = nil, translations = {})` method
1241
1164
 
1242
1165
  <details>
1243
1166
  <summary>Define custom translations for CKEditor components and UI</summary>
@@ -1270,40 +1193,6 @@ end
1270
1193
 
1271
1194
  </details>
1272
1195
 
1273
- #### `compression(enabled: true)` method
1274
-
1275
- <details>
1276
- <summary>Enable or disable compression of the inline plugins or patches</summary>
1277
-
1278
- <br />
1279
-
1280
- Defines whether the inline plugins should be compressed. It **must** be called before the `inline_plugin` and `version` methods. The example below shows how to disable compression:
1281
-
1282
- ```rb
1283
- # config/initializers/ckeditor5.rb
1284
-
1285
- CKEditor5::Rails.configure do
1286
- compression enabled: false
1287
-
1288
- # ... other configuration
1289
- end
1290
- ```
1291
-
1292
- :warning: Compression is enabled by default, and it's recommended to keep it enabled for production environments. It reduces the size of the inline plugins and patches, which improves the loading time of the editor.
1293
- If you want to disable compression for a specific plugin, you can pass the `compress: false` keyword argument to the `inline_plugin` method:
1294
-
1295
- ```rb
1296
- # config/initializers/ckeditor5.rb
1297
-
1298
- CKEditor5::Rails.configure do
1299
- # ... other configuration
1300
-
1301
- inline_plugin :MyCustomPlugin, plugin_code, compress: false
1302
- end
1303
- ```
1304
-
1305
- </details>
1306
-
1307
1196
  ### Controller / View helpers 📦
1308
1197
 
1309
1198
  #### `ckeditor5_translation_ref(key)` method
@@ -1373,7 +1262,7 @@ It may be useful when you want to define a preset based on the current user or r
1373
1262
  class ApplicationController < ActionController::Base
1374
1263
  def show
1375
1264
  @preset = ckeditor5_preset do
1376
- version '47.6.0'
1265
+ version '44.3.0'
1377
1266
 
1378
1267
  toolbar :sourceEditing, :|, :bold, :italic, :underline, :strikethrough,
1379
1268
  :subscript, :superscript, :removeFormat, :|, :bulletedList, :numberedList,
@@ -1408,7 +1297,7 @@ If you want to override the preset defined in the initializer, you can search fo
1408
1297
  class ApplicationController < ActionController::Base
1409
1298
  def show
1410
1299
  @preset = ckeditor5_preset(:default).override do
1411
- version '47.6.0'
1300
+ version '44.3.0'
1412
1301
 
1413
1302
  toolbar :sourceEditing, :|, :bold, :italic, :underline, :strikethrough,
1414
1303
  :subscript, :superscript, :removeFormat, :|, :bulletedList, :numberedList,
@@ -1581,7 +1470,7 @@ In that scenario it's recommended to add `gpl` method to the initializer along w
1581
1470
 
1582
1471
  CKEditor5::Rails.configure do
1583
1472
  gpl
1584
- version '47.6.0'
1473
+ version '44.3.0'
1585
1474
  end
1586
1475
  ```
1587
1476
 
@@ -1950,13 +1839,13 @@ For example:
1950
1839
  ⚠️ Direct access of `instance` property of the web component. Keep in mind it's unsafe and may cause issues if the editor is not loaded yet.
1951
1840
 
1952
1841
  ```js
1953
- document.getElementById('editor').instance;
1842
+ document.getElementById('editor').instance
1954
1843
  ```
1955
1844
 
1956
1845
  👌 Accessing the editor instance using `instancePromise` property. It's a promise that resolves to the editor instance when the editor is ready.
1957
1846
 
1958
1847
  ```js
1959
- document.getElementById('editor').instancePromise.then((editor) => {
1848
+ document.getElementById('editor').instancePromise.then(editor => {
1960
1849
  console.log(editor);
1961
1850
  });
1962
1851
  ```
@@ -1964,7 +1853,7 @@ document.getElementById('editor').instancePromise.then((editor) => {
1964
1853
  ✅ Accessing the editor through the `runAfterEditorReady` helper method. It's a safe way to access the editor instance when the editor is ready.
1965
1854
 
1966
1855
  ```js
1967
- document.getElementById('editor').runAfterEditorReady((editor) => {
1856
+ document.getElementById('editor').runAfterEditorReady(editor => {
1968
1857
  console.log(editor);
1969
1858
  });
1970
1859
  ```
@@ -2364,18 +2253,9 @@ If you want to contribute to the gem, you can clone the repository and run the f
2364
2253
  ```sh
2365
2254
  gem install bundler -v 2.5.22
2366
2255
  bundle install
2367
- npm install
2368
2256
  bundle exec guard -g rails
2369
2257
  ```
2370
2258
 
2371
- ### Building NPM package 📦
2372
-
2373
- To build the NPM package, you can run the following command:
2374
-
2375
- ```sh
2376
- npm run build
2377
- ```
2378
-
2379
2259
  ### Running tests 🧪
2380
2260
 
2381
2261
  You can run the tests using the following command:
@@ -2390,19 +2270,6 @@ If you want to watch the tests, you can use the following command:
2390
2270
  bundle exec guard -g rspec
2391
2271
  ```
2392
2272
 
2393
- ## Psst... 👀
2394
-
2395
- If you're looking for similar stuff, check these out:
2396
-
2397
- * [ckeditor5-phoenix](https://github.com/Mati365/ckeditor5-phoenix)
2398
- Seamless CKEditor 5 integration for Phoenix Framework. Plug & play support for LiveView forms with dynamic content, localization, and custom builds.
2399
-
2400
- * [ckeditor5-livewire](https://github.com/Mati365/ckeditor5-livewire)
2401
- Drop-in CKEditor 5 solution for Laravel + Livewire apps. Works great with Blade forms too. Includes JS hooks, flexible config, and easy customization.
2402
-
2403
- * [ckeditor5-symfony](https://github.com/Mati365/ckeditor5-symfony)
2404
- Native CKEditor 5 integration for Symfony. Works with Symfony 6.x+, standard forms and Twig. Supports custom builds, multiple editor configurations, asset management, and localization. Designed to be simple, predictable, and framework-native.
2405
-
2406
2273
  ## Trademarks 📜
2407
2274
 
2408
2275
  CKEditor® is a trademark of [CKSource Holding sp. z o.o.](https://cksource.com/) All rights reserved. For more information about the license of CKEditor® please visit [CKEditor's licensing page](https://ckeditor.com/legal/ckeditor-oss-license/).
@@ -52,9 +52,9 @@ module CKEditor5::Rails::Assets
52
52
  private
53
53
 
54
54
  def window_scripts_tags(nonce: nil)
55
- scripts = bundle.scripts.map do |script|
55
+ scripts = bundle.scripts.filter_map do |script|
56
56
  tag.script(src: script.url, nonce: nonce, crossorigin: 'anonymous') if script.window?
57
- end.compact
57
+ end
58
58
 
59
59
  safe_join(scripts)
60
60
  end
@@ -8,14 +8,33 @@ module CKEditor5::Rails::Assets
8
8
  include ActionView::Helpers::TagHelper
9
9
  include Singleton
10
10
 
11
- NPM_PACKAGE_PATH = File.join(__dir__, '..', '..', '..', '..', 'npm_package').freeze
11
+ WEBCOMPONENTS_PATH = File.join(__dir__, 'webcomponents')
12
+ WEBCOMPONENTS_MODULES = [
13
+ 'utils.mjs',
14
+ 'components/editable.mjs',
15
+ 'components/ui-part.mjs',
16
+ 'components/editor.mjs',
17
+ 'components/context.mjs'
18
+ ].freeze
12
19
 
13
20
  def source
14
- @source ||= File.read(File.join(NPM_PACKAGE_PATH, 'dist/index.cjs')).html_safe
21
+ @source ||= compress_source(raw_source)
15
22
  end
16
23
 
17
24
  def to_html(nonce: nil)
18
25
  tag.script(source, type: 'module', nonce: nonce)
19
26
  end
27
+
28
+ private
29
+
30
+ def raw_source
31
+ @raw_source ||= WEBCOMPONENTS_MODULES.map do |file|
32
+ File.read(File.join(WEBCOMPONENTS_PATH, file))
33
+ end.join("\n")
34
+ end
35
+
36
+ def compress_source(code)
37
+ Terser.new(compress: true, mangle: true).compile(code).html_safe
38
+ end
20
39
  end
21
40
  end
@@ -0,0 +1,123 @@
1
+ class CKEditorContextComponent extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ['plugins', 'config'];
4
+ }
5
+
6
+ /** @type {import('ckeditor5').Context|null} */
7
+ instance = null;
8
+
9
+ /** @type {Promise<import('ckeditor5').Context>} */
10
+ instancePromise = Promise.withResolvers();
11
+
12
+ /** @type {Set<CKEditorComponent>} */
13
+ #connectedEditors = new Set();
14
+
15
+ async connectedCallback() {
16
+ try {
17
+ execIfDOMReady(() => this.#initializeContext());
18
+ } catch (error) {
19
+ console.error('Failed to initialize context:', error);
20
+ this.dispatchEvent(new CustomEvent('context-error', { detail: error }));
21
+ }
22
+ }
23
+
24
+ async attributeChangedCallback(name, oldValue, newValue) {
25
+ if (oldValue !== null && oldValue !== newValue) {
26
+ await this.#initializeContext();
27
+ }
28
+ }
29
+
30
+ async disconnectedCallback() {
31
+ if (this.instance) {
32
+ await this.instance.destroy();
33
+ this.instance = null;
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Register editor component with this context
39
+ *
40
+ * @param {CKEditorComponent} editor
41
+ */
42
+ registerEditor(editor) {
43
+ this.#connectedEditors.add(editor);
44
+ }
45
+
46
+ /**
47
+ * Unregister editor component from this context
48
+ *
49
+ * @param {CKEditorComponent} editor
50
+ */
51
+ unregisterEditor(editor) {
52
+ this.#connectedEditors.delete(editor);
53
+ }
54
+
55
+ /**
56
+ * Initialize CKEditor context with shared configuration
57
+ *
58
+ * @private
59
+ */
60
+ async #initializeContext() {
61
+ if (this.instance) {
62
+ this.instancePromise = Promise.withResolvers();
63
+
64
+ await this.instance.destroy();
65
+
66
+ this.instance = null;
67
+ }
68
+
69
+ // Broadcast context initialization event
70
+ window.dispatchEvent(
71
+ new CustomEvent('ckeditor:context:attach:before', { detail: { element: this } })
72
+ );
73
+
74
+ const { Context, ContextWatchdog } = await import('ckeditor5');
75
+ const plugins = await this.#getPlugins();
76
+ const config = this.#getConfig();
77
+
78
+ // Broadcast context mounting event with configuration
79
+ window.dispatchEvent(
80
+ new CustomEvent('ckeditor:context:attach', { detail: { config, element: this } })
81
+ );
82
+
83
+ this.instance = new ContextWatchdog(Context, {
84
+ crashNumberLimit: 10
85
+ });
86
+
87
+ await this.instance.create({
88
+ ...config,
89
+ plugins
90
+ });
91
+
92
+ this.instance.on('itemError', (...args) => {
93
+ console.error('Context item error:', ...args);
94
+ });
95
+
96
+ this.instancePromise.resolve(this.instance);
97
+ this.dispatchEvent(new CustomEvent('context-ready', { detail: this.instance }));
98
+
99
+ // Reinitialize connected editors.
100
+ await Promise.all(
101
+ [...this.#connectedEditors].map(editor => editor.reinitializeEditor())
102
+ );
103
+ }
104
+
105
+ async #getPlugins() {
106
+ const raw = this.getAttribute('plugins');
107
+
108
+ return loadAsyncImports(raw ? JSON.parse(raw) : []);
109
+ }
110
+
111
+ /**
112
+ * Gets context configuration with resolved element references.
113
+ *
114
+ * @private
115
+ */
116
+ #getConfig() {
117
+ const config = JSON.parse(this.getAttribute('config') || '{}');
118
+
119
+ return resolveElementReferences(config);
120
+ }
121
+ }
122
+
123
+ customElements.define('ckeditor-context-component', CKEditorContextComponent);
@@ -0,0 +1,113 @@
1
+ class CKEditorEditableComponent extends HTMLElement {
2
+ /**
3
+ * List of attributes that trigger updates when changed
4
+ *
5
+ * @static
6
+ * @returns {string[]} Array of attribute names to observe
7
+ */
8
+ static get observedAttributes() {
9
+ return ['name'];
10
+ }
11
+
12
+ /**
13
+ * Gets the name of this editable region
14
+ *
15
+ * @returns {string} The name attribute value
16
+ */
17
+ get name() {
18
+ // The default value is set mainly for decoupled editors where the name is not required.
19
+ return this.getAttribute('name') || 'editable';
20
+ }
21
+
22
+ /**
23
+ * Gets the actual editable DOM element
24
+ * @returns {HTMLDivElement|null} The div element containing editable content
25
+ */
26
+ get editableElement() {
27
+ return this.querySelector('div');
28
+ }
29
+
30
+ /**
31
+ * Lifecycle callback when element is added to DOM
32
+ * Sets up the editable element and registers it with the parent editor
33
+ *
34
+ * @throws {Error} If not used as child of ckeditor-component
35
+ */
36
+ connectedCallback() {
37
+ execIfDOMReady(() => {
38
+ const editorComponent = this.#queryEditorElement();
39
+
40
+ if (!editorComponent ) {
41
+ throw new Error('ckeditor-editable-component must be a child of ckeditor-component');
42
+ }
43
+
44
+ this.innerHTML = `<div>${this.innerHTML}</div>`;
45
+ this.style.display = 'block';
46
+
47
+ if (editorComponent.isDecoupled()) {
48
+ editorComponent.runAfterEditorReady(editor => {
49
+ this.appendChild(editor.ui.view[this.name].element);
50
+ });
51
+ } else {
52
+ if (!this.name) {
53
+ throw new Error('Editable component missing required "name" attribute');
54
+ }
55
+
56
+ editorComponent.editables[this.name] = this;
57
+ }
58
+ });
59
+ }
60
+
61
+ /**
62
+ * Lifecycle callback for attribute changes
63
+ * Handles name changes and propagates other attributes to editable element
64
+ *
65
+ * @param {string} name - Name of changed attribute
66
+ * @param {string|null} oldValue - Previous value
67
+ * @param {string|null} newValue - New value
68
+ */
69
+ attributeChangedCallback(name, oldValue, newValue) {
70
+ if (oldValue === newValue) {
71
+ return;
72
+ }
73
+
74
+ if (name === 'name') {
75
+ if (!oldValue) {
76
+ return;
77
+ }
78
+
79
+ const editorComponent = this.#queryEditorElement();
80
+
81
+ if (editorComponent) {
82
+ editorComponent.editables[newValue] = editorComponent.editables[oldValue];
83
+ delete editorComponent.editables[oldValue];
84
+ }
85
+ } else {
86
+ this.editableElement.setAttribute(name, newValue);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Lifecycle callback when element is removed
92
+ * Un-registers this editable from the parent editor
93
+ */
94
+ disconnectedCallback() {
95
+ const editorComponent = this.#queryEditorElement();
96
+
97
+ if (editorComponent) {
98
+ delete editorComponent.editables[this.name];
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Finds the parent editor component
104
+ *
105
+ * @private
106
+ * @returns {CKEditorComponent|null} Parent editor component or null if not found
107
+ */
108
+ #queryEditorElement() {
109
+ return this.closest('ckeditor-component') || document.body.querySelector('ckeditor-component');
110
+ }
111
+ }
112
+
113
+ customElements.define('ckeditor-editable-component', CKEditorEditableComponent);