ckeditor5 1.26.2 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +65 -0
- data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +14 -0
- data/lib/ckeditor5/rails/engine.rb +1 -1
- data/lib/ckeditor5/rails/plugins/custom_translations_loader.rb +97 -0
- data/lib/ckeditor5/rails/plugins.rb +1 -0
- data/lib/ckeditor5/rails/presets/preset_builder.rb +41 -8
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/spec/e2e/features/ajax_form_integration_spec.rb +1 -1
- data/spec/e2e/features/editor_types_spec.rb +3 -3
- data/spec/e2e/features/form_integration_spec.rb +1 -1
- data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +56 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93b0f87e014924cf2ba04dc4d8ce96afef84152c4c8fc7bdebf5a736db864b95
|
4
|
+
data.tar.gz: 02b97648d5c94907741382795721e5944ecc0752c3b2792cfe0c7455c482f81f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992f3a903d5bd123e91b572f0d0154c42044f90768264fe07a5c61d343431921ed3a45515f8f74ad48a68a0870876e9f73184cdc14266f4c0e43a4f393306a93
|
7
|
+
data.tar.gz: 64a1063477787141603fd850b6de704223c15b8dd6dbedcd713ea4a5ae69fb1ebf630ba1eaef9fc245a95272f4b32b40618065e04e0c69d72b8536677ef107bd
|
data/README.md
CHANGED
@@ -149,7 +149,9 @@ For extending CKEditor's functionality, refer to the [plugins directory](https:/
|
|
149
149
|
- [`simple_upload_adapter(url)` method](#simple_upload_adapterurl-method)
|
150
150
|
- [`special_characters(&block)` method](#special_charactersblock-method)
|
151
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)
|
152
153
|
- [Controller / View helpers 📦](#controller--view-helpers-)
|
154
|
+
- [`ckeditor5_translation_ref(key)` method](#ckeditor5_translation_refkey-method)
|
153
155
|
- [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
|
154
156
|
- [`ckeditor5_preset(name = nil, &block)` method](#ckeditor5_presetname--nil-block-method)
|
155
157
|
- [Including CKEditor 5 assets 📦](#including-ckeditor-5-assets-)
|
@@ -1197,8 +1199,71 @@ For more info about the WProofreader plugin, check the [official documentation](
|
|
1197
1199
|
|
1198
1200
|
</details>
|
1199
1201
|
|
1202
|
+
#### `custom_translations(lang_code = nil, translations = {})` method
|
1203
|
+
|
1204
|
+
<details>
|
1205
|
+
<summary>Define custom translations for CKEditor components and UI</summary>
|
1206
|
+
|
1207
|
+
<br />
|
1208
|
+
|
1209
|
+
Allows setting custom translations for editor components, UI elements, and headings. The translations are applied globally since they override the global translation object.
|
1210
|
+
|
1211
|
+
> [!NOTE]
|
1212
|
+
> This helper allows overriding builtin translations of the editor, but translations are overridden globally, as the CKEditor 5 uses a single translation object for all instances of the editor. It's recommended to use the `ckeditor5_translation_ref` helper to reference the translations in the configuration.
|
1213
|
+
|
1214
|
+
```rb
|
1215
|
+
# config/initializers/ckeditor5.rb
|
1216
|
+
|
1217
|
+
CKEditor5::Rails.configure do
|
1218
|
+
# ... other configuration
|
1219
|
+
|
1220
|
+
custom_translations :en, {
|
1221
|
+
'Heading 1': 'Your custom translation value'
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
configure :heading, {
|
1225
|
+
options: [
|
1226
|
+
{ model: 'heading1', title: ckeditor5_translation_ref('Heading 1') },
|
1227
|
+
# ...
|
1228
|
+
]
|
1229
|
+
}
|
1230
|
+
end
|
1231
|
+
```
|
1232
|
+
|
1233
|
+
</details>
|
1234
|
+
|
1200
1235
|
### Controller / View helpers 📦
|
1201
1236
|
|
1237
|
+
#### `ckeditor5_translation_ref(key)` method
|
1238
|
+
|
1239
|
+
<details>
|
1240
|
+
<summary>Defines a reference to a CKEditor 5 translation</summary>
|
1241
|
+
|
1242
|
+
<br />
|
1243
|
+
|
1244
|
+
Allows you to reference CKEditor 5 translations in the configuration. It's particularly useful when you want to use custom translations in the editor configuration.
|
1245
|
+
|
1246
|
+
```rb
|
1247
|
+
# config/initializers/ckeditor5.rb
|
1248
|
+
|
1249
|
+
CKEditor5::Rails.configure do
|
1250
|
+
# ... other configuration
|
1251
|
+
|
1252
|
+
custom_translations :en, {
|
1253
|
+
'Heading 1': 'Your custom translation value'
|
1254
|
+
}
|
1255
|
+
|
1256
|
+
configure :heading, {
|
1257
|
+
options: [
|
1258
|
+
{ model: 'heading1', title: ckeditor5_translation_ref('Heading 1') },
|
1259
|
+
# ...
|
1260
|
+
]
|
1261
|
+
}
|
1262
|
+
end
|
1263
|
+
```
|
1264
|
+
|
1265
|
+
</details>
|
1266
|
+
|
1202
1267
|
#### `ckeditor5_element_ref(selector)` method
|
1203
1268
|
|
1204
1269
|
<details>
|
@@ -17,6 +17,20 @@ module CKEditor5::Rails::Editor::Helpers
|
|
17
17
|
{ '$element': selector }
|
18
18
|
end
|
19
19
|
|
20
|
+
# Creates a reference to a translation key that will be used by CKEditor.
|
21
|
+
# This helper creates a special object that CKEditor recognizes as a translation reference.
|
22
|
+
#
|
23
|
+
# @param key [String] The translation key to reference
|
24
|
+
# @return [Hash] A hash with the translation reference in CKEditor's format
|
25
|
+
#
|
26
|
+
# @example Referencing a translation in plugin configuration
|
27
|
+
# configure :toolbar, {
|
28
|
+
# placeholder: ckeditor5_translation_ref("editor.placeholder")
|
29
|
+
# }
|
30
|
+
def ckeditor5_translation_ref(key)
|
31
|
+
{ '$translation': key }
|
32
|
+
end
|
33
|
+
|
20
34
|
# Creates or retrieves a preset configuration for CKEditor.
|
21
35
|
# When called with a name, finds and returns an existing preset.
|
22
36
|
# When called with a block, creates a new preset with the given configuration.
|
@@ -78,7 +78,7 @@ module CKEditor5::Rails
|
|
78
78
|
:type, :menubar, :plugins, :plugin, :inline_plugin,
|
79
79
|
:toolbar, :block_toolbar, :balloon_toolbar,
|
80
80
|
:language, :ckbox, :configure, :automatic_upgrades, :simple_upload_adapter,
|
81
|
-
:editable_height, :wproofreader, to: :default_preset
|
81
|
+
:editable_height, :wproofreader, :custom_translations, to: :default_preset
|
82
82
|
|
83
83
|
def initialize(configuration)
|
84
84
|
@configuration = configuration
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../editor/props_inline_plugin'
|
4
|
+
|
5
|
+
module CKEditor5::Rails::Plugins
|
6
|
+
class CustomTranslationsLoader < CKEditor5::Rails::Editor::PropsInlinePlugin
|
7
|
+
def initialize(translations) # rubocop:disable Metrics/MethodLength
|
8
|
+
code = <<~JS.freeze
|
9
|
+
const { Plugin } = await import('ckeditor5');
|
10
|
+
|
11
|
+
function resolveTranslationReferences(uiLanguage, config, visited = new WeakSet()) {
|
12
|
+
if (!config || typeof config !== 'object') {
|
13
|
+
return config;
|
14
|
+
}
|
15
|
+
|
16
|
+
if (visited.has(config)) {
|
17
|
+
return config;
|
18
|
+
}
|
19
|
+
|
20
|
+
visited.add(config);
|
21
|
+
|
22
|
+
if (Array.isArray(config)) {
|
23
|
+
config.forEach((item, index) => {
|
24
|
+
config[index] = resolveTranslationReferences(uiLanguage, item, visited);
|
25
|
+
});
|
26
|
+
|
27
|
+
return config;
|
28
|
+
}
|
29
|
+
|
30
|
+
for (const key of Object.getOwnPropertyNames(config)) {
|
31
|
+
const value = config[key];
|
32
|
+
|
33
|
+
if (value && typeof value === 'object') {
|
34
|
+
if (value.$translation) {
|
35
|
+
const translationKey = value.$translation;
|
36
|
+
const translations = window.CKEDITOR_TRANSLATIONS?.[uiLanguage];
|
37
|
+
|
38
|
+
if (!translations?.dictionary[translationKey]) {
|
39
|
+
console.warn(`Translation not found for key: ${translationKey}`);
|
40
|
+
}
|
41
|
+
|
42
|
+
config[key] = translations?.dictionary[translationKey] || translationKey;
|
43
|
+
} else {
|
44
|
+
resolveTranslationReferences(uiLanguage, value, visited);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
return config;
|
50
|
+
}
|
51
|
+
|
52
|
+
return class CustomTranslationsLoader extends Plugin {
|
53
|
+
static CUSTOM_TRANSLATIONS = Object.create( #{translations.to_json} );
|
54
|
+
|
55
|
+
static get pluginName() {
|
56
|
+
return 'CustomTranslationsLoader';
|
57
|
+
}
|
58
|
+
|
59
|
+
constructor( editor ) {
|
60
|
+
super( editor );
|
61
|
+
|
62
|
+
const { locale, config } = this.editor;
|
63
|
+
|
64
|
+
this.#extendPack();
|
65
|
+
resolveTranslationReferences(locale.uiLanguage, config._config)
|
66
|
+
}
|
67
|
+
|
68
|
+
#extendPack() {
|
69
|
+
const { uiLanguage } = this.editor.locale;
|
70
|
+
const translations = this.#translations;
|
71
|
+
|
72
|
+
if (!window.CKEDITOR_TRANSLATIONS) {
|
73
|
+
window.CKEDITOR_TRANSLATIONS = {};
|
74
|
+
}
|
75
|
+
|
76
|
+
if (!window.CKEDITOR_TRANSLATIONS[uiLanguage]) {
|
77
|
+
window.CKEDITOR_TRANSLATIONS[uiLanguage] = { dictionary: {} };
|
78
|
+
}
|
79
|
+
|
80
|
+
Object.entries(translations).forEach(([key, value]) => {
|
81
|
+
window.CKEDITOR_TRANSLATIONS[uiLanguage].dictionary[key] = value;
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
get #translations() {
|
86
|
+
const { uiLanguage } = this.editor.locale;
|
87
|
+
|
88
|
+
return CustomTranslationsLoader.CUSTOM_TRANSLATIONS[uiLanguage];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
JS
|
92
|
+
|
93
|
+
super(:CustomTranslationsLoader, code)
|
94
|
+
compress!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -9,6 +9,7 @@ end
|
|
9
9
|
require_relative 'plugins/simple_upload_adapter'
|
10
10
|
require_relative 'plugins/wproofreader'
|
11
11
|
require_relative 'plugins/special_characters_bootstrap'
|
12
|
+
require_relative 'plugins/custom_translations_loader'
|
12
13
|
|
13
14
|
# Plugin patches and fixes
|
14
15
|
require_relative 'plugins/patches/fix_color_picker_race_condition'
|
@@ -6,7 +6,7 @@ require_relative 'special_characters_builder'
|
|
6
6
|
|
7
7
|
module CKEditor5::Rails
|
8
8
|
module Presets
|
9
|
-
class PresetBuilder
|
9
|
+
class PresetBuilder # rubocop:disable Metrics/ClassLength
|
10
10
|
include Editor::Helpers::Config
|
11
11
|
include Concerns::ConfigurationMethods
|
12
12
|
include Concerns::PluginMethods
|
@@ -27,6 +27,7 @@ module CKEditor5::Rails
|
|
27
27
|
@ckbox = nil
|
28
28
|
@editable_height = nil
|
29
29
|
@automatic_upgrades = false
|
30
|
+
@custom_translations = {}
|
30
31
|
@config = {
|
31
32
|
plugins: [],
|
32
33
|
toolbar: []
|
@@ -35,6 +36,12 @@ module CKEditor5::Rails
|
|
35
36
|
instance_eval(&block) if block_given?
|
36
37
|
end
|
37
38
|
|
39
|
+
def deconstruct_keys(keys)
|
40
|
+
keys.index_with do |key|
|
41
|
+
public_send(key)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
38
45
|
# @example Copy preset and modify it
|
39
46
|
# original = PresetBuilder.new
|
40
47
|
# copied = original.initialize_copy(original)
|
@@ -43,6 +50,7 @@ module CKEditor5::Rails
|
|
43
50
|
|
44
51
|
@translations = source.translations.dup
|
45
52
|
@ckbox = source.ckbox.dup if source.ckbox
|
53
|
+
@custom_translations = source.custom_translations.deep_dup
|
46
54
|
@config = {
|
47
55
|
plugins: source.config[:plugins].map(&:dup),
|
48
56
|
toolbar: deep_copy_toolbar(source.config[:toolbar])
|
@@ -63,12 +71,6 @@ module CKEditor5::Rails
|
|
63
71
|
license_key == 'GPL'
|
64
72
|
end
|
65
73
|
|
66
|
-
def deconstruct_keys(keys)
|
67
|
-
keys.index_with do |key|
|
68
|
-
public_send(key)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
74
|
# Create a new preset by overriding current configuration
|
73
75
|
# @example Override existing preset
|
74
76
|
# preset.override do
|
@@ -199,7 +201,7 @@ module CKEditor5::Rails
|
|
199
201
|
# Apply integration patches for the current version
|
200
202
|
# @return [void]
|
201
203
|
def apply_integration_patches
|
202
|
-
patch_plugin
|
204
|
+
patch_plugin(Plugins::Patches::FixColorPickerRaceCondition.new)
|
203
205
|
end
|
204
206
|
|
205
207
|
# Enable or disable automatic version upgrades
|
@@ -333,6 +335,37 @@ module CKEditor5::Rails
|
|
333
335
|
config[:language].present?
|
334
336
|
end
|
335
337
|
|
338
|
+
# Configure custom translations for the editor
|
339
|
+
# @param lang_code [Symbol] Language code for translations (e.g. :en, :pl)
|
340
|
+
# @param translations [Hash] A hash containing translations in format { key => translation }
|
341
|
+
# @example Add multiple translations
|
342
|
+
# custom_translations :en, {
|
343
|
+
# 'my.button': 'My Button'
|
344
|
+
# }
|
345
|
+
# custom_translations :pl, {
|
346
|
+
# 'my.button': 'Mój przycisk'
|
347
|
+
# }
|
348
|
+
# @example Use translations in configuration with ckeditor5_translation_ref
|
349
|
+
# custom_translations :en, {
|
350
|
+
# 'custom.heading': 'Custom Section'
|
351
|
+
# }
|
352
|
+
#
|
353
|
+
# configure :heading, {
|
354
|
+
# options: [
|
355
|
+
# { model: 'heading1', title: ckeditor5_translation_ref('custom.heading') }
|
356
|
+
# ]
|
357
|
+
# }
|
358
|
+
# @return [void]
|
359
|
+
def custom_translations(lang_code = nil, translations = {})
|
360
|
+
return @custom_translations if lang_code.blank?
|
361
|
+
|
362
|
+
@custom_translations[lang_code.to_sym] ||= {}
|
363
|
+
@custom_translations[lang_code.to_sym].merge!(translations)
|
364
|
+
|
365
|
+
plugins.remove(:CustomTranslationsLoader)
|
366
|
+
plugins.prepend(Plugins::CustomTranslationsLoader.new(@custom_translations))
|
367
|
+
end
|
368
|
+
|
336
369
|
# Configure editor language
|
337
370
|
# @param ui [Symbol, nil] UI language code
|
338
371
|
# @param content [Symbol] Content language code
|
@@ -8,7 +8,7 @@ RSpec.describe 'AJAX Form Integration', type: :feature, js: true do
|
|
8
8
|
setup_form_tracking(page)
|
9
9
|
end
|
10
10
|
|
11
|
-
shared_examples 'an ajax form with CKEditor' do |form_testid, editor_testid, submit_testid, response_id|
|
11
|
+
shared_examples 'an ajax form with CKEditor' do |form_testid, editor_testid, submit_testid, response_id|
|
12
12
|
let(:form) { find("[data-testid='#{form_testid}']") }
|
13
13
|
let(:editor) { find("[data-testid='#{editor_testid}']") }
|
14
14
|
let(:editable) { editor.find('.ck-editor__editable') }
|
@@ -44,10 +44,10 @@ RSpec.describe 'CKEditor5 Types Integration', type: :feature, js: true do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
shared_examples 'a multiroot editor that fires change events' do |path, editables|
|
47
|
+
shared_examples 'a multiroot editor that fires change events' do |path, editables|
|
48
48
|
before { visit path }
|
49
49
|
|
50
|
-
it 'sends properly change events with proper payload for editables' do
|
50
|
+
it 'sends properly change events with proper payload for editables' do
|
51
51
|
editors = editables.map do |name|
|
52
52
|
find("[data-testid='#{name}-editable']")
|
53
53
|
end
|
@@ -151,7 +151,7 @@ RSpec.describe 'CKEditor5 Types Integration', type: :feature, js: true do
|
|
151
151
|
expect(page).to have_css('.ck-toolbar', count: 1)
|
152
152
|
end
|
153
153
|
|
154
|
-
it 'handles dynamically added editables' do
|
154
|
+
it 'handles dynamically added editables' do
|
155
155
|
# Set up event listener
|
156
156
|
page.execute_script(<<~JS)
|
157
157
|
window._newEditableEvents = [];
|
@@ -8,7 +8,7 @@ RSpec.describe 'Form Integration', type: :feature, js: true do
|
|
8
8
|
setup_form_tracking(page)
|
9
9
|
end
|
10
10
|
|
11
|
-
shared_examples 'a form with CKEditor' do |form_testid, editor_testid, submit_testid|
|
11
|
+
shared_examples 'a form with CKEditor' do |form_testid, editor_testid, submit_testid|
|
12
12
|
let(:form) { find("[data-testid='#{form_testid}']") }
|
13
13
|
let(:editor) { find("[data-testid='#{editor_testid}']") }
|
14
14
|
let(:editable) { editor.find('.ck-editor__editable') }
|
@@ -494,6 +494,61 @@ RSpec.describe CKEditor5::Rails::Presets::PresetBuilder do
|
|
494
494
|
end
|
495
495
|
end
|
496
496
|
|
497
|
+
describe '#custom_translations' do
|
498
|
+
it 'returns empty hash when called without arguments' do
|
499
|
+
expect(builder.custom_translations).to eq({})
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'stores translations for a language' do
|
503
|
+
translations = { 'my.button': 'My Button' }
|
504
|
+
builder.custom_translations(:en, translations)
|
505
|
+
expect(builder.custom_translations).to eq({ en: translations })
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'merges translations for the same language' do
|
509
|
+
builder.custom_translations(:en, { 'button.one': 'One' })
|
510
|
+
builder.custom_translations(:en, { 'button.two': 'Two' })
|
511
|
+
|
512
|
+
expect(builder.custom_translations[:en]).to eq({
|
513
|
+
'button.one': 'One',
|
514
|
+
'button.two': 'Two'
|
515
|
+
})
|
516
|
+
end
|
517
|
+
|
518
|
+
it 'handles multiple languages' do
|
519
|
+
builder.custom_translations(:en, { 'button': 'Button' })
|
520
|
+
builder.custom_translations(:pl, { 'button': 'Przycisk' })
|
521
|
+
|
522
|
+
expect(builder.custom_translations).to eq({
|
523
|
+
en: { button: 'Button' },
|
524
|
+
pl: { button: 'Przycisk' }
|
525
|
+
})
|
526
|
+
end
|
527
|
+
|
528
|
+
it 'normalizes language codes to symbols' do
|
529
|
+
builder.custom_translations('EN', { 'button': 'Button' })
|
530
|
+
expect(builder.custom_translations.keys).to eq([:EN])
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'adds and replaces CustomTranslationsLoader plugin' do
|
534
|
+
translations = { 'my.button': 'My Button' }
|
535
|
+
|
536
|
+
expect do
|
537
|
+
builder.custom_translations(:en, translations)
|
538
|
+
end.to change { builder.config[:plugins].count }.by(1)
|
539
|
+
|
540
|
+
plugin = builder.config[:plugins].first
|
541
|
+
expect(plugin).to be_a(CKEditor5::Rails::Plugins::CustomTranslationsLoader)
|
542
|
+
|
543
|
+
# Adding more translations should replace the plugin
|
544
|
+
expect do
|
545
|
+
builder.custom_translations(:pl, { 'my.button': 'Mój przycisk' })
|
546
|
+
end.not_to(change { builder.config[:plugins].count })
|
547
|
+
|
548
|
+
expect(builder.config[:plugins].first).to be_a(CKEditor5::Rails::Plugins::CustomTranslationsLoader)
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
497
552
|
describe '#deep_copy_toolbar' do
|
498
553
|
context 'with array toolbar' do
|
499
554
|
it 'returns duplicated array' do
|
@@ -552,7 +607,7 @@ RSpec.describe CKEditor5::Rails::Presets::PresetBuilder do
|
|
552
607
|
expect { builder.special_characters }.not_to raise_error
|
553
608
|
end
|
554
609
|
|
555
|
-
it 'configures special characters with groups and items' do
|
610
|
+
it 'configures special characters with groups and items' do
|
556
611
|
builder.special_characters do
|
557
612
|
group 'Emoji', label: 'Emoticons' do
|
558
613
|
item 'smiley', '😊'
|
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.
|
4
|
+
version: 1.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mateusz Bagiński
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-02-
|
12
|
+
date: 2025-02-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/ckeditor5/rails/hooks/importmap.rb
|
91
91
|
- lib/ckeditor5/rails/hooks/simple_form.rb
|
92
92
|
- lib/ckeditor5/rails/plugins.rb
|
93
|
+
- lib/ckeditor5/rails/plugins/custom_translations_loader.rb
|
93
94
|
- lib/ckeditor5/rails/plugins/patches/fix_color_picker_race_condition.rb
|
94
95
|
- lib/ckeditor5/rails/plugins/simple_upload_adapter.rb
|
95
96
|
- lib/ckeditor5/rails/plugins/special_characters_bootstrap.rb
|