ckeditor5 1.18.3 → 1.19.1
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 +35 -0
- data/lib/ckeditor5/rails/assets/assets_bundle.rb +21 -13
- data/lib/ckeditor5/rails/assets/assets_bundle_html_serializer.rb +25 -5
- data/lib/ckeditor5/rails/assets/webcomponents/utils.mjs +20 -6
- data/lib/ckeditor5/rails/cdn/helpers.rb +7 -0
- data/lib/ckeditor5/rails/editor/props_base_plugin.rb +2 -2
- data/lib/ckeditor5/rails/editor/props_external_plugin.rb +5 -2
- data/lib/ckeditor5/rails/presets/concerns/plugin_methods.rb +1 -0
- data/lib/ckeditor5/rails/presets/preset_builder.rb +2 -2
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/spec/lib/ckeditor5/rails/assets/asset_bundle_hml_serializer_spec.rb +95 -37
- data/spec/lib/ckeditor5/rails/assets/assets_bundle_spec.rb +42 -79
- data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +24 -0
- data/spec/lib/ckeditor5/rails/editor/props_base_plugin_spec.rb +3 -3
- data/spec/lib/ckeditor5/rails/editor/props_external_plugin_spec.rb +7 -9
- data/spec/lib/ckeditor5/rails/engine_spec.rb +22 -4
- data/spec/lib/ckeditor5/rails/plugins/wproofreader_spec.rb +8 -12
- data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +42 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39db7b05796b6fd781f005ccb45d014a7936312619e4068d053378a5a5050bfd
|
4
|
+
data.tar.gz: 2f1746e2a1cb82ea6dc65465a616995e10744983f122f5e2822158e89ac710df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bbf9f23f3db08a9afef4873c4ba6d9ae57289130b0aa2c8581175c380a51d116668d32b209fd817abe7a255dbc0b3efc7cb869e7ec004749705d571df4c1a75
|
7
|
+
data.tar.gz: f096236e1d7a76c12803928b3e3efdb7d07d4b4ba5d5011af9d1597e8c33ba1622897430dcba9516fb87ee538ab1d5dce49210771a357e05d233ea03ba0c3839
|
data/README.md
CHANGED
@@ -161,6 +161,7 @@ For extending CKEditor's functionality, refer to the [plugins directory](https:/
|
|
161
161
|
- [Setting the language in the initializer](#setting-the-language-in-the-initializer)
|
162
162
|
- [Setting the language on the editor level](#setting-the-language-on-the-editor-level)
|
163
163
|
- [Preloading multiple translation packs](#preloading-multiple-translation-packs)
|
164
|
+
- [Spell and Grammar Checking 📝](#spell-and-grammar-checking-)
|
164
165
|
- [Integrating with Forms 📋](#integrating-with-forms-)
|
165
166
|
- [Rails form builder integration](#rails-form-builder-integration)
|
166
167
|
- [Simple form integration](#simple-form-integration)
|
@@ -928,6 +929,23 @@ CKEditor5::Rails.configure do
|
|
928
929
|
end
|
929
930
|
```
|
930
931
|
|
932
|
+
If no `language` is set, the plugin will use the default language of the editor. If you want to set the language of the WProofreader plugin, you can use the `language` keyword argument:
|
933
|
+
|
934
|
+
```rb
|
935
|
+
# config/initializers/ckeditor5.rb
|
936
|
+
|
937
|
+
CKEditor5::Rails.configure do
|
938
|
+
# ... other configuration
|
939
|
+
|
940
|
+
wproofreader serviceId: 'your-service-ID',
|
941
|
+
srcUrl: 'https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js',
|
942
|
+
language: :en_US,
|
943
|
+
localization: :pl
|
944
|
+
end
|
945
|
+
```
|
946
|
+
|
947
|
+
For more info about the WProofreader plugin, check the [official documentation](https://ckeditor.com/docs/ckeditor5/latest/features/spelling-and-grammar-checking.html).
|
948
|
+
|
931
949
|
</details>
|
932
950
|
|
933
951
|
### Controller / View helpers 📦
|
@@ -1585,6 +1603,23 @@ CKEditor5::Rails.configure do
|
|
1585
1603
|
end
|
1586
1604
|
```
|
1587
1605
|
|
1606
|
+
### Spell and Grammar Checking 📝
|
1607
|
+
|
1608
|
+
CKEditor 5 provides a spell and grammar checking feature through the WProofreader plugin. You can enable this feature by configuring the WProofreader plugin in the initializer.
|
1609
|
+
|
1610
|
+
```rb
|
1611
|
+
# config/initializers/ckeditor5.rb
|
1612
|
+
|
1613
|
+
CKEditor5::Rails.configure do
|
1614
|
+
wproofreader serviceId: 'your-service-ID',
|
1615
|
+
srcUrl: 'https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js'
|
1616
|
+
end
|
1617
|
+
```
|
1618
|
+
|
1619
|
+
See [`wproofreader(version: nil, cdn: nil, **config)` method](#wproofreaderversion-nil-cdn-nil-config-method) for more information about the WProofreader plugin configuration.
|
1620
|
+
|
1621
|
+
See the [official documentation](https://ckeditor.com/docs/ckeditor5/latest/features/spelling-and-grammar-checking.html) for more information about the WProofreader plugin.
|
1622
|
+
|
1588
1623
|
### Integrating with Forms 📋
|
1589
1624
|
|
1590
1625
|
You can integrate CKEditor 5 with Rails form builders like `form_for` or `simple_form`. The example below shows how to integrate CKEditor 5 with a Rails form using the `form_for` helper:
|
@@ -1,11 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/core_ext/module'
|
4
|
+
require 'uri'
|
4
5
|
|
5
6
|
module CKEditor5::Rails::Assets
|
6
7
|
class AssetsBundle
|
7
|
-
def initialize
|
8
|
-
|
8
|
+
def initialize(scripts: nil, stylesheets: nil)
|
9
|
+
@scripts = scripts
|
10
|
+
@stylesheets = stylesheets
|
11
|
+
end
|
12
|
+
|
13
|
+
def scripts
|
14
|
+
@scripts || []
|
15
|
+
end
|
16
|
+
|
17
|
+
def stylesheets
|
18
|
+
@stylesheets || []
|
9
19
|
end
|
10
20
|
|
11
21
|
def empty?
|
@@ -17,7 +27,7 @@ module CKEditor5::Rails::Assets
|
|
17
27
|
end
|
18
28
|
|
19
29
|
def preloads
|
20
|
-
stylesheets + scripts.map(&:
|
30
|
+
stylesheets + scripts.map(&:preloads)
|
21
31
|
end
|
22
32
|
|
23
33
|
def <<(other)
|
@@ -26,16 +36,6 @@ module CKEditor5::Rails::Assets
|
|
26
36
|
@scripts = scripts + other.scripts
|
27
37
|
@stylesheets = stylesheets + other.stylesheets
|
28
38
|
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def validate_implementation!
|
33
|
-
%i[scripts stylesheets].each do |method|
|
34
|
-
unless respond_to?(method, true)
|
35
|
-
raise NotImplementedError, "#{self.class} must implement the ##{method} method"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
39
|
end
|
40
40
|
|
41
41
|
class JSUrlImportMeta
|
@@ -56,6 +56,14 @@ module CKEditor5::Rails::Assets
|
|
56
56
|
def to_h
|
57
57
|
import_meta.to_h.merge({ url: url })
|
58
58
|
end
|
59
|
+
|
60
|
+
def preloads
|
61
|
+
{
|
62
|
+
as: 'script',
|
63
|
+
rel: esm? ? 'modulepreload' : 'preload',
|
64
|
+
href: url
|
65
|
+
}
|
66
|
+
end
|
59
67
|
end
|
60
68
|
|
61
69
|
class JSImportMeta
|
@@ -19,10 +19,10 @@ module CKEditor5::Rails::Assets
|
|
19
19
|
|
20
20
|
def to_html
|
21
21
|
safe_join([
|
22
|
+
scripts_import_map_tag,
|
22
23
|
preload_tags,
|
23
24
|
styles_tags,
|
24
25
|
window_scripts_tags,
|
25
|
-
scripts_import_map_tag,
|
26
26
|
web_component_tag
|
27
27
|
])
|
28
28
|
end
|
@@ -51,7 +51,9 @@ module CKEditor5::Rails::Assets
|
|
51
51
|
return @scripts_import_map_tag if defined?(@scripts_import_map_tag)
|
52
52
|
|
53
53
|
import_map = bundle.scripts.each_with_object({}) do |script, map|
|
54
|
-
|
54
|
+
next if !script.esm? || looks_like_url?(script.import_name)
|
55
|
+
|
56
|
+
map[script.import_name] = script.url
|
55
57
|
end
|
56
58
|
|
57
59
|
@scripts_import_map_tag = tag.script(
|
@@ -68,10 +70,28 @@ module CKEditor5::Rails::Assets
|
|
68
70
|
end
|
69
71
|
|
70
72
|
def preload_tags
|
71
|
-
@preload_tags ||= safe_join(bundle.preloads.map do |
|
72
|
-
|
73
|
-
|
73
|
+
@preload_tags ||= safe_join(bundle.preloads.map do |preload|
|
74
|
+
if preload.is_a?(Hash) && preload[:as] && preload[:href]
|
75
|
+
tag.link(
|
76
|
+
**preload,
|
77
|
+
crossorigin: 'anonymous'
|
78
|
+
)
|
79
|
+
else
|
80
|
+
tag.link(
|
81
|
+
href: preload,
|
82
|
+
rel: 'preload',
|
83
|
+
as: self.class.url_resource_preload_type(preload),
|
84
|
+
crossorigin: 'anonymous'
|
85
|
+
)
|
86
|
+
end
|
74
87
|
end)
|
75
88
|
end
|
89
|
+
|
90
|
+
def looks_like_url?(str)
|
91
|
+
uri = URI.parse(str)
|
92
|
+
uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
|
93
|
+
rescue URI::InvalidURIError
|
94
|
+
false
|
95
|
+
end
|
76
96
|
end
|
77
97
|
end
|
@@ -86,6 +86,20 @@ function loadAsyncImports(imports = []) {
|
|
86
86
|
}));
|
87
87
|
}
|
88
88
|
|
89
|
+
/**
|
90
|
+
* Checks if stylesheet with given href already exists in document
|
91
|
+
*
|
92
|
+
* @param {string} href - Stylesheet URL to check
|
93
|
+
* @returns {boolean} True if stylesheet already exists
|
94
|
+
*/
|
95
|
+
function stylesheetExists(href) {
|
96
|
+
return Array
|
97
|
+
.from(document.styleSheets)
|
98
|
+
.some(sheet =>
|
99
|
+
sheet.href === href || sheet.href === new URL(href, window.location.href).href
|
100
|
+
);
|
101
|
+
}
|
102
|
+
|
89
103
|
/**
|
90
104
|
* Dynamically loads CSS files based on configuration
|
91
105
|
*
|
@@ -96,19 +110,19 @@ function loadAsyncImports(imports = []) {
|
|
96
110
|
function loadAsyncCSS(stylesheets = []) {
|
97
111
|
const promises = stylesheets.map(href =>
|
98
112
|
new Promise((resolve, reject) => {
|
99
|
-
|
113
|
+
if (stylesheetExists(href)) {
|
114
|
+
resolve();
|
115
|
+
return;
|
116
|
+
}
|
100
117
|
|
118
|
+
const link = document.createElement('link');
|
101
119
|
link.rel = 'stylesheet';
|
102
120
|
link.href = href;
|
103
121
|
|
104
122
|
link.onerror = reject;
|
105
|
-
link.onload = () =>
|
106
|
-
resolve();
|
107
|
-
};
|
123
|
+
link.onload = () => resolve();
|
108
124
|
|
109
125
|
document.head.appendChild(link);
|
110
|
-
|
111
|
-
return link;
|
112
126
|
})
|
113
127
|
);
|
114
128
|
|
@@ -26,6 +26,7 @@ module CKEditor5::Rails
|
|
26
26
|
bundle = build_base_cdn_bundle(cdn, version, translations)
|
27
27
|
bundle << build_premium_cdn_bundle(cdn, version, translations) if premium
|
28
28
|
bundle << build_ckbox_cdn_bundle(ckbox) if ckbox
|
29
|
+
bundle << build_plugins_cdn_bundle(mapped_preset.plugins.items)
|
29
30
|
|
30
31
|
@__ckeditor_context = {
|
31
32
|
license_key: license_key,
|
@@ -98,5 +99,11 @@ module CKEditor5::Rails
|
|
98
99
|
cdn: ckbox[:cdn] || :ckbox
|
99
100
|
)
|
100
101
|
end
|
102
|
+
|
103
|
+
def build_plugins_cdn_bundle(plugins)
|
104
|
+
plugins.each_with_object(Assets::AssetsBundle.new(scripts: [], stylesheets: [])) do |plugin, bundle|
|
105
|
+
bundle << plugin.preload_assets_bundle if plugin.preload_assets_bundle.present?
|
106
|
+
end
|
107
|
+
end
|
101
108
|
end
|
102
109
|
end
|
@@ -18,8 +18,11 @@ module CKEditor5::Rails::Editor
|
|
18
18
|
)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
@
|
21
|
+
def preload_assets_bundle
|
22
|
+
@preload_assets_bundle ||= CKEditor5::Rails::Assets::AssetsBundle.new(
|
23
|
+
scripts: [@js_import_meta],
|
24
|
+
stylesheets: @stylesheets
|
25
|
+
)
|
23
26
|
end
|
24
27
|
|
25
28
|
def to_h
|
@@ -207,8 +207,8 @@ module CKEditor5::Rails
|
|
207
207
|
def wproofreader(version: nil, cdn: nil, **config)
|
208
208
|
configure :wproofreader, config
|
209
209
|
plugins do
|
210
|
-
prepend
|
211
|
-
append
|
210
|
+
prepend(Plugins::WProofreaderSync.new)
|
211
|
+
append(Plugins::WProofreader.new(version: version, cdn: cdn))
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
@@ -3,20 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe CKEditor5::Rails::Assets::AssetsBundleHtmlSerializer do
|
6
|
-
let(:test_bundle_class) do
|
7
|
-
Class.new(CKEditor5::Rails::Assets::AssetsBundle) do
|
8
|
-
attr_accessor :scripts, :stylesheets
|
9
|
-
|
10
|
-
def initialize(scripts, stylesheets)
|
11
|
-
@scripts = scripts
|
12
|
-
@stylesheets = stylesheets
|
13
|
-
super()
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:bundle) { test_bundle_class.new(scripts, stylesheets) }
|
19
|
-
|
20
6
|
let(:scripts) do
|
21
7
|
[
|
22
8
|
CKEditor5::Rails::Assets::JSUrlImportMeta.new(
|
@@ -31,7 +17,7 @@ RSpec.describe CKEditor5::Rails::Assets::AssetsBundleHtmlSerializer do
|
|
31
17
|
end
|
32
18
|
|
33
19
|
let(:stylesheets) { ['https://cdn.com/style1.css', 'https://cdn.com/style2.css'] }
|
34
|
-
let(:
|
20
|
+
let(:bundle) { CKEditor5::Rails::Assets::AssetsBundle.new(scripts: scripts, stylesheets: stylesheets) }
|
35
21
|
|
36
22
|
subject(:serializer) { described_class.new(bundle) }
|
37
23
|
|
@@ -48,43 +34,102 @@ RSpec.describe CKEditor5::Rails::Assets::AssetsBundleHtmlSerializer do
|
|
48
34
|
describe '#to_html' do
|
49
35
|
subject(:html) { serializer.to_html }
|
50
36
|
|
51
|
-
it 'includes window
|
52
|
-
expect(html).to
|
53
|
-
|
54
|
-
|
37
|
+
it 'includes window script tags' do
|
38
|
+
expect(html).to have_tag('script', with: {
|
39
|
+
src: 'https://cdn.com/script1.js',
|
40
|
+
nonce: 'true',
|
41
|
+
crossorigin: 'anonymous'
|
42
|
+
})
|
55
43
|
end
|
56
44
|
|
57
45
|
it 'includes import map' do
|
58
|
-
expect(html).to
|
59
|
-
|
46
|
+
expect(html).to have_tag('script', with: { type: 'importmap' }) do
|
47
|
+
with_text(%r{"@ckeditor/script2":"https://cdn\.com/script2\.js"})
|
48
|
+
end
|
60
49
|
end
|
61
50
|
|
62
|
-
it 'includes
|
63
|
-
|
64
|
-
|
65
|
-
|
51
|
+
it 'includes import map with correct attributes' do
|
52
|
+
expect(html).to have_tag('script', with: {
|
53
|
+
type: 'importmap',
|
54
|
+
nonce: 'true'
|
55
|
+
})
|
66
56
|
end
|
67
57
|
|
68
|
-
it '
|
69
|
-
|
70
|
-
|
58
|
+
it 'does not include URL-like imports in import map' do
|
59
|
+
bundle = CKEditor5::Rails::Assets::AssetsBundle.new(
|
60
|
+
scripts: [
|
61
|
+
CKEditor5::Rails::Assets::JSUrlImportMeta.new(
|
62
|
+
'https://cdn.com/script.js',
|
63
|
+
import_name: 'https://example.com/module'
|
64
|
+
),
|
65
|
+
CKEditor5::Rails::Assets::JSUrlImportMeta.new(
|
66
|
+
'https://cdn.com/script.js',
|
67
|
+
import_name: 'module'
|
68
|
+
)
|
69
|
+
]
|
71
70
|
)
|
71
|
+
html = described_class.new(bundle).to_html
|
72
72
|
|
73
|
-
expect(html).to
|
74
|
-
'
|
75
|
-
|
73
|
+
expect(html).to have_tag('script', with: { type: 'importmap' }) do
|
74
|
+
with_text('{"imports":{"module":"https://cdn.com/script.js"}}')
|
75
|
+
end
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
78
|
+
it 'includes only ESM scripts in import map' do
|
79
|
+
bundle = CKEditor5::Rails::Assets::AssetsBundle.new(
|
80
|
+
scripts: [
|
81
|
+
CKEditor5::Rails::Assets::JSUrlImportMeta.new(
|
82
|
+
'https://cdn.com/script1.js',
|
83
|
+
window_name: 'WindowScript'
|
84
|
+
),
|
85
|
+
CKEditor5::Rails::Assets::JSUrlImportMeta.new(
|
86
|
+
'https://cdn.com/script2.js',
|
87
|
+
import_name: '@ckeditor/module'
|
88
|
+
)
|
89
|
+
]
|
79
90
|
)
|
91
|
+
html = described_class.new(bundle).to_html
|
80
92
|
|
81
|
-
expect(html).to
|
82
|
-
'
|
83
|
-
|
93
|
+
expect(html).to have_tag('script', with: { type: 'importmap' }) do
|
94
|
+
with_text('{"imports":{"@ckeditor/module":"https://cdn.com/script2.js"}}')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'includes stylesheet links' do
|
99
|
+
stylesheets.each do |url|
|
100
|
+
expect(html).to have_tag('link', with: {
|
101
|
+
href: url,
|
102
|
+
rel: 'stylesheet',
|
103
|
+
crossorigin: 'anonymous'
|
104
|
+
})
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'includes preload links' do
|
109
|
+
scripts.each do |script|
|
110
|
+
expect(html).to have_tag('link', with: {
|
111
|
+
href: script.url,
|
112
|
+
rel: script.esm? ? 'modulepreload' : 'preload',
|
113
|
+
as: 'script',
|
114
|
+
crossorigin: 'anonymous'
|
115
|
+
})
|
116
|
+
end
|
117
|
+
|
118
|
+
stylesheets.each do |url|
|
119
|
+
expect(html).to have_tag('link', with: {
|
120
|
+
href: url,
|
121
|
+
rel: 'preload',
|
122
|
+
as: 'style',
|
123
|
+
crossorigin: 'anonymous'
|
124
|
+
})
|
125
|
+
end
|
84
126
|
end
|
85
127
|
|
86
128
|
it 'includes web component script' do
|
87
|
-
expect(html).to
|
129
|
+
expect(html).to have_tag('script', with: {
|
130
|
+
type: 'module',
|
131
|
+
nonce: 'true'
|
132
|
+
})
|
88
133
|
end
|
89
134
|
|
90
135
|
it 'memoizes scripts import map' do
|
@@ -108,4 +153,17 @@ RSpec.describe CKEditor5::Rails::Assets::AssetsBundleHtmlSerializer do
|
|
108
153
|
expect(described_class.url_resource_preload_type('file.unknown')).to eq('fetch')
|
109
154
|
end
|
110
155
|
end
|
156
|
+
|
157
|
+
describe '#looks_like_url? (private)' do
|
158
|
+
subject(:serializer) { described_class.new(CKEditor5::Rails::Assets::AssetsBundle.new) }
|
159
|
+
|
160
|
+
it 'returns false for invalid URIs' do
|
161
|
+
expect(serializer.send(:looks_like_url?, '@ckeditor/foo')).to be false
|
162
|
+
expect(serializer.send(:looks_like_url?, 'http')).to be false
|
163
|
+
expect(serializer.send(:looks_like_url?, 'invalid')).to be false
|
164
|
+
expect(serializer.send(:looks_like_url?, 'http://[invalid')).to be false
|
165
|
+
expect(serializer.send(:looks_like_url?, "http://example.com\nmalicious")).to be false
|
166
|
+
expect(serializer.send(:looks_like_url?, 'http://<invalid>')).to be false
|
167
|
+
end
|
168
|
+
end
|
111
169
|
end
|
@@ -3,48 +3,45 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
RSpec.describe CKEditor5::Rails::Assets::AssetsBundle do
|
6
|
-
let(:concrete_class) do
|
7
|
-
Class.new(described_class) do
|
8
|
-
def scripts
|
9
|
-
[]
|
10
|
-
end
|
11
|
-
|
12
|
-
def stylesheets
|
13
|
-
[]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
6
|
describe '#initialize' do
|
19
|
-
it '
|
20
|
-
|
7
|
+
it 'initializes with empty arrays by default' do
|
8
|
+
bundle = described_class.new
|
9
|
+
expect(bundle.scripts).to eq([])
|
10
|
+
expect(bundle.stylesheets).to eq([])
|
21
11
|
end
|
22
12
|
|
23
|
-
it '
|
24
|
-
|
13
|
+
it 'accepts scripts and stylesheets' do
|
14
|
+
bundle = described_class.new(scripts: [:script], stylesheets: [:stylesheet])
|
15
|
+
expect(bundle.scripts).to eq([:script])
|
16
|
+
expect(bundle.stylesheets).to eq([:stylesheet])
|
25
17
|
end
|
26
18
|
end
|
27
19
|
|
28
20
|
describe '#empty?' do
|
29
|
-
subject(:bundle) { concrete_class.new }
|
30
|
-
|
31
21
|
it 'returns true when no assets are present' do
|
22
|
+
bundle = described_class.new
|
32
23
|
expect(bundle).to be_empty
|
33
24
|
end
|
25
|
+
|
26
|
+
it 'returns false when scripts are present' do
|
27
|
+
bundle = described_class.new(scripts: [:script])
|
28
|
+
expect(bundle).not_to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns false when stylesheets are present' do
|
32
|
+
bundle = described_class.new(stylesheets: [:stylesheet])
|
33
|
+
expect(bundle).not_to be_empty
|
34
|
+
end
|
34
35
|
end
|
35
36
|
|
36
37
|
describe '#translations_scripts' do
|
37
|
-
let(:bundle) { concrete_class.new }
|
38
38
|
let(:translation_script) do
|
39
39
|
instance_double(CKEditor5::Rails::Assets::JSUrlImportMeta, translation?: true)
|
40
40
|
end
|
41
41
|
let(:regular_script) { instance_double(CKEditor5::Rails::Assets::JSUrlImportMeta, translation?: false) }
|
42
42
|
|
43
|
-
before do
|
44
|
-
allow(bundle).to receive(:scripts).and_return([translation_script, regular_script])
|
45
|
-
end
|
46
|
-
|
47
43
|
it 'returns only translation scripts' do
|
44
|
+
bundle = described_class.new(scripts: [translation_script, regular_script])
|
48
45
|
expect(bundle.translations_scripts).to eq([translation_script])
|
49
46
|
end
|
50
47
|
end
|
@@ -54,41 +51,8 @@ RSpec.describe CKEditor5::Rails::Assets::AssetsBundle do
|
|
54
51
|
let(:script2) { instance_double(CKEditor5::Rails::Assets::JSUrlImportMeta) }
|
55
52
|
let(:stylesheet1) { '/path/to/style1.css' }
|
56
53
|
let(:stylesheet2) { '/path/to/style2.css' }
|
57
|
-
|
58
|
-
let(:
|
59
|
-
Class.new(described_class) do
|
60
|
-
attr_writer :scripts, :stylesheets
|
61
|
-
|
62
|
-
def scripts
|
63
|
-
@scripts ||= []
|
64
|
-
end
|
65
|
-
|
66
|
-
def stylesheets
|
67
|
-
@stylesheets ||= []
|
68
|
-
end
|
69
|
-
end.new
|
70
|
-
end
|
71
|
-
|
72
|
-
let(:bundle2) do
|
73
|
-
Class.new(described_class) do
|
74
|
-
attr_writer :scripts, :stylesheets
|
75
|
-
|
76
|
-
def scripts
|
77
|
-
@scripts ||= []
|
78
|
-
end
|
79
|
-
|
80
|
-
def stylesheets
|
81
|
-
@stylesheets ||= []
|
82
|
-
end
|
83
|
-
end.new
|
84
|
-
end
|
85
|
-
|
86
|
-
before do
|
87
|
-
bundle1.scripts = [script1]
|
88
|
-
bundle1.stylesheets = [stylesheet1]
|
89
|
-
bundle2.scripts = [script2]
|
90
|
-
bundle2.stylesheets = [stylesheet2]
|
91
|
-
end
|
54
|
+
let(:bundle1) { described_class.new(scripts: [script1], stylesheets: [stylesheet1]) }
|
55
|
+
let(:bundle2) { described_class.new(scripts: [script2], stylesheets: [stylesheet2]) }
|
92
56
|
|
93
57
|
it 'raises TypeError when argument is not an AssetsBundle' do
|
94
58
|
expect { bundle1 << 'not a bundle' }.to raise_error(TypeError)
|
@@ -103,36 +67,23 @@ RSpec.describe CKEditor5::Rails::Assets::AssetsBundle do
|
|
103
67
|
end
|
104
68
|
|
105
69
|
describe '#preloads' do
|
106
|
-
let(:script1) {
|
107
|
-
let(:script2) {
|
70
|
+
let(:script1) { CKEditor5::Rails::Assets::JSUrlImportMeta.new('/js/script1.js', import_name: 'script1') }
|
71
|
+
let(:script2) { CKEditor5::Rails::Assets::JSUrlImportMeta.new('/js/script2.js', import_name: 'script2') }
|
108
72
|
let(:stylesheet1) { '/css/style1.css' }
|
109
73
|
let(:stylesheet2) { '/css/style2.css' }
|
110
|
-
|
111
74
|
let(:bundle) do
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
@scripts ||= []
|
117
|
-
end
|
118
|
-
|
119
|
-
def stylesheets
|
120
|
-
@stylesheets ||= []
|
121
|
-
end
|
122
|
-
end.new
|
123
|
-
end
|
124
|
-
|
125
|
-
before do
|
126
|
-
bundle.scripts = [script1, script2]
|
127
|
-
bundle.stylesheets = [stylesheet1, stylesheet2]
|
75
|
+
described_class.new(
|
76
|
+
scripts: [script1, script2],
|
77
|
+
stylesheets: [stylesheet1, stylesheet2]
|
78
|
+
)
|
128
79
|
end
|
129
80
|
|
130
81
|
it 'returns array of stylesheet paths and script urls' do
|
131
82
|
expect(bundle.preloads).to eq([
|
132
83
|
'/css/style1.css',
|
133
84
|
'/css/style2.css',
|
134
|
-
'/js/script1.js',
|
135
|
-
'/js/script2.js'
|
85
|
+
{ as: 'script', rel: 'modulepreload', href: '/js/script1.js' },
|
86
|
+
{ as: 'script', rel: 'modulepreload', href: '/js/script2.js' }
|
136
87
|
])
|
137
88
|
end
|
138
89
|
end
|
@@ -168,6 +119,18 @@ RSpec.describe CKEditor5::Rails::Assets::JSUrlImportMeta do
|
|
168
119
|
})
|
169
120
|
end
|
170
121
|
end
|
122
|
+
|
123
|
+
describe '#preloads' do
|
124
|
+
it 'returns preload hash' do
|
125
|
+
meta = described_class.new(url, window_name: 'module')
|
126
|
+
expect(meta.preloads).to eq({ as: 'script', rel: 'preload', href: url })
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns modulepreload hash when esm' do
|
130
|
+
meta = described_class.new(url, import_name: 'module')
|
131
|
+
expect(meta.preloads).to include({ as: 'script', rel: 'modulepreload', href: url })
|
132
|
+
end
|
133
|
+
end
|
171
134
|
end
|
172
135
|
|
173
136
|
RSpec.describe CKEditor5::Rails::Assets::JSImportMeta do
|
@@ -108,6 +108,30 @@ RSpec.describe CKEditor5::Rails::Cdn::Helpers do
|
|
108
108
|
helper.ckeditor5_assets(preset: :default)
|
109
109
|
end
|
110
110
|
end
|
111
|
+
|
112
|
+
context 'with plugins having preload assets' do
|
113
|
+
let(:plugin_bundle) { CKEditor5::Rails::Assets::AssetsBundle.new(scripts: ['plugin.js']) }
|
114
|
+
let(:plugin) { instance_double('Plugin', preload_assets_bundle: plugin_bundle) }
|
115
|
+
let(:plugin_without_preload) { instance_double('Plugin', preload_assets_bundle: nil) }
|
116
|
+
|
117
|
+
before do
|
118
|
+
allow(preset).to receive_message_chain(:plugins, :items)
|
119
|
+
.and_return([plugin, plugin_without_preload])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'includes plugin preload assets in the bundle' do
|
123
|
+
helper.ckeditor5_assets(preset: :default)
|
124
|
+
expect(context[:bundle].scripts).to include('plugin.js')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'merges plugin assets with the main bundle' do
|
128
|
+
expect(serializer).to receive(:to_html)
|
129
|
+
helper.ckeditor5_assets(preset: :default)
|
130
|
+
|
131
|
+
bundle = context[:bundle]
|
132
|
+
expect(bundle.scripts).to include('plugin.js')
|
133
|
+
end
|
134
|
+
end
|
111
135
|
end
|
112
136
|
|
113
137
|
context 'when overriding preset values' do
|
@@ -33,11 +33,11 @@ RSpec.describe CKEditor5::Rails::Editor::PropsBasePlugin do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe '#
|
37
|
-
it 'returns
|
36
|
+
describe '#preload_assets_bundle' do
|
37
|
+
it 'returns nil by default' do
|
38
38
|
plugin = described_class.new(:Bold)
|
39
39
|
|
40
|
-
expect(plugin.
|
40
|
+
expect(plugin.preload_assets_bundle).to be_nil
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -8,7 +8,7 @@ RSpec.describe CKEditor5::Rails::Editor::PropsExternalPlugin do
|
|
8
8
|
plugin = described_class.new('Test', script: 'https://example.org/plugin.js')
|
9
9
|
|
10
10
|
expect(plugin.name).to eq('Test')
|
11
|
-
expect(plugin.
|
11
|
+
expect(plugin.preload_assets_bundle.scripts.first.url).to eq('https://example.org/plugin.js')
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'accepts optional parameters' do
|
@@ -20,23 +20,21 @@ RSpec.describe CKEditor5::Rails::Editor::PropsExternalPlugin do
|
|
20
20
|
stylesheets: ['https://example.org/style.css']
|
21
21
|
)
|
22
22
|
|
23
|
-
expect(plugin.
|
23
|
+
expect(plugin.preload_assets_bundle.stylesheets).to include('https://example.org/style.css')
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
describe '#
|
28
|
-
it 'returns
|
27
|
+
describe '#preload_assets_bundle' do
|
28
|
+
it 'returns bundle with script and stylesheets' do
|
29
29
|
plugin = described_class.new(
|
30
30
|
'Test',
|
31
31
|
script: 'https://example.org/plugin.js',
|
32
32
|
stylesheets: ['https://example.org/style1.css', 'https://example.org/style2.css']
|
33
33
|
)
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
'https://example.org/plugin.js'
|
39
|
-
])
|
35
|
+
bundle = plugin.preload_assets_bundle
|
36
|
+
expect(bundle.scripts.first.url).to eq('https://example.org/plugin.js')
|
37
|
+
expect(bundle.stylesheets).to eq(['https://example.org/style1.css', 'https://example.org/style2.css'])
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
@@ -78,10 +78,28 @@ RSpec.describe CKEditor5::Rails::Engine do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
describe 'simple_form initializer'
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
describe 'simple_form initializer' do
|
82
|
+
context 'when SimpleForm is defined' do
|
83
|
+
it 'registers ckeditor5 input type' do
|
84
|
+
expect(SimpleForm::FormBuilder.mappings[:ckeditor5])
|
85
|
+
.to eq(CKEditor5::Rails::Hooks::SimpleForm::CKEditor5Input)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when SimpleForm is not defined' do
|
90
|
+
before do
|
91
|
+
@simple_form = SimpleForm if defined?(SimpleForm)
|
92
|
+
Object.send(:remove_const, :SimpleForm) if defined?(SimpleForm)
|
93
|
+
end
|
94
|
+
|
95
|
+
after do
|
96
|
+
Object.const_set(:SimpleForm, @simple_form) if @simple_form
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'does not raise error' do
|
100
|
+
initializer = described_class.initializers.find { |i| i.name == 'ckeditor5.simple_form' }
|
101
|
+
expect { initializer.run(Rails.application) }.not_to raise_error
|
102
|
+
end
|
85
103
|
end
|
86
104
|
end
|
87
105
|
end
|
@@ -14,12 +14,10 @@ RSpec.describe CKEditor5::Rails::Plugins::WProofreader do
|
|
14
14
|
expect(plugin.name).to eq(:WProofreader)
|
15
15
|
end
|
16
16
|
|
17
|
-
it 'returns correct preload assets
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
]
|
22
|
-
expect(plugin.preload_assets_urls).to eq(expected_urls)
|
17
|
+
it 'returns correct preload assets bundle' do
|
18
|
+
bundle = plugin.preload_assets_bundle
|
19
|
+
expect(bundle.stylesheets).to eq(["#{default_cdn}@#{default_version}/dist/browser/index.css"])
|
20
|
+
expect(bundle.scripts.first.url).to eq("#{default_cdn}@#{default_version}/dist/browser/index.js")
|
23
21
|
end
|
24
22
|
|
25
23
|
it 'returns correct hash representation' do
|
@@ -39,12 +37,10 @@ RSpec.describe CKEditor5::Rails::Plugins::WProofreader do
|
|
39
37
|
let(:custom_version) { '4.0.0' }
|
40
38
|
subject(:plugin) { described_class.new(version: custom_version, cdn: custom_cdn) }
|
41
39
|
|
42
|
-
it 'returns correct preload assets
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
]
|
47
|
-
expect(plugin.preload_assets_urls).to eq(expected_urls)
|
40
|
+
it 'returns correct preload assets bundle with custom CDN' do
|
41
|
+
bundle = plugin.preload_assets_bundle
|
42
|
+
expect(bundle.stylesheets).to eq(["#{custom_cdn}@#{custom_version}/dist/browser/index.css"])
|
43
|
+
expect(bundle.scripts.first.url).to eq("#{custom_cdn}@#{custom_version}/dist/browser/index.js")
|
48
44
|
end
|
49
45
|
|
50
46
|
it 'returns correct hash representation with custom CDN' do
|
@@ -226,6 +226,48 @@ RSpec.describe CKEditor5::Rails::Presets::PresetBuilder do
|
|
226
226
|
end
|
227
227
|
end
|
228
228
|
|
229
|
+
describe '#plugin' do
|
230
|
+
it 'adds normalized plugin to config' do
|
231
|
+
plugin = builder.plugin('Test')
|
232
|
+
|
233
|
+
expect(builder.config[:plugins]).to include(plugin)
|
234
|
+
expect(plugin).to be_a(CKEditor5::Rails::Editor::PropsPlugin)
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'accepts plugin options' do
|
238
|
+
plugin = builder.plugin('Test', premium: true)
|
239
|
+
|
240
|
+
expect(plugin.to_h[:import_name]).to eq('ckeditor5-premium-features')
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'sets premium flag when premium option provided' do
|
244
|
+
builder.plugin('Test', premium: true)
|
245
|
+
expect(builder.premium?).to be true
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe '#external_plugin' do
|
250
|
+
it 'adds external plugin to config' do
|
251
|
+
plugin = builder.external_plugin('Test', script: 'https://example.org/script.js')
|
252
|
+
|
253
|
+
expect(builder.config[:plugins]).to include(plugin)
|
254
|
+
expect(plugin).to be_a(CKEditor5::Rails::Editor::PropsExternalPlugin)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'accepts plugin options' do
|
258
|
+
plugin = builder.external_plugin(
|
259
|
+
'Test',
|
260
|
+
script: 'https://example.org/script.js',
|
261
|
+
import_as: 'ABC',
|
262
|
+
stylesheets: ['https://example.org/style.css']
|
263
|
+
)
|
264
|
+
|
265
|
+
expect(plugin.to_h[:import_name]).to eq('https://example.org/script.js')
|
266
|
+
expect(plugin.to_h[:import_as]).to eq('ABC')
|
267
|
+
expect(plugin.to_h[:stylesheets]).to include('https://example.org/style.css')
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
229
271
|
describe '#cdn' do
|
230
272
|
it 'returns current cdn when called without arguments' do
|
231
273
|
expect(builder.cdn).to eq(:jsdelivr)
|
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.19.1
|
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: 2024-11-
|
12
|
+
date: 2024-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|