ckeditor5 1.18.3 → 1.19.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: 63ee1d664150a118c2c9fe63458b1e3163afaea9ed3ebecd5e2ddc712403be1e
|
4
|
+
data.tar.gz: d36eefbd3b1d662a68d92396639d8905cb448fedd7cef6ad7a332feaed9083a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25ee39187fa672d9a9df9bda4fce9108db977b7b1771a451c94f3f6934f85e32680ea9c91738fafdcfee4b9b1620782d59878921cb7a76a04a0213fbc5aed713
|
7
|
+
data.tar.gz: 1c69b5973b264cd16aaec7f697bff803f3ffaafed4a600ef47fb7abbb16577cad681714fa4c18268f9fb0095392b44f73296e2e00585874cbf62e9e4e294913d
|
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.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: 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
|