ckeditor5 1.14.1 → 1.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +58 -9
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +6 -0
- data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +7 -0
- data/lib/ckeditor5/rails/presets/manager.rb +1 -0
- data/lib/ckeditor5/rails/presets/preset_builder.rb +15 -1
- data/lib/ckeditor5/rails/semver.rb +40 -10
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/lib/ckeditor5/rails/version_detector.rb +80 -0
- data/lib/ckeditor5/rails.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7d0dce96ea4b299699c42c1567c3f101a257c465a0e93b8856847fff94c6062
|
4
|
+
data.tar.gz: 9ca6f4faa82bc9f62efa91b65634b8b9a037ce7fda0bf99507cefc87fca8348b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c484342136c54b500b98e3615647f8c9c92c403d4af5569cadc910a520250f7767ccf020f9d697853fce9a9ae67a4bfa7dedb883b0691a6008f65b3b04c93190
|
7
|
+
data.tar.gz: f98cb8faacebed0f36ffda4a8523443f4307b138b20136e670ee9dc7894bd91d9889c9acc14f0abe736c34c7339d1ff664b9332f8cf22555348c8094cfa7b592
|
data/README.md
CHANGED
@@ -28,7 +28,12 @@ In your config (the default config is defined [here](https://github.com/Mati365/
|
|
28
28
|
# config/initializers/ckeditor5.rb
|
29
29
|
|
30
30
|
CKEditor5::Rails.configure do
|
31
|
-
version '43.3.0'
|
31
|
+
version '43.3.0' # 🔖 Specify the version of editor you want.
|
32
|
+
# ⚙️ Configuration includes:
|
33
|
+
# 📝 Classic editor build
|
34
|
+
# 🧩 Essential plugins (paragraphs, basic styles)
|
35
|
+
# 🎛️ Default toolbar layout
|
36
|
+
# 📜 GPL license
|
32
37
|
end
|
33
38
|
```
|
34
39
|
|
@@ -54,38 +59,43 @@ In your view:
|
|
54
59
|
<!-- app/views/demos/index.html.erb -->
|
55
60
|
|
56
61
|
<% content_for :head do %>
|
62
|
+
<!-- 📦 Loads CKEditor assets via importmap based on initializer config -->
|
57
63
|
<%= ckeditor5_assets %>
|
58
64
|
<% end %>
|
59
65
|
|
66
|
+
<!-- 🖋️ Renders rich text editor interface using WebComponent -->
|
60
67
|
<%= ckeditor5_editor %>
|
61
68
|
```
|
62
69
|
|
63
70
|
Voilà! You have CKEditor 5 integrated with your Rails application. 🎉
|
64
71
|
|
65
|
-
## Demos
|
72
|
+
## Try Our Demos! 🎮 ✨
|
66
73
|
|
67
|
-
|
74
|
+
Want to see some cool examples? We've got you covered! Check out our interactive [demo application](https://github.com/Mati365/ckeditor5-rails/tree/main/sandbox/app/views/demos) packed with various editor configurations. You can also explore official CKEditor 5 [examples](https://ckeditor.com/docs/ckeditor5/latest/examples/builds/classic-editor.html) for more inspiration! 💡
|
68
75
|
|
69
|
-
|
76
|
+
Ready to play with the demos locally? It's super easy! Just follow these steps: 🚀
|
70
77
|
|
71
78
|
```bash
|
72
|
-
bundle install
|
73
|
-
|
74
|
-
bundle exec rails server -p 3000
|
79
|
+
bundle install # Install all the goodies 📦
|
80
|
+
bundle exec guard -g rails # Fire up the server 🔥
|
75
81
|
```
|
76
82
|
|
77
|
-
|
83
|
+
Now the fun part - open [http://localhost:3000/](http://localhost:3000/) in your browser and start experimenting! 🎯 Feel free to tweak the code and make it your own! 🎨
|
84
|
+
|
85
|
+
Want to extend CKEditor's functionality? Check out our [plugins directory](https://github.com/Mati365/ckeditor5-rails/tree/main/lib/ckeditor5/rails/plugins) and create your own awesome plugins! 🔌 We love community contributions - your plugin could be the next great addition to our ecosystem! ⭐
|
78
86
|
|
79
87
|
## Table of Contents 📚
|
80
88
|
|
81
89
|
- [CKEditor 5 Rails Integration ✨](#ckeditor-5-rails-integration-)
|
82
90
|
- [Installation 🛠️](#installation-️)
|
83
|
-
- [Demos
|
91
|
+
- [Try Our Demos! 🎮 ✨](#try-our-demos--)
|
84
92
|
- [Table of Contents 📚](#table-of-contents-)
|
85
93
|
- [Presets 🎨](#presets-)
|
94
|
+
- [Automatic upgrades 🔄](#automatic-upgrades-)
|
86
95
|
- [Available Configuration Methods ⚙️](#available-configuration-methods-️)
|
87
96
|
- [`cdn(cdn = nil, &block)` method](#cdncdn--nil-block-method)
|
88
97
|
- [`version(version)` method](#versionversion-method)
|
98
|
+
- [`automatic_upgrades(enabled: true)` method](#automatic_upgradesenabled-true-method)
|
89
99
|
- [`gpl` method](#gpl-method)
|
90
100
|
- [`license_key(key)` method](#license_keykey-method)
|
91
101
|
- [`premium` method](#premium-method)
|
@@ -164,6 +174,11 @@ CKEditor5::Rails.configure do
|
|
164
174
|
presets.define :blank_preset, inherit: false do
|
165
175
|
version '44.0.0'
|
166
176
|
|
177
|
+
# It tells the integration to fetch the newest security patches and bug fixes.
|
178
|
+
# It may be disabled, but it's highly recommended to keep it enabled to avoid
|
179
|
+
# potential security issues.
|
180
|
+
automatic_upgrades
|
181
|
+
|
167
182
|
gpl
|
168
183
|
type :classic
|
169
184
|
|
@@ -208,6 +223,22 @@ end
|
|
208
223
|
|
209
224
|
Configuration of the editor can be complex, and it's recommended to use the [CKEditor 5 online builder](https://ckeditor.com/ckeditor-5/online-builder/) to generate the configuration. It allows you to select the features you want to include and generate the configuration code in JavaScript format. Keep in mind that you need to convert the JavaScript configuration to Ruby format before using it in this gem.
|
210
225
|
|
226
|
+
### Automatic upgrades 🔄
|
227
|
+
|
228
|
+
The gem includes a feature that automatically upgrades the CKEditor 5 version when it's released. It's enabled by default for the `:default` preset. It means that the editor will automatically check the version of the editor during the initialization and upgrade it to the latest version if the new patch or minor version is released.
|
229
|
+
|
230
|
+
If you want to disable automatic upgrades, you can pass the `enabled: false` keyword argument to the `automatic_upgrades` method.
|
231
|
+
|
232
|
+
```rb
|
233
|
+
# config/initializers/ckeditor5.rb
|
234
|
+
|
235
|
+
CKEditor5::Rails.configure do
|
236
|
+
# ... other configuration
|
237
|
+
|
238
|
+
automatic_upgrades enabled: false
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
211
242
|
### Available Configuration Methods ⚙️
|
212
243
|
|
213
244
|
#### `cdn(cdn = nil, &block)` method
|
@@ -254,6 +285,24 @@ CKEditor5::Rails.configure do
|
|
254
285
|
end
|
255
286
|
```
|
256
287
|
|
288
|
+
#### `automatic_upgrades(enabled: true)` method
|
289
|
+
|
290
|
+
Defines if automatic upgrades should be enabled. It's enabled for the `:default` preset by default. The example below shows how to disable automatic upgrades:
|
291
|
+
|
292
|
+
```rb
|
293
|
+
# config/initializers/ckeditor5.rb
|
294
|
+
|
295
|
+
CKEditor5::Rails.configure do
|
296
|
+
# ... other configuration
|
297
|
+
|
298
|
+
automatic_upgrades enabled: false
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
302
|
+
It means that the editor will automatically upgrade to the latest version when the gem is updated. It'll upgrade the editor only if the new patch or minor version is released. If you want to disable automatic upgrades, you can pass the `enabled: false` keyword argument to the `automatic_upgrades` method.
|
303
|
+
|
304
|
+
Version is checked every nth day, where n is the number of days since the last check. Currently it's 4 days.
|
305
|
+
|
257
306
|
#### `gpl` method
|
258
307
|
|
259
308
|
Defines the license of CKEditor 5. The example below shows how to set the license to GPL:
|
@@ -76,6 +76,12 @@ module CKEditor5::Rails
|
|
76
76
|
editor_config = config || preset.config
|
77
77
|
editor_config = editor_config.deep_merge(extra_config)
|
78
78
|
editor_config[:initialData] = initial_data if initial_data
|
79
|
+
|
80
|
+
if preset.automatic_upgrades? && editor_config[:version].present?
|
81
|
+
detected_version = VersionDetector.latest_safe_version(editor_config[:version])
|
82
|
+
editor_config[:version] = detected_version if detected_version
|
83
|
+
end
|
84
|
+
|
79
85
|
editor_config
|
80
86
|
end
|
81
87
|
|
@@ -36,6 +36,13 @@ module CKEditor5::Rails::Plugins
|
|
36
36
|
xhr.open('POST', config.uploadUrl, true);
|
37
37
|
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
38
38
|
|
39
|
+
// Add CSRF token from meta tag
|
40
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;
|
41
|
+
|
42
|
+
if (csrfToken) {
|
43
|
+
xhr.setRequestHeader('X-CSRF-Token', csrfToken);
|
44
|
+
}
|
45
|
+
|
39
46
|
xhr.upload.onprogress = (evt) => {
|
40
47
|
if (evt.lengthComputable) {
|
41
48
|
loader.uploadTotal = evt.total;
|
@@ -16,6 +16,7 @@ module CKEditor5::Rails
|
|
16
16
|
@type = :classic
|
17
17
|
@ckbox = nil
|
18
18
|
@editable_height = nil
|
19
|
+
@automatic_upgrades = false
|
19
20
|
@config = {
|
20
21
|
plugins: [],
|
21
22
|
toolbar: []
|
@@ -105,7 +106,20 @@ module CKEditor5::Rails
|
|
105
106
|
def version(version = nil)
|
106
107
|
return @version.to_s if version.nil?
|
107
108
|
|
108
|
-
@
|
109
|
+
if @automatic_upgrades && version
|
110
|
+
detected = VersionDetector.latest_safe_version(version)
|
111
|
+
@version = Semver.new(detected || version)
|
112
|
+
else
|
113
|
+
@version = Semver.new(version)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def automatic_upgrades(enabled: true)
|
118
|
+
@automatic_upgrades = enabled
|
119
|
+
end
|
120
|
+
|
121
|
+
def automatic_upgrades?
|
122
|
+
@automatic_upgrades
|
109
123
|
end
|
110
124
|
|
111
125
|
def cdn(cdn = nil, &block)
|
@@ -1,18 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module CKEditor5
|
4
|
+
module Rails
|
5
|
+
class Semver
|
6
|
+
SEMVER_PATTERN = /\A\d+\.\d+\.\d+\z/
|
5
7
|
|
6
|
-
|
8
|
+
attr_reader :major, :minor, :patch
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
include Comparable
|
11
|
+
|
12
|
+
def initialize(version_string)
|
13
|
+
validate!(version_string)
|
14
|
+
@major, @minor, @patch = version_string.split('.').map(&:to_i)
|
15
|
+
end
|
16
|
+
|
17
|
+
def <=>(other)
|
18
|
+
return nil unless other.is_a?(Semver)
|
19
|
+
|
20
|
+
[major, minor, patch] <=> [other.major, other.minor, other.patch]
|
21
|
+
end
|
22
|
+
|
23
|
+
def safe_update?(other_version)
|
24
|
+
other = self.class.new(other_version)
|
25
|
+
|
26
|
+
return false if other.major != major
|
27
|
+
return true if other.minor > minor
|
28
|
+
return true if other.minor == minor && other.patch > patch
|
29
|
+
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def version
|
34
|
+
"#{major}.#{minor}.#{patch}"
|
35
|
+
end
|
36
|
+
|
37
|
+
alias to_s :version
|
38
|
+
|
39
|
+
private
|
12
40
|
|
13
|
-
|
41
|
+
def validate!(version_string)
|
42
|
+
return if version_string.is_a?(String) && version_string.match?(SEMVER_PATTERN)
|
14
43
|
|
15
|
-
|
16
|
-
|
44
|
+
raise ArgumentError, 'invalid version format'
|
45
|
+
end
|
46
|
+
end
|
17
47
|
end
|
18
48
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'json'
|
5
|
+
require 'singleton'
|
6
|
+
require 'monitor'
|
7
|
+
require_relative 'semver'
|
8
|
+
|
9
|
+
module CKEditor5::Rails
|
10
|
+
class VersionDetector
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
NPM_PACKAGE = 'ckeditor5'
|
14
|
+
CACHE_DURATION = 345_600 # 4 days in seconds
|
15
|
+
|
16
|
+
class << self
|
17
|
+
delegate :latest_safe_version, to: :instance
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@cache = {}
|
22
|
+
@monitor = Monitor.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def latest_safe_version(current_version)
|
26
|
+
@monitor.synchronize do
|
27
|
+
cache_key = "#{current_version}_latest"
|
28
|
+
return @cache[cache_key][:version] if valid_cache_entry?(cache_key)
|
29
|
+
|
30
|
+
version = find_latest_safe_version(current_version)
|
31
|
+
@cache[cache_key] = { version: version, timestamp: Time.now.to_i }
|
32
|
+
version
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def valid_cache_entry?(key)
|
39
|
+
entry = @cache[key]
|
40
|
+
entry && (Time.now.to_i - entry[:timestamp] < CACHE_DURATION)
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_latest_safe_version(current_version)
|
44
|
+
versions = fetch_all_versions
|
45
|
+
return nil if versions.empty?
|
46
|
+
|
47
|
+
current_semver = Semver.new(current_version)
|
48
|
+
versions
|
49
|
+
.reject { |v| v.include?('nightly') || v.include?('dev') }
|
50
|
+
.select { |v| v.match?(Semver::SEMVER_PATTERN) }
|
51
|
+
.sort_by { |v| Semver.new(v) }
|
52
|
+
.reverse
|
53
|
+
.find { |v| current_semver.safe_update?(v) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def fetch_all_versions
|
57
|
+
uri = URI("https://registry.npmjs.org/#{NPM_PACKAGE}")
|
58
|
+
response = fetch_with_timeout(uri)
|
59
|
+
|
60
|
+
if response.is_a?(Net::HTTPSuccess)
|
61
|
+
data = JSON.parse(response.body)
|
62
|
+
data['versions'].keys
|
63
|
+
else
|
64
|
+
warn 'Failed to fetch CKEditor versions'
|
65
|
+
[]
|
66
|
+
end
|
67
|
+
rescue StandardError => e
|
68
|
+
warn "Error fetching versions: #{e.message}"
|
69
|
+
[]
|
70
|
+
end
|
71
|
+
|
72
|
+
def fetch_with_timeout(uri)
|
73
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
74
|
+
http.use_ssl = (uri.scheme == 'https')
|
75
|
+
http.open_timeout = 1
|
76
|
+
http.read_timeout = 1
|
77
|
+
http.get(uri.request_uri)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/ckeditor5/rails.rb
CHANGED
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.15.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-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- lib/ckeditor5/rails/presets/toolbar_builder.rb
|
75
75
|
- lib/ckeditor5/rails/semver.rb
|
76
76
|
- lib/ckeditor5/rails/version.rb
|
77
|
+
- lib/ckeditor5/rails/version_detector.rb
|
77
78
|
- spec/lib/ckeditor5/rails/cdn/url_generator_spec.rb
|
78
79
|
- spec/lib/ckeditor5/rails/semver_spec.rb
|
79
80
|
- spec/spec_helper.rb
|