ckeditor5 1.15.8 → 1.15.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -5
- data/README.md +3 -0
- data/lib/ckeditor5/rails/cdn/ckbox_bundle.rb +2 -2
- data/lib/ckeditor5/rails/cdn/helpers.rb +6 -0
- data/lib/ckeditor5/rails/context/helpers.rb +1 -1
- data/lib/ckeditor5/rails/editor/editable_height_normalizer.rb +50 -0
- data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +3 -3
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +5 -4
- data/lib/ckeditor5/rails/editor/props.rb +3 -20
- data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +1 -1
- data/lib/ckeditor5/rails/presets/preset_builder.rb +2 -3
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/lib/ckeditor5/rails/version_detector.rb +6 -0
- data/spec/lib/ckeditor5/rails/assets/asset_bundle_hml_serializer_spec.rb +104 -0
- data/spec/lib/ckeditor5/rails/assets/assets_bundle_spec.rb +191 -0
- data/spec/lib/ckeditor5/rails/cdn/ckbox_bundle_spec.rb +69 -0
- data/spec/lib/ckeditor5/rails/cdn/ckeditor_bundle_spec.rb +72 -0
- data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +217 -0
- data/spec/lib/ckeditor5/rails/context/helpers_spec.rb +67 -0
- data/spec/lib/ckeditor5/rails/context/props_spec.rb +70 -0
- data/spec/lib/ckeditor5/rails/editor/editable_height_normalizer_spec.rb +50 -0
- data/spec/lib/ckeditor5/rails/editor/helpers/config_helpers_spec.rb +52 -0
- data/spec/lib/ckeditor5/rails/editor/helpers/editor_helpers_spec.rb +192 -0
- data/spec/lib/ckeditor5/rails/editor/props_inline_plugin_spec.rb +43 -0
- data/spec/lib/ckeditor5/rails/editor/props_plugin_spec.rb +66 -0
- data/spec/lib/ckeditor5/rails/editor/props_spec.rb +104 -0
- data/spec/lib/ckeditor5/rails/hooks/form_spec.rb +47 -0
- data/spec/lib/ckeditor5/rails/presets/manager_spec.rb +100 -0
- data/spec/lib/ckeditor5/rails/presets/plugins_builder_spec.rb +98 -0
- data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +337 -0
- data/spec/lib/ckeditor5/rails/presets/toolbar_builder_spec.rb +70 -0
- data/spec/lib/ckeditor5/rails/semver_spec.rb +58 -0
- data/spec/lib/ckeditor5/rails/version_detector_spec.rb +131 -0
- data/spec/lib/ckeditor5/rails/version_spec.rb +25 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/support/test_models.rb +6 -0
- metadata +44 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 604312ff3ad324ca5ebbccca70efe7157e9ee67608d6a3b8d3b2d4b7c070213b
|
4
|
+
data.tar.gz: 8c44e0810acd1bb837cdcc8a37c4fb3051b5323a243e7b5a16341e9c8e3ef9a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54fc1a049c23a9c45bee8fc307de81f7976407850d068f018e715396b93a47e3c37f77c45682ba7ee4f36fe1d5cef156eeb5791dbf0793c35503a93e09e41f8a
|
7
|
+
data.tar.gz: 23a2299e6b8685cf120fa40be70d23737ec68f732e6e96af4428d785234600ab17a24596f4d4794093b14fdd0625b20e3a2953950659e0ab0c9deda7fc2c1cc9
|
data/Gemfile
CHANGED
@@ -13,14 +13,9 @@ group :development do
|
|
13
13
|
gem 'pry-rails', '~> 0.3', '>= 0.3.11'
|
14
14
|
gem 'rails', '~> 7.0', '>= 7.0.0'
|
15
15
|
gem 'rake', '~> 13.2', '>= 13.2.1'
|
16
|
-
gem 'rspec', '~> 3.13'
|
17
|
-
gem 'rspec-expectations', '~> 3.13'
|
18
|
-
gem 'rspec-rails', '~> 7.0'
|
19
16
|
gem 'rubocop', '~> 1.66', require: false
|
20
17
|
gem 'rubocop-rails', '~> 2.26', '>= 2.26.2', require: false
|
21
18
|
gem 'rubocop-rails-omakase', '~> 1.0.0', require: false
|
22
|
-
gem 'simplecov', '~> 0.21', '>= 0.21.2', require: false
|
23
|
-
gem 'simplecov_json_formatter', '~> 0.1.4', require: false
|
24
19
|
gem 'simple_form', '~> 5.3', '>= 5.3.0'
|
25
20
|
gem 'slim', '~> 5.2', '>= 5.2.0'
|
26
21
|
gem 'sprockets-rails', '~> 3.2', '>= 3.2.2'
|
@@ -29,6 +24,12 @@ end
|
|
29
24
|
|
30
25
|
group :test, :development do
|
31
26
|
gem 'capybara', '~> 3.40'
|
27
|
+
gem 'rspec', '~> 3.13'
|
28
|
+
gem 'rspec-expectations', '~> 3.13'
|
29
|
+
gem 'rspec-html-matchers', '~> 0.10.0'
|
30
|
+
gem 'rspec-rails', '~> 7.0'
|
31
|
+
gem 'simplecov', '~> 0.21', '>= 0.21.2', require: false
|
32
|
+
gem 'simplecov_json_formatter', '~> 0.1.4', require: false
|
32
33
|
end
|
33
34
|
|
34
35
|
gemspec
|
data/README.md
CHANGED
@@ -74,6 +74,9 @@ CKEditor5::Rails.configure do
|
|
74
74
|
# Optionally, you can specify version of CKEditor 5 to use.
|
75
75
|
# If it's not specified the default version specified in the gem will be used.
|
76
76
|
# version '43.3.1'
|
77
|
+
|
78
|
+
# Upload images to the server using the simple upload adapter, instead of Base64 encoding.
|
79
|
+
# simple_upload_adapter
|
77
80
|
end
|
78
81
|
```
|
79
82
|
|
@@ -1,5 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../semver'
|
4
|
+
require_relative '../editor/props'
|
5
|
+
require_relative '../editor/helpers/config_helpers'
|
6
|
+
require_relative '../presets/manager'
|
7
|
+
require_relative '../assets/assets_bundle_html_serializer'
|
8
|
+
|
3
9
|
require_relative 'url_generator'
|
4
10
|
require_relative 'ckeditor_bundle'
|
5
11
|
require_relative 'ckbox_bundle'
|
@@ -7,7 +7,7 @@ module CKEditor5::Rails::Context
|
|
7
7
|
def ckeditor5_context(**config, &block)
|
8
8
|
context_props = Props.new(config)
|
9
9
|
|
10
|
-
tag.
|
10
|
+
tag.public_send(:'ckeditor-context-component', **context_props.to_attributes, &block)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CKEditor5::Rails::Editor
|
4
|
+
class InvalidEditableHeightError < ArgumentError; end
|
5
|
+
|
6
|
+
class EditableHeightNormalizer
|
7
|
+
def initialize(editor_type)
|
8
|
+
@editor_type = editor_type
|
9
|
+
end
|
10
|
+
|
11
|
+
def normalize(value)
|
12
|
+
return nil if value.nil?
|
13
|
+
|
14
|
+
validate_editor_type!
|
15
|
+
convert_to_pixel_value(value)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :editor_type
|
21
|
+
|
22
|
+
def validate_editor_type!
|
23
|
+
return if editor_type == :classic
|
24
|
+
|
25
|
+
raise InvalidEditableHeightError,
|
26
|
+
'editable_height can be used only with ClassicEditor'
|
27
|
+
end
|
28
|
+
|
29
|
+
def convert_to_pixel_value(value)
|
30
|
+
case value
|
31
|
+
when Integer then "#{value}px"
|
32
|
+
when String then convert_string_to_pixel_value(value)
|
33
|
+
else
|
34
|
+
raise_invalid_height_error(value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def convert_string_to_pixel_value(value)
|
39
|
+
return value if value.match?(/^\d+px$/)
|
40
|
+
|
41
|
+
raise_invalid_height_error(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def raise_invalid_height_error(value)
|
45
|
+
raise InvalidEditableHeightError,
|
46
|
+
"editable_height must be an integer representing pixels or string ending with 'px'\n" \
|
47
|
+
"(e.g. 500 or '500px'). Got: #{value.inspect}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module CKEditor5::Rails
|
4
|
-
module
|
3
|
+
module CKEditor5::Rails::Editor::Helpers
|
4
|
+
module Config
|
5
5
|
def ckeditor5_element_ref(selector)
|
6
6
|
{ '$element': selector }
|
7
7
|
end
|
8
8
|
|
9
9
|
def ckeditor5_preset(name = nil, &block)
|
10
|
-
return Engine.find_preset(name) if name
|
10
|
+
return CKEditor5::Rails::Engine.find_preset(name) if name
|
11
11
|
|
12
12
|
raise ArgumentError, 'Configuration block is required for preset definition' unless block_given?
|
13
13
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../version_detector'
|
4
|
+
require_relative '../../presets/preset_builder'
|
3
5
|
require_relative 'config_helpers'
|
4
6
|
|
5
7
|
module CKEditor5::Rails
|
@@ -8,7 +10,6 @@ module CKEditor5::Rails
|
|
8
10
|
|
9
11
|
class EditorContextError < StandardError; end
|
10
12
|
class PresetNotFoundError < ArgumentError; end
|
11
|
-
class InvalidEditableHeightError < ArgumentError; end
|
12
13
|
|
13
14
|
# Creates a CKEditor 5 editor instance
|
14
15
|
#
|
@@ -45,15 +46,15 @@ module CKEditor5::Rails
|
|
45
46
|
|
46
47
|
tag_attributes = html_attributes.merge(editor_props.to_attributes)
|
47
48
|
|
48
|
-
tag.
|
49
|
+
tag.public_send(:'ckeditor-component', **tag_attributes, &block)
|
49
50
|
end
|
50
51
|
|
51
52
|
def ckeditor5_editable(name = nil, **kwargs, &block)
|
52
|
-
tag.
|
53
|
+
tag.public_send(:'ckeditor-editable-component', name: name, **kwargs, &block)
|
53
54
|
end
|
54
55
|
|
55
56
|
def ckeditor5_ui_part(name, **kwargs, &block)
|
56
|
-
tag.
|
57
|
+
tag.public_send(:'ckeditor-ui-part-component', name: name, **kwargs, &block)
|
57
58
|
end
|
58
59
|
|
59
60
|
def ckeditor5_toolbar(**kwargs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'props_plugin'
|
4
|
+
require_relative 'editable_height_normalizer'
|
4
5
|
|
5
6
|
module CKEditor5::Rails::Editor
|
6
7
|
class Props
|
@@ -19,7 +20,7 @@ module CKEditor5::Rails::Editor
|
|
19
20
|
@watchdog = watchdog
|
20
21
|
@type = type
|
21
22
|
@config = config
|
22
|
-
@editable_height =
|
23
|
+
@editable_height = EditableHeightNormalizer.new(type).normalize(editable_height)
|
23
24
|
end
|
24
25
|
|
25
26
|
def to_attributes
|
@@ -48,7 +49,7 @@ module CKEditor5::Rails::Editor
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def serialize_translations
|
51
|
-
controller_context[:bundle]
|
52
|
+
controller_context[:bundle]&.translations_scripts&.map(&:to_h).to_json || '[]'
|
52
53
|
end
|
53
54
|
|
54
55
|
def serialize_plugins
|
@@ -61,23 +62,5 @@ module CKEditor5::Rails::Editor
|
|
61
62
|
.tap { |cfg| cfg[:licenseKey] = controller_context[:license_key] if controller_context[:license_key] }
|
62
63
|
.to_json
|
63
64
|
end
|
64
|
-
|
65
|
-
def normalize_editable_height(editable_height)
|
66
|
-
return nil if editable_height.nil?
|
67
|
-
|
68
|
-
unless type == :classic
|
69
|
-
raise InvalidEditableHeightError,
|
70
|
-
'editable_height can be used only with ClassicEditor'
|
71
|
-
end
|
72
|
-
|
73
|
-
case editable_height
|
74
|
-
when String, /^\d+px$/ then editable_height
|
75
|
-
when Integer, /^\d+$/ then "#{editable_height}px"
|
76
|
-
else
|
77
|
-
raise InvalidEditableHeightError,
|
78
|
-
"editable_height must be an integer representing pixels or string ending with 'px'\n" \
|
79
|
-
"(e.g. 500 or '500px'). Got: #{editable_height.inspect}"
|
80
|
-
end
|
81
|
-
end
|
82
65
|
end
|
83
66
|
end
|
@@ -104,7 +104,7 @@ module CKEditor5::Rails
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def version(version = nil)
|
107
|
-
return @version
|
107
|
+
return @version&.to_s if version.nil?
|
108
108
|
|
109
109
|
if @automatic_upgrades && version
|
110
110
|
detected = VersionDetector.latest_safe_version(version)
|
@@ -164,7 +164,7 @@ module CKEditor5::Rails
|
|
164
164
|
|
165
165
|
return unless block
|
166
166
|
|
167
|
-
builder =
|
167
|
+
builder = ToolbarBuilder.new(@config[:toolbar][:items])
|
168
168
|
builder.instance_eval(&block)
|
169
169
|
end
|
170
170
|
|
@@ -174,7 +174,6 @@ module CKEditor5::Rails
|
|
174
174
|
|
175
175
|
def plugin(name, **kwargs)
|
176
176
|
plugin_obj = PluginsBuilder.create_plugin(name, **kwargs)
|
177
|
-
|
178
177
|
@config[:plugins] << plugin_obj
|
179
178
|
plugin_obj
|
180
179
|
end
|
@@ -4,6 +4,8 @@ require 'net/http'
|
|
4
4
|
require 'json'
|
5
5
|
require 'singleton'
|
6
6
|
require 'monitor'
|
7
|
+
|
8
|
+
require_relative 'version'
|
7
9
|
require_relative 'semver'
|
8
10
|
|
9
11
|
module CKEditor5::Rails
|
@@ -22,6 +24,10 @@ module CKEditor5::Rails
|
|
22
24
|
@monitor = Monitor.new
|
23
25
|
end
|
24
26
|
|
27
|
+
def clear_cache!
|
28
|
+
@monitor.synchronize { @cache.clear }
|
29
|
+
end
|
30
|
+
|
25
31
|
def latest_safe_version(current_version)
|
26
32
|
@monitor.synchronize do
|
27
33
|
cache_key = "#{current_version}_latest"
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
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
|
+
let(:scripts) do
|
21
|
+
[
|
22
|
+
CKEditor5::Rails::Assets::JSExportsMeta.new(
|
23
|
+
'https://cdn.com/script1.js',
|
24
|
+
window_name: 'CKEditor5'
|
25
|
+
),
|
26
|
+
CKEditor5::Rails::Assets::JSExportsMeta.new(
|
27
|
+
'https://cdn.com/script2.js',
|
28
|
+
import_name: '@ckeditor/script2'
|
29
|
+
)
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:stylesheets) { ['https://cdn.com/style1.css', 'https://cdn.com/style2.css'] }
|
34
|
+
let(:preloads) { bundle.preloads }
|
35
|
+
|
36
|
+
subject(:serializer) { described_class.new(bundle) }
|
37
|
+
|
38
|
+
describe '#initialize' do
|
39
|
+
context 'with invalid bundle' do
|
40
|
+
let(:bundle) { 'not a bundle' }
|
41
|
+
|
42
|
+
it 'raises TypeError' do
|
43
|
+
expect { serializer }.to raise_error(TypeError, 'bundle must be an instance of AssetsBundle')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#to_html' do
|
49
|
+
subject(:html) { serializer.to_html }
|
50
|
+
|
51
|
+
it 'includes window scripts' do
|
52
|
+
expect(html).to include(
|
53
|
+
'<script src="https://cdn.com/script1.js" nonce="true" crossorigin="anonymous">'
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'includes import map' do
|
58
|
+
expect(html).to include('type="importmap"')
|
59
|
+
expect(html).to include('"@ckeditor/script2":"https://cdn.com/script2.js"')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'includes stylesheet links' do
|
63
|
+
stylesheets.each do |url|
|
64
|
+
expect(html).to include("<link href=\"#{url}\" rel=\"stylesheet\" crossorigin=\"anonymous\">")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'includes preload links' do
|
69
|
+
expect(html).to include(
|
70
|
+
'<link href="https://cdn.com/style1.css" rel="preload" as="style" crossorigin="anonymous">'
|
71
|
+
)
|
72
|
+
|
73
|
+
expect(html).to include(
|
74
|
+
'<link href="https://cdn.com/style2.css" rel="preload" as="style" crossorigin="anonymous">'
|
75
|
+
)
|
76
|
+
|
77
|
+
expect(html).to include(
|
78
|
+
'<link href="https://cdn.com/script1.js" rel="preload" as="script" crossorigin="anonymous">'
|
79
|
+
)
|
80
|
+
|
81
|
+
expect(html).to include(
|
82
|
+
'<link href="https://cdn.com/script2.js" rel="preload" as="script" crossorigin="anonymous">'
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'includes web component script' do
|
87
|
+
expect(html).to include('<script type="module" nonce="true">')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '.url_resource_preload_type' do
|
92
|
+
it 'returns correct type for js files' do
|
93
|
+
expect(described_class.url_resource_preload_type('file.js')).to eq('script')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'returns correct type for css files' do
|
97
|
+
expect(described_class.url_resource_preload_type('file.css')).to eq('style')
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'returns fetch for unknown extensions' do
|
101
|
+
expect(described_class.url_resource_preload_type('file.unknown')).to eq('fetch')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
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
|
+
describe '#initialize' do
|
19
|
+
it 'raises error when required methods are not implemented' do
|
20
|
+
expect { described_class.new }.to raise_error(NotImplementedError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'initializes successfully when required methods are implemented' do
|
24
|
+
expect { concrete_class.new }.not_to raise_error
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#empty?' do
|
29
|
+
subject(:bundle) { concrete_class.new }
|
30
|
+
|
31
|
+
it 'returns true when no assets are present' do
|
32
|
+
expect(bundle).to be_empty
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#translations_scripts' do
|
37
|
+
let(:bundle) { concrete_class.new }
|
38
|
+
let(:translation_script) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta, translation?: true) }
|
39
|
+
let(:regular_script) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta, translation?: false) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
allow(bundle).to receive(:scripts).and_return([translation_script, regular_script])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns only translation scripts' do
|
46
|
+
expect(bundle.translations_scripts).to eq([translation_script])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#<<' do
|
51
|
+
let(:script1) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta) }
|
52
|
+
let(:script2) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta) }
|
53
|
+
let(:stylesheet1) { '/path/to/style1.css' }
|
54
|
+
let(:stylesheet2) { '/path/to/style2.css' }
|
55
|
+
|
56
|
+
let(:bundle1) do
|
57
|
+
Class.new(described_class) do
|
58
|
+
attr_writer :scripts, :stylesheets
|
59
|
+
|
60
|
+
def scripts
|
61
|
+
@scripts ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
def stylesheets
|
65
|
+
@stylesheets ||= []
|
66
|
+
end
|
67
|
+
end.new
|
68
|
+
end
|
69
|
+
|
70
|
+
let(:bundle2) do
|
71
|
+
Class.new(described_class) do
|
72
|
+
attr_writer :scripts, :stylesheets
|
73
|
+
|
74
|
+
def scripts
|
75
|
+
@scripts ||= []
|
76
|
+
end
|
77
|
+
|
78
|
+
def stylesheets
|
79
|
+
@stylesheets ||= []
|
80
|
+
end
|
81
|
+
end.new
|
82
|
+
end
|
83
|
+
|
84
|
+
before do
|
85
|
+
bundle1.scripts = [script1]
|
86
|
+
bundle1.stylesheets = [stylesheet1]
|
87
|
+
bundle2.scripts = [script2]
|
88
|
+
bundle2.stylesheets = [stylesheet2]
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'raises TypeError when argument is not an AssetsBundle' do
|
92
|
+
expect { bundle1 << 'not a bundle' }.to raise_error(TypeError)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'merges scripts and stylesheets from both bundles' do
|
96
|
+
bundle1 << bundle2
|
97
|
+
|
98
|
+
expect(bundle1.scripts).to eq([script1, script2])
|
99
|
+
expect(bundle1.stylesheets).to eq([stylesheet1, stylesheet2])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#preloads' do
|
104
|
+
let(:script1) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta, url: '/js/script1.js') }
|
105
|
+
let(:script2) { instance_double(CKEditor5::Rails::Assets::JSExportsMeta, url: '/js/script2.js') }
|
106
|
+
let(:stylesheet1) { '/css/style1.css' }
|
107
|
+
let(:stylesheet2) { '/css/style2.css' }
|
108
|
+
|
109
|
+
let(:bundle) do
|
110
|
+
Class.new(described_class) do
|
111
|
+
attr_writer :scripts, :stylesheets
|
112
|
+
|
113
|
+
def scripts
|
114
|
+
@scripts ||= []
|
115
|
+
end
|
116
|
+
|
117
|
+
def stylesheets
|
118
|
+
@stylesheets ||= []
|
119
|
+
end
|
120
|
+
end.new
|
121
|
+
end
|
122
|
+
|
123
|
+
before do
|
124
|
+
bundle.scripts = [script1, script2]
|
125
|
+
bundle.stylesheets = [stylesheet1, stylesheet2]
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'returns array of stylesheet paths and script urls' do
|
129
|
+
expect(bundle.preloads).to eq([
|
130
|
+
'/css/style1.css',
|
131
|
+
'/css/style2.css',
|
132
|
+
'/js/script1.js',
|
133
|
+
'/js/script2.js'
|
134
|
+
])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
RSpec.describe CKEditor5::Rails::Assets::JSExportsMeta do
|
140
|
+
let(:url) { '/path/to/script.js' }
|
141
|
+
|
142
|
+
describe '#initialize' do
|
143
|
+
it 'creates instance with import_name' do
|
144
|
+
meta = described_class.new(url, import_name: 'module')
|
145
|
+
expect(meta.import_name).to eq('module')
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'creates instance with window_name' do
|
149
|
+
meta = described_class.new(url, window_name: 'MyModule')
|
150
|
+
expect(meta.window_name).to eq('MyModule')
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'marks as translation when specified' do
|
154
|
+
meta = described_class.new(url, translation: true, import_name: 'module')
|
155
|
+
expect(meta).to be_translation
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
RSpec.describe CKEditor5::Rails::Assets::JSImportMeta do
|
161
|
+
describe '#initialize' do
|
162
|
+
it 'raises error when neither import_name nor window_name is provided' do
|
163
|
+
expect { described_class.new }.to raise_error(ArgumentError)
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'raises error when import_as is present without import_name' do
|
167
|
+
expect { described_class.new(import_as: 'alias', window_name: 'Module') }
|
168
|
+
.to raise_error(ArgumentError)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'creates valid instance with import_name' do
|
172
|
+
meta = described_class.new(import_name: 'module')
|
173
|
+
expect(meta).to be_esm
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'creates valid instance with window_name' do
|
177
|
+
meta = described_class.new(window_name: 'Module')
|
178
|
+
expect(meta).to be_window
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#to_h' do
|
183
|
+
it 'returns hash with only present values' do
|
184
|
+
meta = described_class.new(import_name: 'module', import_as: 'alias')
|
185
|
+
expect(meta.to_h).to eq({
|
186
|
+
import_name: 'module',
|
187
|
+
import_as: 'alias'
|
188
|
+
})
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CKEditor5::Rails::Cdn::CKBoxBundle do
|
6
|
+
let(:version) { CKEditor5::Rails::Semver.new('2.6.0') }
|
7
|
+
let(:cdn) { :jsdelivr }
|
8
|
+
let(:theme) { :lark }
|
9
|
+
let(:translations) { [] }
|
10
|
+
let(:bundle) { described_class.new(version, theme: theme, cdn: cdn, translations: translations) }
|
11
|
+
|
12
|
+
describe '#initialize' do
|
13
|
+
context 'with valid parameters' do
|
14
|
+
it 'creates bundle successfully' do
|
15
|
+
expect { bundle }.not_to raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with invalid parameters' do
|
20
|
+
it 'raises error for invalid version' do
|
21
|
+
expect { described_class.new('invalid', theme: theme) }
|
22
|
+
.to raise_error(ArgumentError, 'version must be semver')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'raises error for invalid theme type' do
|
26
|
+
expect { described_class.new(version, theme: 123) }
|
27
|
+
.to raise_error(ArgumentError, 'theme must be a string or symbol')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises error for invalid translations type' do
|
31
|
+
expect { described_class.new(version, theme: theme, translations: 'invalid') }
|
32
|
+
.to raise_error(ArgumentError, 'translations must be an array')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#scripts' do
|
38
|
+
it 'returns array with main script' do
|
39
|
+
expect(bundle.scripts.first).to be_a(CKEditor5::Rails::Assets::JSExportsMeta)
|
40
|
+
expect(bundle.scripts.first.url).to include('ckbox.js')
|
41
|
+
expect(bundle.scripts.first.window_name).to eq('CKBox')
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'with translations' do
|
45
|
+
let(:translations) { [:pl] }
|
46
|
+
|
47
|
+
it 'includes translation scripts' do
|
48
|
+
translation_script = bundle.scripts.last
|
49
|
+
expect(translation_script.url).to include('translations/pl.js')
|
50
|
+
expect(translation_script.window_name).to eq('CKBOX_TRANSLATIONS')
|
51
|
+
expect(translation_script.translation?).to be true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#stylesheets' do
|
57
|
+
it 'returns array with theme stylesheet' do
|
58
|
+
expect(bundle.stylesheets.first).to include('styles/themes/lark.css')
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'with custom theme' do
|
62
|
+
let(:theme) { :custom }
|
63
|
+
|
64
|
+
it 'uses custom theme in stylesheet path' do
|
65
|
+
expect(bundle.stylesheets.first).to include('styles/themes/custom.css')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|