ckeditor5 1.23.3 → 1.23.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ckeditor5/rails/assets/webcomponent_bundle.rb +32 -48
- data/lib/ckeditor5/rails/assets/webcomponents/components/editor.mjs +2 -6
- data/lib/ckeditor5/rails/assets/webcomponents/utils.mjs +1 -21
- data/lib/ckeditor5/rails/cdn/helpers.rb +1 -2
- data/lib/ckeditor5/rails/context/helpers.rb +2 -2
- data/lib/ckeditor5/rails/context/preset_builder.rb +1 -2
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +4 -8
- data/lib/ckeditor5/rails/editor/props.rb +1 -1
- data/lib/ckeditor5/rails/editor/props_inline_plugin.rb +0 -29
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/spec/lib/ckeditor5/rails/context/helpers_spec.rb +0 -13
- data/spec/lib/ckeditor5/rails/editor/helpers/editor_helpers_spec.rb +0 -50
- data/spec/lib/ckeditor5/rails/hooks/form_spec.rb +14 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d99c9fa1e8761c6520144f71741d0159c4e9509f524082e59b38a489635a37a
|
4
|
+
data.tar.gz: 951dacff990b009ba778901a4603a30315e5d95215c6b03f6837cba89a08e2e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbc115e51be9f39716846ee4037a37d67deb81d7894b1eb460b7b4775e10a240a949c176033512fa44fd71bc4ec8f5f15feadc36bddfdb15ca0ab06016f7c345
|
7
|
+
data.tar.gz: 735541e4c765dfb8fe86537ee0261066be0fe18f9fec3b706da3c6e3d23b188cff772671e892fca55b9f3f1c4323ba9f5f2703bac35da54ac97aded3bbbb2113
|
@@ -3,54 +3,38 @@
|
|
3
3
|
require 'singleton'
|
4
4
|
require 'terser'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
inject_inline_code_signatures(content)
|
39
|
-
else
|
40
|
-
content
|
41
|
-
end
|
42
|
-
end.join("\n")
|
43
|
-
end
|
44
|
-
|
45
|
-
def inject_inline_code_signatures(content)
|
46
|
-
json_signatures = Editor::InlinePluginsSignaturesRegistry.instance.to_a.to_json
|
47
|
-
|
48
|
-
content.sub('__INLINE_CODE_SIGNATURES_PLACEHOLDER__', json_signatures)
|
49
|
-
end
|
50
|
-
|
51
|
-
def compress_source(code)
|
52
|
-
Terser.new(compress: true, mangle: true).compile(code).html_safe
|
53
|
-
end
|
6
|
+
module CKEditor5::Rails::Assets
|
7
|
+
class WebComponentBundle
|
8
|
+
include ActionView::Helpers::TagHelper
|
9
|
+
include Singleton
|
10
|
+
|
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
|
19
|
+
|
20
|
+
def source
|
21
|
+
@source ||= compress_source(raw_source)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_html
|
25
|
+
@to_html ||= tag.script(source, type: 'module', nonce: true)
|
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
|
54
38
|
end
|
55
39
|
end
|
56
40
|
end
|
@@ -568,14 +568,10 @@ class CKEditorComponent extends HTMLElement {
|
|
568
568
|
}
|
569
569
|
|
570
570
|
/**
|
571
|
-
* Gets bundle JSON description from translations attribute
|
572
|
-
*
|
573
|
-
* **warning**: It's present only if the editor is loaded lazily.
|
571
|
+
* Gets bundle JSON description from translations attribute
|
574
572
|
*/
|
575
573
|
#getBundle() {
|
576
|
-
return this.#bundle ||= JSON.parse(
|
577
|
-
this.getAttribute('bundle') || '{ "scripts": [], "stylesheets": [] }'
|
578
|
-
);
|
574
|
+
return this.#bundle ||= JSON.parse(this.getAttribute('bundle'));
|
579
575
|
}
|
580
576
|
|
581
577
|
|
@@ -20,22 +20,6 @@ function execIfDOMReady(callback) {
|
|
20
20
|
}
|
21
21
|
}
|
22
22
|
|
23
|
-
/**
|
24
|
-
* Verifies code signature using SHA-256 hash.
|
25
|
-
*
|
26
|
-
* @param {string} code - Source code to verify
|
27
|
-
* @returns {Promise<boolean>} True if code signature is valid
|
28
|
-
*/
|
29
|
-
async function verifyCodeSignature(code) {
|
30
|
-
const signature = await crypto.subtle
|
31
|
-
.digest('SHA-256', new TextEncoder().encode(code))
|
32
|
-
.then(hash => Array.from(new Uint8Array(hash))
|
33
|
-
.map(b => b.toString(16).padStart(2, '0'))
|
34
|
-
.join(''));
|
35
|
-
|
36
|
-
return __INLINE_CODE_SIGNATURES_PLACEHOLDER__.includes(signature);
|
37
|
-
}
|
38
|
-
|
39
23
|
/**
|
40
24
|
* Dynamically imports modules based on configuration
|
41
25
|
*
|
@@ -47,14 +31,10 @@ async function verifyCodeSignature(code) {
|
|
47
31
|
* @param {Object} imports[].window_name - Global window object name (for external type)
|
48
32
|
* @param {('inline'|'external')} imports[].type - Type of import
|
49
33
|
* @returns {Promise<Array<any>>} Array of loaded modules
|
50
|
-
* @throws {Error} When plugin loading fails
|
34
|
+
* @throws {Error} When plugin loading fails
|
51
35
|
*/
|
52
36
|
function loadAsyncImports(imports = []) {
|
53
37
|
const loadInlinePlugin = async ({ name, code }) => {
|
54
|
-
if (!await verifyCodeSignature(code)) {
|
55
|
-
throw new Error(`Invalid code signature for inline plugin "${name}"!`);
|
56
|
-
}
|
57
|
-
|
58
38
|
const module = await import(`data:text/javascript,${encodeURIComponent(code)}`);
|
59
39
|
|
60
40
|
if (!module.default) {
|
@@ -40,8 +40,8 @@ module CKEditor5::Rails::Context
|
|
40
40
|
# <% preset = ckeditor5_context_preset do
|
41
41
|
# plugins :Comments, :TrackChanges, :Collaboration # Shared functionality plugins
|
42
42
|
# end %>
|
43
|
-
def ckeditor5_context_preset(
|
44
|
-
PresetBuilder.new(
|
43
|
+
def ckeditor5_context_preset(&block)
|
44
|
+
PresetBuilder.new(&block)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -56,7 +56,7 @@ module CKEditor5::Rails
|
|
56
56
|
# <%= form_for @post do |f| %>
|
57
57
|
# <%= f.ckeditor5 :content, required: true %>
|
58
58
|
# <% end %>
|
59
|
-
def ckeditor5_editor( # rubocop:disable Metrics/ParameterLists
|
59
|
+
def ckeditor5_editor( # rubocop:disable Metrics/ParameterLists
|
60
60
|
preset: nil,
|
61
61
|
config: nil, extra_config: {}, type: nil,
|
62
62
|
initial_data: nil, watchdog: true,
|
@@ -78,9 +78,7 @@ module CKEditor5::Rails
|
|
78
78
|
|
79
79
|
editor_props = Editor::Props.new(
|
80
80
|
type, config,
|
81
|
-
|
82
|
-
# So web-component will be loaded from the CDN.
|
83
|
-
bundle: context[:lazy] ? context[:bundle] : nil,
|
81
|
+
bundle: context[:bundle],
|
84
82
|
watchdog: watchdog,
|
85
83
|
editable_height: editable_height || preset.editable_height
|
86
84
|
)
|
@@ -161,15 +159,13 @@ module CKEditor5::Rails
|
|
161
159
|
|
162
160
|
return {
|
163
161
|
bundle: create_preset_bundle(found_preset),
|
164
|
-
preset: found_preset
|
165
|
-
lazy: true
|
162
|
+
preset: found_preset
|
166
163
|
}
|
167
164
|
end
|
168
165
|
|
169
166
|
{
|
170
167
|
bundle: nil,
|
171
|
-
preset: Engine.default_preset
|
172
|
-
lazy: true
|
168
|
+
preset: Engine.default_preset
|
173
169
|
}
|
174
170
|
end
|
175
171
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'singleton'
|
4
|
-
require 'digest'
|
5
|
-
|
6
3
|
require_relative 'props_base_plugin'
|
7
4
|
|
8
5
|
module CKEditor5::Rails::Editor
|
@@ -14,8 +11,6 @@ module CKEditor5::Rails::Editor
|
|
14
11
|
|
15
12
|
@code = code
|
16
13
|
validate_code!
|
17
|
-
|
18
|
-
InlinePluginsSignaturesRegistry.instance.register(code)
|
19
14
|
end
|
20
15
|
|
21
16
|
def to_h
|
@@ -37,28 +32,4 @@ module CKEditor5::Rails::Editor
|
|
37
32
|
'Code must include `export default` that exports plugin definition!'
|
38
33
|
end
|
39
34
|
end
|
40
|
-
|
41
|
-
class InlinePluginsSignaturesRegistry
|
42
|
-
include Singleton
|
43
|
-
|
44
|
-
def initialize
|
45
|
-
@signatures = Set.new
|
46
|
-
end
|
47
|
-
|
48
|
-
def register(code)
|
49
|
-
signature = generate_signature(code)
|
50
|
-
@signatures.add(signature)
|
51
|
-
signature
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_a
|
55
|
-
@signatures.to_a
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def generate_signature(code)
|
61
|
-
Digest::SHA256.hexdigest(code)
|
62
|
-
end
|
63
|
-
end
|
64
35
|
end
|
@@ -107,18 +107,5 @@ RSpec.describe CKEditor5::Rails::Context::Helpers do
|
|
107
107
|
preset: :custom
|
108
108
|
)
|
109
109
|
end
|
110
|
-
|
111
|
-
it 'raises error when trying to define inline plugin' do
|
112
|
-
expect do
|
113
|
-
helper.ckeditor5_context_preset do
|
114
|
-
inline_plugin :TestPlugin, <<~JS
|
115
|
-
export default class TestPlugin { }
|
116
|
-
JS
|
117
|
-
end
|
118
|
-
end.to raise_error(
|
119
|
-
CKEditor5::Rails::Presets::Concerns::PluginMethods::DisallowedInlinePlugin,
|
120
|
-
'Inline plugins are not allowed here.'
|
121
|
-
)
|
122
|
-
end
|
123
110
|
end
|
124
111
|
end
|
@@ -58,7 +58,6 @@ RSpec.describe CKEditor5::Rails::Editor::Helpers::Editor do
|
|
58
58
|
result = helper.ckeditor5_context_or_fallback(:custom)
|
59
59
|
expect(result).to match({
|
60
60
|
bundle: 'custom-bundle',
|
61
|
-
lazy: true,
|
62
61
|
preset: custom_preset
|
63
62
|
})
|
64
63
|
end
|
@@ -72,33 +71,9 @@ RSpec.describe CKEditor5::Rails::Editor::Helpers::Editor do
|
|
72
71
|
result = helper.ckeditor5_context_or_fallback(nil)
|
73
72
|
expect(result).to match({
|
74
73
|
bundle: nil,
|
75
|
-
lazy: true,
|
76
74
|
preset: :default
|
77
75
|
})
|
78
76
|
end
|
79
|
-
|
80
|
-
it 'includes lazy flag in fallback context' do
|
81
|
-
allow(CKEditor5::Rails::Engine).to receive(:default_preset)
|
82
|
-
.and_return(:default)
|
83
|
-
|
84
|
-
result = helper.ckeditor5_context_or_fallback(nil)
|
85
|
-
expect(result[:lazy]).to be true
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'includes lazy flag in preset context' do
|
89
|
-
custom_preset = instance_double(CKEditor5::Rails::Presets::PresetBuilder)
|
90
|
-
|
91
|
-
allow(CKEditor5::Rails::Engine).to receive(:find_preset)
|
92
|
-
.with(:custom)
|
93
|
-
.and_return(custom_preset)
|
94
|
-
|
95
|
-
allow(helper).to receive(:create_preset_bundle)
|
96
|
-
.with(custom_preset)
|
97
|
-
.and_return('custom-bundle')
|
98
|
-
|
99
|
-
result = helper.ckeditor5_context_or_fallback(:custom)
|
100
|
-
expect(result[:lazy]).to be true
|
101
|
-
end
|
102
77
|
end
|
103
78
|
|
104
79
|
describe '#ckeditor5_editor' do
|
@@ -250,31 +225,6 @@ RSpec.describe CKEditor5::Rails::Editor::Helpers::Editor do
|
|
250
225
|
expect(helper.ckeditor5_editor(editable_height: 600)).to include('editable-height="600px"')
|
251
226
|
end
|
252
227
|
end
|
253
|
-
|
254
|
-
context 'when using bundles' do
|
255
|
-
let(:bundle) { 'test-bundle' }
|
256
|
-
let(:context) { { preset: :default, bundle: bundle, lazy: true } }
|
257
|
-
|
258
|
-
it 'uses bundle from context when lazy is true' do
|
259
|
-
expect(CKEditor5::Rails::Editor::Props).to receive(:new)
|
260
|
-
.with(anything, anything, hash_including(bundle: bundle))
|
261
|
-
.and_call_original
|
262
|
-
|
263
|
-
helper.ckeditor5_editor
|
264
|
-
end
|
265
|
-
|
266
|
-
context 'when lazy is false' do
|
267
|
-
let(:context) { { preset: :default, bundle: bundle, lazy: false } }
|
268
|
-
|
269
|
-
it 'does not use bundle from context' do
|
270
|
-
expect(CKEditor5::Rails::Editor::Props).to receive(:new)
|
271
|
-
.with(anything, anything, hash_including(bundle: nil))
|
272
|
-
.and_call_original
|
273
|
-
|
274
|
-
helper.ckeditor5_editor
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
228
|
end
|
279
229
|
|
280
230
|
describe '#ckeditor5_editable' do
|
@@ -18,10 +18,24 @@ RSpec.describe CKEditor5::Rails::Hooks::Form do
|
|
18
18
|
subject(:rendered_editor) { builder.build_editor(:content) }
|
19
19
|
|
20
20
|
it 'renders ckeditor element' do
|
21
|
+
bundle_json = {
|
22
|
+
scripts: [
|
23
|
+
{
|
24
|
+
import_name: 'ckeditor5',
|
25
|
+
url: 'https://cdn.jsdelivr.net/npm/ckeditor5@34.1.0/dist/browser/ckeditor5.js',
|
26
|
+
translation: false
|
27
|
+
}
|
28
|
+
],
|
29
|
+
stylesheets: [
|
30
|
+
'https://cdn.jsdelivr.net/npm/ckeditor5@34.1.0/dist/browser/ckeditor5.css'
|
31
|
+
]
|
32
|
+
}.to_json
|
33
|
+
|
21
34
|
attrs = {
|
22
35
|
name: 'post[content]',
|
23
36
|
id: 'post_content',
|
24
37
|
type: 'ClassicEditor',
|
38
|
+
bundle: bundle_json,
|
25
39
|
watchdog: 'true'
|
26
40
|
}
|
27
41
|
|