ckeditor5 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b4d6c95733dd5744553bb787f20f9efaf474086c6268d6842561905747ec10f
4
- data.tar.gz: 17052fae7a4e0e88fcc7c0af8ab397c8fadb3421ce611c64a10fe597d15a9d82
3
+ metadata.gz: 2a9a17d760584b0e960fe984a39421cb779f6ecbbbff0e01dd996530051e5257
4
+ data.tar.gz: 9612989fa0d36927280d3d2023499a5944c7cd22cae9f7a3f9eb1b56fb5a5651
5
5
  SHA512:
6
- metadata.gz: 4dbaefb77863ceaeaad0805d430c86b90c7fbec675a7478fc55994a9706bfc3b8ec59c7791ce916389346da508f47a88ce2ff8c38a79d1c9189aa77405769f9f
7
- data.tar.gz: 6b1d599bbfe28b35c81d037b052085c15fe55c1248f8e858efc77b7515c88b5ea2818187082f0db7810192b7d2cdfd3bb45d3dba57f7cf03cd0f53932dfbb202
6
+ metadata.gz: 7fe424cef2178f16106821edf3f195d2d4a6ba6076c4aa093a7f65aad2cc0fbe9836606bdfdaf2eb65c917bb561375c5f2ab5ab293baeb27f21173bf6a4e739c
7
+ data.tar.gz: 71b177012a1d865f613b36968f5d8bab3822fb6b8c67dedc04ec05a1f0729228b9c48b568c27ba00632e971e69e645b94f13c9eb3ed07ad6c2a1be52c0445e67
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,23 +59,42 @@ 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
 
72
+ ## Try Our Demos! 🎮 ✨
73
+
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! 💡
75
+
76
+ Ready to play with the demos locally? It's super easy! Just follow these steps: 🚀
77
+
78
+ ```bash
79
+ bundle install # Install all the goodies 📦
80
+ bundle exec guard -g rails # Fire up the server 🔥
81
+ ```
82
+
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! ⭐
86
+
65
87
  ## Table of Contents 📚
66
88
 
67
89
  - [CKEditor 5 Rails Integration ✨](#ckeditor-5-rails-integration-)
68
90
  - [Installation 🛠️](#installation-️)
91
+ - [Try Our Demos! 🎮 ✨](#try-our-demos--)
69
92
  - [Table of Contents 📚](#table-of-contents-)
70
93
  - [Presets 🎨](#presets-)
71
94
  - [Available Configuration Methods ⚙️](#available-configuration-methods-️)
72
95
  - [`cdn(cdn = nil, &block)` method](#cdncdn--nil-block-method)
73
96
  - [`version(version)` method](#versionversion-method)
97
+ - [`automatic_upgrades(enabled: true)` method](#automatic_upgradesenabled-true-method)
74
98
  - [`gpl` method](#gpl-method)
75
99
  - [`license_key(key)` method](#license_keykey-method)
76
100
  - [`premium` method](#premium-method)
@@ -86,6 +110,7 @@ Voilà! You have CKEditor 5 integrated with your Rails application. 🎉
86
110
  - [`plugins(*names, **kwargs)` method](#pluginsnames-kwargs-method)
87
111
  - [`inline_plugin(name, code)` method](#inline_pluginname-code-method)
88
112
  - [`simple_upload_adapter(url)` method](#simple_upload_adapterurl-method)
113
+ - [Automatic upgrades 🔄](#automatic-upgrades-)
89
114
  - [Controller / View helpers 📦](#controller--view-helpers-)
90
115
  - [`ckeditor5_element_ref(selector)` method](#ckeditor5_element_refselector-method)
91
116
  - [`ckeditor5_preset(&block)` method](#ckeditor5_presetblock-method)
@@ -149,6 +174,11 @@ CKEditor5::Rails.configure do
149
174
  presets.define :blank_preset, inherit: false do
150
175
  version '44.0.0'
151
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
+
152
182
  gpl
153
183
  type :classic
154
184
 
@@ -239,6 +269,24 @@ CKEditor5::Rails.configure do
239
269
  end
240
270
  ```
241
271
 
272
+ #### `automatic_upgrades(enabled: true)` method
273
+
274
+ 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:
275
+
276
+ ```rb
277
+ # config/initializers/ckeditor5.rb
278
+
279
+ CKEditor5::Rails.configure do
280
+ # ... other configuration
281
+
282
+ automatic_upgrades enabled: false
283
+ end
284
+ ```
285
+
286
+ 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.
287
+
288
+ Version is checked every nth day, where n is the number of days since the last check. Currently it's 4 days.
289
+
242
290
  #### `gpl` method
243
291
 
244
292
  Defines the license of CKEditor 5. The example below shows how to set the license to GPL:
@@ -590,7 +638,11 @@ CKEditor5::Rails.configure do
590
638
  end
591
639
  ```
592
640
 
593
- Remember to remove the `Base64UploadAdapter` plugin from the plugins list if you want to use the simple upload adapter. It may cause issues.
641
+ ### Automatic upgrades 🔄
642
+
643
+ The gem includes a feature that automatically upgrades the CKEditor&nbsp;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.
644
+
645
+ If you want to disable automatic upgrades, you can pass the `enabled: false` keyword argument to the `automatic_upgrades` method.
594
646
 
595
647
  ```rb
596
648
  # config/initializers/ckeditor5.rb
@@ -598,9 +650,7 @@ Remember to remove the `Base64UploadAdapter` plugin from the plugins list if you
598
650
  CKEditor5::Rails.configure do
599
651
  # ... other configuration
600
652
 
601
- plugins do
602
- remove :Base64UploadAdapter
603
- end
653
+ automatic_upgrades enabled: false
604
654
  end
605
655
  ```
606
656
 
@@ -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
 
@@ -42,6 +42,7 @@ module CKEditor5::Rails::Presets
42
42
 
43
43
  def define_default_preset # rubocop:disable Metrics/MethodLength
44
44
  define :default do
45
+ automatic_upgrades
45
46
  gpl
46
47
  type :classic
47
48
  menubar
@@ -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: []
@@ -24,6 +25,19 @@ module CKEditor5::Rails
24
25
  instance_eval(&block) if block_given?
25
26
  end
26
27
 
28
+ def initialize_copy(source)
29
+ super
30
+
31
+ @translations = source.translations.dup
32
+ @ckbox = source.ckbox.dup if source.ckbox
33
+ @config = {
34
+ plugins: source.config[:plugins].map(&:dup),
35
+ toolbar: deep_copy_toolbar(source.config[:toolbar])
36
+ }.merge(
37
+ source.config.except(:plugins, :toolbar).deep_dup
38
+ )
39
+ end
40
+
27
41
  def premium?
28
42
  @premium
29
43
  end
@@ -92,7 +106,20 @@ module CKEditor5::Rails
92
106
  def version(version = nil)
93
107
  return @version.to_s if version.nil?
94
108
 
95
- @version = Semver.new(version)
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
96
123
  end
97
124
 
98
125
  def cdn(cdn = nil, &block)
@@ -174,12 +201,24 @@ module CKEditor5::Rails
174
201
 
175
202
  def simple_upload_adapter(upload_url = '/uploads')
176
203
  plugins do
177
- remove :Base64UploadAdapter
204
+ remove(:Base64UploadAdapter)
178
205
  end
179
206
 
180
207
  plugin(Plugins::SimpleUploadAdapter.new)
181
208
  configure(:simpleUpload, { uploadUrl: upload_url })
182
209
  end
210
+
211
+ private
212
+
213
+ def deep_copy_toolbar(toolbar)
214
+ return toolbar.dup if toolbar.is_a?(Array)
215
+ return {} if toolbar.nil?
216
+
217
+ {
218
+ items: toolbar[:items].dup,
219
+ shouldNotGroupWhenFull: toolbar[:shouldNotGroupWhenFull]
220
+ }
221
+ end
183
222
  end
184
223
  end
185
224
  end
@@ -1,18 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CKEditor5::Rails::Semver
4
- attr_reader :version
3
+ module CKEditor5
4
+ module Rails
5
+ class Semver
6
+ SEMVER_PATTERN = /\A\d+\.\d+\.\d+\z/
5
7
 
6
- alias to_s :version
8
+ attr_reader :major, :minor, :patch
7
9
 
8
- def initialize(version)
9
- @version = version.to_s
10
- validate!
11
- end
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
- private
41
+ def validate!(version_string)
42
+ return if version_string.is_a?(String) && version_string.match?(SEMVER_PATTERN)
14
43
 
15
- def validate!
16
- raise ArgumentError, 'invalid version format' unless version.match?(/\A\d+\.\d+\.\d+\z/)
44
+ raise ArgumentError, 'invalid version format'
45
+ end
46
+ end
17
47
  end
18
48
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CKEditor5
4
4
  module Rails
5
- VERSION = '1.14.0'
5
+ VERSION = '1.15.0'
6
6
  end
7
7
  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
@@ -3,6 +3,7 @@
3
3
  module CKEditor5
4
4
  module Rails
5
5
  require_relative 'rails/version'
6
+ require_relative 'rails/version_detector'
6
7
  require_relative 'rails/semver'
7
8
  require_relative 'rails/assets/assets_bundle'
8
9
  require_relative 'rails/assets/assets_bundle_html_serializer'
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.14.0
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Bagiński
@@ -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